Bug 1399274 - Block invisible text optimizations when using WebRender. r=jrmuizel
authorAlexis Beingessner <a.beingessner@gmail.com>
Wed, 13 Sep 2017 14:05:51 -0400
changeset 380800 b22037b06fb65d176045065ee4c791d6ac016b30
parent 380799 95bcc263da5e74f605a9694427e29d970dade05a
child 380801 edd732009802c0fcbdaf88c946d0a27f14fc1a99
push id32496
push userkwierso@gmail.com
push dateThu, 14 Sep 2017 06:17:49 +0000
treeherdermozilla-central@9517eea4a1a5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1399274
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxTextRun.cpp
gfx/thebes/gfxTextRun.h
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
--- 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
@@ -6845,17 +6845,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;
@@ -6882,22 +6884,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");
 
@@ -7281,33 +7285,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 {
@@ -7488,17 +7493,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;