Skip to content

Commit

Permalink
Bug 1700434 - Implement faster subpixel text blend mode for SWGL. r=j…
Browse files Browse the repository at this point in the history
…rmuizel

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

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/5ff6e9101b77af8f88a394b6a6b2efdbbf798be8
  • Loading branch information
lsalzman committed May 21, 2021
1 parent a5945ec commit 9b0ff52
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 5 deletions.
7 changes: 7 additions & 0 deletions glsl-to-cxx/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions swgl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
7 changes: 7 additions & 0 deletions swgl/src/blend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion swgl/src/gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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__),
Expand Down
1 change: 1 addition & 0 deletions swgl/src/gl_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions swgl/src/swgl_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 10 additions & 4 deletions webrender/res/ps_text_run.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down

0 comments on commit 9b0ff52

Please sign in to comment.