tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }