Bug 1536423 - Remove SVGCharClipDisplayItem r=mattwoodrow
authorMiko Mynttinen <mikokm@gmail.com>
Thu, 04 Apr 2019 18:04:49 +0000
changeset 526847 10584c20a8985a3fe5a350ec6f5a5e94b941dfc0
parent 526846 664efc1162c431bfcc1127da5c578de727e4e21a
child 526848 dfe534711b4ad3ab68029d06b0efedec70732952
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1536423
milestone68.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 1536423 - Remove SVGCharClipDisplayItem r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D26191
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
layout/painting/nsDisplayItemTypesList.h
layout/painting/nsDisplayList.h
layout/svg/SVGTextFrame.cpp
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5104,17 +5104,18 @@ void nsDisplayText::RenderToContext(gfxC
   params.dirtyRect = extraVisible;
 
   if (aBuilder->IsForGenerateGlyphMask()) {
     params.state = nsTextFrame::PaintTextParams::GenerateTextMask;
   } else {
     params.state = nsTextFrame::PaintTextParams::PaintText;
   }
 
-  f->PaintText(params, *this, mOpacity);
+  f->PaintText(params, mVisIStartEdge, mVisIEndEdge, ToReferenceFrame(),
+               IsSelected(), mOpacity);
 
   if (willClip) {
     aCtx->PopClip();
   }
 }
 
 void nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                    const nsDisplayListSet& aLists) {
@@ -6766,32 +6767,33 @@ void nsTextFrame::PaintShadows(nsCSSShad
 
   for (uint32_t i = aShadow->Length(); i > 0; --i) {
     PaintOneShadow(aParams, aShadow->ShadowAt(i - 1),
                    shadowMetrics.mBoundingBox, blurFlags);
   }
 }
 
 void nsTextFrame::PaintText(const PaintTextParams& aParams,
-                            const nsCharClipDisplayItem& aItem,
+                            const nscoord aVisIStartEdge,
+                            const nscoord aVisIEndEdge,
+                            const nsPoint& aToReferenceFrame,
+                            const bool aIsSelected,
                             float aOpacity /* = 1.0f */) {
   // Don't pass in the rendering context here, because we need a
   // *reference* context and rendering context might have some transform
   // in it
   // XXX get the block and line passed to us somehow! This is slow!
   gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
   if (!mTextRun) return;
 
   PropertyProvider provider(this, iter, nsTextFrame::eInflated, mFontMetrics);
 
-  const bool isSelected = aItem.IsSelected();
-
   // Trim trailing whitespace, unless we're painting a selection highlight,
   // which should include trailing spaces if present (bug 1146754).
-  provider.InitializeForDisplay(!isSelected);
+  provider.InitializeForDisplay(!aIsSelected);
 
   const bool reversed = mTextRun->IsInlineReversed();
   const bool verticalRun = mTextRun->IsVertical();
   WritingMode wm = GetWritingMode();
   const float frameWidth = GetSize().width;
   const float frameHeight = GetSize().height;
   gfx::Point textBaselinePt;
   if (verticalRun) {
@@ -6810,33 +6812,33 @@ void nsTextFrame::PaintText(const PaintT
         reversed ? aParams.framePt.x + frameWidth : aParams.framePt.x,
         nsLayoutUtils::GetSnappedBaselineY(this, aParams.context,
                                            aParams.framePt.y, mAscent));
   }
   Range range = ComputeTransformedRange(provider);
   uint32_t startOffset = range.start;
   uint32_t maxLength = range.Length();
   nscoord snappedStartEdge, snappedEndEdge;
-  if (!MeasureCharClippedText(provider, aItem.mVisIStartEdge,
-                              aItem.mVisIEndEdge, &startOffset, &maxLength,
-                              &snappedStartEdge, &snappedEndEdge)) {
+  if (!MeasureCharClippedText(provider, aVisIStartEdge, aVisIEndEdge,
+                              &startOffset, &maxLength, &snappedStartEdge,
+                              &snappedEndEdge)) {
     return;
   }
   if (verticalRun) {
     textBaselinePt.y += reversed ? -snappedEndEdge : snappedStartEdge;
   } else {
     textBaselinePt.x += reversed ? -snappedEndEdge : snappedStartEdge;
   }
-  nsCharClipDisplayItem::ClipEdges clipEdges(aItem, snappedStartEdge,
-                                             snappedEndEdge);
+  nsCharClipDisplayItem::ClipEdges clipEdges(this, aToReferenceFrame,
+                                             snappedStartEdge, snappedEndEdge);
   nsTextPaintStyle textPaintStyle(this);
   textPaintStyle.SetResolveColors(!aParams.callbacks);
 
   // Fork off to the (slower) paint-with-selection path if necessary.
-  if (isSelected) {
+  if (aIsSelected) {
     MOZ_ASSERT(aOpacity == 1.0f, "We don't support opacity with selections!");
     gfxSkipCharsIterator tmp(provider.GetStart());
     Range contentRange(
         uint32_t(tmp.ConvertSkippedToOriginal(startOffset)),
         uint32_t(tmp.ConvertSkippedToOriginal(startOffset + maxLength)));
     PaintTextSelectionParams params(aParams);
     params.textBaselinePt = textBaselinePt;
     params.provider = &provider;
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -451,18 +451,19 @@ class nsTextFrame : public nsFrame {
     explicit DrawTextParams(gfxContext* aContext)
         : DrawTextRunParams(aContext) {}
   };
 
   // Primary frame paint method called from nsDisplayText.  Can also be used
   // to generate paths rather than paint the frame's text by passing a callback
   // object.  The private DrawText() is what applies the text to a graphics
   // context.
-  void PaintText(const PaintTextParams& aParams,
-                 const nsCharClipDisplayItem& aItem, float aOpacity = 1.0f);
+  void PaintText(const PaintTextParams& aParams, const nscoord aVisIStartEdge,
+                 const nscoord aVisIEndEdge, const nsPoint& aToReferenceFrame,
+                 const bool aIsSelected, float aOpacity = 1.0f);
   // helper: paint text frame when we're impacted by at least one selection.
   // Return false if the text was not painted and we should continue with
   // the fast path.
   bool PaintTextWithSelection(
       const PaintTextSelectionParams& aParams,
       const nsCharClipDisplayItem::ClipEdges& aClipEdges);
   // helper: paint text with foreground and background colors determined
   // by selection(s). Also computes a mask of all selection types applying to
--- a/layout/painting/nsDisplayItemTypesList.h
+++ b/layout/painting/nsDisplayItemTypesList.h
@@ -61,18 +61,16 @@ DECLARE_DISPLAY_ITEM_TYPE(SELECTION_OVER
 DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR_REGION, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(SUBDOCUMENT, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(MASK, 0)
 DECLARE_DISPLAY_ITEM_TYPE(FILTER, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(SVG_GEOMETRY, TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(SVG_TEXT, TYPE_IS_CONTENTFUL)
-DECLARE_DISPLAY_ITEM_TYPE(SVG_CHAR_CLIP,
-                          TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(SVG_WRAPPER, 0)
 DECLARE_DISPLAY_ITEM_TYPE(FOREIGN_OBJECT, TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_BACKGROUND, 0)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_SELECTION, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_COLLAPSE, 0)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_BACKGROUND_COLOR, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_BACKGROUND_IMAGE, TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(TABLE_THEMED_BACKGROUND_IMAGE, TYPE_IS_CONTENTFUL)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2157,43 +2157,16 @@ class nsDisplayItem : public nsDisplayIt
   typedef mozilla::gfx::CompositorHitTestInfo CompositorHitTestInfo;
 
   // This is never instantiated directly (it has pure virtual methods), so no
   // need to count constructors and destructors.
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                 const ActiveScrolledRoot* aActiveScrolledRoot);
 
-  /**
-   * This constructor is only used in rare cases when we need to construct
-   * temporary items.
-   */
-  explicit nsDisplayItem(nsIFrame* aFrame)
-      : mFrame(aFrame),
-        mClipChain(nullptr),
-        mClip(nullptr),
-        mActiveScrolledRoot(nullptr),
-        mReferenceFrame(nullptr),
-        mAnimatedGeometryRoot(nullptr),
-        mForceNotVisible(false),
-        mDisableSubpixelAA(false),
-        mReusedItem(false),
-        mBackfaceIsHidden(mFrame->BackfaceIsHidden()),
-        mCombines3DTransformWithAncestors(
-            mFrame->Combines3DTransformWithAncestors()),
-        mPaintRectValid(false),
-        mCanBeReused(true)
-#ifdef MOZ_DUMP_PAINTING
-        ,
-        mPainted(false)
-#endif
-  {
-    MOZ_COUNT_CTOR(nsDisplayItem);
-  }
-
   nsDisplayItem() = delete;
 
  protected:
   virtual ~nsDisplayItem() {
     MOZ_COUNT_DTOR(nsDisplayItem);
     SetDisplayItemData(nullptr, nullptr);
     if (mFrame) {
       mFrame->RemoveDisplayItem(this);
@@ -7066,34 +7039,30 @@ class nsDisplayPerspective : public nsDi
  * The values must be non-negative.
  * The default value for both edges is zero, which means everything is painted.
  */
 class nsCharClipDisplayItem : public nsDisplayItem {
  public:
   nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
       : nsDisplayItem(aBuilder, aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
 
-  explicit nsCharClipDisplayItem(nsIFrame* aFrame)
-      : nsDisplayItem(aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
-
   void RestoreState() override { nsDisplayItem::RestoreState(); }
 
   nsDisplayItemGeometry* AllocateGeometry(
       nsDisplayListBuilder* aBuilder) override;
 
   void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                  const nsDisplayItemGeometry* aGeometry,
                                  nsRegion* aInvalidRegion) const override;
 
   struct ClipEdges {
-    ClipEdges(const nsDisplayItem& aItem, nscoord aVisIStartEdge,
-              nscoord aVisIEndEdge) {
-      nsRect r =
-          aItem.Frame()->GetScrollableOverflowRect() + aItem.ToReferenceFrame();
-      if (aItem.Frame()->GetWritingMode().IsVertical()) {
+    ClipEdges(const nsIFrame* aFrame, const nsPoint& aToReferenceFrame,
+              nscoord aVisIStartEdge, nscoord aVisIEndEdge) {
+      nsRect r = aFrame->GetScrollableOverflowRect() + aToReferenceFrame;
+      if (aFrame->GetWritingMode().IsVertical()) {
         mVisIStart = aVisIStartEdge > 0 ? r.y + aVisIStartEdge : nscoord_MIN;
         mVisIEnd = aVisIEndEdge > 0
                        ? std::max(r.YMost() - aVisIEndEdge, mVisIStart)
                        : nscoord_MAX;
       } else {
         mVisIStart = aVisIStartEdge > 0 ? r.x + aVisIStartEdge : nscoord_MIN;
         mVisIEnd = aVisIEndEdge > 0
                        ? std::max(r.XMost() - aVisIEndEdge, mVisIStart)
@@ -7106,24 +7075,18 @@ class nsCharClipDisplayItem : public nsD
       *aVisIStart = std::max(*aVisIStart, mVisIStart);
       *aVisISize = std::max(std::min(end, mVisIEnd) - *aVisIStart, 0);
     }
 
     nscoord mVisIStart;
     nscoord mVisIEnd;
   };
 
-  ClipEdges Edges() const {
-    return ClipEdges(*this, mVisIStartEdge, mVisIEndEdge);
-  }
-
   static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
-    DisplayItemType t = aItem->GetType();
-    return (t == DisplayItemType::TYPE_TEXT ||
-            t == DisplayItemType::TYPE_SVG_CHAR_CLIP)
+    return (aItem->GetType() == DisplayItemType::TYPE_TEXT)
                ? static_cast<nsCharClipDisplayItem*>(aItem)
                : nullptr;
   }
 
   bool IsSelected() const;
 
   // Lengths measured from the visual inline start and end sides
   // (i.e. left and right respectively in horizontal writing modes,
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -552,23 +552,20 @@ struct TextRenderedRun {
    * glyphs is at the right edge of the glyph cell.
    *
    *
    * For any other use of an nsTextFrame in the context of a particular run
    * (such as hit testing, or getting its rectangle),
    * GetTransformFromRunUserSpaceToUserSpace should be used.
    *
    * @param aContext The context to use for unit conversions.
-   * @param aItem The nsCharClipDisplayItem that holds the amount of clipping
-   *   from the left and right edges of the text frame for this rendered run.
-   *   An appropriate nsCharClipDisplayItem can be obtained by constructing an
-   *   SVGCharClipDisplayItem for the TextRenderedRun.
    */
   gfxMatrix GetTransformFromUserSpaceForPainting(
-      nsPresContext* aContext, const nsCharClipDisplayItem& aItem) const;
+      nsPresContext* aContext, const nscoord aVisIStartEdge,
+      const nscoord aVisIEndEdge) const;
 
   /**
    * Returns the transform that converts from "run user space" to a <text>
    * element's user space.  Run user space is a coordinate system that has the
    * same size as the <text>'s user space but rotated and translated such that
    * (0,0) is the top-left of the rectangle that bounds the text.
    *
    * @param aContext The context to use for unit conversions.
@@ -740,17 +737,18 @@ struct TextRenderedRun {
   /**
    * The character index in the whole SVG <text> element that this text rendered
    * run begins at.
    */
   uint32_t mTextElementCharIndex;
 };
 
 gfxMatrix TextRenderedRun::GetTransformFromUserSpaceForPainting(
-    nsPresContext* aContext, const nsCharClipDisplayItem& aItem) const {
+    nsPresContext* aContext, const nscoord aVisIStartEdge,
+    const nscoord aVisIEndEdge) const {
   // We transform to device pixels positioned such that painting the text frame
   // at (0,0) with aItem will result in the text being in the right place.
 
   gfxMatrix m;
   if (!mFrame) {
     return m;
   }
 
@@ -765,23 +763,24 @@ gfxMatrix TextRenderedRun::GetTransformF
 
   // Rotation due to rotate="" or a <textPath>.
   m.PreRotate(mRotate);
 
   m.PreScale(mLengthAdjustScaleFactor, 1.0);
 
   // Translation to get the text frame in the right place.
   nsPoint t;
+
   if (IsVertical()) {
     t = nsPoint(-mBaseline, IsRightToLeft()
-                                ? -mFrame->GetRect().height + aItem.mVisIEndEdge
-                                : -aItem.mVisIStartEdge);
+                                ? -mFrame->GetRect().height + aVisIEndEdge
+                                : -aVisIStartEdge);
   } else {
-    t = nsPoint(IsRightToLeft() ? -mFrame->GetRect().width + aItem.mVisIEndEdge
-                                : -aItem.mVisIStartEdge,
+    t = nsPoint(IsRightToLeft() ? -mFrame->GetRect().width + aVisIEndEdge
+                                : -aVisIStartEdge,
                 -mBaseline);
   }
   m.PreTranslate(AppUnitsToGfxUnits(t, aContext));
 
   return m;
 }
 
 gfxMatrix TextRenderedRun::GetTransformFromRunUserSpaceToUserSpace(
@@ -2509,33 +2508,16 @@ bool CharIterator::MatchesFilter() const
     return !IsOriginalCharUnaddressable();
   }
 
   return (mFilter == eClusterAndLigatureGroupStart) ==
          IsClusterAndLigatureGroupStart();
 }
 
 // -----------------------------------------------------------------------------
-// nsCharClipDisplayItem
-
-/**
- * An nsCharClipDisplayItem that obtains its left and right clip edges from a
- * TextRenderedRun object.
- */
-class SVGCharClipDisplayItem final : public nsCharClipDisplayItem {
- public:
-  explicit SVGCharClipDisplayItem(const TextRenderedRun& aRun)
-      : nsCharClipDisplayItem(aRun.mFrame) {
-    aRun.GetClipEdges(mVisIStartEdge, mVisIEndEdge);
-  }
-
-  NS_DISPLAY_DECL_NAME("SVGCharClip", TYPE_SVG_CHAR_CLIP)
-};
-
-// -----------------------------------------------------------------------------
 // SVGTextDrawPathCallbacks
 
 /**
  * Text frame draw callback class that paints the text and text decoration parts
  * of an nsTextFrame using SVG painting properties, and selection backgrounds
  * and decorations as they would normally.
  *
  * An instance of this class is passed to nsTextFrame::PaintText if painting
@@ -3350,52 +3332,54 @@ void SVGTextFrame::PaintSVG(gfxContext& 
   TextRenderedRun run = it.Current();
 
   SVGContextPaint* outerContextPaint =
       SVGContextPaint::GetContextPaint(GetContent());
 
   while (run.mFrame) {
     nsTextFrame* frame = run.mFrame;
 
-    // Determine how much of the left and right edges of the text frame we
-    // need to ignore.
-    SVGCharClipDisplayItem item(run);
-
     RefPtr<SVGContextPaintImpl> contextPaint = new SVGContextPaintImpl();
     DrawMode drawMode = contextPaint->Init(&aDrawTarget, initialMatrix, frame,
                                            outerContextPaint, aImgParams);
     if (drawMode & DrawMode::GLYPH_STROKE) {
       ctxSR.EnsureSaved(&aContext);
       // This may change the gfxContext's transform (for non-scaling stroke),
       // in which case this needs to happen before we call SetMatrix() below.
       nsSVGUtils::SetupStrokeGeometry(frame, &aContext, outerContextPaint);
     }
 
+    nscoord startEdge, endEdge;
+    run.GetClipEdges(startEdge, endEdge);
+
     // Set up the transform for painting the text frame for the substring
     // indicated by the run.
-    gfxMatrix runTransform =
-        run.GetTransformFromUserSpaceForPainting(presContext, item) *
-        currentMatrix;
+    gfxMatrix runTransform = run.GetTransformFromUserSpaceForPainting(
+                                 presContext, startEdge, endEdge) *
+                             currentMatrix;
     aContext.SetMatrixDouble(runTransform);
 
     if (drawMode != DrawMode(0)) {
       bool paintSVGGlyphs;
       nsTextFrame::PaintTextParams params(&aContext);
       params.framePt = Point();
       params.dirtyRect = LayoutDevicePixel::FromAppUnits(
           frame->GetVisualOverflowRect(), auPerDevPx);
       params.contextPaint = contextPaint;
+
+      const bool isSelected = frame->IsSelected();
+
       if (ShouldRenderAsPath(frame, paintSVGGlyphs)) {
         SVGTextDrawPathCallbacks callbacks(this, aContext, frame,
                                            matrixForPaintServers, aImgParams,
                                            paintSVGGlyphs);
         params.callbacks = &callbacks;
-        frame->PaintText(params, item);
+        frame->PaintText(params, startEdge, endEdge, nsPoint(), isSelected);
       } else {
-        frame->PaintText(params, item);
+        frame->PaintText(params, startEdge, endEdge, nsPoint(), isSelected);
       }
     }
 
     if (frame == caretFrame && ShouldPaintCaret(run, caret)) {
       // XXX Should we be looking at the fill/stroke colours to paint the
       // caret with, rather than using the color property?
       caret->PaintCaret(aDrawTarget, frame, nsPoint());
       aContext.NewPath();