Bug 821477 - Don't build nsDisplay{Canvas}BackgroundImage items when the image is empty. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 14 Dec 2012 11:16:14 +1300
changeset 115972 777fd91b7fda0325d0dc715967fc798fd68dd5ef
parent 115971 afc699fc7e652428f9dd016b8f921b7426bfcf74
child 115973 fb65298e7117d72491c786a32d1c1ec961c1711b
push id19655
push usermwoodrow@mozilla.com
push dateThu, 13 Dec 2012 22:16:20 +0000
treeherdermozilla-inbound@777fd91b7fda [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs821477
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
Bug 821477 - Don't build nsDisplay{Canvas}BackgroundImage items when the image is empty. r=roc
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.cpp
layout/generic/nsCanvasFrame.cpp
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2840,18 +2840,17 @@ nsCSSRendering::ComputeBackgroundPositio
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
     geometryFrame->ApplySkipSides(border);
     bgPositioningArea.Deflate(border);
   }
 
   nsIFrame* attachedToFrame = aForFrame;
-  if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment &&
-      !aLayer.mImage.IsEmpty()) {
+  if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
     // If it's a fixed background attachment, then the image is placed
     // relative to the viewport, which is the area of the root frame
     // in a screen context or the page content frame in a print context.
     attachedToFrame = aPresContext->PresShell()->FrameManager()->GetRootFrame();
     NS_ASSERTION(attachedToFrame, "no root frame");
     nsIFrame* pageContentFrame = nullptr;
     if (aPresContext->IsPaginated()) {
       pageContentFrame =
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1544,18 +1544,17 @@ nsDisplayBackgroundImage::nsDisplayBackg
     }
   } else if (mBackgroundStyle) {
     // Set HasFixedItems if we construct a background-attachment:fixed item
     if (mLayer != mBackgroundStyle->mImageCount - 1) {
       mIsBottommostLayer = false;
     }
 
     // Check if this background layer is attachment-fixed
-    if (!mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty() &&
-        mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED) {
+    if (mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED) {
       aBuilder->SetHasFixedItems();
     }
   }
 
   mBounds = GetBoundsInternal();
 }
 
 nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
@@ -1589,21 +1588,39 @@ nsDisplayBackgroundImage::AppendBackgrou
                                                drawBackgroundImage, drawBackgroundColor);
   }
 
   // Even if we don't actually have a background color to paint, we still need
   // to create the item because it's used for hit testing.
   aList->AppendNewToTop(
       new (aBuilder) nsDisplayBackgroundColor(aBuilder, aFrame, bg,
                                               drawBackgroundColor ? color : NS_RGBA(0, 0, 0, 0)));
+
+  if (isThemed) {
+    nsDisplayBackgroundImage* bgItem =
+      new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, 0, isThemed, nullptr);
+    nsresult rv = aList->AppendNewToTop(bgItem);
+    if (rv != NS_OK) {
+      return rv;
+    }
+    *aBackground = bgItem;
+    return NS_OK;
+  }
+
+  if (!bg) {
+    return NS_OK;
+  }
  
   // Passing bg == nullptr in this macro will result in one iteration with
   // i = 0.
   bool backgroundSet = !aBackground;
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
+    if (bg->mLayers[i].mImage.IsEmpty()) {
+      continue;
+    }
     nsDisplayBackgroundImage* bgItem =
       new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, isThemed, bg);
     nsresult rv = aList->AppendNewToTop(bgItem);
     if (rv != NS_OK) {
       return rv;
     }
     if (!backgroundSet) {
       *aBackground = bgItem;
@@ -1997,20 +2014,16 @@ nsDisplayBackgroundImage::IsUniform(nsDi
     }
     return false;
   }
 
   if (!mBackgroundStyle) {
     *aColor = NS_RGBA(0,0,0,0);
     return true;
   }
-  if (mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty()) {
-    *aColor = NS_RGBA(0,0,0,0);
-    return true;
-  }
   return false;
 }
 
 bool
 nsDisplayBackgroundImage::IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
                                                          nsIFrame* aFrame)
 {
   // theme background overrides any other background and is never fixed
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -305,19 +305,31 @@ nsCanvasFrame::BuildDisplayList(nsDispla
     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));
+  
+    if (isThemed) {
+      return aLists.BorderBackground()->AppendNewToTop(
+        new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, 0, isThemed, nullptr));
+    }
+
+    if (!bg) {
+      return NS_OK;
+    }
 
     // Create separate items for each background layer.
     NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
+      if (bg->mLayers[i].mImage.IsEmpty()) {
+        continue;
+      }
       rv = aLists.BorderBackground()->AppendNewToTop(
           new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, i,
                                                         isThemed, bg));
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   nsIFrame* kid;