Bug 1460279: Avoid copying clips during FrameLayerBuilder. r=mattwoodrow draft
authorBas Schouten <bschouten@mozilla.com>
Wed, 09 May 2018 18:10:42 +0200
changeset 793159 0bd0478cd893848ba6f321abe39e2f0137f98345
parent 793109 e58cd9cce17f079fb964287553c49c706732833d
child 793641 d263f282c3ee1eb5d315184bde6c671fc10b0c15
push id109300
push userbschouten@mozilla.com
push dateWed, 09 May 2018 16:11:07 +0000
reviewersmattwoodrow
bugs1460279
milestone62.0a1
Bug 1460279: Avoid copying clips during FrameLayerBuilder. r=mattwoodrow MozReview-Commit-ID: DNBXJTL4QaH
layout/painting/FrameLayerBuilder.cpp
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -540,16 +540,17 @@ public:
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
     mDisableFlattening(false),
     mBackfaceHidden(false),
     mShouldPaintOnContentSide(false),
     mDTCRequiresTargetConfirmation(false),
     mImage(nullptr),
+    mItemClip(nullptr),
     mNewChildLayersIndex(-1)
   {}
 
 #ifdef MOZ_DUMP_PAINTING
   /**
    * Keep track of important decisions for debugging.
    */
   nsCString mLog;
@@ -751,17 +752,17 @@ public:
   /**
    * Stores the clip that we need to apply to the image or, if there is no
    * image, a clip for SOME item in the layer. There is no guarantee which
    * item's clip will be stored here and mItemClip should not be used to clip
    * the whole layer - only some part of the clip should be used, as determined
    * by PaintedDisplayItemLayerUserData::GetCommonClipCount() - which may even be
    * no part at all.
    */
-  DisplayItemClip mItemClip;
+  const DisplayItemClip* mItemClip;
   /**
    * Index of this layer in mNewChildLayers.
    */
   int32_t mNewChildLayersIndex;
   /**
    * The region of visible content above the layer and below the
    * next PaintedLayerData currently in the stack, if any.
    * This is a conservative approximation: it contains the true region.
@@ -3267,19 +3268,19 @@ ContainerState::PrepareImageLayer(Painte
   }
 
   RefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer(aData->mLayer);
   imageLayer->SetContainer(imageContainer);
   aData->mImage->ConfigureLayer(imageLayer, mParameters);
   imageLayer->SetPostScale(mParameters.mXScale,
                            mParameters.mYScale);
 
-  if (aData->mItemClip.HasClip()) {
+  if (aData->mItemClip->HasClip()) {
     ParentLayerIntRect clip =
-      ViewAs<ParentLayerPixel>(ScaleToNearestPixels(aData->mItemClip.GetClipRect()));
+      ViewAs<ParentLayerPixel>(ScaleToNearestPixels(aData->mItemClip->GetClipRect()));
     clip.MoveBy(ViewAs<ParentLayerPixel>(mParameters.mOffset));
     imageLayer->SetClipRect(Some(clip));
   } else {
     imageLayer->SetClipRect(Nothing());
   }
 
   FLB_LOG_PAINTED_LAYER_DECISION(aData,
                                  "  Selected image layer=%p\n", imageLayer.get());
@@ -3455,17 +3456,17 @@ void ContainerState::FinishPaintedLayerD
         printf_stderr("Invalidating layer %p: %s\n", data->mLayer, str.get());
       }
 #endif
       data->mLayer->InvalidateWholeLayer();
     }
     userData->mForcedBackgroundColor = backgroundColor;
   } else {
     // mask layer for image and color layers
-    SetupMaskLayer(layer, data->mItemClip);
+    SetupMaskLayer(layer, *data->mItemClip);
   }
 
   uint32_t flags = 0;
   nsIWidget* widget = mContainerReferenceFrame->PresContext()->GetRootWidget();
   // See bug 941095. Not quite ready to disable this.
   bool hidpi = false && widget && widget->GetDefaultScale().scale >= 2;
   if (hidpi) {
     flags |= Layer::CONTENT_DISABLE_SUBPIXEL_AA;
@@ -3615,16 +3616,19 @@ PaintedLayerData::Accumulate(ContainerSt
                              LayerState aLayerState,
                              nsDisplayList* aList,
                              DisplayItemEntryType aType)
 {
   FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", aItem->Name(), aItem, aItem->Frame(), this);
 
   const bool hasOpacity = mOpacityIndices.Length() > 0;
 
+  const DisplayItemClip* oldClip = mItemClip;
+  mItemClip = &aClip;
+
   if (aType == DisplayItemEntryType::POP_OPACITY) {
     MOZ_ASSERT(!mOpacityIndices.IsEmpty());
     mOpacityIndices.RemoveLastElement();
 
     AssignedDisplayItem item(aItem, aLayerState,
                              nullptr, aType, hasOpacity);
     mAssignedDisplayItems.AppendElement(Move(item));
     return;
@@ -3649,18 +3653,17 @@ PaintedLayerData::Accumulate(ContainerSt
         AssignedDisplayItem& item = mAssignedDisplayItems[i];
         MOZ_ASSERT(item.mType == DisplayItemEntryType::PUSH_OPACITY ||
                    item.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG);
         item.mType = DisplayItemEntryType::PUSH_OPACITY_WITH_BG;
       }
     }
   }
 
-  bool clipMatches = mItemClip == aClip;
-  mItemClip = aClip;
+  bool clipMatches = (oldClip == mItemClip) || (oldClip && *oldClip == *mItemClip);
 
   DisplayItemData* currentData =
     aItem->HasMergedFrames() ? nullptr : aItem->GetDisplayItemData();
 
   DisplayItemData* oldData =
     aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
                                                aItem->GetPerFrameKey(),
                                                currentData);