Bug 1022612. Part 44: Make nsSimplePageSequence only paint the pages that are actually in the dirty rect. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 17 Jul 2014 15:39:39 +1200
changeset 217090 9fdf302757f5ea47fa6e2d4cb6e8916287e4b181
parent 217089 85a06c38dd4340553ab22fd7364148431948ceb7
child 217091 cb4b268ef5936ebfa6bed2c5835e8bc58b1662c0
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [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 44: Make nsSimplePageSequence only paint the pages that are actually in the dirty rect. r=mattwoodrow
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsPageFrame.cpp
layout/generic/nsSimplePageSequenceFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5231,16 +5231,22 @@ nsIFrame::GetOverflowAreasRelativeToSelf
 
 nsRect
 nsIFrame::GetScrollableOverflowRectRelativeToParent() const
 {
   return GetScrollableOverflowRect() + mRect.TopLeft();
 }
 
 nsRect
+nsIFrame::GetVisualOverflowRectRelativeToParent() const
+{
+  return GetVisualOverflowRect() + mRect.TopLeft();
+}
+
+nsRect
 nsIFrame::GetScrollableOverflowRectRelativeToSelf() const
 {
   if (IsTransformed()) {
     nsOverflowAreas* preTransformOverflows = static_cast<nsOverflowAreas*>
       (Properties().Get(PreTransformOverflowAreasProperty()));
     if (preTransformOverflows)
       return preTransformOverflows->ScrollableOverflow();
   }
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2265,16 +2265,25 @@ public:
    * coordinate system (before transforms are applied).
    *
    * @return the rect relative to this frame, before any CSS transforms have
    * been applied, i.e. in this frame's coordinate system
    */
   nsRect GetVisualOverflowRectRelativeToSelf() const;
 
   /**
+   * Same as GetVisualOverflowRect, except relative to the parent
+   * frame.
+   *
+   * @return the rect relative to the parent frame, in the parent frame's
+   * coordinate system
+   */
+  nsRect GetVisualOverflowRectRelativeToParent() const;
+
+  /**
    * Returns this frame's visual overflow rect as it would be before taking
    * account of SVG effects or transforms. The rect returned is relative to
    * this frame.
    */
   nsRect GetPreEffectsVisualOverflowRect() const;
 
   /**
    * Store the overflow area in the frame's mOverflow.mVisualDeltas
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -517,16 +517,22 @@ nsPageFrame::BuildDisplayList(nsDisplayL
     // 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,
           dirtyRect + child->GetOffsetTo(page), &content);
     }
 
+    // Invoke AutoBuildingDisplayList to ensure that the correct dirtyRect
+    // is used to compute the visible rect if AddCanvasBackgroundColorItem
+    // creates a display item.
+    nsDisplayListBuilder::AutoBuildingDisplayList
+      building(aBuilder, child, dirtyRect, true);
+
     // 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(
       *aBuilder, content, child, backgroundRect, NS_RGBA(0,0,0,0));
   }
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -783,20 +783,25 @@ nsSimplePageSequenceFrame::BuildDisplayL
 
   {
     // Clear clip state while we construct the children of the
     // nsDisplayTransform, since they'll be in a different coordinate system.
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
     clipState.Clear();
 
     nsIFrame* child = GetFirstPrincipalChild();
+    nsRect dirty = aDirtyRect;
+    dirty.ScaleInverseRoundOut(PresContext()->GetPrintPreviewScale());
+
     while (child) {
-      child->BuildDisplayListForStackingContext(aBuilder,
-          child->GetVisualOverflowRectRelativeToSelf(), &content);
-      aBuilder->ResetMarkedFramesForDisplayList();
+      if (child->GetVisualOverflowRectRelativeToParent().Intersects(dirty)) {
+        child->BuildDisplayListForStackingContext(aBuilder,
+            dirty - child->GetPosition(), &content);
+        aBuilder->ResetMarkedFramesForDisplayList();
+      }
       child = child->GetNextSibling();
     }
   }
 
   content.AppendNewToTop(new (aBuilder)
       nsDisplayTransform(aBuilder, this, &content, content.GetVisibleRect(),
                          ::ComputePageSequenceTransform));