Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / gfx / wr / webrender / res / shared.glsl
blobdc1b9ea2e1471040d163155c4eb31771e945023c
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 #ifdef WR_FEATURE_TEXTURE_EXTERNAL
6 // Please check https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
7 // for this extension.
8 #extension GL_OES_EGL_image_external_essl3 : require
9 #endif
11 #ifdef WR_FEATURE_TEXTURE_EXTERNAL_ESSL1
12 // Some GLES 3 devices do not support GL_OES_EGL_image_external_essl3, so we
13 // must use GL_OES_EGL_image_external instead and make the shader ESSL1
14 // compatible.
15 #extension GL_OES_EGL_image_external : require
16 #endif
18 #ifdef WR_FEATURE_TEXTURE_EXTERNAL_BT709
19 #extension GL_EXT_YUV_target : require
20 #endif
22 #ifdef WR_FEATURE_ADVANCED_BLEND
23 #extension GL_KHR_blend_equation_advanced : require
24 #endif
26 #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
27 #ifdef GL_ES
28 #extension GL_EXT_blend_func_extended : require
29 #else
30 #extension GL_ARB_explicit_attrib_location : require
31 #endif
32 #endif
34 #include base
36 #if defined(WR_FEATURE_TEXTURE_EXTERNAL_ESSL1)
37 #define TEX_SAMPLE(sampler, tex_coord) texture2D(sampler, tex_coord.xy)
38 #elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
39 // Force conversion from yuv to rgb using BT709 colorspace
40 #define TEX_SAMPLE(sampler, tex_coord) vec4(yuv_2_rgb(texture(sampler, tex_coord.xy).xyz, itu_709), 1.0)
41 #else
42 #define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
43 #endif
45 #if defined(WR_FEATURE_TEXTURE_EXTERNAL) && defined(PLATFORM_ANDROID)
46 // On some Mali GPUs we have encountered crashes in glDrawElements when using
47 // textureSize(samplerExternalOES) in a vertex shader without potentially
48 // sampling from the texture. This tricks the driver in to thinking the texture
49 // may be sampled from, avoiding the crash. See bug 1692848.
50 uniform bool u_mali_workaround_dummy;
51 #define TEX_SIZE(sampler) (u_mali_workaround_dummy ? ivec2(texture(sampler, vec2(0.0, 0.0)).rr) : textureSize(sampler, 0))
52 #else
53 #define TEX_SIZE(sampler) textureSize(sampler, 0)
54 #endif
56 //======================================================================================
57 // Vertex shader attributes and uniforms
58 //======================================================================================
59 #ifdef WR_VERTEX_SHADER
60     // Uniform inputs
61     uniform mat4 uTransform;       // Orthographic projection
63     // Attribute inputs
64     attribute vec2 aPosition;
66     // get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
67     // TODO: convert back to a function once the driver issues are resolved, if ever.
68     // https://github.com/servo/webrender/pull/623
69     // https://github.com/servo/servo/issues/13953
70     // Do the division with unsigned ints because that's more efficient with D3D
71     #define get_fetch_uv(i, vpi)  ivec2(int(vpi * (uint(i) % (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi))), int(uint(i) / (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi)))
72 #endif
74 //======================================================================================
75 // Fragment shader attributes and uniforms
76 //======================================================================================
77 #ifdef WR_FRAGMENT_SHADER
78     // Uniform inputs
80     // Fragment shader outputs
81     #ifdef WR_FEATURE_ADVANCED_BLEND
82         layout(blend_support_all_equations) out;
83     #endif
85     #if __VERSION__ == 100
86         #define oFragColor gl_FragColor
87     #elif defined(WR_FEATURE_DUAL_SOURCE_BLENDING)
88         layout(location = 0, index = 0) out vec4 oFragColor;
89         layout(location = 0, index = 1) out vec4 oFragBlend;
90     #else
91         out vec4 oFragColor;
92     #endif
94     // Write an output color in normal shaders.
95     void write_output(vec4 color) {
96         oFragColor = color;
97     }
99     #define EPSILON                     0.0001
101     // "Show Overdraw" color. Premultiplied.
102     #define WR_DEBUG_OVERDRAW_COLOR     vec4(0.110, 0.077, 0.027, 0.125)
104     float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
105         vec2 dir_to_p0 = p0 - p;
106         return dot(normalize(perp_dir), dir_to_p0);
107     }
109 // fwidth is not defined in ESSL 1, but that's okay because we don't need
110 // it for any ESSL 1 shader variants.
111 #if __VERSION__ != 100
112     /// Find the appropriate half range to apply the AA approximation over.
113     /// This range represents a coefficient to go from one CSS pixel to half a device pixel.
114     vec2 compute_aa_range_xy(vec2 position) {
115         return fwidth(position);
116     }
118     float compute_aa_range(vec2 position) {
119         // The constant factor is chosen to compensate for the fact that length(fw) is equal
120         // to sqrt(2) times the device pixel ratio in the typical case.
121         //
122         // This coefficient is chosen to ensure that any sample 0.5 pixels or more inside of
123         // the shape has no anti-aliasing applied to it (since pixels are sampled at their center,
124         // such a pixel (axis aligned) is fully inside the border). We need this so that antialiased
125         // curves properly connect with non-antialiased vertical or horizontal lines, among other things.
126         //
127         // Lines over a half-pixel away from the pixel center *can* intersect with the pixel square;
128         // indeed, unless they are horizontal or vertical, they are guaranteed to. However, choosing
129         // a nonzero area for such pixels causes noticeable artifacts at the junction between an anti-
130         // aliased corner and a straight edge.
131         //
132         // We may want to adjust this constant in specific scenarios (for example keep the principled
133         // value for straight edges where we want pixel-perfect equivalence with non antialiased lines
134         // when axis aligned, while selecting a larger and smoother aa range on curves).
135         //
136         // As a further optimization, we compute the reciprocal of this range, such that we
137         // can then use the cheaper inversesqrt() instead of length(). This also elides a
138         // division that would otherwise be necessary inside distance_aa.
139         #ifdef SWGL
140             // SWGL uses an approximation for fwidth() such that it returns equal x and y.
141             // Thus, sqrt(2)/length(w) = sqrt(2)/sqrt(x*x + x*x) = recip(x).
142             return recip(fwidth(position).x);
143         #else
144             // sqrt(2)/length(w) = inversesqrt(0.5 * dot(w, w))
145             vec2 w = fwidth(position);
146             return inversesqrt(0.5 * dot(w, w));
147         #endif
148     }
149 #endif
151     /// Return the blending coefficient for distance antialiasing.
152     ///
153     /// 0.0 means inside the shape, 1.0 means outside.
154     ///
155     /// This makes the simplifying assumption that the area of a 1x1 pixel square
156     /// under a line is reasonably similar to just the signed Euclidian distance
157     /// from the center of the square to that line. This diverges slightly from
158     /// better approximations of the exact area, but the difference between the
159     /// methods is not perceptibly noticeable, while this approximation is much
160     /// faster to compute.
161     ///
162     /// See the comments in `compute_aa_range()` for more information on the
163     /// cutoff values of -0.5 and 0.5.
164     float distance_aa_xy(vec2 aa_range, vec2 signed_distance) {
165         // The aa_range is the raw per-axis filter width, so we need to divide
166         // the local signed distance by the filter width to get an approximation
167         // of screen distance.
168         #ifdef SWGL
169             // The SWGL fwidth() approximation returns uniform X and Y ranges.
170             vec2 dist = signed_distance * recip(aa_range.x);
171         #else
172             vec2 dist = signed_distance / aa_range;
173         #endif
174         // Choose whichever axis is further outside the rectangle for AA.
175         return clamp(0.5 - max(dist.x, dist.y), 0.0, 1.0);
176     }
178     float distance_aa(float aa_range, float signed_distance) {
179         // The aa_range is already stored as a reciprocal with uniform scale,
180         // so just multiply it, then use that for AA.
181         float dist = signed_distance * aa_range;
182         return clamp(0.5 - dist, 0.0, 1.0);
183     }
185     /// Component-wise selection.
186     ///
187     /// The idea of using this is to ensure both potential branches are executed before
188     /// selecting the result, to avoid observable timing differences based on the condition.
189     ///
190     /// Example usage: color = if_then_else(LessThanEqual(color, vec3(0.5)), vec3(0.0), vec3(1.0));
191     ///
192     /// The above example sets each component to 0.0 or 1.0 independently depending on whether
193     /// their values are below or above 0.5.
194     ///
195     /// This is written as a macro in order to work with vectors of any dimension.
196     ///
197     /// Note: Some older android devices don't support mix with bvec. If we ever run into them
198     /// the only option we have is to polyfill it with a branch per component.
199     #define if_then_else(cond, then_branch, else_branch) mix(else_branch, then_branch, cond)
200 #endif
202 //======================================================================================
203 // Shared shader uniforms
204 //======================================================================================
205 #ifdef WR_FEATURE_TEXTURE_2D
206 uniform sampler2D sColor0;
207 uniform sampler2D sColor1;
208 uniform sampler2D sColor2;
209 #elif defined WR_FEATURE_TEXTURE_RECT
210 uniform sampler2DRect sColor0;
211 uniform sampler2DRect sColor1;
212 uniform sampler2DRect sColor2;
213 #elif defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_EXTERNAL_ESSL1)
214 uniform samplerExternalOES sColor0;
215 uniform samplerExternalOES sColor1;
216 uniform samplerExternalOES sColor2;
217 #elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
218 uniform __samplerExternal2DY2YEXT sColor0;
219 uniform __samplerExternal2DY2YEXT sColor1;
220 uniform __samplerExternal2DY2YEXT sColor2;
221 #endif
223 #ifdef WR_FEATURE_DITHERING
224 uniform sampler2D sDither;
225 #endif
227 //======================================================================================
228 // Interpolator definitions
229 //======================================================================================
231 //======================================================================================
232 // VS only types and UBOs
233 //======================================================================================
235 //======================================================================================
236 // VS only functions
237 //======================================================================================