Bug 482689. Optimize display lists for backgrounds. r/sr=roc
--- 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;