Bug 1410904 - Convert WeakFrame to nsIFrame* earlier to avoid copying WeakFrames draft
authorMiko Mynttinen <mikokm@gmail.com>
Mon, 23 Oct 2017 18:19:39 +0200
changeset 684779 e6d31dc194f557d90ccda6cd9de4ee74e716245a
parent 684703 d49501f258b105c5e2dcd0a59896ec1ceabf726b
child 736967 5003ff24704ce543898d42eb0aa757d8a661d059
push id85728
push userbmo:mikokm@gmail.com
push dateMon, 23 Oct 2017 16:20:18 +0000
bugs1410904
milestone58.0a1
Bug 1410904 - Convert WeakFrame to nsIFrame* earlier to avoid copying WeakFrames MozReview-Commit-ID: KVzOtVATpNa
layout/painting/RetainedDisplayListBuilder.cpp
layout/painting/RetainedDisplayListBuilder.h
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -451,62 +451,68 @@ RetainedDisplayListBuilder::MergeDisplay
       old->Destroy(&mBuilder);
     }
   }
 
   aOutList->AppendToTop(&merged);
 }
 
 static void
-TakeAndAddModifiedFramesFromRootFrame(std::vector<WeakFrame>& aFrames,
+TakeAndAddModifiedFramesFromRootFrame(nsTArray<nsIFrame*>& aFrames,
                                       nsIFrame* aRootFrame)
 {
   MOZ_ASSERT(aRootFrame);
 
   std::vector<WeakFrame>* frames =
     aRootFrame->GetProperty(nsIFrame::ModifiedFrameList());
 
-  if (frames) {
-    for (WeakFrame& frame : *frames) {
-      aFrames.push_back(Move(frame));
+  if (!frames) {
+    return;
+  }
+
+  for (WeakFrame& frame : *frames) {
+    nsIFrame* f = frame.GetFrame();
+
+    if (f) {
+      aFrames.AppendElement(f);
     }
+  }
 
-    frames->clear();
-  }
+  frames->clear();
 }
 
 static bool
 SubDocEnumCb(nsIDocument* aDocument, void* aData)
 {
   MOZ_ASSERT(aDocument);
   MOZ_ASSERT(aData);
 
-  std::vector<WeakFrame>* modifiedFrames =
-    static_cast<std::vector<WeakFrame>*>(aData);
+  nsTArray<nsIFrame*>* modifiedFrames =
+    static_cast<nsTArray<nsIFrame*>*>(aData);
 
   nsIPresShell* presShell = aDocument->GetShell();
   nsIFrame* rootFrame = presShell ? presShell->GetRootFrame() : nullptr;
 
   if (rootFrame) {
     TakeAndAddModifiedFramesFromRootFrame(*modifiedFrames, rootFrame);
   }
 
   aDocument->EnumerateSubDocuments(SubDocEnumCb, aData);
   return true;
 }
 
-static std::vector<WeakFrame>
+static nsTArray<nsIFrame*>
 GetModifiedFrames(nsIFrame* aDisplayRootFrame)
 {
   MOZ_ASSERT(aDisplayRootFrame);
 
-  std::vector<WeakFrame> modifiedFrames;
+  nsTArray<nsIFrame*> modifiedFrames;
   TakeAndAddModifiedFramesFromRootFrame(modifiedFrames, aDisplayRootFrame);
 
-  nsIDocument *rootdoc = aDisplayRootFrame->PresContext()->Document();
+  nsIDocument* rootdoc = aDisplayRootFrame->PresContext()->Document();
 
   if (rootdoc) {
     rootdoc->EnumerateSubDocuments(SubDocEnumCb, &modifiedFrames);
   }
 
   return modifiedFrames;
 }
 
@@ -540,26 +546,24 @@ GetModifiedFrames(nsIFrame* aDisplayRoot
  * @param aOutModifiedAGR The modified AGR for the root stacking context.
  * @param aOutFramesWithProps The list of frames to which we attached partial build
  * data so that it can be cleaned up.
  *
  * @return true if we succesfully computed a partial rebuild region, false if a full
  * build is required.
  */
 bool
-RetainedDisplayListBuilder::ComputeRebuildRegion(std::vector<WeakFrame>& aModifiedFrames,
+RetainedDisplayListBuilder::ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedFrames,
                                                  nsRect* aOutDirty,
                                                  AnimatedGeometryRoot** aOutModifiedAGR,
                                                  nsTArray<nsIFrame*>* aOutFramesWithProps)
 {
   CRR_LOG("Computing rebuild regions for %d frames:\n", aModifiedFrames.size());
   for (nsIFrame* f : aModifiedFrames) {
-    if (!f) {
-      continue;
-    }
+    MOZ_ASSERT(f);
 
     if (f->HasOverrideDirtyRegion()) {
       aOutFramesWithProps->AppendElement(f);
     }
 
     // TODO: There is almost certainly a faster way of doing this, probably can be combined with the ancestor
     // walk for TransformFrameRectToAncestor.
     AnimatedGeometryRoot* agr = mBuilder.FindAnimatedGeometryRootFor(f)->GetAsyncAGR();
@@ -680,17 +684,18 @@ RetainedDisplayListBuilder::AttemptParti
 {
   mBuilder.RemoveModifiedWindowDraggingRegion();
   if (mBuilder.ShouldSyncDecodeImages()) {
     MarkFramesWithItemsAndImagesModified(&mList);
   }
 
   mBuilder.EnterPresShell(mBuilder.RootReferenceFrame());
 
-  std::vector<WeakFrame> modifiedFrames = GetModifiedFrames(mBuilder.RootReferenceFrame());
+  nsTArray<nsIFrame*> modifiedFrames =
+    GetModifiedFrames(mBuilder.RootReferenceFrame());
 
   if (mPreviousCaret != mBuilder.GetCaretFrame()) {
     if (mPreviousCaret) {
       mBuilder.MarkFrameModifiedDuringBuilding(mPreviousCaret);
     }
 
     if (mBuilder.GetCaretFrame()) {
       mBuilder.MarkFrameModifiedDuringBuilding(mBuilder.GetCaretFrame());
@@ -748,17 +753,16 @@ RetainedDisplayListBuilder::AttemptParti
 
   // TODO: Do we mark frames as modified during displaylist building? If
   // we do this isn't gonna work.
   for (nsIFrame* f : modifiedFrames) {
     if (f) {
       f->SetFrameIsModified(false);
     }
   }
-  modifiedFrames.clear();
 
   // Override dirty regions should only exist during this function. We set them up during
   // ComputeRebuildRegion, and clear them here.
   for (nsIFrame* f: framesWithProps) {
     f->SetHasOverrideDirtyRegion(false);
     f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingRect());
     f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
   }
--- a/layout/painting/RetainedDisplayListBuilder.h
+++ b/layout/painting/RetainedDisplayListBuilder.h
@@ -29,17 +29,17 @@ struct RetainedDisplayListBuilder {
 
 private:
   void PreProcessDisplayList(nsDisplayList* aList, AnimatedGeometryRoot* aAGR);
 
   void MergeDisplayLists(nsDisplayList* aNewList,
                          nsDisplayList* aOldList,
                          nsDisplayList* aOutList);
 
-  bool ComputeRebuildRegion(std::vector<WeakFrame>& aModifiedFrames,
+  bool ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedFrames,
                             nsRect* aOutDirty,
                             AnimatedGeometryRoot** aOutModifiedAGR,
                             nsTArray<nsIFrame*>* aOutFramesWithProps);
 
   void IncrementSubDocPresShellPaintCount(nsDisplayItem* aItem);
 
   nsDisplayListBuilder mBuilder;
   nsDisplayList mList;