Bug 1022612. Part 5: BuildDisplayListForExtraPage needs to pass the correct dirty rect in. r=mattwoodrow
☠☠ backed out by f365873fc32c ☠ ☠
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 09 Jun 2014 16:47:58 +1200
changeset 214795 6d2fc524e961188e589a7a1bc15ec23be28d2d21
parent 214794 cdaa916f6851fe278d16c48ce41b021c3cb8d421
child 214796 1ad096055f1d1d15a339fbe9e82edcf25a12ef74
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1022612
milestone33.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 1022612. Part 5: BuildDisplayListForExtraPage needs to pass the correct dirty rect in. r=mattwoodrow When printing, every page has the same origin. So doing this change naively would result in the first page having all the display items for every page added to it, and all but the first page's display items being pruned away by PruneDisplayListForExtraPage. This would making printing long documents very slow. We avoid that problem with the new check for NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO, so the only pages other than the current page we descend into are the ones with placeholders for abs-pos content on the current page.
layout/generic/nsPageFrame.cpp
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -409,32 +409,32 @@ PruneDisplayListForExtraPage(nsDisplayLi
         continue;
       }
     }
     newList.AppendToTop(i);
   }
   aList->AppendToTop(&newList);
 }
 
-static nsresult
+static void
 BuildDisplayListForExtraPage(nsDisplayListBuilder* aBuilder,
                              nsPageFrame* aPage, nsIFrame* aExtraPage,
-                             nsDisplayList* aList)
+                             const nsRect& aDirtyRect, nsDisplayList* aList)
 {
+  // The only content in aExtraPage we care about is out-of-flow content whose
+  // placeholders have occurred in aPage. If
+  // NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO is not set, then aExtraPage has
+  // no such content.
+  if (!aExtraPage->HasAnyStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
+    return;
+  }
   nsDisplayList list;
-  // Pass an empty dirty rect since we're only interested in finding
-  // placeholders whose out-of-flows are in the page
-  // aBuilder->GetReferenceFrame(), and the paths to those placeholders
-  // have already been marked as NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO.
-  // Note that we should still do a prune step since we don't want to
-  // rely on dirty-rect checking for correctness.
-  aExtraPage->BuildDisplayListForStackingContext(aBuilder, nsRect(), &list);
+  aExtraPage->BuildDisplayListForStackingContext(aBuilder, aDirtyRect, &list);
   PruneDisplayListForExtraPage(aBuilder, aPage, aExtraPage, &list);
   aList->AppendToTop(&list);
-  return NS_OK;
 }
 
 static nsIFrame*
 GetNextPage(nsIFrame* aPageContentFrame)
 {
   // XXX ugh
   nsIFrame* pageFrame = aPageContentFrame->GetParent();
   NS_ASSERTION(pageFrame->GetType() == nsGkAtoms::pageFrame,
@@ -501,29 +501,30 @@ nsPageFrame::BuildDisplayList(nsDisplayL
   {
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
 
     // Overwrite current clip, since we're going to wrap in a transform
     // and the current clip is no longer meaningful.
     clipState.Clear();
     clipState.ClipContainingBlockDescendants(clipRect, nullptr);
 
-    child->BuildDisplayListForStackingContext(aBuilder,
-      child->GetVisualOverflowRectRelativeToSelf(), &content);
+    nsRect dirtyRect = child->GetVisualOverflowRectRelativeToSelf();
+    child->BuildDisplayListForStackingContext(aBuilder, dirtyRect, &content);
 
     // We may need to paint out-of-flow frames whose placeholders are
     // on other pages. Add those pages to our display list. Note that
     // out-of-flow frames can't be placed after their placeholders so
     // we don't have to process earlier pages. The display lists for
     // these extra pages are pruned so that only display items for the
     // page we currently care about (which we would have reached by
     // following placeholders to their out-of-flows) end up on the list.
     nsIFrame* page = child;
     while ((page = GetNextPage(page)) != nullptr) {
-      BuildDisplayListForExtraPage(aBuilder, this, page, &content);
+      BuildDisplayListForExtraPage(aBuilder, this, page,
+          dirtyRect + child->GetOffsetTo(page), &content);
     }
 
     // Add the canvas background color to the bottom of the list. This
     // happens after we've built the list so that AddCanvasBackgroundColorItem
     // can monkey with the contents if necessary.
     nsRect backgroundRect =
       nsRect(aBuilder->ToReferenceFrame(child), child->GetSize());
     PresContext()->GetPresShell()->AddCanvasBackgroundColorItem(