Bug 800287 - Optimize display list processing. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 12 Oct 2012 12:38:25 +1300
changeset 110127 f283941dbf752aa8a1a8fa39ea857a644b387cdf
parent 110126 b1c3b7ae35719a30ce1e129bb0bfc6c14766a8a8
child 110128 b3c814e2d015fb6f98a3fd82dffb4363f367dc86
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersroc
bugs800287
milestone19.0a1
Bug 800287 - Optimize display list processing. r=roc
layout/base/FrameLayerBuilder.cpp
layout/base/nsDisplayList.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2000,16 +2000,20 @@ PaintInactiveLayer(nsDisplayListBuilder*
  * of ContainerState::Finish.
  */
 void
 ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
                                     FrameLayerBuilder::Clip& aClip,
                                     uint32_t aFlags)
 {
   SAMPLE_LABEL("ContainerState", "ProcessDisplayItems");
+
+  const nsIFrame* lastActiveScrolledRoot = nullptr;
+  nsPoint topLeft;
+
   for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
     nsDisplayItem::Type type = item->GetType();
     if (type == nsDisplayItem::TYPE_CLIP ||
         type == nsDisplayItem::TYPE_CLIP_ROUNDED_RECT) {
       FrameLayerBuilder::Clip childClip(aClip, item);
       ProcessDisplayItems(*item->GetList(), childClip, aFlags);
       continue;
     }
@@ -2030,29 +2034,31 @@ ContainerState::ProcessDisplayItems(cons
     mBounds.UnionRect(mBounds, itemContent);
     itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect);
 
     LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
 
     bool isFixed;
     bool forceInactive;
     const nsIFrame* activeScrolledRoot;
-    nsPoint topLeft;
     if (aFlags & NO_COMPONENT_ALPHA) {
       // When NO_COMPONENT_ALPHA is set, items will be flattened onto the
       // reference frame. In this case, force the active scrolled root to
       // that frame.
       forceInactive = true;
       activeScrolledRoot = mContainerReferenceFrame;
       topLeft = nsPoint(0, 0);
       isFixed = mBuilder->IsFixedItem(item, nullptr, activeScrolledRoot);
     } else {
       forceInactive = false;
       isFixed = mBuilder->IsFixedItem(item, &activeScrolledRoot);
-      topLeft = activeScrolledRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
+      if (activeScrolledRoot != lastActiveScrolledRoot) {
+        lastActiveScrolledRoot = activeScrolledRoot;
+        topLeft = activeScrolledRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
+      }
     }
   
     nsAutoPtr<nsDisplayItemGeometry> geometry(item->AllocateGeometry(mBuilder));
 
     // Assign the item to a layer
     if (layerState == LAYER_ACTIVE_FORCE ||
         (!forceInactive &&
          (layerState == LAYER_ACTIVE_EMPTY ||
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -658,17 +658,17 @@ public:
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     : mFrame(aFrame)
 #ifdef MOZ_DUMP_PAINTING
     , mPainted(false)
 #endif
   {
     if (aFrame) {
       mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame);
-      mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
+      mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
     }
   }
   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                 const nsIFrame* aReferenceFrame,
                 const nsPoint& aToReferenceFrame)
     : mFrame(aFrame)
     , mReferenceFrame(aReferenceFrame)
     , mToReferenceFrame(aToReferenceFrame)