b=786100 consider display item snap when hunting uniform background color r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 05 Dec 2012 15:53:17 +1300
changeset 115153 3399897304da595848f9626d32cc9f14982d4038
parent 115152 7ad2846f3ece3174e9ceb7678a8d4055d58012b7
child 115154 d3dc0b80efe3c2342eeaebbaa78ef17c908e37af
push id23973
push useremorley@mozilla.com
push dateThu, 06 Dec 2012 10:04:18 +0000
treeherdermozilla-central@ddda5400c826 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs786100
milestone20.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
b=786100 consider display item snap when hunting uniform background color r=roc
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1496,21 +1496,52 @@ ContainerState::FindOpaqueBackgroundColo
     intersection.And(candidate->mVisibleRegion, target->mVisibleRegion);
     if (intersection.IsEmpty()) {
       // The layer doesn't intersect our target, ignore it and move on
       continue;
     }
 
     // The candidate intersects our target. If any layer has a solid-color
     // area behind our target, this must be it. Scan its display items.
-    nsRect rect =
-      target->mVisibleRegion.GetBounds().ToAppUnits(mAppUnitsPerDevPixel);
-    rect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
-    return mLayerBuilder->
-      FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect);
+    nsIntRect deviceRect = target->mVisibleRegion.GetBounds();
+    nsRect appUnitRect = deviceRect.ToAppUnits(mAppUnitsPerDevPixel);
+    appUnitRect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
+
+    FrameLayerBuilder::ThebesLayerItemsEntry* entry =
+      mLayerBuilder->GetThebesLayerItemsEntry(candidate->mLayer);
+    NS_ASSERTION(entry, "Must know about this layer!");
+    for (int32_t j = entry->mItems.Length() - 1; j >= 0; --j) {
+      nsDisplayItem* item = entry->mItems[j].mItem;
+      bool snap;
+      nsRect bounds = item->GetBounds(mBuilder, &snap);
+      if (snap && mSnappingEnabled) {
+        nsIntRect snappedBounds = ScaleToNearestPixels(bounds);
+        if (!snappedBounds.Intersects(deviceRect))
+          continue;
+
+        if (!snappedBounds.Contains(deviceRect))
+          break;
+
+      } else {
+        // The layer's visible rect is already (close enough to) pixel
+        // aligned, so no need to round out and in here.
+        if (!bounds.Intersects(appUnitRect))
+          continue;
+
+        if (!bounds.Contains(appUnitRect))
+          break;
+      }
+
+      nscolor color;
+      if (item->IsUniform(mBuilder, &color) && NS_GET_A(color) == 255)
+        return color;
+
+      break;
+    }
+    break;
   }
   return NS_RGBA(0,0,0,0);
 }
 
 void
 ContainerState::ThebesLayerData::UpdateCommonClipCount(
     const FrameLayerBuilder::Clip& aCurrentClip)
 {
@@ -2608,38 +2639,16 @@ FrameLayerBuilder::SaveLastPaintOffset(T
     if (entry->mContainerLayerGeneration == 0) {
       entry->mContainerLayerGeneration = mContainerLayerGeneration;
     }
     entry->mLastPaintOffset = GetTranslationForThebesLayer(aLayer);
     entry->mHasExplicitLastPaintOffset = true;
   }
 }
 
-nscolor
-FrameLayerBuilder::FindOpaqueColorCovering(nsDisplayListBuilder* aBuilder,
-                                           ThebesLayer* aLayer,
-                                           const nsRect& aRect)
-{
-  ThebesLayerItemsEntry* entry = mThebesLayerItems.GetEntry(aLayer);
-  NS_ASSERTION(entry, "Must know about this layer!");
-  for (int32_t i = entry->mItems.Length() - 1; i >= 0; --i) {
-    nsDisplayItem* item = entry->mItems[i].mItem;
-    const nsRect& visible = item->GetVisibleRect();
-    if (!visible.Intersects(aRect))
-      continue;
-
-    nscolor color;
-    if (visible.Contains(aRect) && item->IsUniform(aBuilder, &color) &&
-        NS_GET_A(color) == 255)
-      return color;
-    break;
-  }
-  return NS_RGBA(0,0,0,0);
-}
-
 void
 ContainerState::CollectOldLayers()
 {
   for (Layer* layer = mContainerLayer->GetFirstChild(); layer;
        layer = layer->GetNextSibling()) {
     NS_ASSERTION(!layer->HasUserData(&gMaskLayerUserData),
                  "Mask layer in layer tree; could not be recycled.");
     if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -301,24 +301,16 @@ public:
                         nsDisplayItemGeometry** aOldGeometry = nullptr, 
                         Clip** aOldClip = nullptr,
                         nsTArray<nsIFrame*>* aChangedFrames = nullptr,
                         bool *aIsInvalid = nullptr);
 
   static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
 
   /**
-   * Try to determine whether the ThebesLayer aLayer paints an opaque
-   * single color everywhere it's visible in aRect.
-   * If successful, return that color, otherwise return NS_RGBA(0,0,0,0).
-   */
-  nscolor FindOpaqueColorCovering(nsDisplayListBuilder* aBuilder,
-                                  ThebesLayer* aLayer, const nsRect& aRect);
-
-  /**
    * Destroy any stored LayerManagerDataProperty and the associated data for
    * aFrame.
    */
   static void DestroyDisplayItemDataFor(nsIFrame* aFrame);
 
   LayerManager* GetRetainingLayerManager() { return mRetainingManager; }
 
   /**