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