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/. */ 4 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 10 11#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING 12#extension GL_ARB_explicit_attrib_location : require 13#endif 14 15#include base 16 17#if defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_RECT) || defined(WR_FEATURE_TEXTURE_2D) 18#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy) 19#else 20#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord) 21#endif 22 23//====================================================================================== 24// Vertex shader attributes and uniforms 25//====================================================================================== 26#ifdef WR_VERTEX_SHADER 27 // A generic uniform that shaders can optionally use to configure 28 // an operation mode for this batch. 29 uniform int uMode; 30 31 // Uniform inputs 32 uniform mat4 uTransform; // Orthographic projection 33 34 // Attribute inputs 35 in vec3 aPosition; 36 37 // get_fetch_uv is a macro to work around a macOS Intel driver parsing bug. 38 // TODO: convert back to a function once the driver issues are resolved, if ever. 39 // https://github.com/servo/webrender/pull/623 40 // https://github.com/servo/servo/issues/13953 41 // Do the division with unsigned ints because that's more efficient with D3D 42 #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))) 43#endif 44 45//====================================================================================== 46// Fragment shader attributes and uniforms 47//====================================================================================== 48#ifdef WR_FRAGMENT_SHADER 49 // Uniform inputs 50 51 // Fragment shader outputs 52 #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING 53 layout(location = 0, index = 0) out vec4 oFragColor; 54 layout(location = 0, index = 1) out vec4 oFragBlend; 55 #else 56 out vec4 oFragColor; 57 #endif 58 59 #define EPSILON 0.0001 60 61 // "Show Overdraw" color. Premultiplied. 62 #define WR_DEBUG_OVERDRAW_COLOR vec4(0.110, 0.077, 0.027, 0.125) 63 64 float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) { 65 vec2 dir_to_p0 = p0 - p; 66 return dot(normalize(perp_dir), dir_to_p0); 67 } 68 69 /// Find the appropriate half range to apply the AA approximation over. 70 /// This range represents a coefficient to go from one CSS pixel to half a device pixel. 71 float compute_aa_range(vec2 position) { 72 // The constant factor is chosen to compensate for the fact that length(fw) is equal 73 // to sqrt(2) times the device pixel ratio in the typical case. 0.5/sqrt(2) = 0.35355. 74 // 75 // This coefficient is chosen to ensure that any sample 0.5 pixels or more inside of 76 // the shape has no anti-aliasing applied to it (since pixels are sampled at their center, 77 // such a pixel (axis aligned) is fully inside the border). We need this so that antialiased 78 // curves properly connect with non-antialiased vertical or horizontal lines, among other things. 79 // 80 // Lines over a half-pixel away from the pixel center *can* intersect with the pixel square; 81 // indeed, unless they are horizontal or vertical, they are guaranteed to. However, choosing 82 // a nonzero area for such pixels causes noticeable artifacts at the junction between an anti- 83 // aliased corner and a straight edge. 84 // 85 // We may want to adjust this constant in specific scenarios (for example keep the principled 86 // value for straight edges where we want pixel-perfect equivalence with non antialiased lines 87 // when axis aligned, while selecting a larger and smoother aa range on curves). 88 return 0.35355 * length(fwidth(position)); 89 } 90 91 /// Return the blending coefficient for distance antialiasing. 92 /// 93 /// 0.0 means inside the shape, 1.0 means outside. 94 /// 95 /// This cubic polynomial approximates the area of a 1x1 pixel square under a 96 /// line, given the signed Euclidean distance from the center of the square to 97 /// that line. Calculating the *exact* area would require taking into account 98 /// not only this distance but also the angle of the line. However, in 99 /// practice, this complexity is not required, as the area is roughly the same 100 /// regardless of the angle. 101 /// 102 /// The coefficients of this polynomial were determined through least-squares 103 /// regression and are accurate to within 2.16% of the total area of the pixel 104 /// square 95% of the time, with a maximum error of 3.53%. 105 /// 106 /// See the comments in `compute_aa_range()` for more information on the 107 /// cutoff values of -0.5 and 0.5. 108 float distance_aa(float aa_range, float signed_distance) { 109 float dist = 0.5 * signed_distance / aa_range; 110 if (dist <= -0.5 + EPSILON) 111 return 1.0; 112 if (dist >= 0.5 - EPSILON) 113 return 0.0; 114 return 0.5 + dist * (0.8431027 * dist * dist - 1.14453603); 115 } 116 117 /// Component-wise selection. 118 /// 119 /// The idea of using this is to ensure both potential branches are executed before 120 /// selecting the result, to avoid observable timing differences based on the condition. 121 /// 122 /// Example usage: color = if_then_else(LessThanEqual(color, vec3(0.5)), vec3(0.0), vec3(1.0)); 123 /// 124 /// The above example sets each component to 0.0 or 1.0 independently depending on whether 125 /// their values are below or above 0.5. 126 /// 127 /// This is written as a macro in order to work with vectors of any dimension. 128 /// 129 /// Note: Some older android devices don't support mix with bvec. If we ever run into them 130 /// the only option we have is to polyfill it with a branch per component. 131 #define if_then_else(cond, then_branch, else_branch) mix(else_branch, then_branch, cond) 132#endif 133 134//====================================================================================== 135// Shared shader uniforms 136//====================================================================================== 137#ifdef WR_FEATURE_TEXTURE_2D 138uniform sampler2D sColor0; 139uniform sampler2D sColor1; 140uniform sampler2D sColor2; 141#elif defined WR_FEATURE_TEXTURE_RECT 142uniform sampler2DRect sColor0; 143uniform sampler2DRect sColor1; 144uniform sampler2DRect sColor2; 145#elif defined WR_FEATURE_TEXTURE_EXTERNAL 146uniform samplerExternalOES sColor0; 147uniform samplerExternalOES sColor1; 148uniform samplerExternalOES sColor2; 149#else 150uniform sampler2DArray sColor0; 151uniform sampler2DArray sColor1; 152uniform sampler2DArray sColor2; 153#endif 154 155#ifdef WR_FEATURE_DITHERING 156uniform sampler2D sDither; 157#endif 158 159//====================================================================================== 160// Interpolator definitions 161//====================================================================================== 162 163//====================================================================================== 164// VS only types and UBOs 165//====================================================================================== 166 167//====================================================================================== 168// VS only functions 169//====================================================================================== 170