зеркало из https://github.com/mozilla/gecko-dev.git
78 строки
2.6 KiB
GLSL
78 строки
2.6 KiB
GLSL
/* 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
|
|
|
|
in ivec4 aTargetRect;
|
|
in ivec2 aStencilOrigin;
|
|
in int aSubpixel;
|
|
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
|