Respect SYNC_DECODE when deciding to use Webrender for nsDisplayBackgroundImage. (
bug 1439960, r?mstange)
Previously CreateWebrenderCommands would use GetLayerState to determine whether to use Webrender or
take the fallback path. GetLayerState would then under some cases call CanOptimizeToImageLayer()
which would get the image container using the appropriate flags for sync decoding.
Now nsDisplayBackgroundImage only uses CanCreateWebrenderCommands, which doesn't pass the correct
flags to image container, leading to reftest failures in some cases. This commit fixes that.
MozReview-Commit-ID: KlslXVHlRi5
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2048,17 +2048,18 @@ nsCSSRendering::PaintStyleImageLayer(con
return PaintStyleImageLayerWithSC(aParams, aRenderingCtx, sc, *aParams.frame->StyleBorder());
}
bool
nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer(LayerManager* aManager,
nsPresContext& aPresCtx,
nsIFrame *aFrame,
const nsStyleBackground* aBackgroundStyle,
- int32_t aLayer)
+ int32_t aLayer,
+ uint32_t mPaintFlags)
{
if (!aBackgroundStyle) {
return false;
}
MOZ_ASSERT(aFrame &&
aLayer >= 0 &&
(uint32_t)aLayer < aBackgroundStyle->mImage.mLayers.Length());
@@ -2081,19 +2082,24 @@ nsCSSRendering::CanBuildWebRenderDisplay
return false;
}
imgRequestProxy* requestProxy = styleImage->GetImageData();
if (!requestProxy) {
return false;
}
+ uint32_t imageFlags = imgIContainer::FLAG_NONE;
+ if (mPaintFlags & nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES) {
+ imageFlags |= imgIContainer::FLAG_SYNC_DECODE;
+ }
+
nsCOMPtr<imgIContainer> srcImage;
requestProxy->GetImage(getter_AddRefs(srcImage));
- if (!srcImage || !srcImage->IsImageContainerAvailable(aManager, imgIContainer::FLAG_NONE)) {
+ if (!srcImage || !srcImage->IsImageContainerAvailable(aManager, imageFlags)) {
return false;
}
return true;
}
if (styleImage->GetType() == eStyleImageType_Gradient) {
return true;
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -526,17 +526,18 @@ struct nsCSSRendering {
gfxContext& aRenderingCtx,
nsStyleContext *mBackgroundSC,
const nsStyleBorder& aBorder);
static bool CanBuildWebRenderDisplayItemsForStyleImageLayer(LayerManager* aManager,
nsPresContext& aPresCtx,
nsIFrame *aFrame,
const nsStyleBackground* aBackgroundStyle,
- int32_t aLayer);
+ int32_t aLayer,
+ uint32_t mPaintFlags);
static ImgDrawResult BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayItem* aItem);
static ImgDrawResult BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4094,41 +4094,43 @@ nsDisplayBackgroundImage::BuildLayer(nsD
}
RefPtr<ImageContainer> imageContainer = GetContainer(aManager, aBuilder);
layer->SetContainer(imageContainer);
ConfigureLayer(layer, aParameters);
return layer.forget();
}
bool
-nsDisplayBackgroundImage::CanBuildWebRenderDisplayItems(LayerManager* aManager)
-{
+nsDisplayBackgroundImage::CanBuildWebRenderDisplayItems(LayerManager* aManager, nsDisplayListBuilder* aDisplayListBuilder)
+{
+ if (aDisplayListBuilder) {
+ mImageFlags = aDisplayListBuilder->GetBackgroundPaintFlags();
+ }
+
return mBackgroundStyle->mImage.mLayers[mLayer].mClip != StyleGeometryBox::Text &&
nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer(aManager,
*StyleFrame()->PresContext(),
StyleFrame(),
mBackgroundStyle,
- mLayer);
+ mLayer,
+ mImageFlags);
}
bool
nsDisplayBackgroundImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
ContainerLayerParameters parameter;
- if (!CanBuildWebRenderDisplayItems(aManager)) {
+ if (!CanBuildWebRenderDisplayItems(aManager, aDisplayListBuilder)) {
return false;
}
- if (aDisplayListBuilder) {
- mImageFlags = aDisplayListBuilder->GetBackgroundPaintFlags();
- }
CheckForBorderItem(this, mImageFlags);
nsCSSRendering::PaintBGParams params =
nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
mVisibleRect, mBackgroundRect,
StyleFrame(), mImageFlags, mLayer,
CompositionOp::OP_OVER);
params.bgClipRect = &mBounds;
ImgDrawResult result =
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3979,17 +3979,17 @@ public:
}
nsDisplayItem::RemoveFrame(aFrame);
}
protected:
typedef class mozilla::layers::ImageContainer ImageContainer;
typedef class mozilla::layers::ImageLayer ImageLayer;
- bool CanBuildWebRenderDisplayItems(LayerManager* aManager);
+ bool CanBuildWebRenderDisplayItems(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrameForBounds = nullptr);
void PaintInternal(nsDisplayListBuilder* aBuilder, gfxContext* 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.