Bug 934860 - Don't paint display items that don't intersect the current invalid rects. r=roc, a=
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 07 Nov 2013 08:10:50 +1300
changeset 166465 99414b9538100a4221f75a0c61a67cc384320915
parent 166464 05c2a19d916d7a746bb4d0b0a4e5fcc2dcddc020
child 166466 019969972ed0d4f34a2ab5973b0fd2ebcb15ca11
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs934860
milestone27.0a2
Bug 934860 - Don't paint display items that don't intersect the current invalid rects. r=roc, a=
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -3164,30 +3164,40 @@ FrameLayerBuilder::RecomputeVisibilityFo
         visible = newVisible;
       }
     }
   }
 }
 
 void
 FrameLayerBuilder::PaintItems(nsTArray<ClippedDisplayItem>& aItems,
+                              const nsIntRect& aRect,
                               gfxContext *aContext,
                               nsRenderingContext *aRC,
                               nsDisplayListBuilder* aBuilder,
                               nsPresContext* aPresContext,
+                              const nsIntPoint& aOffset,
+                              float aXScale, float aYScale,
                               int32_t aCommonClipCount)
 {
+  int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
+  nsRect boundRect = aRect.ToAppUnits(appUnitsPerDevPixel);
+  boundRect.MoveBy(NSIntPixelsToAppUnits(aOffset.x, appUnitsPerDevPixel),
+                 NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel));
+  boundRect.ScaleInverseRoundOut(aXScale, aYScale);
+
   DisplayItemClip currentClip;
   bool currentClipIsSetInContext = false;
   DisplayItemClip tmpClip;
 
   for (uint32_t i = 0; i < aItems.Length(); ++i) {
     ClippedDisplayItem* cdi = &aItems[i];
 
-    if (cdi->mItem->GetVisibleRect().IsEmpty())
+    nsRect paintRect = cdi->mItem->GetVisibleRect().Intersect(boundRect);
+    if (paintRect.IsEmpty())
       continue;
 
     // If the new desired clip state is different from the current state,
     // update the clip.
     const DisplayItemClip* clip = &cdi->mItem->GetClip();
     if (clip->GetRoundedRectCount() > 0 &&
         !clip->IsRectClippedByRoundedCorner(cdi->mItem->GetVisibleRect())) {
       tmpClip = *clip;
@@ -3358,29 +3368,31 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
       DrawForcedBackgroundColor(aContext, aLayer, userData->mForcedBackgroundColor);
 
       // Apply the residual transform if it has been enabled, to ensure that
       // snapping when we draw into aContext exactly matches the ideal transform.
       // See above for why this is OK.
       aContext->Translate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y));
       aContext->Scale(userData->mXScale, userData->mYScale);
 
-      layerBuilder->PaintItems(entry->mItems, aContext, rc,
+      layerBuilder->PaintItems(entry->mItems, *iterRect, aContext, rc,
                                builder, presContext,
+                               offset, userData->mXScale, userData->mYScale,
                                entry->mCommonClipCount);
     }
   } else {
     // Apply the residual transform if it has been enabled, to ensure that
     // snapping when we draw into aContext exactly matches the ideal transform.
     // See above for why this is OK.
     aContext->Translate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y));
     aContext->Scale(userData->mXScale, userData->mYScale);
 
-    layerBuilder->PaintItems(entry->mItems, aContext, rc,
+    layerBuilder->PaintItems(entry->mItems, aRegionToDraw.GetBounds(), aContext, rc,
                              builder, presContext,
+                             offset, userData->mXScale, userData->mYScale,
                              entry->mCommonClipCount);
   }
 
   if (presContext->GetPaintFlashing()) {
     FlashPaint(aContext);
   }
 
   if (!aRegionToInvalidate.IsEmpty()) {
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -525,20 +525,23 @@ protected:
                                           nsDisplayListBuilder* aBuilder,
                                           const nsIntRegion& aRegionToDraw,
                                           const nsIntPoint& aOffset,
                                           int32_t aAppUnitsPerDevPixel,
                                           float aXScale,
                                           float aYScale);
 
   void PaintItems(nsTArray<ClippedDisplayItem>& aItems,
+                  const nsIntRect& aRect,
                   gfxContext* aContext,
                   nsRenderingContext* aRC,
                   nsDisplayListBuilder* aBuilder,
                   nsPresContext* aPresContext,
+                  const nsIntPoint& aOffset,
+                  float aXScale, float aYScale,
                   int32_t aCommonClipCount);
 
   /**
    * We accumulate ClippedDisplayItem elements in a hashtable during
    * the paint process. This is the hashentry for that hashtable.
    */
 public:
   class ThebesLayerItemsEntry : public nsPtrHashKey<ThebesLayer> {