Backout 4777ad9776ec (bug 820246) for causing frequent failures in background-image-zoom-1.html on Android
authorEd Morley <emorley@mozilla.com>
Thu, 13 Dec 2012 12:25:12 +0000
changeset 115891 e543e17b98243a806c5447df4fd281c31670b069
parent 115890 36a3cac9e3d99c1ee651bbe67dd7c712c90bccdf
child 115892 93beff102db235fcf61d8760bb97cbfb365879a9
push id19611
push useremorley@mozilla.com
push dateThu, 13 Dec 2012 12:25:44 +0000
treeherdermozilla-inbound@e543e17b9824 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs820246
milestone20.0a1
backs out4777ad9776ec145b6cf0f1fb4d262af7158246ca
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
Backout 4777ad9776ec (bug 820246) for causing frequent failures in background-image-zoom-1.html on Android
layout/base/nsDisplayItemTypesList.h
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsPresShell.cpp
layout/generic/nsCanvasFrame.cpp
layout/generic/nsCanvasFrame.h
layout/reftests/image/reftest.list
--- a/layout/base/nsDisplayItemTypesList.h
+++ b/layout/base/nsDisplayItemTypesList.h
@@ -4,18 +4,17 @@ DECLARE_DISPLAY_ITEM_TYPE_FLAGS(BACKGROU
 DECLARE_DISPLAY_ITEM_TYPE(BORDER)
 DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER)
 DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER)
 DECLARE_DISPLAY_ITEM_TYPE(BULLET)
 DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BORDER_BACKGROUND)
 DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BOX_SHADOW_OUTER)
 DECLARE_DISPLAY_ITEM_TYPE(BUTTON_FOREGROUND)
 DECLARE_DISPLAY_ITEM_TYPE(CANVAS)
-DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_COLOR)
-DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_IMAGE)
+DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND)
 DECLARE_DISPLAY_ITEM_TYPE(CANVAS_FOCUS)
 DECLARE_DISPLAY_ITEM_TYPE(CARET)
 DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX)
 DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON)
 DECLARE_DISPLAY_ITEM_TYPE(CLIP)
 DECLARE_DISPLAY_ITEM_TYPE(CLIP_ROUNDED_RECT)
 DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE)
 DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS)
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -44,17 +44,16 @@
 #include "nsSVGElement.h"
 #include "nsSVGClipPathFrame.h"
 #include "sampler.h"
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
 #include "nsIViewManager.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
-#include "nsCanvasFrame.h"
 
 #include "mozilla/StandardInteger.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 typedef FrameMetrics::ViewID ViewID;
@@ -2079,32 +2078,24 @@ static void CheckForBorderItem(nsDisplay
       nextItem->GetType() == nsDisplayItem::TYPE_BORDER) {
     aFlags |= nsCSSRendering::PAINTBG_WILL_PAINT_BORDER;
   }
 }
 
 void
 nsDisplayBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
                                 nsRenderingContext* aCtx) {
-  PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr);
-}
-
-void
-nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
-                                        nsRenderingContext* aCtx, const nsRect& aBounds,
-                                        nsRect* aClipRect) {
+
   nsPoint offset = ToReferenceFrame();
   uint32_t flags = aBuilder->GetBackgroundPaintFlags();
   CheckForBorderItem(this, flags);
-
   nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
-                                  aBounds,
+                                  mVisibleRect,
                                   nsRect(offset, mFrame->GetSize()),
-                                  flags, aClipRect, mLayer);
-
+                                  flags, nullptr, mLayer);
 }
 
 void nsDisplayBackgroundImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                                          const nsDisplayItemGeometry* aGeometry,
                                                          nsRegion* aInvalidRegion)
 {
   if (!mBackgroundStyle) {
     return;
@@ -2153,20 +2144,16 @@ nsDisplayBackgroundImage::GetBoundsInter
     return r + ToReferenceFrame();
   }
 
   if (!mBackgroundStyle) {
     return nsRect();
   }
 
   nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
-  if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
-    nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
-    borderBox = frame->CanvasArea() + ToReferenceFrame();
-  }
   const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
   return nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
                                                 borderBox, *mBackgroundStyle, layer);
 }
 
 uint32_t
 nsDisplayBackgroundImage::GetPerFrameKey()
 {
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -1908,19 +1908,16 @@ protected:
   typedef class mozilla::layers::ImageLayer ImageLayer;
 
   bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
   bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aClipRect,
                                   gfxRect* aDestRect);
   nsRect GetBoundsInternal();
 
-  void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
-                     const nsRect& aBounds, nsRect* aClipRect);
-
   // Cache the result of nsCSSRendering::FindBackground. Always null if
   // mIsThemed is true or if FindBackground returned false.
   const nsStyleBackground* mBackgroundStyle;
   /* If this background can be a simple image layer, we store the format here. */
   nsRefPtr<ImageContainer> mImageContainer;
   gfxRect mDestRect;
   /* Bounds of this display item */
   nsRect mBounds;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3747,17 +3747,17 @@ PresShell::IsSafeToFlush() const
 
   return isSafeToFlush;
 }
 
 
 void
 PresShell::FlushPendingNotifications(mozFlushType aType)
 {
-  // by default, flush animations if aType >= Flush_Style
+  // by default, flush animations if aType >= Flush_Style
   mozilla::ChangesToFlush flush(aType, aType >= Flush_Style);
   FlushPendingNotifications(flush);
 }
 
 void
 PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush)
 {
   /**
@@ -4826,18 +4826,18 @@ PresShell::AddPrintPreviewBackgroundItem
 }
 
 static bool
 AddCanvasBackgroundColor(const nsDisplayList& aList, nsIFrame* aCanvasFrame,
                          nscolor aColor)
 {
   for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
     if (i->GetUnderlyingFrame() == aCanvasFrame &&
-        i->GetType() == nsDisplayItem::TYPE_CANVAS_BACKGROUND_COLOR) {
-      nsDisplayCanvasBackgroundColor* bg = static_cast<nsDisplayCanvasBackgroundColor*>(i);
+        i->GetType() == nsDisplayItem::TYPE_CANVAS_BACKGROUND) {
+      nsDisplayCanvasBackground* bg = static_cast<nsDisplayCanvasBackground*>(i);
       bg->SetExtraBackgroundColor(aColor);
       return true;
     }
     nsDisplayList* sublist = i->GetSameCoordinateSystemChildren();
     if (sublist && AddCanvasBackgroundColor(*sublist, aCanvasFrame, aColor))
       return true;
   }
   return false;
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -173,47 +173,40 @@ nsRect nsCanvasFrame::CanvasArea() const
   nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
   if (scrollableFrame) {
     nsRect portRect = scrollableFrame->GetScrollPortRect();
     result.UnionRect(result, nsRect(nsPoint(0, 0), portRect.Size()));
   }
   return result;
 }
 
-void
-nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
-                                      nsRenderingContext* aCtx)
-{
-  nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
-  nsPoint offset = ToReferenceFrame();
-  nsRect bgClipRect = frame->CanvasArea() + offset;
-  if (NS_GET_A(mColor) > 0) {
-    aCtx->SetColor(mColor);
-    aCtx->FillRect(bgClipRect);
-  }
-}
-
 static void BlitSurface(gfxContext* aDest, const gfxRect& aRect, gfxASurface* aSource)
 {
   aDest->Translate(gfxPoint(aRect.x, aRect.y));
   aDest->SetSource(aSource);
   aDest->NewPath();
   aDest->Rectangle(gfxRect(0, 0, aRect.width, aRect.height));
   aDest->Fill();
   aDest->Translate(-gfxPoint(aRect.x, aRect.y));
 }
 
 void
-nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
-                                      nsRenderingContext* aCtx)
+nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
+                                 nsRenderingContext* aCtx)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
+  if (mIsBottommostLayer && NS_GET_A(mExtraBackgroundColor) > 0) {
+    aCtx->SetColor(mExtraBackgroundColor);
+    aCtx->FillRect(bgClipRect);
+  }
 
+  bool snap;
+  nsRect bounds = GetBounds(aBuilder, &snap);
   nsRenderingContext context;
   nsRefPtr<gfxContext> dest = aCtx->ThebesContext();
   nsRefPtr<gfxASurface> surf;
   nsRefPtr<gfxContext> ctx;
   gfxRect destRect;
 #ifndef MOZ_GFX_OPTIMIZE_MOBILE
   if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
       aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
@@ -232,24 +225,25 @@ nsDisplayCanvasBackgroundImage::Paint(ns
     if (surf) {
       ctx = new gfxContext(surf);
       ctx->Translate(-gfxPoint(destRect.x, destRect.y));
       context.Init(aCtx->DeviceContext(), ctx);
     }
   }
 #endif
 
-  PaintInternal(aBuilder,
-                surf ? &context : aCtx,
-                surf ? bgClipRect: mVisibleRect,
-                &bgClipRect);
-
+  nsCSSRendering::PaintBackground(mFrame->PresContext(), surf ? context : *aCtx, mFrame,
+                                  surf ? bounds : mVisibleRect,
+                                  nsRect(offset, mFrame->GetSize()),
+                                  aBuilder->GetBackgroundPaintFlags(),
+                                  &bgClipRect, mLayer);
   if (surf) {
     BlitSurface(dest, destRect, surf);
-    frame->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get());
+
+    GetUnderlyingFrame()->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get());
   }
 }
 
 /**
  * A display item to paint the focus ring for the document.
  *
  * The only reason this can't use nsDisplayGeneric is overriding GetBounds.
  */
@@ -303,24 +297,21 @@ nsCanvasFrame::BuildDisplayList(nsDispla
   if (IsVisibleForPainting(aBuilder)) {
     nsStyleContext* bgSC;
     const nsStyleBackground* bg = nullptr;
     bool isThemed = IsThemed();
     if (!isThemed &&
         nsCSSRendering::FindBackground(PresContext(), this, &bgSC)) {
       bg = bgSC->GetStyleBackground();
     }
-    aLists.BorderBackground()->AppendNewToTop(
-        new (aBuilder) nsDisplayCanvasBackgroundColor(aBuilder, this));
-
     // Create separate items for each background layer.
     NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
       rv = aLists.BorderBackground()->AppendNewToTop(
-          new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, i,
-                                                        isThemed, bg));
+          new (aBuilder) nsDisplayCanvasBackground(aBuilder, this, i,
+                                                   isThemed, bg));
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   nsIFrame* kid;
   for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
     // Put our child into its own pseudo-stack.
     rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -117,94 +117,91 @@ protected:
 };
 
 /**
  * Override nsDisplayBackground methods so that we pass aBGClipRect to
  * PaintBackground, covering the whole overflow area.
  * We can also paint an "extra background color" behind the normal
  * background.
  */
-class nsDisplayCanvasBackgroundColor : public nsDisplayItem {
+class nsDisplayCanvasBackground : public nsDisplayBackgroundImage {
 public:
-  nsDisplayCanvasBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame)
-    : nsDisplayItem(aBuilder, aFrame)
-    , mColor(NS_RGBA(0,0,0,0))
+  nsDisplayCanvasBackground(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
+                            uint32_t aLayer, bool aIsThemed,
+                            const nsStyleBackground* aBackgroundStyle)
+    : nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aIsThemed, aBackgroundStyle),
+      mExtraBackgroundColor(NS_RGBA(0,0,0,0))
   {
   }
 
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                  nsRegion* aVisibleRegion,
                                  const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE
   {
-    return NS_GET_A(mColor) > 0;
+    return NS_GET_A(mExtraBackgroundColor) > 0 ||
+      nsDisplayBackgroundImage::ComputeVisibility(aBuilder, aVisibleRegion,
+                                             aAllowVisibleRegionExpansion);
   }
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) MOZ_OVERRIDE
   {
-    if (NS_GET_A(mColor) == 255) {
+    if (NS_GET_A(mExtraBackgroundColor) == 255) {
       return nsRegion(GetBounds(aBuilder, aSnap));
     }
-    return nsRegion();
+    return nsDisplayBackgroundImage::GetOpaqueRegion(aBuilder, aSnap);
   }
   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE
   {
-    *aColor = mColor;
+    nscolor background;
+    if (!nsDisplayBackgroundImage::IsUniform(aBuilder, &background))
+      return false;
+    NS_ASSERTION(background == NS_RGBA(0,0,0,0),
+                 "The nsDisplayBackground for a canvas frame doesn't paint "
+                 "its background color normally");
+    *aColor = mExtraBackgroundColor;
     return true;
   }
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
   {
     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
     *aSnap = true;
     return frame->CanvasArea() + ToReferenceFrame();
   }
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE
   {
     // We need to override so we don't consider border-radius.
     aOutFrames->AppendElement(mFrame);
   }
+  virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
+  {
+    // Put background-attachment:fixed canvas background images in their own
+    // compositing layer. Since we know their background painting area can't
+    // change (unless the viewport size itself changes), async scrolling
+    // will work well.
+    return mBackgroundStyle &&
+      mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
+      !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
+  }
   virtual void NotifyRenderingChanged() MOZ_OVERRIDE
   {
     mFrame->Properties().Delete(nsIFrame::CachedBackgroundImage());
   }
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) MOZ_OVERRIDE;
+ 
+  // We still need to paint a background color as well as an image for this item, 
+  // so we can't support this yet.
+  virtual bool SupportsOptimizingToImage() { return false; }
 
   void SetExtraBackgroundColor(nscolor aColor)
   {
-    mColor = aColor;
+    mExtraBackgroundColor = aColor;
   }
 
-  NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR)
+  NS_DISPLAY_DECL_NAME("CanvasBackground", TYPE_CANVAS_BACKGROUND)
 
 private:
-  nscolor mColor;
-};
-
-class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
-public:
-  nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
-                                 uint32_t aLayer, bool aIsThemed, const nsStyleBackground* aBg)
-    : nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aIsThemed, aBg)
-  {}
-
-  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
-
-  virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
-  {
-    // Put background-attachment:fixed canvas background images in their own
-    // compositing layer. Since we know their background painting area can't
-    // change (unless the viewport size itself changes), async scrolling
-    // will work well.
-    return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
-           !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
-  }
- 
-  // We still need to paint a background color as well as an image for this item, 
-  // so we can't support this yet.
-  virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return false; }
-  
-  
-  NS_DISPLAY_DECL_NAME("CanvasBackgroundImage", TYPE_CANVAS_BACKGROUND_IMAGE)
+  nscolor mExtraBackgroundColor;
 };
 
 #endif /* nsCanvasFrame_h___ */
--- a/layout/reftests/image/reftest.list
+++ b/layout/reftests/image/reftest.list
@@ -1,9 +1,9 @@
-random-if(bug685516) fuzzy-if(Android,4,2) == background-image-zoom-1.html background-image-zoom-1-ref.html
+random-if(bug685516) == background-image-zoom-1.html background-image-zoom-1-ref.html
 == background-image-zoom-2.html about:blank
 == image-zoom-1.html image-zoom-1-ref.html
 == image-zoom-2.html image-zoom-1-ref.html
 == invalid-url-image-1.html invalid-url-image-1-ref.html
 == sync-image-switch-1a.html sync-image-switch-1-ref.html
 == sync-image-switch-1b.html sync-image-switch-1-ref.html
 == sync-image-switch-1c.html sync-image-switch-1-ref.html
 == sync-image-switch-1d.html sync-image-switch-1-ref.html