aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/webrender/webrender/res/pf_vector_cover.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrender/webrender/res/pf_vector_cover.glsl')
-rw-r--r--third_party/webrender/webrender/res/pf_vector_cover.glsl77
1 files changed, 77 insertions, 0 deletions
diff --git a/third_party/webrender/webrender/res/pf_vector_cover.glsl b/third_party/webrender/webrender/res/pf_vector_cover.glsl
new file mode 100644
index 00000000000..1b2eeabb7dc
--- /dev/null
+++ b/third_party/webrender/webrender/res/pf_vector_cover.glsl
@@ -0,0 +1,77 @@
+/* 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/. */
+
+#include shared
+
+#ifdef WR_VERTEX_SHADER
+
+PER_INSTANCE in ivec4 aTargetRect;
+PER_INSTANCE in ivec2 aStencilOrigin;
+PER_INSTANCE in int aSubpixel;
+PER_INSTANCE in int aPad;
+
+out vec2 vStencilUV;
+flat out int vSubpixel;
+
+void main(void) {
+ vec4 targetRect = vec4(aTargetRect);
+ vec2 stencilOrigin = vec2(aStencilOrigin);
+
+ vec2 targetOffset = mix(vec2(0.0), targetRect.zw, aPosition.xy);
+ vec2 targetPosition = targetRect.xy + targetOffset;
+ vec2 stencilOffset = targetOffset * vec2(aSubpixel == 0 ? 1.0 : 3.0, 1.0);
+ vec2 stencilPosition = stencilOrigin + stencilOffset;
+
+ gl_Position = uTransform * vec4(targetPosition, aPosition.z, 1.0);
+ vStencilUV = stencilPosition;
+ vSubpixel = aSubpixel;
+}
+
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+
+#define LCD_FILTER_FACTOR_0 (86.0 / 255.0)
+#define LCD_FILTER_FACTOR_1 (77.0 / 255.0)
+#define LCD_FILTER_FACTOR_2 (8.0 / 255.0)
+
+in vec2 vStencilUV;
+flat in int vSubpixel;
+
+/// Applies a slight horizontal blur to reduce color fringing on LCD screens
+/// when performing subpixel AA.
+///
+/// The algorithm should be identical to that of FreeType:
+/// https://www.freetype.org/freetype2/docs/reference/ft2-lcd_filtering.html
+float lcdFilter(float shadeL2, float shadeL1, float shade0, float shadeR1, float shadeR2) {
+ return LCD_FILTER_FACTOR_2 * shadeL2 +
+ LCD_FILTER_FACTOR_1 * shadeL1 +
+ LCD_FILTER_FACTOR_0 * shade0 +
+ LCD_FILTER_FACTOR_1 * shadeR1 +
+ LCD_FILTER_FACTOR_2 * shadeR2;
+}
+
+void main(void) {
+ ivec2 stencilUV = ivec2(vStencilUV);
+ float shade0 = abs(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(0, 0)).r);
+
+ if (vSubpixel == 0) {
+ oFragColor = vec4(shade0);
+ return;
+ }
+
+ vec3 shadeL = abs(vec3(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-1, 0)).r,
+ TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-2, 0)).r,
+ TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-3, 0)).r));
+ vec3 shadeR = abs(vec3(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(1, 0)).r,
+ TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(2, 0)).r,
+ TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(3, 0)).r));
+
+ oFragColor = vec4(lcdFilter(shadeL.z, shadeL.y, shadeL.x, shade0, shadeR.x),
+ lcdFilter(shadeL.y, shadeL.x, shade0, shadeR.x, shadeR.y),
+ lcdFilter(shadeL.x, shade0, shadeR.x, shadeR.y, shadeR.z),
+ 1.0);
+}
+
+#endif