Bug 1705433 - Pack more varyings in vectors to work around Adreno 3xx bug. r=kvark
[gecko.git] / gfx / wr / webrender / res / cs_clip_box_shadow.glsl
blobc73026c3218f0a5aef96099141f212262c9e8d3f
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include shared,clip_shared
7 varying vec4 vLocalPos;
8 varying vec2 vUv;
9 flat varying vec4 vUvBounds;
10 flat varying vec4 vEdge;
11 flat varying vec4 vUvBounds_NoClamp;
12 #if defined(PLATFORM_ANDROID) && !defined(SWGL)
13 // Work around Adreno 3xx driver bug. See the v_perspective comment in
14 // brush_image or bug 1630356 for details.
15 flat varying vec2 vClipModeVec;
16 #define vClipMode vClipModeVec.x
17 #else
18 flat varying float vClipMode;
19 #endif
21 #define MODE_STRETCH        0
22 #define MODE_SIMPLE         1
24 #ifdef WR_VERTEX_SHADER
26 PER_INSTANCE in ivec2 aClipDataResourceAddress;
27 PER_INSTANCE in vec2 aClipSrcRectSize;
28 PER_INSTANCE in int aClipMode;
29 PER_INSTANCE in ivec2 aStretchMode;
30 PER_INSTANCE in vec4 aClipDestRect;
32 struct ClipMaskInstanceBoxShadow {
33     ClipMaskInstanceCommon base;
34     ivec2 resource_address;
37 ClipMaskInstanceBoxShadow fetch_clip_item() {
38     ClipMaskInstanceBoxShadow cmi;
40     cmi.base = fetch_clip_item_common();
41     cmi.resource_address = aClipDataResourceAddress;
43     return cmi;
46 struct BoxShadowData {
47     vec2 src_rect_size;
48     int clip_mode;
49     int stretch_mode_x;
50     int stretch_mode_y;
51     RectWithSize dest_rect;
54 BoxShadowData fetch_data() {
55     BoxShadowData bs_data = BoxShadowData(
56         aClipSrcRectSize,
57         aClipMode,
58         aStretchMode.x,
59         aStretchMode.y,
60         RectWithSize(aClipDestRect.xy, aClipDestRect.zw)
61     );
62     return bs_data;
65 void main(void) {
66     ClipMaskInstanceBoxShadow cmi = fetch_clip_item();
67     Transform clip_transform = fetch_transform(cmi.base.clip_transform_id);
68     Transform prim_transform = fetch_transform(cmi.base.prim_transform_id);
69     BoxShadowData bs_data = fetch_data();
70     ImageSource res = fetch_image_source_direct(cmi.resource_address);
72     RectWithSize dest_rect = bs_data.dest_rect;
74     ClipVertexInfo vi = write_clip_tile_vertex(
75         dest_rect,
76         prim_transform,
77         clip_transform,
78         cmi.base.sub_rect,
79         cmi.base.task_origin,
80         cmi.base.screen_origin,
81         cmi.base.device_pixel_scale
82     );
83     vClipMode = float(bs_data.clip_mode);
85     vec2 texture_size = vec2(TEX_SIZE(sColor0));
86     vec2 local_pos = vi.local_pos.xy / vi.local_pos.w;
87     vLocalPos = vi.local_pos;
89     switch (bs_data.stretch_mode_x) {
90         case MODE_STRETCH: {
91             vEdge.x = 0.5;
92             vEdge.z = (dest_rect.size.x / bs_data.src_rect_size.x) - 0.5;
93             vUv.x = (local_pos.x - dest_rect.p0.x) / bs_data.src_rect_size.x;
94             break;
95         }
96         case MODE_SIMPLE:
97         default: {
98             vEdge.xz = vec2(1.0);
99             vUv.x = (local_pos.x - dest_rect.p0.x) / dest_rect.size.x;
100             break;
101         }
102     }
104     switch (bs_data.stretch_mode_y) {
105         case MODE_STRETCH: {
106             vEdge.y = 0.5;
107             vEdge.w = (dest_rect.size.y / bs_data.src_rect_size.y) - 0.5;
108             vUv.y = (local_pos.y - dest_rect.p0.y) / bs_data.src_rect_size.y;
109             break;
110         }
111         case MODE_SIMPLE:
112         default: {
113             vEdge.yw = vec2(1.0);
114             vUv.y = (local_pos.y - dest_rect.p0.y) / dest_rect.size.y;
115             break;
116         }
117     }
119     vUv *= vi.local_pos.w;
120     vec2 uv0 = res.uv_rect.p0;
121     vec2 uv1 = res.uv_rect.p1;
122     vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
123     vUvBounds_NoClamp = vec4(uv0, uv1) / texture_size.xyxy;
125 #endif
127 #ifdef WR_FRAGMENT_SHADER
128 void main(void) {
129     vec2 uv_linear = vUv / vLocalPos.w;
130     vec2 uv = clamp(uv_linear, vec2(0.0), vEdge.xy);
131     uv += max(vec2(0.0), uv_linear - vEdge.zw);
132     uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv);
133     uv = clamp(uv, vUvBounds.xy, vUvBounds.zw);
135     float in_shadow_rect = init_transform_rough_fs(vLocalPos.xy / vLocalPos.w);
137     float texel = TEX_SAMPLE(sColor0, uv).r;
139     float alpha = mix(texel, 1.0 - texel, vClipMode);
140     float result = vLocalPos.w > 0.0 ? mix(vClipMode, alpha, in_shadow_rect) : 0.0;
142     oFragColor = vec4(result);
144 #endif