Bug 1244258 - Back out bug 1201327 on Aurora in order to fix bug 1227327 and friends. a=lizzard
authorMarkus Stange <mstange@themasta.com>
Fri, 29 Jan 2016 21:16:46 +0100
changeset 304380 8248eb3a6e691340b49eab2963f94f98b360b859
parent 304379 7f5e09f676ed1f68d39a316bb6d5c32e00eef1f6
child 304381 a42a8c60245f542244b07c42be7ae4e3aa2eccdb
push id9187
push usercbook@mozilla.com
push dateFri, 04 Mar 2016 12:27:31 +0000
treeherdermozilla-aurora@8248eb3a6e69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslizzard
bugs1244258, 1201327, 1227327
milestone46.0a2
Bug 1244258 - Back out bug 1201327 on Aurora in order to fix bug 1227327 and friends. a=lizzard
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsDisplayListInvalidation.cpp
layout/base/nsDisplayListInvalidation.h
layout/reftests/image-rect/reftest.list
layout/reftests/invalidation/background-position-1-ref.html
layout/reftests/invalidation/background-position-1.html
layout/reftests/invalidation/reftest.list
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2285,40 +2285,21 @@ nsDisplayBackgroundImage::nsDisplayBackg
   : nsDisplayImageContainer(aBuilder, aFrame)
   , mBackgroundStyle(aBackgroundStyle)
   , mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
   , mLayer(aLayer)
 {
   MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
 
   mBounds = GetBoundsInternal(aBuilder);
-  mDestArea = GetDestAreaInternal(aBuilder);
   if (ShouldFixToViewport(aBuilder)) {
     mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
   }
 }
 
-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
 }
 
 static nsStyleContext* GetBackgroundStyleContext(nsIFrame* aFrame)
@@ -2609,17 +2590,17 @@ nsDisplayBackgroundImage::CanOptimizeToI
   if (!allowPartialImages && !state.mFillArea.Contains(state.mDestArea)) {
     return false;
   }
 
   // XXX Ignoring state.mAnchor. ImageLayer drawing snaps mDestArea edges to
   // layer pixel boundaries. This should be OK for now.
 
   int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
-  mImageLayerDestRect =
+  mDestRect =
     LayoutDeviceRect::FromAppUnits(state.mDestArea, appUnitsPerDevPixel);
 
   // Ok, we can turn this into a layer if needed.
   mImage = imageRenderer->GetImage();
   MOZ_ASSERT(mImage);
 
   return true;
 }
@@ -2702,17 +2683,17 @@ nsDisplayBackgroundImage::GetLayerState(
 
     MOZ_ASSERT(mImage);
     int32_t imageWidth;
     int32_t imageHeight;
     mImage->GetWidth(&imageWidth);
     mImage->GetHeight(&imageHeight);
     NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
 
-    const LayerRect destLayerRect = mImageLayerDestRect * aParameters.Scale();
+    const LayerRect destLayerRect = mDestRect * aParameters.Scale();
 
     // Calculate the scaling factor for the frame.
     const gfxSize scale = gfxSize(destLayerRect.width / imageWidth,
                                   destLayerRect.height / imageHeight);
 
     if ((scale.width != 1.0f || scale.height != 1.0f) &&
         (destLayerRect.width * destLayerRect.height >= 64 * 64)) {
       // Separate this image into a layer.
@@ -2764,20 +2745,20 @@ nsDisplayBackgroundImage::ConfigureLayer
   }
 
   // XXX(seth): Right now we ignore aParameters.Scale() and
   // aParameters.Offset(), because FrameLayerBuilder already applies
   // aParameters.Scale() via the layer's post-transform, and
   // aParameters.Offset() is always zero.
   MOZ_ASSERT(aParameters.Offset() == LayerIntPoint(0,0));
 
-  const LayoutDevicePoint p = mImageLayerDestRect.TopLeft();
+  const LayoutDevicePoint p = mDestRect.TopLeft();
   Matrix transform = Matrix::Translation(p.x, p.y);
-  transform.PreScale(mImageLayerDestRect.width / imageWidth,
-                     mImageLayerDestRect.height / imageHeight);
+  transform.PreScale(mDestRect.width / imageWidth,
+                     mDestRect.height / imageHeight);
   aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
 }
 
 void
 nsDisplayBackgroundImage::HitTest(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aRect,
                                   HitTestState* aState,
                                   nsTArray<nsIFrame*> *aOutFrames)
@@ -2963,23 +2944,16 @@ 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
@@ -2718,21 +2718,16 @@ 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();
 
@@ -2766,17 +2761,16 @@ 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,
@@ -2786,21 +2780,20 @@ protected:
   ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
                                          LayerManager* aManager);
 
   // 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;
+  LayoutDeviceRect mDestRect;
   AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
   /* 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,25 +58,23 @@ 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,17 +189,16 @@ 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-6) == background-draw-nothing-malformed-images.html background-draw-nothing-ref.html # Bug 576419
+asserts(0-4) == 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
deleted file mode 100644
--- a/layout/reftests/invalidation/background-position-1-ref.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<meta charset="utf-8">
-<title>Changes to background-position should not cause things to repaint that don't intersect the background image.</title>
-
-<style>
-
-body {
-  margin: 0;
-}
-
-#background {
-  height: 512px;
-  background-image: url(image_rgrg-256x256.png);
-  background-repeat: no-repeat;
-  background-position: 300px 100px;
-}
-
-#not-intersecting-background {
-  box-sizing: border-box;
-  width: 200px;
-  height: 200px;
-  margin: 50px;
-  border: 1px solid lime;
-}
-
-</style>
-
-<div id="background">
-  <div id="not-intersecting-background"></div>
-</div>
deleted file mode 100644
--- a/layout/reftests/invalidation/background-position-1.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<html lang="en" class="reftest-wait">
-<meta charset="utf-8">
-<title>Changes to background-position should not cause things to repaint that don't intersect the background image.</title>
-
-<style>
-
-body {
-  margin: 0;
-}
-
-#background {
-  height: 512px;
-  background-image: url(image_rgrg-256x256.png);
-  background-repeat: no-repeat;
-  background-position: 300px 50px;
-}
-
-#not-intersecting-background {
-  box-sizing: border-box;
-  width: 200px;
-  height: 200px;
-  margin: 50px;
-  border: 1px solid lime;
-}
-
-</style>
-
-<div id="background">
-  <div id="not-intersecting-background" class="reftest-no-paint"></div>
-</div>
-
-<script>
-
-function doTest() {
-  document.querySelector("#background").style.backgroundPosition = "300px 100px";
-  document.documentElement.removeAttribute("class");
-}
-document.addEventListener("MozReftestInvalidate", doTest);
-
-</script>
--- a/layout/reftests/invalidation/reftest.list
+++ b/layout/reftests/invalidation/reftest.list
@@ -65,12 +65,11 @@ pref(layers.single-tile.enabled,false) !
 != layer-splitting-6.html about:blank
 != layer-splitting-7.html about:blank
 fuzzy-if(gtkWidget,2,4) fuzzy-if(asyncPan,2,3955) fuzzy-if(OSX,179,30) == image-scrolling-zoom-1.html image-scrolling-zoom-1-ref.html
 != image-scrolling-zoom-1-ref.html image-scrolling-zoom-1-notref.html
 pref(layers.single-tile.enabled,false) != fast-scrolling.html about:blank
 != fractional-transform-1.html about:blank
 != fractional-transform-2.html about:blank
 != fractional-transform-3.html about:blank
-== background-position-1.html background-position-1-ref.html
 == zero-opacity-animation.html about:blank
 == zero-opacity-text.html about:blank
 == negative-w-component.html negative-w-component-ref.html
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2268,42 +2268,37 @@ nsStyleBackground::Destroy(nsPresContext
 
 nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
 {
   const nsStyleBackground* moreLayers =
     mImageCount > aOther.mImageCount ? this : &aOther;
   const nsStyleBackground* lessLayers =
     mImageCount > aOther.mImageCount ? &aOther : this;
 
-  nsChangeHint hint = nsChangeHint(0);
+  bool hasVisualDifference = false;
 
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, moreLayers) {
     if (i < lessLayers->mImageCount) {
-      nsChangeHint layerDifference = moreLayers->mLayers[i].CalcDifference(lessLayers->mLayers[i]);
-      hint |= layerDifference;
-      if (layerDifference &&
-          ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
-           (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))) {
-        hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
+      if (moreLayers->mLayers[i] != lessLayers->mLayers[i]) {
+        if ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
+            (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))
+          return NS_CombineHint(nsChangeHint_UpdateEffects,
+                                nsChangeHint_RepaintFrame);
+        hasVisualDifference = true;
       }
     } else {
-      hint |= nsChangeHint_RepaintFrame;
-      if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) {
-        hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
-      }
+      if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element)
+        return NS_CombineHint(nsChangeHint_UpdateEffects,
+                              nsChangeHint_RepaintFrame);
+      hasVisualDifference = true;
     }
   }
 
-  if (mBackgroundColor != aOther.mBackgroundColor) {
-    hint |= nsChangeHint_RepaintFrame;
-  }
-
-  if (hint) {
-    return hint;
-  }
+  if (hasVisualDifference || mBackgroundColor != aOther.mBackgroundColor)
+    return nsChangeHint_RepaintFrame;
 
   if (mAttachmentCount != aOther.mAttachmentCount ||
       mClipCount != aOther.mClipCount ||
       mOriginCount != aOther.mOriginCount ||
       mRepeatCount != aOther.mRepeatCount ||
       mPositionCount != aOther.mPositionCount ||
       mSizeCount != aOther.mSizeCount) {
     return nsChangeHint_NeutralChange;
@@ -2504,35 +2499,16 @@ nsStyleBackground::Layer::operator==(con
          mOrigin == aOther.mOrigin &&
          mRepeat == aOther.mRepeat &&
          mBlendMode == aOther.mBlendMode &&
          mPosition == aOther.mPosition &&
          mSize == aOther.mSize &&
          mImage == aOther.mImage;
 }
 
-nsChangeHint
-nsStyleBackground::Layer::CalcDifference(const Layer& aOther) const
-{
-  nsChangeHint hint = nsChangeHint(0);
-  if (mAttachment != aOther.mAttachment ||
-      mClip != aOther.mClip ||
-      mOrigin != aOther.mOrigin ||
-      mRepeat != aOther.mRepeat ||
-      mBlendMode != aOther.mBlendMode ||
-      mSize != aOther.mSize ||
-      mImage != aOther.mImage) {
-    hint |= nsChangeHint_RepaintFrame;
-  }
-  if (mPosition != aOther.mPosition) {
-    hint |= nsChangeHint_SchedulePaint;
-  }
-  return hint;
-}
-
 // --------------------
 // nsStyleDisplay
 //
 void nsTimingFunction::AssignFromKeyword(int32_t aTimingFunctionType)
 {
   switch (aTimingFunctionType) {
     case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
       mType = Type::StepStart;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -407,20 +407,19 @@ struct nsStyleBackground
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
   }
   void Destroy(nsPresContext* aContext);
 
   nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
   static nsChangeHint MaxDifference() {
-    return nsChangeHint_UpdateEffects |
-           nsChangeHint_RepaintFrame |
-           nsChangeHint_SchedulePaint |
-           nsChangeHint_NeutralChange;
+    return NS_CombineHint(nsChangeHint_UpdateEffects,
+                          NS_CombineHint(nsChangeHint_RepaintFrame,
+                                         nsChangeHint_NeutralChange));
   }
   static nsChangeHint DifferenceAlwaysHandledForDescendants() {
     // CalcDifference never returns the reflow hints that are sometimes
     // handled for descendants at all.
     return nsChangeHint(0);
   }
 
   struct Position;
@@ -564,19 +563,16 @@ struct nsStyleBackground
 
     // True if the rendering of this layer might change when the size
     // of the background positioning area changes.  This is true for any
     // non-solid-color background whose position or size depends on
     // the size of the positioning area.  It's also true for SVG images
     // whose root <svg> node has a viewBox.
     bool RenderingMightDependOnPositioningAreaSizeChange() const;
 
-    // Compute the change hint required by changes in just this layer.
-    nsChangeHint CalcDifference(const Layer& aOther) const;
-
     // An equality operator that compares the images using URL-equality
     // rather than pointer-equality.
     bool operator==(const Layer& aOther) const;
     bool operator!=(const Layer& aOther) const {
       return !(*this == aOther);
     }
   };