CompositorD3D11.hlsl (7396B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "BlendShaderConstants.h" 7 8 typedef float4 rect; 9 10 float4x4 mLayerTransform : register(vs, c0); 11 float4x4 mProjection : register(vs, c4); 12 float4 vRenderTargetOffset : register(vs, c8); 13 rect vTextureCoords : register(vs, c9); 14 rect vLayerQuad : register(vs, c10); 15 float4 vRoundedClipRect : register(vs, c11); 16 17 float4 fLayerColor : register(ps, c0); 18 float fLayerOpacity : register(ps, c1); 19 20 // x = layer type 21 // y = mask type 22 // z = blend op 23 // w = is premultiplied 24 25 float fCoefficient : register(ps, c3); 26 27 float4 vRoundedClipRadii : register(ps, c4); 28 29 row_major float3x3 mYuvColorMatrix : register(ps, c5); 30 31 sampler sSampler : register(ps, s0); 32 33 // The mix-blend mega shader uses all variables, so we have to make sure they 34 // are assigned fixed slots. 35 Texture2D tRGB : register(ps, t0); 36 Texture2D tY : register(ps, t1); 37 Texture2D tCb : register(ps, t2); 38 Texture2D tCr : register(ps, t3); 39 40 struct VS_INPUT { 41 float2 vPosition : POSITION; 42 }; 43 44 struct VS_TEX_INPUT { 45 float2 vPosition : POSITION; 46 float2 vTexCoords : TEXCOORD0; 47 }; 48 49 struct VS_OUTPUT { 50 float4 vPosition : SV_Position; 51 float2 vTexCoords : TEXCOORD0; 52 }; 53 54 struct VS_CLIP_OUTPUT { 55 float4 vPosition : SV_Position; 56 float2 vTexCoords : TEXCOORD0; 57 float2 vRoundedClipSize : TEXCOORD1; 58 float2 vRoundedClipPos : TEXCOORD2; 59 }; 60 61 struct PS_OUTPUT { 62 float4 vSrc; 63 float4 vAlpha; 64 }; 65 66 float2 TexCoords(const float2 aPosition) 67 { 68 float2 result; 69 const float2 size = vTextureCoords.zw; 70 result.x = vTextureCoords.x + aPosition.x * size.x; 71 result.y = vTextureCoords.y + aPosition.y * size.y; 72 73 return result; 74 } 75 76 SamplerState LayerTextureSamplerLinear 77 { 78 Filter = MIN_MAG_MIP_LINEAR; 79 AddressU = Clamp; 80 AddressV = Clamp; 81 }; 82 83 float4 TransformedPosition(float2 aInPosition) 84 { 85 // the current vertex's position on the quad 86 // [x,y,0,1] is mandated by the CSS Transforms spec as the point value to transform 87 float4 position = float4(0, 0, 0, 1); 88 89 // We use 4 component floats to uniquely describe a rectangle, by the structure 90 // of x, y, width, height. This allows us to easily generate the 4 corners 91 // of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the 92 // stream source for our LayerQuad vertex shader. We do this by doing: 93 // Xout = x + Xin * width 94 // Yout = y + Yin * height 95 float2 size = vLayerQuad.zw; 96 position.x = vLayerQuad.x + aInPosition.x * size.x; 97 position.y = vLayerQuad.y + aInPosition.y * size.y; 98 99 position = mul(mLayerTransform, position); 100 101 return position; 102 } 103 104 float4 VertexPosition(float4 aTransformedPosition) 105 { 106 float4 result; 107 result.w = aTransformedPosition.w; 108 result.xyz = aTransformedPosition.xyz / aTransformedPosition.w; 109 result -= vRenderTargetOffset; 110 result.xyz *= result.w; 111 112 result = mul(mProjection, result); 113 114 return result; 115 } 116 117 VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex) 118 { 119 VS_OUTPUT outp; 120 float4 position = TransformedPosition(aVertex.vPosition); 121 122 outp.vPosition = VertexPosition(position); 123 outp.vTexCoords = TexCoords(aVertex.vPosition.xy); 124 125 return outp; 126 } 127 128 VS_CLIP_OUTPUT LayerQuadClipVS(const VS_INPUT aVertex) 129 { 130 VS_CLIP_OUTPUT outp; 131 float4 position = TransformedPosition(aVertex.vPosition); 132 133 outp.vPosition = VertexPosition(position); 134 outp.vTexCoords = TexCoords(aVertex.vPosition.xy); 135 136 float2 halfSize = 0.5 * vRoundedClipRect.zw; 137 outp.vRoundedClipPos = vRoundedClipRect.xy + halfSize - position.xy; 138 outp.vRoundedClipSize = halfSize; 139 140 return outp; 141 } 142 143 /* From Rec601: 144 [R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16] 145 [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128] 146 [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128] 147 148 For [0,1] instead of [0,255], and to 5 places: 149 [R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275] 150 [G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196] 151 [B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196] 152 153 From Rec709: 154 [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16] 155 [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128] 156 [B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128] 157 158 For [0,1] instead of [0,255], and to 5 places: 159 [R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275] 160 [G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196] 161 [B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196] 162 */ 163 float4 CalculateYCbCrColor(const float2 aTexCoords) 164 { 165 float3 yuv = float3( 166 tY.Sample(sSampler, aTexCoords).r, 167 tCb.Sample(sSampler, aTexCoords).r, 168 tCr.Sample(sSampler, aTexCoords).r); 169 yuv = yuv * fCoefficient - float3(0.06275, 0.50196, 0.50196); 170 171 return float4(mul(mYuvColorMatrix, yuv), 1.0); 172 } 173 174 float4 CalculateNV12Color(const float2 aTexCoords) 175 { 176 float3 yuv = float3( 177 tY.Sample(sSampler, aTexCoords).r, 178 tCb.Sample(sSampler, aTexCoords).r, 179 tCb.Sample(sSampler, aTexCoords).g); 180 yuv = yuv * fCoefficient - float3(0.06275, 0.50196, 0.50196); 181 182 return float4(mul(mYuvColorMatrix, yuv), 1.0); 183 } 184 185 float SignedDistRoundBox(float2 pos, float2 half_box_size, float4 radii) { 186 radii.xy = (pos.x > 0.0) ? radii.xy : radii.zw; 187 radii.x = (pos.y > 0.0) ? radii.x : radii.y; 188 float2 q = abs(pos) - half_box_size + radii.x; 189 return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radii.x; 190 } 191 192 float CalculateClip(const float2 aPosition, const float2 aHalfBoxSize) 193 { 194 float d = SignedDistRoundBox(aPosition, aHalfBoxSize, vRoundedClipRadii); 195 // TODO(gw): Probably want some proper AA step here 196 return 1.0 - clamp(d, 0.0, 1.0); 197 } 198 199 float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target 200 { 201 return fLayerColor; 202 } 203 204 float4 RGBAShader(const VS_OUTPUT aVertex) : SV_Target 205 { 206 return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity; 207 } 208 209 float4 RGBAClipShader(const VS_CLIP_OUTPUT aVertex) : SV_Target 210 { 211 return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * CalculateClip(aVertex.vRoundedClipPos, aVertex.vRoundedClipSize); 212 } 213 214 float4 RGBShader(const VS_OUTPUT aVertex) : SV_Target 215 { 216 float4 result; 217 result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity; 218 result.a = fLayerOpacity; 219 return result; 220 } 221 222 float4 RGBClipShader(const VS_CLIP_OUTPUT aVertex) : SV_Target 223 { 224 float4 result; 225 float a = fLayerOpacity * CalculateClip(aVertex.vRoundedClipPos, aVertex.vRoundedClipSize); 226 result = tRGB.Sample(sSampler, aVertex.vTexCoords) * a; 227 result.a = a; 228 return result; 229 } 230 231 float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target 232 { 233 return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity; 234 } 235 236 float4 YCbCrClipShader(const VS_CLIP_OUTPUT aVertex) : SV_Target 237 { 238 return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * CalculateClip(aVertex.vRoundedClipPos, aVertex.vRoundedClipSize); 239 } 240 241 float4 NV12Shader(const VS_OUTPUT aVertex) : SV_Target 242 { 243 return CalculateNV12Color(aVertex.vTexCoords) * fLayerOpacity; 244 } 245 246 float4 NV12ClipShader(const VS_CLIP_OUTPUT aVertex) : SV_Target 247 { 248 return CalculateNV12Color(aVertex.vTexCoords) * fLayerOpacity * CalculateClip(aVertex.vRoundedClipPos, aVertex.vRoundedClipSize); 249 }