Respect SYNC_DECODE when deciding to use Webrender for nsDisplayBackgroundImage. (bug 1439960, r?mstange) draft
authorRyan Hunt <rhunt@eqrion.net>
Tue, 20 Mar 2018 13:42:05 -0500
changeset 770122 e81ed40aab34bd48cbabb6e80f1529fc8b8ecc0e
parent 770121 447e835dc664549a8bdbd4097d42773acf523f08
push id103336
push userbmo:rhunt@eqrion.net
push dateTue, 20 Mar 2018 20:03:46 +0000
reviewersmstange
bugs1439960
milestone61.0a1
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
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- 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.