Bug 482689. Optimize display lists for backgrounds. r/sr=roc
authorStuart Parmenter <pavlov@pavlov.net>
Wed, 08 Apr 2009 08:19:51 -0700
changeset 27153 a5468a6bd7ee0ea95e5ca37c4af7969d6afd2285
parent 27152 683b00c3d1d1394ec6bb978a8baaf53dec3ce7d2
child 27154 e8c9280dce9196f971ef2a5876c7f4eaa7e9b893
push id6409
push userpavlov@mozilla.com
push dateFri, 10 Apr 2009 02:01:51 +0000
treeherdermozilla-central@a5468a6bd7ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs482689
milestone1.9.2a1pre
Bug 482689. Optimize display lists for backgrounds. r/sr=roc
gfx/src/thebes/nsThebesImage.cpp
layout/base/nsDisplayList.cpp
--- a/gfx/src/thebes/nsThebesImage.cpp
+++ b/gfx/src/thebes/nsThebesImage.cpp
@@ -798,10 +798,11 @@ nsThebesImage::ShouldUseImageSurfaces()
 // performance win -- the pixels are still correct and have the A byte
 // set to 0xff.
 void
 nsThebesImage::SetHasNoAlpha()
 {
     if (mFormat == gfxASurface::ImageFormatARGB32) {
         mFormat = gfxASurface::ImageFormatRGB24;
         mFormatChanged = PR_TRUE;
+        mAlphaDepth = 0;
     }
 }
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -52,16 +52,21 @@
 #include "gfxContext.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleTransformMatrix.h"
 #include "gfxMatrix.h"
 #ifdef MOZ_SVG
 #include "nsSVGIntegrationUtils.h"
 #endif
 
+#include "imgIContainer.h"
+#include "gfxIImageFrame.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIImage.h"
+
 nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
     PRBool aIsForEvents, PRBool aBuildCaret)
     : mReferenceFrame(aReferenceFrame),
       mMovingFrame(nsnull),
       mIgnoreScrollFrame(nsnull),
       mCurrentTableItem(nsnull),
       mBuildCaret(aBuildCaret),
       mEventDelivery(aIsForEvents),
@@ -488,24 +493,50 @@ void nsDisplayList::Sort(nsDisplayListBu
 
 PRBool
 nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
   // theme background overrides any other background
   if (mIsThemed)
     return PR_FALSE;
 
   const nsStyleBackground* bg;
-  PRBool hasBG =
-    nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg);
+
+  if (!nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg))
+    return PR_FALSE;
+
+  const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer();
+
+  // bottom layer's clip is used for the color
+  if (bottomLayer.mClip != NS_STYLE_BG_CLIP_BORDER ||
+      nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
+    return PR_FALSE;
+
+  if (NS_GET_A(bg->mBackgroundColor) == 255)
+    return PR_TRUE;
 
-  return (hasBG && NS_GET_A(bg->mBackgroundColor) == 255 &&
-          // bottom layer's clip is used for the color
-          bg->BottomLayer().mClip == NS_STYLE_BG_CLIP_BORDER &&
-          !nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->
-                                         mBorderRadius));
+  if (bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY) {
+    if (bottomLayer.mImage.mRequest) {
+      nsCOMPtr<imgIContainer> container;
+      bottomLayer.mImage.mRequest->GetImage(getter_AddRefs(container));
+      
+      PRUint32 nframes;
+      container->GetNumFrames(&nframes);
+      if (nframes == 1) {
+        nsCOMPtr<gfxIImageFrame> imgFrame;
+        container->GetCurrentFrame(getter_AddRefs(imgFrame));
+        nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
+
+        PRBool hasMask = img->GetHasAlphaMask();
+
+        return !hasMask;
+      }
+    }
+  }
+
+  return PR_FALSE;
 }
 
 PRBool
 nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder) {
   // theme background overrides any other background
   if (mIsThemed)
     return PR_FALSE;