summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/res/shared.glsl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/wr/webrender/res/shared.glsl192
1 files changed, 192 insertions, 0 deletions
diff --git a/gfx/wr/webrender/res/shared.glsl b/gfx/wr/webrender/res/shared.glsl
new file mode 100644
index 0000000000..b784d528e6
--- /dev/null
+++ b/gfx/wr/webrender/res/shared.glsl
@@ -0,0 +1,192 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef WR_FEATURE_TEXTURE_EXTERNAL
+// Please check https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
+// for this extension.
+#extension GL_OES_EGL_image_external_essl3 : require
+#endif
+
+#ifdef WR_FEATURE_ADVANCED_BLEND
+#extension GL_KHR_blend_equation_advanced : require
+#endif
+
+#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
+#ifdef GL_ES
+#extension GL_EXT_blend_func_extended : require
+#else
+#extension GL_ARB_explicit_attrib_location : require
+#endif
+#endif
+
+#include base
+
+#if defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_RECT) || defined(WR_FEATURE_TEXTURE_2D)
+#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
+#else
+#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord)
+#endif
+
+//======================================================================================
+// Vertex shader attributes and uniforms
+//======================================================================================
+#ifdef WR_VERTEX_SHADER
+ // A generic uniform that shaders can optionally use to configure
+ // an operation mode for this batch.
+ uniform int uMode;
+
+ // Uniform inputs
+ uniform mat4 uTransform; // Orthographic projection
+
+ // Attribute inputs
+ in vec2 aPosition;
+
+ // get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
+ // TODO: convert back to a function once the driver issues are resolved, if ever.
+ // https://github.com/servo/webrender/pull/623
+ // https://github.com/servo/servo/issues/13953
+ // Do the division with unsigned ints because that's more efficient with D3D
+ #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)))
+#endif
+
+//======================================================================================
+// Fragment shader attributes and uniforms
+//======================================================================================
+#ifdef WR_FRAGMENT_SHADER
+ // Uniform inputs
+
+ // Fragment shader outputs
+ #ifdef WR_FEATURE_ADVANCED_BLEND
+ layout(blend_support_all_equations) out;
+ #endif
+
+ #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
+ layout(location = 0, index = 0) out vec4 oFragColor;
+ layout(location = 0, index = 1) out vec4 oFragBlend;
+ #else
+ out vec4 oFragColor;
+ #endif
+
+ // Write an output color in normal shaders.
+ void write_output(vec4 color) {
+ oFragColor = color;
+ }
+
+ #define EPSILON 0.0001
+
+ // "Show Overdraw" color. Premultiplied.
+ #define WR_DEBUG_OVERDRAW_COLOR vec4(0.110, 0.077, 0.027, 0.125)
+
+ float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
+ vec2 dir_to_p0 = p0 - p;
+ return dot(normalize(perp_dir), dir_to_p0);
+ }
+
+ /// Find the appropriate half range to apply the AA approximation over.
+ /// This range represents a coefficient to go from one CSS pixel to half a device pixel.
+ float compute_aa_range(vec2 position) {
+ // The constant factor is chosen to compensate for the fact that length(fw) is equal
+ // to sqrt(2) times the device pixel ratio in the typical case. 1/sqrt(2) = 0.7071.
+ //
+ // This coefficient is chosen to ensure that any sample 0.5 pixels or more inside of
+ // the shape has no anti-aliasing applied to it (since pixels are sampled at their center,
+ // such a pixel (axis aligned) is fully inside the border). We need this so that antialiased
+ // curves properly connect with non-antialiased vertical or horizontal lines, among other things.
+ //
+ // Lines over a half-pixel away from the pixel center *can* intersect with the pixel square;
+ // indeed, unless they are horizontal or vertical, they are guaranteed to. However, choosing
+ // a nonzero area for such pixels causes noticeable artifacts at the junction between an anti-
+ // aliased corner and a straight edge.
+ //
+ // We may want to adjust this constant in specific scenarios (for example keep the principled
+ // value for straight edges where we want pixel-perfect equivalence with non antialiased lines
+ // when axis aligned, while selecting a larger and smoother aa range on curves).
+ #ifdef SWGL
+ // SWGL uses an approximation for fwidth() such that it returns equal x and y.
+ // Thus, 1/sqrt(2) * length((x,y)) = 1/sqrt(2) * sqrt(x*x + x*x) = x.
+ return fwidth(position).x;
+ #else
+ return 0.7071 * length(fwidth(position));
+ #endif
+ }
+
+ /// Return the blending coefficient for distance antialiasing.
+ ///
+ /// 0.0 means inside the shape, 1.0 means outside.
+ ///
+ /// This cubic polynomial approximates the area of a 1x1 pixel square under a
+ /// line, given the signed Euclidean distance from the center of the square to
+ /// that line. Calculating the *exact* area would require taking into account
+ /// not only this distance but also the angle of the line. However, in
+ /// practice, this complexity is not required, as the area is roughly the same
+ /// regardless of the angle.
+ ///
+ /// The coefficients of this polynomial were determined through least-squares
+ /// regression and are accurate to within 2.16% of the total area of the pixel
+ /// square 95% of the time, with a maximum error of 3.53%.
+ ///
+ /// See the comments in `compute_aa_range()` for more information on the
+ /// cutoff values of -0.5 and 0.5.
+ float distance_aa(float aa_range, float signed_distance) {
+ float dist = signed_distance / aa_range;
+ bool inside = dist <= -0.5 + EPSILON;
+ bool outside = dist >= 0.5 - EPSILON;
+ return inside || outside
+ ? float(inside)
+ : 0.5 + dist * (0.8431027 * dist * dist - 1.14453603);
+ }
+
+ /// Component-wise selection.
+ ///
+ /// The idea of using this is to ensure both potential branches are executed before
+ /// selecting the result, to avoid observable timing differences based on the condition.
+ ///
+ /// Example usage: color = if_then_else(LessThanEqual(color, vec3(0.5)), vec3(0.0), vec3(1.0));
+ ///
+ /// The above example sets each component to 0.0 or 1.0 independently depending on whether
+ /// their values are below or above 0.5.
+ ///
+ /// This is written as a macro in order to work with vectors of any dimension.
+ ///
+ /// Note: Some older android devices don't support mix with bvec. If we ever run into them
+ /// the only option we have is to polyfill it with a branch per component.
+ #define if_then_else(cond, then_branch, else_branch) mix(else_branch, then_branch, cond)
+#endif
+
+//======================================================================================
+// Shared shader uniforms
+//======================================================================================
+#ifdef WR_FEATURE_TEXTURE_2D
+uniform sampler2D sColor0;
+uniform sampler2D sColor1;
+uniform sampler2D sColor2;
+#elif defined WR_FEATURE_TEXTURE_RECT
+uniform sampler2DRect sColor0;
+uniform sampler2DRect sColor1;
+uniform sampler2DRect sColor2;
+#elif defined WR_FEATURE_TEXTURE_EXTERNAL
+uniform samplerExternalOES sColor0;
+uniform samplerExternalOES sColor1;
+uniform samplerExternalOES sColor2;
+#elif defined WR_FEATURE_TEXTURE_2D_ARRAY
+uniform sampler2DArray sColor0;
+uniform sampler2DArray sColor1;
+uniform sampler2DArray sColor2;
+#endif
+
+#ifdef WR_FEATURE_DITHERING
+uniform sampler2D sDither;
+#endif
+
+//======================================================================================
+// Interpolator definitions
+//======================================================================================
+
+//======================================================================================
+// VS only types and UBOs
+//======================================================================================
+
+//======================================================================================
+// VS only functions
+//======================================================================================