Bug 1201327 - Let DLBI detect background-position changes. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Wed, 28 Oct 2015 22:52:15 +0100
changeset 270846 b0a00d6915bb7c858ae7e1d94c7507b76e23eddd
parent 270845 fec3431b0b127da40a84181bff9d039ad23050ee
child 270847 21cabf6ab3e9a254cdc9370986f300213b346cb2
push id29626
push usercbook@mozilla.com
push dateTue, 03 Nov 2015 11:00:46 +0000
treeherdermozilla-central@bb4d614a0b09 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1201327
milestone45.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 1201327 - Let DLBI detect background-position changes. r=mattwoodrow
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsDisplayListInvalidation.cpp
layout/base/nsDisplayListInvalidation.h
layout/reftests/image-rect/reftest.list
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2136,16 +2136,35 @@ nsDisplayBackgroundImage::nsDisplayBackg
                                                    const nsStyleBackground* aBackgroundStyle)
   : nsDisplayImageContainer(aBuilder, aFrame)
   , mBackgroundStyle(aBackgroundStyle)
   , mLayer(aLayer)
 {
   MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
 
   mBounds = GetBoundsInternal(aBuilder);
+  mDestArea = GetDestAreaInternal(aBuilder);
+}
+
+nsRect
+nsDisplayBackgroundImage::GetDestAreaInternal(nsDisplayListBuilder* aBuilder)
+{
+  if (!mBackgroundStyle) {
+    return nsRect();
+  }
+
+  nsPresContext* presContext = mFrame->PresContext();
+  uint32_t flags = aBuilder->GetBackgroundPaintFlags();
+  nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
+  const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+
+  nsBackgroundLayerState state =
+    nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
+                                           borderArea, borderArea, layer);
+  return state.mDestArea;
 }
 
 nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
   MOZ_COUNT_DTOR(nsDisplayBackgroundImage);
 #endif
 }
@@ -2786,16 +2805,23 @@ void nsDisplayBackgroundImage::ComputeIn
     // so invalidate everything (both old and new painting areas).
     aInvalidRegion->Or(bounds, geometry->mBounds);
 
     if (positioningArea.Size() != geometry->mPositioningArea.Size()) {
       NotifyRenderingChanged();
     }
     return;
   }
+  if (!mDestArea.IsEqualInterior(geometry->mDestArea)) {
+    // Dest area changed in a way that could cause everything to change,
+    // so invalidate everything (both old and new painting areas).
+    aInvalidRegion->Or(bounds, geometry->mBounds);
+    NotifyRenderingChanged();
+    return;
+  }
   if (aBuilder->ShouldSyncDecodeImages()) {
     const nsStyleImage& image = mBackgroundStyle->mLayers[mLayer].mImage;
     if (image.GetType() == eStyleImageType_Image &&
         geometry->ShouldInvalidateToSyncDecodeImages()) {
       aInvalidRegion->Or(*aInvalidRegion, bounds);
 
       NotifyRenderingChanged();
     }
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2571,16 +2571,21 @@ public:
   /**
    * Return the background positioning area.
    * (GetBounds() returns the background painting area.)
    * Can be called only when mBackgroundStyle is non-null.
    */
   nsRect GetPositioningArea();
 
   /**
+   * Return the destination area of one instance of the image.
+   */
+  nsRect GetDestArea() const { return mDestArea; }
+
+  /**
    * Returns true if existing rendered pixels of this display item may need
    * to be redrawn if the positioning area size changes but its position does
    * not.
    * If false, only the changed painting area needs to be redrawn when the
    * positioning area size changes but its position does not.
    */
   bool RenderingMightDependOnPositioningAreaSizeChange();
 
@@ -2610,16 +2615,17 @@ protected:
   typedef class mozilla::layers::ImageLayer ImageLayer;
 
   bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
   bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aClipRect,
                                   gfxRect* aDestRect);
   bool IsNonEmptyFixedImage() const;
   nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
+  nsRect GetDestAreaInternal(nsDisplayListBuilder* aBuilder);
 
   void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
                      const nsRect& aBounds, nsRect* aClipRect);
 
   // Determine whether we want to be separated into our own layer, independent
   // of whether this item can actually be layerized.
   enum ImageLayerization {
     WHENEVER_POSSIBLE,
@@ -2632,16 +2638,17 @@ protected:
   // Cache the result of nsCSSRendering::FindBackground. Always null if
   // mIsThemed is true or if FindBackground returned false.
   const nsStyleBackground* mBackgroundStyle;
   nsCOMPtr<imgIContainer> mImage;
   RefPtr<ImageContainer> mImageContainer;
   LayoutDeviceRect mImageLayerDestRect;
   /* Bounds of this display item */
   nsRect mBounds;
+  nsRect mDestArea;
   uint32_t mLayer;
 };
 
 
 /**
  * A display item to paint the native theme background for a frame.
  */
 class nsDisplayThemedBackground : public nsDisplayItem {
--- a/layout/base/nsDisplayListInvalidation.cpp
+++ b/layout/base/nsDisplayListInvalidation.cpp
@@ -58,23 +58,25 @@ nsDisplayBorderGeometry::MoveBy(const ns
   mContentRect.MoveBy(aOffset);
 }
 
 nsDisplayBackgroundGeometry::nsDisplayBackgroundGeometry(nsDisplayBackgroundImage* aItem,
                                                          nsDisplayListBuilder* aBuilder)
   : nsDisplayItemGeometry(aItem, aBuilder)
   , nsImageGeometryMixin(aItem, aBuilder)
   , mPositioningArea(aItem->GetPositioningArea())
+  , mDestArea(aItem->GetDestArea())
 {}
 
 void
 nsDisplayBackgroundGeometry::MoveBy(const nsPoint& aOffset)
 {
   nsDisplayItemGeometry::MoveBy(aOffset);
   mPositioningArea.MoveBy(aOffset);
+  mDestArea.MoveBy(aOffset);
 }
 
 nsDisplayThemedBackgroundGeometry::nsDisplayThemedBackgroundGeometry(nsDisplayThemedBackground* aItem,
                                                                      nsDisplayListBuilder* aBuilder)
   : nsDisplayItemGeometry(aItem, aBuilder)
   , mPositioningArea(aItem->GetPositioningArea())
   , mWindowIsActive(aItem->IsWindowActive())
 {}
--- a/layout/base/nsDisplayListInvalidation.h
+++ b/layout/base/nsDisplayListInvalidation.h
@@ -189,16 +189,17 @@ class nsDisplayBackgroundGeometry
   , public nsImageGeometryMixin<nsDisplayBackgroundGeometry>
 {
 public:
   nsDisplayBackgroundGeometry(nsDisplayBackgroundImage* aItem, nsDisplayListBuilder* aBuilder);
 
   virtual void MoveBy(const nsPoint& aOffset) override;
 
   nsRect mPositioningArea;
+  nsRect mDestArea;
 };
 
 class nsDisplayThemedBackgroundGeometry : public nsDisplayItemGeometry
 {
 public:
   nsDisplayThemedBackgroundGeometry(nsDisplayThemedBackground* aItem, nsDisplayListBuilder* aBuilder);
 
   virtual void MoveBy(const nsPoint& aOffset) override;
--- a/layout/reftests/image-rect/reftest.list
+++ b/layout/reftests/image-rect/reftest.list
@@ -1,14 +1,14 @@
 skip-if(B2G||Mulet) == background-common-usage-floating-point.html background-common-usage-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
 == background-common-usage-percent.html background-common-usage-ref.html
 == background-common-usage-pixel.html background-common-usage-ref.html
 == background-draw-nothing-empty-rect.html background-draw-nothing-ref.html
 == background-draw-nothing-invalid-syntax.html background-draw-nothing-ref.html
-asserts(0-4) == background-draw-nothing-malformed-images.html background-draw-nothing-ref.html # Bug 576419
+asserts(0-6) == background-draw-nothing-malformed-images.html background-draw-nothing-ref.html # Bug 576419
 == background-monster-rect.html background-monster-rect-ref.html
 == background-over-size-rect.html background-over-size-rect-ref.html
 == background-test-parser.html background-test-parser-ref.html
 fuzzy-if(Android||B2G,113,124) == background-with-other-properties.html background-with-other-properties-ref.html
 fuzzy-if(Android||B2G||Mulet,16,22) == background-zoom-1.html background-zoom-1-ref.html  # Bug 1128229 # Bug 1153574
 fuzzy-if(Mulet,2,11) == background-zoom-2.html background-zoom-2-ref.html # Bug 1153574
 == background-zoom-3.html background-zoom-3-ref.html
 == background-zoom-4.html background-zoom-4-ref.html