Bug 1399274 - Block invisible text optimizations when using WebRender. r?jrmuizel
Mostly just threading the TextDrawTarget deeper into the code to use a boolean.
A lot of places are trying to optimize away invisible text!
MozReview-Commit-ID: 89sDAwUv0HA
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2001,16 +2001,17 @@ gfxFont::DrawGlyphs(const gfxShapedText
void
gfxFont::DrawEmphasisMarks(const gfxTextRun* aShapedText, gfxPoint* aPt,
uint32_t aOffset, uint32_t aCount,
const EmphasisMarkDrawParams& aParams)
{
gfxFloat& inlineCoord = aParams.isVertical ? aPt->y : aPt->x;
gfxTextRun::Range markRange(aParams.mark);
gfxTextRun::DrawParams params(aParams.context);
+ params.textDrawer = aParams.textDrawer;
gfxFloat clusterStart = -std::numeric_limits<gfxFloat>::infinity();
bool shouldDrawEmphasisMark = false;
for (uint32_t i = 0, idx = aOffset; i < aCount; ++i, ++idx) {
if (aParams.spacing) {
inlineCoord += aParams.direction * aParams.spacing[i].mBefore;
}
if (aShapedText->IsClusterStart(idx) ||
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -70,16 +70,19 @@ class gfxMathTable;
struct gfxTextRunDrawCallbacks;
namespace mozilla {
class SVGContextPaint;
namespace gfx {
class GlyphRenderingOptions;
} // namespace gfx
+namespace layout {
+class TextDrawTarget;
+} // namespace layout
} // namespace mozilla
struct gfxFontStyle {
gfxFontStyle();
gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
gfxFloat aSize, nsIAtom *aLanguage, bool aExplicitLanguage,
float aSizeAdjust, bool aSystemFont,
bool aPrinterFont,
@@ -2305,16 +2308,17 @@ struct MOZ_STACK_CLASS FontDrawParams {
mozilla::gfx::DrawOptions drawOptions;
bool isVerticalFont;
bool haveSVGGlyphs;
bool haveColorGlyphs;
};
struct MOZ_STACK_CLASS EmphasisMarkDrawParams {
gfxContext* context;
+ mozilla::layout::TextDrawTarget* textDrawer = nullptr;
gfxFont::Spacing* spacing;
gfxTextRun* mark;
gfxFloat advance;
gfxFloat direction;
bool isVertical;
};
#endif
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -602,17 +602,17 @@ gfxTextRun::Draw(Range aRange, gfxPoint
"GLYPH_PATH cannot be used with GLYPH_FILL, GLYPH_STROKE or GLYPH_STROKE_UNDERNEATH");
NS_ASSERTION(aParams.drawMode == DrawMode::GLYPH_PATH || !aParams.callbacks,
"callback must not be specified unless using GLYPH_PATH");
bool skipDrawing = mSkipDrawing;
if (aParams.drawMode & DrawMode::GLYPH_FILL) {
Color currentColor;
if (aParams.context->GetDeviceColor(currentColor) &&
- currentColor.a == 0) {
+ currentColor.a == 0 && !aParams.textDrawer) {
skipDrawing = true;
}
}
gfxFloat direction = GetDirection();
if (skipDrawing) {
// We don't need to draw anything;
@@ -719,24 +719,27 @@ gfxTextRun::Draw(Range aRange, gfxPoint
if (aParams.advanceWidth) {
*aParams.advanceWidth = advance;
}
}
// This method is mostly parallel to Draw().
void
-gfxTextRun::DrawEmphasisMarks(gfxContext *aContext, gfxTextRun* aMark,
+gfxTextRun::DrawEmphasisMarks(gfxContext *aContext,
+ mozilla::layout::TextDrawTarget* aTextDrawer,
+ gfxTextRun* aMark,
gfxFloat aMarkAdvance, gfxPoint aPt,
Range aRange, PropertyProvider* aProvider) const
{
MOZ_ASSERT(aRange.end <= GetLength());
EmphasisMarkDrawParams params;
params.context = aContext;
+ params.textDrawer = aTextDrawer;
params.mark = aMark;
params.advance = aMarkAdvance;
params.direction = GetDirection();
params.isVertical = IsVertical();
gfxFloat& inlineCoord = params.isVertical ? aPt.y : aPt.x;
gfxFloat direction = params.direction;
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -37,16 +37,19 @@ class gfxUserFontEntry;
class gfxUserFontSet;
class nsIAtom;
class nsLanguageAtomService;
class gfxMissingFontRecorder;
namespace mozilla {
class SVGContextPaint;
enum class StyleHyphens : uint8_t;
+namespace layout {
+class TextDrawTarget;
+};
};
/**
* Callback for Draw() to use when drawing text with mode
* DrawMode::GLYPH_PATH.
*/
struct gfxTextRunDrawCallbacks {
@@ -239,16 +242,17 @@ public:
// Return the appUnitsPerDevUnit value to be used when measuring.
// Only called if the hyphen width is requested.
virtual uint32_t GetAppUnitsPerDevUnit() const = 0;
};
struct MOZ_STACK_CLASS DrawParams
{
gfxContext* context;
+ mozilla::layout::TextDrawTarget* textDrawer = nullptr;
DrawMode drawMode = DrawMode::GLYPH_FILL;
nscolor textStrokeColor = 0;
gfxPattern* textStrokePattern = nullptr;
const mozilla::gfx::StrokeOptions *strokeOpts = nullptr;
const mozilla::gfx::DrawOptions *drawOpts = nullptr;
PropertyProvider* provider = nullptr;
// If non-null, the advance width of the substring is set.
gfxFloat* advanceWidth = nullptr;
@@ -279,17 +283,19 @@ public:
*/
void Draw(Range aRange, gfxPoint aPt, const DrawParams& aParams) const;
/**
* Draws the emphasis marks for this text run. Uses only GetSpacing
* from aProvider. The provided point is the baseline origin of the
* line of emphasis marks.
*/
- void DrawEmphasisMarks(gfxContext* aContext, gfxTextRun* aMark,
+ void DrawEmphasisMarks(gfxContext* aContext,
+ mozilla::layout::TextDrawTarget* aTextDrawer,
+ gfxTextRun* aMark,
gfxFloat aMarkAdvance, gfxPoint aPt,
Range aRange, PropertyProvider* aProvider) const;
/**
* Computes the ReflowMetrics for a substring.
* Uses GetSpacing from aBreakProvider.
* @param aBoundingBoxType which kind of bounding box (loose/tight)
*/
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -6851,17 +6851,19 @@ nsTextFrame::PaintTextWithSelection(
PaintTextSelectionDecorations(aParams, details, selectionType);
}
}
return true;
}
void
-nsTextFrame::DrawEmphasisMarks(gfxContext* aContext, WritingMode aWM,
+nsTextFrame::DrawEmphasisMarks(gfxContext* aContext,
+ TextDrawTarget* aTextDrawer,
+ WritingMode aWM,
const gfxPoint& aTextBaselinePt,
const gfxPoint& aFramePt, Range aRange,
const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider)
{
const EmphasisMarkInfo* info = GetProperty(EmphasisMarkProperty());
if (!info) {
return;
@@ -6888,22 +6890,24 @@ nsTextFrame::DrawEmphasisMarks(gfxContex
} else {
if (aWM.IsVerticalRL()) {
pt.x -= info->baselineOffset;
} else {
pt.x += info->baselineOffset;
}
}
if (!isTextCombined) {
- mTextRun->DrawEmphasisMarks(aContext, info->textRun.get(), info->advance,
- pt, aRange, aProvider);
+ mTextRun->DrawEmphasisMarks(aContext, aTextDrawer, info->textRun.get(),
+ info->advance, pt, aRange, aProvider);
} else {
pt.y += (GetSize().height - info->advance) / 2;
+ gfxTextRun::DrawParams params(aContext);
+ params.textDrawer = aTextDrawer;
info->textRun->Draw(Range(info->textRun.get()), pt,
- gfxTextRun::DrawParams(aContext));
+ params);
}
}
nscolor
nsTextFrame::GetCaretColorAt(int32_t aOffset)
{
NS_PRECONDITION(aOffset >= 0, "aOffset must be positive");
@@ -7287,33 +7291,34 @@ nsTextFrame::PaintText(const PaintTextPa
static void
DrawTextRun(const gfxTextRun* aTextRun,
const gfxPoint& aTextBaselinePt,
gfxTextRun::Range aRange,
const nsTextFrame::DrawTextRunParams& aParams)
{
gfxTextRun::DrawParams params(aParams.context);
+ params.textDrawer = aParams.textDrawer;
params.provider = aParams.provider;
params.advanceWidth = aParams.advanceWidth;
params.contextPaint = aParams.contextPaint;
params.callbacks = aParams.callbacks;
if (aParams.callbacks) {
aParams.callbacks->NotifyBeforeText(aParams.textColor);
params.drawMode = DrawMode::GLYPH_PATH;
aTextRun->Draw(aRange, aTextBaselinePt, params);
aParams.callbacks->NotifyAfterText();
} else {
- if (NS_GET_A(aParams.textColor) != 0) {
+ if (NS_GET_A(aParams.textColor) != 0 || aParams.textDrawer) {
aParams.context->SetColor(Color::FromABGR(aParams.textColor));
} else {
params.drawMode = DrawMode::GLYPH_STROKE;
}
- if (NS_GET_A(aParams.textStrokeColor) != 0 &&
+ if ((NS_GET_A(aParams.textStrokeColor) != 0 || aParams.textDrawer) &&
aParams.textStrokeWidth != 0.0f) {
StrokeOptions strokeOpts;
params.drawMode |= DrawMode::GLYPH_STROKE;
params.textStrokeColor = aParams.textStrokeColor;
strokeOpts.mLineWidth = aParams.textStrokeWidth;
params.strokeOpts = &strokeOpts;
aTextRun->Draw(aRange, aTextBaselinePt, params);
} else {
@@ -7494,17 +7499,17 @@ nsTextFrame::DrawTextRunAndDecorations(R
// and *then* line-throughs
DrawTextRun(aRange, aTextBaselinePt, aParams);
}
// Emphasis marks
if (aParams.textDrawer) {
aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eEmphasisMarks);
}
- DrawEmphasisMarks(aParams.context, wm,
+ DrawEmphasisMarks(aParams.context, aParams.textDrawer, wm,
aTextBaselinePt, aParams.framePt, aRange,
aParams.decorationOverrideColor, aParams.provider);
// Line-throughs
if (aParams.textDrawer && aDecorations.mStrikes.Length() > 0) {
aParams.textDrawer->StartDrawing(TextDrawTarget::Phase::eLineThrough);
}
params.decoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -533,16 +533,17 @@ public:
SelectionTypeMask* aAllSelectionTypeMask,
const nsCharClipDisplayItem::ClipEdges& aClipEdges);
// helper: paint text decorations for text selected by aSelectionType
void PaintTextSelectionDecorations(const PaintTextSelectionParams& aParams,
const mozilla::UniquePtr<SelectionDetails>& aDetails,
SelectionType aSelectionType);
void DrawEmphasisMarks(gfxContext* aContext,
+ TextDrawTarget* aTextDrawer,
mozilla::WritingMode aWM,
const gfxPoint& aTextBaselinePt,
const gfxPoint& aFramePt,
Range aRange,
const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider);
nscolor GetCaretColorAt(int32_t aOffset) override;