diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js index e9973f076fba..39ab8d2dab6e 100644 --- a/devtools/server/actors/animation-type-longhand.js +++ b/devtools/server/actors/animation-type-longhand.js @@ -280,7 +280,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ "color", "column-rule-color", "flood-color", - "-moz-font-smoothing-background-color", "lighting-color", "outline-color", "scrollbar-color", diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index dccdc1dc99fe..745dcf20748d 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -2078,7 +2078,6 @@ class GFX2D_API Factory { #ifdef XP_DARWIN static already_AddRefed CreateScaledFontForMacFont( CGFontRef aCGFont, const RefPtr& aUnscaledFont, Float aSize, - const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing = true, bool aApplySyntheticBold = false, bool aHasColorGlyphs = false); #endif diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 5bd65ac643af..a03864923984 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -594,11 +594,10 @@ already_AddRefed Factory::CreateUnscaledFontFromFontDescriptor( #ifdef XP_DARWIN already_AddRefed Factory::CreateScaledFontForMacFont( CGFontRef aCGFont, const RefPtr& aUnscaledFont, Float aSize, - const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing, - bool aApplySyntheticBold, bool aHasColorGlyphs) { - return MakeAndAddRef( - aCGFont, aUnscaledFont, aSize, false, aFontSmoothingBackgroundColor, - aUseFontSmoothing, aApplySyntheticBold, aHasColorGlyphs); + bool aUseFontSmoothing, bool aApplySyntheticBold, bool aHasColorGlyphs) { + return MakeAndAddRef(aCGFont, aUnscaledFont, aSize, false, + aUseFontSmoothing, aApplySyntheticBold, + aHasColorGlyphs); } #endif diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index 83c7f0241339..f6a0d97504c4 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -499,7 +499,6 @@ bool ScaledFontDWrite::GetWRFontInstanceOptions( if (Factory::GetBGRSubpixelOrder()) { options.flags |= wr::FontInstanceFlags::SUBPIXEL_BGR; } - options.bg_color = wr::ToColorU(DeviceColor()); options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle()); diff --git a/gfx/2d/ScaledFontFontconfig.cpp b/gfx/2d/ScaledFontFontconfig.cpp index e3025c107236..01e4b30092d8 100644 --- a/gfx/2d/ScaledFontFontconfig.cpp +++ b/gfx/2d/ScaledFontFontconfig.cpp @@ -402,7 +402,6 @@ bool ScaledFontFontconfig::GetWRFontInstanceOptions( if (UseSubpixelPosition()) { options.flags |= wr::FontInstanceFlags::SUBPIXEL_POSITION; } - options.bg_color = wr::ToColorU(DeviceColor()); options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle()); diff --git a/gfx/2d/ScaledFontFreeType.cpp b/gfx/2d/ScaledFontFreeType.cpp index 3e335e49c3a2..6575a97d5dbb 100644 --- a/gfx/2d/ScaledFontFreeType.cpp +++ b/gfx/2d/ScaledFontFreeType.cpp @@ -93,7 +93,6 @@ bool ScaledFontFreeType::GetWRFontInstanceOptions( options.flags |= wr::FontInstanceFlags::SUBPIXEL_POSITION; } options.flags |= wr::FontInstanceFlags::EMBEDDED_BITMAPS; - options.bg_color = wr::ToColorU(DeviceColor()); options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle()); diff --git a/gfx/2d/ScaledFontMac.cpp b/gfx/2d/ScaledFontMac.cpp index f6aade1196c3..ba4dcd50a4a3 100644 --- a/gfx/2d/ScaledFontMac.cpp +++ b/gfx/2d/ScaledFontMac.cpp @@ -125,12 +125,10 @@ CTFontRef CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize, ScaledFontMac::ScaledFontMac(CGFontRef aFont, const RefPtr& aUnscaledFont, Float aSize, bool aOwnsFont, - const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing, bool aApplySyntheticBold, bool aHasColorGlyphs) : ScaledFontBase(aUnscaledFont, aSize), mFont(aFont), - mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor), mUseFontSmoothing(aUseFontSmoothing), mApplySyntheticBold(aApplySyntheticBold), mHasColorGlyphs(aHasColorGlyphs) { @@ -146,12 +144,10 @@ ScaledFontMac::ScaledFontMac(CGFontRef aFont, ScaledFontMac::ScaledFontMac(CTFontRef aFont, const RefPtr& aUnscaledFont, - const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing, bool aApplySyntheticBold, bool aHasColorGlyphs) : ScaledFontBase(aUnscaledFont, CTFontGetSize(aFont)), mCTFont(aFont), - mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor), mUseFontSmoothing(aUseFontSmoothing), mApplySyntheticBold(aApplySyntheticBold), mHasColorGlyphs(aHasColorGlyphs) { @@ -457,7 +453,6 @@ bool ScaledFontMac::GetWRFontInstanceOptions( if (mHasColorGlyphs) { options.flags |= wr::FontInstanceFlags::EMBEDDED_BITMAPS; } - options.bg_color = wr::ToColorU(mFontSmoothingBackgroundColor); options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle()); *aOutOptions = Some(options); @@ -480,11 +475,6 @@ ScaledFontMac::InstanceData::InstanceData( if (aOptions->flags & wr::FontInstanceFlags::EMBEDDED_BITMAPS) { mHasColorGlyphs = true; } - if (aOptions->bg_color.a != 0) { - mFontSmoothingBackgroundColor = - DeviceColor::FromU8(aOptions->bg_color.r, aOptions->bg_color.g, - aOptions->bg_color.b, aOptions->bg_color.a); - } } } @@ -731,10 +721,9 @@ already_AddRefed UnscaledFontMac::CreateScaledFont( font = CTFontCreateWithFontDescriptor(fontDesc, aGlyphSize, nullptr); } } - scaledFont = new ScaledFontMac( - font, this, instanceData.mFontSmoothingBackgroundColor, - instanceData.mUseFontSmoothing, instanceData.mApplySyntheticBold, - instanceData.mHasColorGlyphs); + scaledFont = new ScaledFontMac(font, this, instanceData.mUseFontSmoothing, + instanceData.mApplySyntheticBold, + instanceData.mHasColorGlyphs); } else { CGFontRef fontRef = mFont; if (aNumVariations > 0) { @@ -746,7 +735,6 @@ already_AddRefed UnscaledFontMac::CreateScaledFont( } scaledFont = new ScaledFontMac(fontRef, this, aGlyphSize, fontRef != mFont, - instanceData.mFontSmoothingBackgroundColor, instanceData.mUseFontSmoothing, instanceData.mApplySyntheticBold, instanceData.mHasColorGlyphs); diff --git a/gfx/2d/ScaledFontMac.h b/gfx/2d/ScaledFontMac.h index 6b430f843e6c..6946b539a20a 100644 --- a/gfx/2d/ScaledFontMac.h +++ b/gfx/2d/ScaledFontMac.h @@ -34,17 +34,13 @@ class UnscaledFontMac; class ScaledFontMac : public ScaledFontBase { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac, override) - ScaledFontMac( - CGFontRef aFont, const RefPtr& aUnscaledFont, Float aSize, - bool aOwnsFont = false, - const DeviceColor& aFontSmoothingBackgroundColor = DeviceColor(), - bool aUseFontSmoothing = true, bool aApplySyntheticBold = false, - bool aHasColorGlyphs = false); - ScaledFontMac( - CTFontRef aFont, const RefPtr& aUnscaledFont, - const DeviceColor& aFontSmoothingBackgroundColor = DeviceColor(), - bool aUseFontSmoothing = true, bool aApplySyntheticBold = false, - bool aHasColorGlyphs = false); + ScaledFontMac(CGFontRef aFont, const RefPtr& aUnscaledFont, + Float aSize, bool aOwnsFont = false, + bool aUseFontSmoothing = true, bool aApplySyntheticBold = false, + bool aHasColorGlyphs = false); + ScaledFontMac(CTFontRef aFont, const RefPtr& aUnscaledFont, + bool aUseFontSmoothing = true, bool aApplySyntheticBold = false, + bool aHasColorGlyphs = false); ~ScaledFontMac(); FontType GetType() const override { return FontType::MAC; } @@ -66,10 +62,6 @@ class ScaledFontMac : public ScaledFontBase { bool UseSubpixelPosition() const override { return true; } - DeviceColor FontSmoothingBackgroundColor() { - return mFontSmoothingBackgroundColor; - } - cairo_font_face_t* CreateCairoFontFace( cairo_font_options_t* aFontOptions) override; @@ -81,23 +73,19 @@ class ScaledFontMac : public ScaledFontBase { CTFontRef mCTFont; // only created if CTFontDrawGlyphs is available, otherwise null - DeviceColor mFontSmoothingBackgroundColor; bool mUseFontSmoothing; bool mApplySyntheticBold; bool mHasColorGlyphs; struct InstanceData { explicit InstanceData(ScaledFontMac* aScaledFont) - : mFontSmoothingBackgroundColor( - aScaledFont->mFontSmoothingBackgroundColor), - mUseFontSmoothing(aScaledFont->mUseFontSmoothing), + : mUseFontSmoothing(aScaledFont->mUseFontSmoothing), mApplySyntheticBold(aScaledFont->mApplySyntheticBold), mHasColorGlyphs(aScaledFont->mHasColorGlyphs) {} InstanceData(const wr::FontInstanceOptions* aOptions, const wr::FontInstancePlatformOptions* aPlatformOptions); - DeviceColor mFontSmoothingBackgroundColor; bool mUseFontSmoothing; bool mApplySyntheticBold; bool mHasColorGlyphs; diff --git a/gfx/src/nsFont.cpp b/gfx/src/nsFont.cpp index 9667be1cc36d..baec648ddb48 100644 --- a/gfx/src/nsFont.cpp +++ b/gfx/src/nsFont.cpp @@ -58,8 +58,7 @@ nsFont::MaxDifference nsFont::CalcDifference(const nsFont& aOther) const { return MaxDifference::eLayoutAffecting; } - if ((smoothing != aOther.smoothing) || - (fontSmoothingBackgroundColor != aOther.fontSmoothingBackgroundColor)) { + if (smoothing != aOther.smoothing) { return MaxDifference::eVisual; } @@ -267,8 +266,6 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle* aStyle, if (smoothing == NS_FONT_SMOOTHING_GRAYSCALE) { aStyle->useGrayscaleAntialiasing = true; } - - aStyle->fontSmoothingBackgroundColor = fontSmoothingBackgroundColor.ToColor(); } void nsFont::AddFontVariationsToStyle(gfxFontStyle* aStyle) const { diff --git a/gfx/src/nsFont.h b/gfx/src/nsFont.h index c70dd518e4a4..155789666334 100644 --- a/gfx/src/nsFont.h +++ b/gfx/src/nsFont.h @@ -41,12 +41,6 @@ struct nsFont final { mozilla::StyleFontSizeAdjust sizeAdjust = mozilla::StyleFontSizeAdjust::None(); - // The estimated background color behind the text. Enables a special - // rendering mode when the alpha component > 0. Only used for text in the - // chrome. - mozilla::StyleAbsoluteColor fontSmoothingBackgroundColor = - mozilla::StyleAbsoluteColor::TRANSPARENT_BLACK; - // Language system tag, to override document language; // this is an OpenType "language system" tag represented as a 32-bit integer // (see http://www.microsoft.com/typography/otspec/languagetags.htm). diff --git a/gfx/thebes/gfxContext.h b/gfx/thebes/gfxContext.h index a6ebe76e7bfd..f70ee7baad34 100644 --- a/gfx/thebes/gfxContext.h +++ b/gfx/thebes/gfxContext.h @@ -582,7 +582,6 @@ class gfxContext final { mozilla::gfx::AntialiasMode aaMode; bool patternTransformChanged; Matrix patternTransform; - DeviceColor fontSmoothingBackgroundColor; // This is used solely for using minimal intermediate surface size. Point deviceOffset; #ifdef DEBUG diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 08e441f7875e..56b24cc292ff 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -4583,7 +4583,6 @@ gfxFontStyle::gfxFontStyle() sizeAdjust(0.0f), baselineOffset(0.0f), languageOverride(NO_FONT_LANGUAGE_OVERRIDE), - fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)), weight(FontWeight::NORMAL), stretch(FontStretch::NORMAL), style(FontSlantStyle::NORMAL), @@ -4610,7 +4609,6 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight, : size(aSize), baselineOffset(0.0f), languageOverride(aLanguageOverride), - fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)), weight(aWeight), stretch(aStretch), style(aStyle), diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 1f7a9c413970..969c07d5ca56 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -147,10 +147,6 @@ struct gfxFontStyle { // in order to get correct glyph shapes.) uint32_t languageOverride; - // The estimated background color behind the text. Enables a special - // rendering mode when NS_GET_A(.) > 0. Only used for text in the chrome. - nscolor fontSmoothingBackgroundColor; - // The Font{Weight,Stretch,SlantStyle} fields are each a 16-bit type. // The weight of the font: 100, 200, ... 900. @@ -253,8 +249,7 @@ struct gfxFontStyle { (variationSettings == other.variationSettings) && (languageOverride == other.languageOverride) && mozilla::NumbersAreBitwiseIdentical(autoOpticalSize, - other.autoOpticalSize) && - (fontSmoothingBackgroundColor == other.fontSmoothingBackgroundColor); + other.autoOpticalSize); } }; diff --git a/gfx/thebes/gfxMacFont.cpp b/gfx/thebes/gfxMacFont.cpp index 19e6e9b96edd..cef13f5f6ff0 100644 --- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -39,7 +39,6 @@ gfxMacFont::gfxMacFont(const RefPtr& aUnscaledFont, : gfxFont(aUnscaledFont, aFontEntry, aFontStyle), mCGFont(nullptr), mCTFont(nullptr), - mFontSmoothingBackgroundColor(aFontStyle->fontSmoothingBackgroundColor), mVariationFont(aFontEntry->HasVariations()) { mApplySyntheticBold = aFontStyle->NeedsSyntheticBold(aFontEntry); @@ -534,7 +533,6 @@ already_AddRefed gfxMacFont::GetScaledFont( bool hasColorGlyphs = fe->HasColorBitmapTable() || fe->TryGetColorGlyphs(); RefPtr newScaledFont = Factory::CreateScaledFontForMacFont( GetCGFontRef(), GetUnscaledFont(), GetAdjustedSize(), - ToDeviceColor(mFontSmoothingBackgroundColor), !mStyle.useGrayscaleAntialiasing, ApplySyntheticBold(), hasColorGlyphs); if (!newScaledFont) { return nullptr; diff --git a/gfx/thebes/gfxMacFont.h b/gfx/thebes/gfxMacFont.h index 47ea81eaa892..f33ad478ec1d 100644 --- a/gfx/thebes/gfxMacFont.h +++ b/gfx/thebes/gfxMacFont.h @@ -83,7 +83,6 @@ class gfxMacFont final : public gfxFont { mozilla::UniquePtr mCoreTextShaper; Metrics mMetrics; - nscolor mFontSmoothingBackgroundColor; bool mVariationFont; // true if font has OpenType variations }; diff --git a/gfx/webrender_bindings/WebRenderTypes.h b/gfx/webrender_bindings/WebRenderTypes.h index ef531b2169f6..64d9955746f9 100644 --- a/gfx/webrender_bindings/WebRenderTypes.h +++ b/gfx/webrender_bindings/WebRenderTypes.h @@ -314,15 +314,6 @@ static inline wr::ColorF ToColorF(const gfx::DeviceColor& color) { return c; } -static inline wr::ColorU ToColorU(const gfx::DeviceColor& color) { - wr::ColorU c; - c.r = uint8_t(color.r * 255.0f); - c.g = uint8_t(color.g * 255.0f); - c.b = uint8_t(color.b * 255.0f); - c.a = uint8_t(color.a * 255.0f); - return c; -} - static inline wr::LayoutPoint ToLayoutPoint( const mozilla::LayoutDevicePoint& point) { wr::LayoutPoint p; diff --git a/gfx/wr/webrender/doc/text-rendering.md b/gfx/wr/webrender/doc/text-rendering.md index b965562b99a2..0ac945ac19d1 100644 --- a/gfx/wr/webrender/doc/text-rendering.md +++ b/gfx/wr/webrender/doc/text-rendering.md @@ -366,355 +366,3 @@ in order to fold the two passes into one: Instead of outputting the two different colors in two separate passes, we output them from the same pass, as two separate fragment shader outputs. Those outputs can then be treated as two different sources in the blend equation. - -## Subpixel Text Rendering to Transparent Destinations with a Background Color Hint - -### Motivation - -As we've seen in the previous section, subpixel text drawing has the limitation that it only works on opaque destinations. - -In other words, if you use the `subpixeltextblend` function to draw something to a transparent surface, -and then composite that surface onto on opaque background, -the result will generally be different from drawing the text directly onto the opaque background. - -Let's express that inequality in code. - -``` - - vec4 text_color - - vec4 mask - - vec4 transparency = vec4(0.0, 0.0, 0.0, 0.0) - - vec4 background with background.a == 1.0 - -over(subpixeltextblend(text_color, mask, transparency), background).rgb - is, in general, not equal to -subpixeltextblend(text_color, mask, background).rgb -``` - -However, one interesting observation is that if the background is black, the two *are* equal: - -``` -vec4 black = vec4(0.0, 0.0, 0.0, 1.0); - -over(subpixeltextblend(text_color, mask, transparency), black).r - = subpixeltextblend(text_color, mask, transparency).r + - (1 - subpixeltextblend(text_color, mask, transparency).a) * black.r - = subpixeltextblend(text_color, mask, transparency).r + - (1 - subpixeltextblend(text_color, mask, transparency).a) * 0 - = subpixeltextblend(text_color, mask, transparency).r - = text_color.r * mask.r + (1 - text_color.a * mask.r) * transparency.r - = text_color.r * mask.r + (1 - text_color.a * mask.r) * 0 - = text_color.r * mask.r + (1 - text_color.a * mask.r) * black.r - = subpixeltextblend(text_color, mask, black).r -``` - -So it works out for black backgrounds. The further your *actual* background color gets away from black, -the more incorrect your result will be. - -If it works for black, is there a way to make it work for other colors? -This is the motivating question for this third way of text blending: - -We want to be able to specify an *estimated background color*, and have a blending function -`vec4 subpixeltextblend_withbgcolor(vec4 text_color, vec4 mask, vec4 bg_color, vec4 dest)`, -in such a way that the error we get by using an intermediate surface is somehow in relation -to the error we made when estimating the background color. In particular, if we estimated -the background color perfectly, we want the intermediate surface to go unnoticed. - -Expressed as code: - -``` -over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, transparency), bg_color) - should always be equal to -subpixeltextblend(text_color, mask, bg_color) -``` - -This is one of three constraints we'd like `subpixeltextblend_withbgcolor` to satisfy. - -The next constraint is the following: If `dest` is already opaque, `subpixeltextblend_withbgcolor` -should have the same results as `subpixeltextblend`, and the background color hint should be ignored. - -``` - If dest.a == 1.0, -subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest) - should always be equal to -subpixeltextblend(text_color, mask, dest) -``` - -And there's a third condition we'd like it to fulfill: -In places where the mask is zero, the destination should be unaffected. - -``` -subpixeltextblend_withbgcolor(text_color, transparency, bg_color, dest) - should always be equal to -dest -``` - -### Use cases - -The primary use case for such a blend method is text on top of vibrant areas of a window on macOS. - -Vibrant backgrounds with behind-window blending are computed by the window server, and they are tinted -in a color that's based on the chosen vibrancy type. - -The window's rgba buffer is transparent in the vibrant areas. Window contents, even text, are drawn onto -that transparent rgba buffer. Then the window server composites the window onto an opaque backdrop. -So the results on the screen are computed as follows: - -```glsl -window_buffer_pixel = subpixeltextblend_withbgcolor(text_color, mask, bg_color, transparency); -screen_pixel = over(window_buffer_pixel, window_backdrop); -``` - -### Prior art - -Apple has implemented such a method of text blending in CoreGraphics, specifically for rendering text onto vibrant backgrounds. -It's hidden behind the private API `CGContextSetFontSmoothingBackgroundColor` and is called by AppKit internally before -calling the `-[NSView drawRect:]` method of your `NSVisualEffectView`, with the appropriate font smoothing background color -for the vibrancy type of that view. - -I'm not aware of any public documentation of this way of text blending. -It seems to be considered an implementation detail by Apple, and is probably hidden by default because it can be a footgun: -If the font smoothing background color you specify is very different from the actual background that our surface is placed -on top of, the text will look glitchy. - -### Deriving the blending function from first principles - -Before we dive into the math, let's repeat our goal once more. - -We want to create a blending function of the form -`vec4 subpixeltextblend_withbgcolor(vec4 text_color, vec4 mask, vec4 bg_color, vec4 dest)` -(with `bg_color` being an opaque color) -which satisfies the following three constraints: - -``` -Constraint I: - over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, transparency), bg_color) - should always be equal to - subpixeltextblend(text_color, mask, bg_color) - -Constraint II: - If dest.a == 1.0, - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest) - should always be equal to - subpixeltextblend(text_color, mask, dest) - -Constraint II: - subpixeltextblend_withbgcolor(text_color, transparency, bg_color, dest) - should always be equal to - dest -``` - -Constraint I and constraint II are about what happens depending on the destination's alpha. -In particular: If the destination is completely transparent, we should blend into the -estimated background color, and if it's completely opaque, we should blend into the destination color. -In fact, we really want to blend into `over(dest, bg_color)`: we want `bg_color` to be used -as a backdrop *behind* the current destination. So let's combine constraints I and II into a new -constraint IV: - -``` -Constraint IV: - over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest), bg_color) - should always be equal to - subpixeltextblend(text_color, mask, over(dest, bg_color)) -``` - -Let's look at just the left side of that equation and rejiggle it a bit: - -``` -over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest), bg_color).r - = subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).r + - (1 - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a) * bg_color.r - -<=> - -over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest), bg_color).r - -(1 - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a) * bg_color.r - = subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).r -``` - -Now insert the right side of constraint IV: - -``` -subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).r - = over(subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest), bg_color).r - - (1 - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a) * bg_color.r - = subpixeltextblend(text_color, mask, over(dest, bg_color)).r - - (1 - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a) * bg_color.r -``` - -Our blend function is almost finished. We just need select an alpha for our result. -Constraints I, II and IV don't really care about the alpha value. But constraint III requires that: - -``` - subpixeltextblend_withbgcolor(text_color, transparency, bg_color, dest).a - should always be equal to - dest.a -``` - -so the computation of the alpha value somehow needs to take into account the mask. - -Let's say we have an unknown function `make_alpha(text_color.a, mask)` which returns -a number between 0 and 1 and which is 0 if the mask is entirely zero, and let's defer -the actual implementation of that function until later. - -Now we can define the alpha of our overall function using the `over` function: - -``` -subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a - := make_alpha(text_color.a, mask) + (1 - make_alpha(text_color.a, mask)) * dest.a -``` - -We can plug this in to our previous result: - -``` -subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).r - = subpixeltextblend(text_color, mask, over(dest, bg_color)).r - - (1 - subpixeltextblend_withbgcolor(text_color, mask, bg_color, dest).a) * bg_color.r - = subpixeltextblend(text_color, mask, over(dest, bg_color)).r - - (1 - (make_alpha(text_color.a, mask) + - (1 - make_alpha(text_color.a, mask)) * dest.a)) * bg_color.r - = text_color.r * mask.r + (1 - text_color.a * mask.r) * over(dest, bg_color).r - - (1 - (make_alpha(text_color.a, mask) - + (1 - make_alpha(text_color.a, mask)) * dest.a)) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * (dest.r + (1 - dest.a) * bg_color.r) - - (1 - (make_alpha(text_color.a, mask) - + (1 - make_alpha(text_color.a, mask)) * dest.a)) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * (dest.r + (1 - dest.a) * bg_color.r) - - (1 - (make_alpha(text_color.a, mask) - + (1 - make_alpha(text_color.a, mask)) * dest.a)) * bg_color.r - = text_color.r * mask.r - + (dest.r + (1 - dest.a) * bg_color.r) - - (text_color.a * mask.r) * (dest.r + (1 - dest.a) * bg_color.r) - - (1 - make_alpha(text_color.a, mask) - - (1 - make_alpha(text_color.a, mask)) * dest.a) * bg_color.r - = text_color.r * mask.r - + dest.r + (1 - dest.a) * bg_color.r - - text_color.a * mask.r * dest.r - - text_color.a * mask.r * (1 - dest.a) * bg_color.r - - (1 - make_alpha(text_color.a, mask) - - (1 - make_alpha(text_color.a, mask)) * dest.a) * bg_color.r - = text_color.r * mask.r - + dest.r + (1 - dest.a) * bg_color.r - - text_color.a * mask.r * dest.r - - text_color.a * mask.r * (1 - dest.a) * bg_color.r - - ((1 - make_alpha(text_color.a, mask)) * 1 - - (1 - make_alpha(text_color.a, mask)) * dest.a) * bg_color.r - = text_color.r * mask.r - + dest.r + (1 - dest.a) * bg_color.r - - text_color.a * mask.r * dest.r - - text_color.a * mask.r * (1 - dest.a) * bg_color.r - - ((1 - make_alpha(text_color.a, mask)) * (1 - dest.a)) * bg_color.r - = text_color.r * mask.r - + dest.r - text_color.a * mask.r * dest.r - + (1 - dest.a) * bg_color.r - - text_color.a * mask.r * (1 - dest.a) * bg_color.r - - (1 - make_alpha(text_color.a, mask)) * (1 - dest.a) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * dest.r - + (1 - dest.a) * bg_color.r - - text_color.a * mask.r * (1 - dest.a) * bg_color.r - - (1 - make_alpha(text_color.a, mask)) * (1 - dest.a) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * dest.r - + (1 - text_color.a * mask.r) * (1 - dest.a) * bg_color.r - - (1 - make_alpha(text_color.a, mask)) * (1 - dest.a) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * dest.r - + ((1 - text_color.a * mask.r) - - (1 - make_alpha(text_color.a, mask))) * (1 - dest.a) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * dest.r - + (1 - text_color.a * mask.r - - 1 + make_alpha(text_color.a, mask)) * (1 - dest.a) * bg_color.r - = text_color.r * mask.r - + (1 - text_color.a * mask.r) * dest.r - + (make_alpha(text_color.a, mask) - text_color.a * mask.r) * (1 - dest.a) * bg_color.r -``` - -We now have a term of the form `A + B + C`, with `A` and `B` being guaranteed to -be between zero and one. - -We also want `C` to be between zero and one. -We can use this restriction to help us decide on an implementation of `make_alpha`. - -If we define `make_alpha` as - -```glsl -float make_alpha(text_color_a, mask) { - float max_rgb = max(max(mask.r, mask.g), mask.b); - return text_color_a * max_rgb; -} -``` - -, then `(make_alpha(text_color.a, mask) - text_color.a * mask.r)` becomes -`(text_color.a * max(max(mask.r, mask.g), mask.b) - text_color.a * mask.r)`, which is -`text_color.a * (max(max(mask.r, mask.g), mask.b) - mask.r)`, and the subtraction will -always yield something that's greater or equal to zero for r, g, and b, -because we will subtract each channel from the maximum of the channels. - -Putting this all together, we have: - -```glsl -vec4 subpixeltextblend_withbgcolor(vec4 text_color, vec4 mask, vec4 bg_color, vec4 dest) { - float max_rgb = max(max(mask.r, mask.g), mask.b); - vec4 result; - result.r = text_color.r * mask.r + (1 - text_color.a * mask.r) * dest.r + - text_color.a * bg_color.r * (max_rgb - mask.r) * (1 - dest.a); - result.g = text_color.g * mask.g + (1 - text_color.a * mask.g) * dest.g + - text_color.a * bg_color.g * (max_rgb - mask.g) * (1 - dest.a); - result.b = text_color.b * mask.b + (1 - text_color.a * mask.b) * dest.b + - text_color.a * bg_color.b * (max_rgb - mask.b) * (1 - dest.a); - result.a = text_color.a * max_rgb + (1 - text_color.a * max_rgb) * dest.a; - return result; -} -``` - -This is the final form of this blend function. It satisfies all of the four constraints. - -### Implementing it with OpenGL - -Our color channel equations consist of three pieces: - - - `text_color.r * mask.r`, which simply gets added to the rest. - - `(1 - text_color.a * mask.r) * dest.r`, a factor which gets multiplied with the destination color. - - `text_color.a * bg_color.r * (max_rgb - mask.r) * (1 - dest.a)`, a factor which gets multiplied - with "one minus destination alpha". - -We will need three passes. Each pass modifies the color channels in the destination. -This means that the part that uses `dest.r` needs to be applied first. -Then we can apply the part that uses `1 - dest.a`. -(This means that the first pass needs to leave `dest.a` untouched.) -And the final pass can apply the `result.a` equation and modify `dest.a`. - -``` -pub fn set_blend_mode_subpixel_with_bg_color_pass0(&self) { - self.gl.blend_func_separate(gl::ZERO, gl::ONE_MINUS_SRC_COLOR, gl::ZERO, gl::ONE); -} -pub fn set_blend_mode_subpixel_with_bg_color_pass1(&self) { - self.gl.blend_func_separate(gl::ONE_MINUS_DST_ALPHA, gl::ONE, gl::ZERO, gl::ONE); -} -pub fn set_blend_mode_subpixel_with_bg_color_pass2(&self) { - self.gl.blend_func_separate(gl::ONE, gl::ONE, gl::ONE, gl::ONE_MINUS_SRC_ALPHA); -} - -Pass0: - oFragColor = vec4(text.color.a) * mask; -Pass1: - oFragColor = vec4(text.color.a) * text.bg_color * (vec4(mask.a) - mask); -Pass2: - oFragColor = text.color * mask; - -result_after_pass0.r = 0 * (text_color.a * mask.r) + (1 - text_color.a * mask.r) * dest.r -result_after_pass0.a = 0 * (text_color.a * mask.a) + 1 * dest.a - -result_after_pass1.r = (1 - result_after_pass0.a) * (text_color.a * (mask.max_rgb - mask.r) * bg_color.r) + 1 * result_after_pass0.r -result_after_pass1.a = 0 * (text_color.a * (mask.max_rgb - mask.a) * bg_color.a) + 1 * result_after_pass0.a - -result_after_pass2.r = 1 * (text_color.r * mask.r) + 1 * result_after_pass1.r -result_after_pass2.a = 1 * (text_color.a * mask.max_rgb) + (1 - text_color.a * mask.max_rgb) * result_after_pass1.a -``` - -Instead of computing `max_rgb` in the shader, we can just require the font rasterization code to fill -`mask.a` with the `max_rgb` value. - diff --git a/gfx/wr/webrender/res/brush_image.glsl b/gfx/wr/webrender/res/brush_image.glsl index 07695b6d6541..4a0cfe2229af 100644 --- a/gfx/wr/webrender/res/brush_image.glsl +++ b/gfx/wr/webrender/res/brush_image.glsl @@ -186,10 +186,6 @@ void brush_vs( int color_mode = prim_user_data.x & 0xffff; int blend_mode = prim_user_data.x >> 16; - if (color_mode == COLOR_MODE_FROM_PASS) { - color_mode = uMode; - } - #endif // Derive the texture coordinates for this image, based on @@ -289,20 +285,14 @@ void brush_vs( v_color = image_data.color; #endif break; - case COLOR_MODE_SUBPX_BG_PASS2: case COLOR_MODE_IMAGE: v_mask_swizzle = vec2(1.0, 0.0); v_color = image_data.color; break; - case COLOR_MODE_SUBPX_BG_PASS0: case COLOR_MODE_COLOR_BITMAP: v_mask_swizzle = vec2(1.0, 0.0); v_color = vec4(image_data.color.a); break; - case COLOR_MODE_SUBPX_BG_PASS1: - v_mask_swizzle = vec2(-1.0, 1.0); - v_color = vec4(image_data.color.a) * image_data.background_color; - break; case COLOR_MODE_SUBPX_DUAL_SOURCE: v_mask_swizzle = vec2(image_data.color.a, 0.0); v_color = image_data.color; diff --git a/gfx/wr/webrender/res/prim_shared.glsl b/gfx/wr/webrender/res/prim_shared.glsl index 1b2267da4fad..1a599bf98038 100644 --- a/gfx/wr/webrender/res/prim_shared.glsl +++ b/gfx/wr/webrender/res/prim_shared.glsl @@ -25,16 +25,12 @@ varying highp vec2 vClipMaskUv; #ifdef WR_VERTEX_SHADER -#define COLOR_MODE_FROM_PASS 0 -#define COLOR_MODE_ALPHA 1 -#define COLOR_MODE_SUBPX_BG_PASS0 2 -#define COLOR_MODE_SUBPX_BG_PASS1 3 -#define COLOR_MODE_SUBPX_BG_PASS2 4 -#define COLOR_MODE_SUBPX_DUAL_SOURCE 5 -#define COLOR_MODE_BITMAP_SHADOW 6 -#define COLOR_MODE_COLOR_BITMAP 7 -#define COLOR_MODE_IMAGE 8 -#define COLOR_MODE_MULTIPLY_DUAL_SOURCE 9 +#define COLOR_MODE_ALPHA 0 +#define COLOR_MODE_SUBPX_DUAL_SOURCE 1 +#define COLOR_MODE_BITMAP_SHADOW 2 +#define COLOR_MODE_COLOR_BITMAP 3 +#define COLOR_MODE_IMAGE 4 +#define COLOR_MODE_MULTIPLY_DUAL_SOURCE 5 uniform HIGHP_SAMPLER_FLOAT sampler2D sPrimitiveHeadersF; uniform HIGHP_SAMPLER_FLOAT isampler2D sPrimitiveHeadersI; diff --git a/gfx/wr/webrender/res/ps_text_run.glsl b/gfx/wr/webrender/res/ps_text_run.glsl index 9c5f34e3a677..aabc1e9d8a29 100644 --- a/gfx/wr/webrender/res/ps_text_run.glsl +++ b/gfx/wr/webrender/res/ps_text_run.glsl @@ -19,7 +19,7 @@ varying highp vec4 v_uv_clip; #ifdef WR_VERTEX_SHADER -#define VECS_PER_TEXT_RUN 2 +#define VECS_PER_TEXT_RUN 1 #define GLYPHS_PER_GPU_BLOCK 2U #ifdef WR_FEATURE_GLYPH_TRANSFORM @@ -66,12 +66,11 @@ GlyphResource fetch_glyph_resource(int address) { struct TextRun { vec4 color; - vec4 bg_color; }; TextRun fetch_text_run(int address) { - vec4 data[2] = fetch_from_gpu_cache_2(address); - return TextRun(data[0], data[1]); + vec4 data = fetch_from_gpu_cache_1(address); + return TextRun(data); } vec2 get_snap_bias(int subpx_dir) { @@ -112,10 +111,6 @@ void main() { TextRun text = fetch_text_run(ph.specific_prim_address); vec2 text_offset = ph.local_rect.p1; - if (color_mode == COLOR_MODE_FROM_PASS) { - color_mode = uMode; - } - // Note that the unsnapped reference frame relative offset has already // been subtracted from the prim local rect origin during batching. // It was done this way to avoid pushing both the snapped and the @@ -249,19 +244,10 @@ void main() { v_color = text.color; #endif break; - case COLOR_MODE_SUBPX_BG_PASS2: - v_mask_swizzle = vec3(1.0, 0.0, 0.0); - v_color = text.color; - break; - case COLOR_MODE_SUBPX_BG_PASS0: case COLOR_MODE_COLOR_BITMAP: v_mask_swizzle = vec3(1.0, 0.0, 0.0); v_color = vec4(text.color.a); break; - case COLOR_MODE_SUBPX_BG_PASS1: - v_mask_swizzle = vec3(-1.0, 1.0, 0.0); - v_color = vec4(text.color.a) * text.bg_color; - break; case COLOR_MODE_SUBPX_DUAL_SOURCE: #ifdef SWGL_BLEND swgl_blendSubpixelText(text.color); diff --git a/gfx/wr/webrender/res/shared.glsl b/gfx/wr/webrender/res/shared.glsl index 4f21bd205d46..a8b41af2b011 100644 --- a/gfx/wr/webrender/res/shared.glsl +++ b/gfx/wr/webrender/res/shared.glsl @@ -50,10 +50,6 @@ uniform bool u_mali_workaround_dummy; // Vertex shader attributes and uniforms //====================================================================================== #ifdef WR_VERTEX_SHADER - // A generic uniform that shaders can optionally use to configure - // an operation mode for this batch. - uniform int uMode; - // Uniform inputs uniform mat4 uTransform; // Orthographic projection diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index fbd617d8b347..f39b60acc641 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -347,21 +347,6 @@ impl AlphaBatchList { let mut selected_batch_index = None; match key.blend_mode { - BlendMode::SubpixelWithBgColor => { - for (batch_index, batch) in self.batches.iter().enumerate().rev() { - // Some subpixel batches are drawn in two passes. Because of this, we need - // to check for overlaps with every batch (which is a bit different - // than the normal batching below). - if self.batch_rects[batch_index].intersects(z_bounding_rect) { - break; - } - - if batch.key.is_compatible_with(&key) { - selected_batch_index = Some(batch_index); - break; - } - } - } BlendMode::Advanced(_) if self.break_advanced_blend_batches => { // don't try to find a batch } @@ -711,7 +696,6 @@ impl AlphaBatchBuilder { BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::PremultipliedDestOut | - BlendMode::SubpixelWithBgColor | BlendMode::SubpixelDualSource | BlendMode::Advanced(_) | BlendMode::MultiplyDualSource | @@ -1194,18 +1178,11 @@ impl BatchBuilder { let (blend_mode, color_mode) = match glyph_format { GlyphFormat::Subpixel | GlyphFormat::TransformedSubpixel => { - if run.used_font.bg_color.a != 0 { - ( - BlendMode::SubpixelWithBgColor, - ShaderColorMode::FromRenderPassMode, - ) - } else { - debug_assert!(ctx.use_dual_source_blending); - ( - BlendMode::SubpixelDualSource, - ShaderColorMode::SubpixelDualSource, - ) - } + debug_assert!(ctx.use_dual_source_blending); + ( + BlendMode::SubpixelDualSource, + ShaderColorMode::SubpixelDualSource, + ) } GlyphFormat::Alpha | GlyphFormat::TransformedAlpha | diff --git a/gfx/wr/webrender/src/device/gl.rs b/gfx/wr/webrender/src/device/gl.rs index 3ce8a3b9f799..a60baae958f3 100644 --- a/gfx/wr/webrender/src/device/gl.rs +++ b/gfx/wr/webrender/src/device/gl.rs @@ -549,7 +549,6 @@ impl Drop for Texture { pub struct Program { id: gl::GLuint, u_transform: gl::GLint, - u_mode: gl::GLint, u_texture_size: gl::GLint, source_info: ProgramSourceInfo, is_initialized: bool, @@ -1074,7 +1073,6 @@ pub struct Device { bound_vao: gl::GLuint, bound_read_fbo: (FBOId, DeviceIntPoint), bound_draw_fbo: FBOId, - program_mode_id: UniformLocation, default_read_fbo: FBOId, default_draw_fbo: FBOId, @@ -1915,7 +1913,6 @@ impl Device { bound_vao: 0, bound_read_fbo: (FBOId(0), DeviceIntPoint::zero()), bound_draw_fbo: FBOId(0), - program_mode_id: UniformLocation::INVALID, default_read_fbo: FBOId(0), default_draw_fbo: FBOId(0), @@ -2175,7 +2172,6 @@ impl Device { // Shader state self.bound_program = 0; - self.program_mode_id = UniformLocation::INVALID; self.gl.use_program(0); // Reset common state @@ -2532,7 +2528,6 @@ impl Device { // If we get here, the link succeeded, so get the uniforms. program.is_initialized = true; program.u_transform = self.gl.get_uniform_location(program.id, "uTransform"); - program.u_mode = self.gl.get_uniform_location(program.id, "uMode"); program.u_texture_size = self.gl.get_uniform_location(program.id, "uTextureSize"); Ok(()) @@ -2553,7 +2548,6 @@ impl Device { self.gl.use_program(program.id); self.bound_program = program.id; self.bound_program_name = program.source_info.full_name_cstr.clone(); - self.program_mode_id = UniformLocation(program.u_mode); } true } @@ -3044,7 +3038,6 @@ impl Device { let program = Program { id: pid, u_transform: 0, - u_mode: 0, u_texture_size: 0, source_info, is_initialized: false, @@ -3104,14 +3097,6 @@ impl Device { .uniform_matrix_4fv(program.u_transform, false, &transform.to_array()); } - pub fn switch_mode(&self, mode: i32) { - debug_assert!(self.inside_frame); - #[cfg(debug_assertions)] - debug_assert!(self.shader_is_ready); - - self.gl.uniform_1i(self.program_mode_id.0, mode); - } - /// Sets the uTextureSize uniform. Most shaders do not require this to be called /// as they use the textureSize GLSL function instead. pub fn set_shader_texture_size( @@ -3933,24 +3918,6 @@ impl Device { (gl::ONE, gl::ONE), ); } - pub fn set_blend_mode_subpixel_with_bg_color_pass0(&mut self) { - self.set_blend_factors( - (gl::ZERO, gl::ONE_MINUS_SRC_COLOR), - (gl::ZERO, gl::ONE), - ); - } - pub fn set_blend_mode_subpixel_with_bg_color_pass1(&mut self) { - self.set_blend_factors( - (gl::ONE_MINUS_DST_ALPHA, gl::ONE), - (gl::ZERO, gl::ONE), - ); - } - pub fn set_blend_mode_subpixel_with_bg_color_pass2(&mut self) { - self.set_blend_factors( - (gl::ONE, gl::ONE), - (gl::ONE, gl::ONE_MINUS_SRC_ALPHA), - ); - } pub fn set_blend_mode_subpixel_dual_source(&mut self) { self.set_blend_factors( (gl::ONE, gl::ONE_MINUS_SRC1_COLOR), diff --git a/gfx/wr/webrender/src/prim_store/text_run.rs b/gfx/wr/webrender/src/prim_store/text_run.rs index 61562306bec8..c6da633fa021 100644 --- a/gfx/wr/webrender/src/prim_store/text_run.rs +++ b/gfx/wr/webrender/src/prim_store/text_run.rs @@ -109,9 +109,6 @@ impl TextRunTemplate { // corresponds to `fetch_glyph` in the shaders if let Some(mut request) = frame_state.gpu_cache.request(&mut self.common.gpu_cache_handle) { request.push(ColorF::from(self.font.color).premultiplied()); - // this is the only case where we need to provide plain color to GPU - let bg_color = ColorF::from(self.font.bg_color); - request.push([bg_color.r, bg_color.g, bg_color.b, 1.0]); let mut gpu_block = [0.0; 4]; for (i, src) in self.glyphs.iter().enumerate() { @@ -244,7 +241,7 @@ impl TextRunPrimitive { surface: &SurfaceInfo, spatial_node_index: SpatialNodeIndex, transform: &LayoutToWorldTransform, - mut allow_subpixel: bool, + allow_subpixel: bool, raster_space: RasterSpace, spatial_tree: &SpatialTree, ) -> bool { @@ -360,10 +357,6 @@ impl TextRunPrimitive { ..specified_font.clone() }; - // If we are using special estimated background subpixel blending, then - // we can allow it regardless of what the surface says. - allow_subpixel |= self.used_font.bg_color.a != 0; - // If using local space glyphs, we don't want subpixel AA. if !allow_subpixel || !use_subpixel_aa { self.used_font.disable_subpixel_aa(); diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs index ac15eae8870c..0eded7ffb4dd 100644 --- a/gfx/wr/webrender/src/renderer/mod.rs +++ b/gfx/wr/webrender/src/renderer/mod.rs @@ -302,16 +302,12 @@ fn flag_changed(before: DebugFlags, after: DebugFlags, select: DebugFlags) -> Op #[repr(C)] #[derive(Copy, Clone, Debug)] pub enum ShaderColorMode { - FromRenderPassMode = 0, - Alpha = 1, - SubpixelWithBgColorPass0 = 2, - SubpixelWithBgColorPass1 = 3, - SubpixelWithBgColorPass2 = 4, - SubpixelDualSource = 5, - BitmapShadow = 6, - ColorBitmap = 7, - Image = 8, - MultiplyDualSource = 9, + Alpha = 0, + SubpixelDualSource = 1, + BitmapShadow = 2, + ColorBitmap = 3, + Image = 4, + MultiplyDualSource = 5, } impl From for ShaderColorMode { @@ -645,7 +641,6 @@ pub enum BlendMode { PremultipliedAlpha, PremultipliedDestOut, SubpixelDualSource, - SubpixelWithBgColor, Advanced(MixBlendMode), MultiplyDualSource, Screen, @@ -2837,23 +2832,6 @@ impl Renderer { BlendMode::SubpixelDualSource => { self.device.set_blend_mode_subpixel_dual_source(); } - BlendMode::SubpixelWithBgColor => { - // Using the three pass "component alpha with font smoothing - // background color" rendering technique: - // - // /webrender/doc/text-rendering.md - // - self.device.set_blend_mode_subpixel_with_bg_color_pass0(); - // need to make sure the shader is bound - shader.bind( - &mut self.device, - projection, - None, - &mut self.renderer_errors, - &mut self.profile, - ); - self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass0 as _); - } BlendMode::Advanced(mode) => { if self.enable_advanced_blend_barriers { self.device.gl().blend_barrier_khr(); @@ -2904,44 +2882,6 @@ impl Renderer { &batch.key.textures, stats ); - - if batch.key.blend_mode == BlendMode::SubpixelWithBgColor { - self.set_blend_mode_subpixel_with_bg_color_pass1(framebuffer_kind); - // re-binding the shader after the blend mode change - shader.bind( - &mut self.device, - projection, - None, - &mut self.renderer_errors, - &mut self.profile, - ); - self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass1 as _); - - // When drawing the 2nd and 3rd passes, we know that the VAO, textures etc - // are all set up from the previous draw_instanced_batch call, - // so just issue a draw call here to avoid re-uploading the - // instances and re-binding textures etc. - self.device - .draw_indexed_triangles_instanced_u16(6, batch.instances.len() as i32); - - self.set_blend_mode_subpixel_with_bg_color_pass2(framebuffer_kind); - // re-binding the shader after the blend mode change - shader.bind( - &mut self.device, - projection, - None, - &mut self.renderer_errors, - &mut self.profile, - ); - self.device.switch_mode(ShaderColorMode::SubpixelWithBgColorPass2 as _); - - self.device - .draw_indexed_triangles_instanced_u16(6, batch.instances.len() as i32); - } - - if batch.key.blend_mode == BlendMode::SubpixelWithBgColor { - prev_blend_mode = BlendMode::None; - } } self.set_blend(false, framebuffer_kind); @@ -5454,24 +5394,6 @@ impl Renderer { } } - fn set_blend_mode_subpixel_with_bg_color_pass1(&mut self, framebuffer_kind: FramebufferKind) { - if framebuffer_kind == FramebufferKind::Main && - self.debug_flags.contains(DebugFlags::SHOW_OVERDRAW) { - self.device.set_blend_mode_show_overdraw(); - } else { - self.device.set_blend_mode_subpixel_with_bg_color_pass1(); - } - } - - fn set_blend_mode_subpixel_with_bg_color_pass2(&mut self, framebuffer_kind: FramebufferKind) { - if framebuffer_kind == FramebufferKind::Main && - self.debug_flags.contains(DebugFlags::SHOW_OVERDRAW) { - self.device.set_blend_mode_show_overdraw(); - } else { - self.device.set_blend_mode_subpixel_with_bg_color_pass2(); - } - } - /// Clears the texture with a given color. fn clear_texture(&mut self, texture: &Texture, color: [f32; 4]) { self.device.bind_draw_target(DrawTarget::from_texture( diff --git a/gfx/wr/webrender/src/renderer/shade.rs b/gfx/wr/webrender/src/renderer/shade.rs index 72b6578a4fb0..4e016d4ad3c0 100644 --- a/gfx/wr/webrender/src/renderer/shade.rs +++ b/gfx/wr/webrender/src/renderer/shade.rs @@ -438,7 +438,6 @@ impl BrushShader { BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::PremultipliedDestOut | - BlendMode::SubpixelWithBgColor | BlendMode::Screen | BlendMode::PlusLighter | BlendMode::Exclusion => { diff --git a/gfx/wr/webrender_api/src/font.rs b/gfx/wr/webrender_api/src/font.rs index 7d4de4f3422d..2a2e2b1dc688 100644 --- a/gfx/wr/webrender_api/src/font.rs +++ b/gfx/wr/webrender_api/src/font.rs @@ -11,7 +11,6 @@ use std::sync::Arc; // local imports use crate::IdNamespace; use crate::channel::Sender; -use crate::color::ColorU; use crate::units::LayoutPoint; /// Hashable floating-point storage for font size. @@ -289,10 +288,6 @@ impl Default for SyntheticItalics { pub struct FontInstanceOptions { pub render_mode: FontRenderMode, pub flags: FontInstanceFlags, - /// When bg_color.a is != 0 and render_mode is FontRenderMode::Subpixel, - /// the text will be rendered with bg_color.r/g/b as an opaque estimated - /// background color. - pub bg_color: ColorU, pub synthetic_italics: SyntheticItalics, } @@ -301,7 +296,6 @@ impl Default for FontInstanceOptions { FontInstanceOptions { render_mode: FontRenderMode::Subpixel, flags: Default::default(), - bg_color: ColorU::new(0, 0, 0, 0), synthetic_italics: SyntheticItalics::disabled(), } } diff --git a/gfx/wr/wr_glyph_rasterizer/src/rasterizer.rs b/gfx/wr/wr_glyph_rasterizer/src/rasterizer.rs index 5153e60c54b8..fafff4f94c1d 100644 --- a/gfx/wr/wr_glyph_rasterizer/src/rasterizer.rs +++ b/gfx/wr/wr_glyph_rasterizer/src/rasterizer.rs @@ -827,7 +827,6 @@ impl FontInstanceMap { options: Some(FontInstanceOptions { render_mode: instance.render_mode, flags: instance.flags, - bg_color: instance.bg_color, synthetic_italics: instance.synthetic_italics, }), platform_options: instance.platform_options, diff --git a/gfx/wr/wrench/reftests/text/bg-color-ref.yaml b/gfx/wr/wrench/reftests/text/bg-color-ref.yaml deleted file mode 100644 index 01af0e93b6f0..000000000000 --- a/gfx/wr/wrench/reftests/text/bg-color-ref.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -root: - items: - - text: "A" - origin: 30 220 - size: 200 - color: black - font: "FreeSans.ttf" diff --git a/gfx/wr/wrench/reftests/text/bg-color.yaml b/gfx/wr/wrench/reftests/text/bg-color.yaml deleted file mode 100644 index 14f53d79be39..000000000000 --- a/gfx/wr/wrench/reftests/text/bg-color.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# verify that drawing a text run on an off-screen surface with a -# specified background color gives the same result as drawing a -# subpixel text run directly on the background. ---- -root: - items: - - type: stacking-context - transform-style: preserve-3d - items: - - text: "A" - origin: 30 220 - size: 200 - color: black - font: "FreeSans.ttf" - bg-color: white diff --git a/gfx/wr/wrench/reftests/text/reftest.list b/gfx/wr/wrench/reftests/text/reftest.list index e77b768c4b23..4a145ae359e8 100644 --- a/gfx/wr/wrench/reftests/text/reftest.list +++ b/gfx/wr/wrench/reftests/text/reftest.list @@ -59,7 +59,6 @@ skip_on(android,device) == shadow-partial-glyph.yaml shadow-partial-glyph-ref.ya fuzzy(2,212) platform(linux) == shadow-transforms.yaml shadow-transforms.png fuzzy(2,370) platform(linux) == raster-space.yaml raster-space.png skip_on(android) skip_on(mac,>=10.14) != allow-subpixel.yaml allow-subpixel-ref.yaml # Android: we don't enable sub-px aa on this platform. -skip_on(android,device) fuzzy-if(platform(swgl),1,1085) == bg-color.yaml bg-color-ref.yaml # Fails on Pixel2 != large-glyphs.yaml blank.yaml != large-line-decoration.yaml blank.yaml skip_on(android,device) == snap-text-offset.yaml snap-text-offset-ref.yaml diff --git a/gfx/wr/wrench/src/yaml_frame_reader.rs b/gfx/wr/wrench/src/yaml_frame_reader.rs index 9bd8b56943a8..2cbe30a51c7a 100644 --- a/gfx/wr/wrench/src/yaml_frame_reader.rs +++ b/gfx/wr/wrench/src/yaml_frame_reader.rs @@ -745,7 +745,6 @@ impl YamlFrameReader { &mut self, font_key: FontKey, size: f32, - bg_color: Option, flags: FontInstanceFlags, synthetic_italics: SyntheticItalics, wrench: &mut Wrench, @@ -753,14 +752,13 @@ impl YamlFrameReader { let font_render_mode = self.font_render_mode; *self.font_instances - .entry((font_key, size.into(), flags, bg_color, synthetic_italics)) + .entry((font_key, size.into(), flags, synthetic_italics)) .or_insert_with(|| { wrench.add_font_instance( font_key, size, flags, font_render_mode, - bg_color, synthetic_italics, ) }) @@ -1350,7 +1348,6 @@ impl YamlFrameReader { ) { let size = item["size"].as_pt_to_f32().unwrap_or(16.0); let color = item["color"].as_colorf().unwrap_or(ColorF::BLACK); - let bg_color = item["bg-color"].as_colorf().map(|c| c.into()); let synthetic_italics = if let Some(angle) = item["synthetic-italics"].as_f32() { SyntheticItalics::from_degrees(angle) } else if item["synthetic-italics"].as_bool().unwrap_or(false) { @@ -1385,7 +1382,6 @@ impl YamlFrameReader { let font_key = self.get_or_create_font(desc, wrench); let font_instance_key = self.get_or_create_font_instance(font_key, size, - bg_color, flags, synthetic_italics, wrench); diff --git a/layout/style/res/scrollbars.css b/layout/style/res/scrollbars.css index ed1e57ce31cc..29a412458027 100644 --- a/layout/style/res/scrollbars.css +++ b/layout/style/res/scrollbars.css @@ -19,7 +19,6 @@ /* These properties are not included in 'all'. */ -moz-context-properties: initial; -moz-control-character-visibility: initial; - -moz-font-smoothing-background-color: initial; -moz-min-font-size-ratio: initial; -moz-box-collapse: initial; diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index a2ea36a3dd5c..5e83162b227c 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -98,17 +98,16 @@ const char* gInaccessibleProperties[] = { "-moz-inert", "-moz-script-level", // parsed by UA sheets only "-moz-math-variant", - "-moz-math-display", // parsed by UA sheets only - "-moz-top-layer", // parsed by UA sheets only - "-moz-min-font-size-ratio", // parsed by UA sheets only - "-moz-box-collapse", // chrome-only internal properties - "-moz-font-smoothing-background-color", // chrome-only internal properties - "-moz-subtree-hidden-only-visually", // chrome-only internal properties - "-moz-window-input-region-margin", // chrome-only internal properties - "-moz-window-opacity", // chrome-only internal properties - "-moz-window-transform", // chrome-only internal properties - "-moz-window-transform-origin", // chrome-only internal properties - "-moz-window-shadow", // chrome-only internal properties + "-moz-math-display", // parsed by UA sheets only + "-moz-top-layer", // parsed by UA sheets only + "-moz-min-font-size-ratio", // parsed by UA sheets only + "-moz-box-collapse", // chrome-only internal properties + "-moz-subtree-hidden-only-visually", // chrome-only internal properties + "-moz-window-input-region-margin", // chrome-only internal properties + "-moz-window-opacity", // chrome-only internal properties + "-moz-window-transform", // chrome-only internal properties + "-moz-window-transform-origin", // chrome-only internal properties + "-moz-window-shadow", // chrome-only internal properties }; inline int is_inaccessible(const char* aPropName) { diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index c0ac86ad11a7..327fb377818a 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -13457,15 +13457,6 @@ if (false) { "2px", ], }; - - gCSSProperties["-moz-font-smoothing-background-color"] = { - // domProp: "MozFontSmoothingBackgroundColor", - inherited: true, - type: CSS_TYPE_LONGHAND, - initial_values: ["transparent"], - other_values: ["green", "#fc3"], - invalid_values: ["000000", "ff00ff"], - }; } gCSSProperties["scrollbar-color"] = { diff --git a/servo/components/style/properties/longhands/font.mako.rs b/servo/components/style/properties/longhands/font.mako.rs index e4d8c72c9b10..f188af5b1f39 100644 --- a/servo/components/style/properties/longhands/font.mako.rs +++ b/servo/components/style/properties/longhands/font.mako.rs @@ -493,18 +493,6 @@ ${helpers.single_keyword( affects="paint", )} -${helpers.predefined_type( - "-moz-font-smoothing-background-color", - "color::MozFontSmoothingBackgroundColor", - "computed::color::MozFontSmoothingBackgroundColor::TRANSPARENT_BLACK", - engines="gecko", - animation_value_type="none", - gecko_ffi_name="mFont.fontSmoothingBackgroundColor", - enabled_in="chrome", - spec="None (Nonstandard internal property)", - affects="paint", -)} - ${helpers.predefined_type( "-moz-min-font-size-ratio", "Percentage", diff --git a/servo/components/style/values/computed/color.rs b/servo/components/style/values/computed/color.rs index a77f26656157..0667cc0a2ce1 100644 --- a/servo/components/style/values/computed/color.rs +++ b/servo/components/style/values/computed/color.rs @@ -19,9 +19,6 @@ pub use crate::values::specified::color::{ColorScheme, ForcedColorAdjust, PrintC /// The computed value of the `color` property. pub type ColorPropertyValue = AbsoluteColor; -/// The computed value of `-moz-font-smoothing-background-color`. -pub type MozFontSmoothingBackgroundColor = AbsoluteColor; - /// A computed value for ``. pub type Color = GenericColor; diff --git a/servo/components/style/values/specified/color.rs b/servo/components/style/values/specified/color.rs index cbcb49a63a2e..480c1329b8ab 100644 --- a/servo/components/style/values/specified/color.rs +++ b/servo/components/style/values/specified/color.rs @@ -925,38 +925,6 @@ impl ToComputedValue for Color { } } -/// Specified color value for `-moz-font-smoothing-background-color`. -/// -/// This property does not support `currentcolor`. We could drop it at -/// parse-time, but it's not exposed to the web so it doesn't really matter. -/// -/// We resolve it to `transparent` instead. -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] -pub struct MozFontSmoothingBackgroundColor(pub Color); - -impl Parse for MozFontSmoothingBackgroundColor { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - Color::parse(context, input).map(MozFontSmoothingBackgroundColor) - } -} - -impl ToComputedValue for MozFontSmoothingBackgroundColor { - type ComputedValue = AbsoluteColor; - - fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { - self.0 - .to_computed_value(context) - .resolve_to_absolute(&AbsoluteColor::TRANSPARENT_BLACK) - } - - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - MozFontSmoothingBackgroundColor(Color::from_absolute_color(*computed)) - } -} - impl SpecifiedValueInfo for Color { const SUPPORTED_TYPES: u8 = CssType::COLOR; diff --git a/toolkit/content/xul.css b/toolkit/content/xul.css index d903e6c914fb..efd523b44d08 100644 --- a/toolkit/content/xul.css +++ b/toolkit/content/xul.css @@ -379,7 +379,6 @@ tooltip { tooltip { appearance: auto; -moz-default-appearance: tooltip; - -moz-font-smoothing-background-color: -moz-mac-tooltip; white-space: pre-wrap; diff --git a/toolkit/themes/osx/global/menu.css b/toolkit/themes/osx/global/menu.css index e47caa948656..2e79b8e57a4f 100644 --- a/toolkit/themes/osx/global/menu.css +++ b/toolkit/themes/osx/global/menu.css @@ -57,7 +57,6 @@ menubar > menu[_moz-menuactive="true"] { menubar > menu[_moz-menuactive="true"][open="true"] { color: -moz-menuhovertext; background-color: -moz-menuhover; - -moz-font-smoothing-background-color: -moz-mac-active-menuitem; } /* Internal content */ diff --git a/toolkit/themes/shared/menu-shared.css b/toolkit/themes/shared/menu-shared.css index 95a6fd151a5b..9ad33423ec09 100644 --- a/toolkit/themes/shared/menu-shared.css +++ b/toolkit/themes/shared/menu-shared.css @@ -94,7 +94,6 @@ menucaption { flex-shrink: 0; list-style-image: none; max-width: 42em; - -moz-font-smoothing-background-color: -moz-mac-menuitem; @media (-moz-platform: linux) { padding: 4px 6px; @@ -110,13 +109,11 @@ menuitem { &:where([disabled="true"]) { color: var(--panel-disabled-color); text-shadow: none; - -moz-font-smoothing-background-color: -moz-mac-menuitem; } &:where([_moz-menuactive]:not([disabled="true"])) { color: -moz-menuhovertext; background-color: -moz-menuhover; - -moz-font-smoothing-background-color: -moz-mac-active-menuitem; } &:where([_moz-menuactive="true"][disabled="true"]) { diff --git a/toolkit/themes/shared/popup.css b/toolkit/themes/shared/popup.css index a1346fb3ab91..66c546e1cbfc 100644 --- a/toolkit/themes/shared/popup.css +++ b/toolkit/themes/shared/popup.css @@ -58,7 +58,6 @@ panel { display: flex; box-sizing: border-box; - -moz-font-smoothing-background-color: var(--panel-background, -moz-mac-menupopup); padding: var(--panel-padding); color: var(--panel-color); background: var(--panel-background);