Bug 1700434 - Implement faster subpixel text blend mode for SWGL. r=jrmuizel

This adds a swgl_blendSubpixelText() extension that enables us to move some
of the complexity of plumbing dual-source blending out of the shader for
subpixel text. This will enable further speed-ups later by allowing us to use
swgl_commitTexture.

Differential Revision: https://phabricator.services.mozilla.com/D115456
This commit is contained in:
Lee Salzman 2021-05-21 06:52:11 +00:00
Родитель ed1d421ba9
Коммит f9e08d3c30
7 изменённых файлов: 37 добавлений и 5 удалений

Просмотреть файл

@ -3844,6 +3844,13 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Void),
vec![Type::new(Vec4)],
);
declare_function(
state,
"swgl_blendSubpixelText",
None,
Type::new(Void),
vec![Type::new(Vec4)],
);
declare_function(
state,
"swgl_clipMask",

Просмотреть файл

@ -204,6 +204,8 @@ useful for implementing clip-out modes by inverting the source texture value.
```
// Premultiplied alpha over blend, but with source color set to source alpha modulated with a constant color.
void swgl_blendDropShadow(vec4 color);
// Premultiplied alpha over blend, but treats the source as a subpixel mask modulated with a constant color.
void swgl_blendSubpixelText(vec4 color);
```
SWGL allows overriding the blend mode per-primitive by calling `swgl_blend`

Просмотреть файл

@ -340,6 +340,7 @@ enum SWGLClipFlag {
static int swgl_ClipFlags = 0;
static BlendKey swgl_BlendOverride = BLEND_KEY_NONE;
static WideRGBA8 swgl_BlendColorRGBA8 = {0};
static WideRGBA8 swgl_BlendAlphaRGBA8 = {0};
// A pointer into the color buffer for the start of the span.
static void* swgl_SpanBuf = nullptr;
@ -689,6 +690,12 @@ static PREFER_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst,
return color + dst - muldiv255(dst, alphas(color));
}
BLEND_CASE(SWGL_BLEND_SUBPIXEL_TEXT):
// Premultiplied alpha over blend, but treats the source as a subpixel mask
// modulated with a constant color.
return applyColor(src, swgl_BlendColorRGBA8) + dst -
muldiv255(dst, applyColor(src, swgl_BlendAlphaRGBA8));
default:
UNREACHABLE;
// return src;

Просмотреть файл

@ -619,7 +619,8 @@ struct Program {
macro(GL_HSL_SATURATION_KHR, 0, 0, 0) \
macro(GL_HSL_COLOR_KHR, 0, 0, 0) \
macro(GL_HSL_LUMINOSITY_KHR, 0, 0, 0) \
macro(SWGL_BLEND_DROP_SHADOW, 0, 0, 0)
macro(SWGL_BLEND_DROP_SHADOW, 0, 0, 0) \
macro(SWGL_BLEND_SUBPIXEL_TEXT, 0, 0, 0)
#define DEFINE_BLEND_KEY(...) BLEND_KEY(__VA_ARGS__),
#define DEFINE_MASK_BLEND_KEY(...) MASK_BLEND_KEY(__VA_ARGS__),

Просмотреть файл

@ -213,3 +213,4 @@ typedef intptr_t GLintptr;
#define GL_HSL_LUMINOSITY_KHR 0x92B0
#define SWGL_BLEND_DROP_SHADOW 0xB001
#define SWGL_BLEND_SUBPIXEL_TEXT 0xB002

Просмотреть файл

@ -1765,6 +1765,14 @@ static ALWAYS_INLINE int calcAAEdgeMask(bvec4_scalar mask) {
swgl_BlendColorRGBA8 = packColor<uint32_t>(color); \
} while (0)
#define swgl_blendSubpixelText(color) \
do { \
swgl_ClipFlags |= SWGL_CLIP_FLAG_BLEND_OVERRIDE; \
swgl_BlendOverride = BLEND_KEY(SWGL_BLEND_SUBPIXEL_TEXT); \
swgl_BlendColorRGBA8 = packColor<uint32_t>(color); \
swgl_BlendAlphaRGBA8 = alphas(swgl_BlendColorRGBA8); \
} while (0)
// Dispatch helper used by the GLSL translator to swgl_drawSpan functions.
// The number of pixels committed is tracked by checking for the difference in
// swgl_SpanLength. Any varying interpolants used will be advanced past the

Просмотреть файл

@ -245,8 +245,14 @@ void main() {
v_color = vec4(text.color.a) * text.bg_color;
break;
case COLOR_MODE_SUBPX_DUAL_SOURCE:
v_mask_swizzle = vec3(text.color.a, 0.0, 0.0);
v_color = text.color;
#ifdef SWGL_BLEND
swgl_blendSubpixelText(text.color);
v_mask_swizzle = vec3(1.0, 0.0, 0.0);
v_color = vec4(1.0);
#else
v_mask_swizzle = vec3(text.color.a, 0.0, 0.0);
v_color = text.color;
#endif
break;
default:
v_mask_swizzle = vec3(0.0, 0.0, 0.0);
@ -283,7 +289,7 @@ Fragment text_fs(void) {
frag.color = v_color * mask;
#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
#if defined(WR_FEATURE_DUAL_SOURCE_BLENDING) && !defined(SWGL_BLEND)
frag.blend = mask * v_mask_swizzle.x + mask.aaaa * v_mask_swizzle.y;
#endif
@ -299,7 +305,7 @@ void main() {
#if defined(WR_FEATURE_DEBUG_OVERDRAW)
oFragColor = WR_DEBUG_OVERDRAW_COLOR;
#elif defined(WR_FEATURE_DUAL_SOURCE_BLENDING)
#elif defined(WR_FEATURE_DUAL_SOURCE_BLENDING) && !defined(SWGL_BLEND)
oFragColor = frag.color;
oFragBlend = frag.blend * clip_mask;
#else