Bug 1376855 - Support nsDisplayBackgroundImage in layers free mode. r=kats draft
authorMorris Tseng <mtseng@mozilla.com>
Wed, 28 Jun 2017 15:07:45 -0700
changeset 603970 859960e7df22bcfc1cab42aca72872dee237b235
parent 603969 d8bb6f47a807a4397a75d589456d08fa95a7be26
child 603971 74ec9bc3b66ad0c1bd478725f88052419e5b28fd
push id66921
push userbmo:mtseng@mozilla.com
push dateWed, 05 Jul 2017 03:31:35 +0000
reviewerskats
bugs1376855
milestone56.0a1
Bug 1376855 - Support nsDisplayBackgroundImage in layers free mode. r=kats MozReview-Commit-ID: KaIAVfNB4E5
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
layout/painting/nsImageRenderer.cpp
layout/painting/nsImageRenderer.h
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -1991,17 +1991,19 @@ nsCSSRendering::CanBuildWebRenderDisplay
   return false;
 }
 
 DrawResult
 nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
                                                              mozilla::wr::DisplayListBuilder& aBuilder,
                                                              const mozilla::layers::StackingContextHelper& aSc,
                                                              nsTArray<WebRenderParentCommand>& aParentCommands,
-                                                             mozilla::layers::WebRenderDisplayItemLayer* aLayer)
+                                                             mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                                             mozilla::layers::WebRenderLayerManager* aManager,
+                                                             nsDisplayItem* aItem)
 {
   NS_PRECONDITION(aParams.frame,
                   "Frame is expected to be provided to BuildWebRenderDisplayItemsForStyleImageLayer");
 
   nsStyleContext *sc;
   if (!FindBackground(aParams.frame, &sc)) {
     // We don't want to bail out if moz-appearance is set on a root
     // node. If it has a parent content node, bail because it's not
@@ -2014,18 +2016,18 @@ nsCSSRendering::BuildWebRenderDisplayIte
 
     nsIContent* content = aParams.frame->GetContent();
     if (!content || content->GetParent()) {
       return DrawResult::SUCCESS;
     }
 
     sc = aParams.frame->StyleContext();
   }
-
-  return BuildWebRenderDisplayItemsForStyleImageLayerWithSC(aParams, aBuilder, aSc, aParentCommands, aLayer,
+  return BuildWebRenderDisplayItemsForStyleImageLayerWithSC(aParams, aBuilder, aSc, aParentCommands,
+                                                            aLayer, aManager, aItem,
                                                             sc, *aParams.frame->StyleBorder());
 }
 
 static bool
 IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
 {
   if (aBorder.GetComputedBorder().Side(aSide) == 0)
     return true;
@@ -2738,25 +2740,21 @@ nsCSSRendering::PaintStyleImageLayerWith
 }
 
 DrawResult
 nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
                                                                    mozilla::wr::DisplayListBuilder& aBuilder,
                                                                    const mozilla::layers::StackingContextHelper& aSc,
                                                                    nsTArray<WebRenderParentCommand>& aParentCommands,
                                                                    mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                                                   mozilla::layers::WebRenderLayerManager* aManager,
+                                                                   nsDisplayItem* aItem,
                                                                    nsStyleContext *aBackgroundSC,
                                                                    const nsStyleBorder& aBorder)
 {
-  MOZ_ASSERT(CanBuildWebRenderDisplayItemsForStyleImageLayer(aLayer->WrManager(),
-                                                             aParams.presCtx,
-                                                             aParams.frame,
-                                                             aBackgroundSC->StyleBackground(),
-                                                             aParams.layer));
-
   MOZ_ASSERT(!(aParams.paintFlags & PAINTBG_MASK_IMAGE));
 
   nscoord appUnitsPerPixel = aParams.presCtx.AppUnitsPerDevPixel();
   ImageLayerClipState clipState;
 
   clipState.mBGClipArea = *aParams.bgClipRect;
   clipState.mCustomClip = true;
   clipState.mHasRoundedCorners = false;
@@ -2783,17 +2781,18 @@ nsCSSRendering::BuildWebRenderDisplayIte
   DrawResult result = DrawResult::SUCCESS;
   nsBackgroundLayerState state =
     PrepareImageLayer(&aParams.presCtx, aParams.frame,
                       aParams.paintFlags, paintBorderArea,
                       clipState.mBGClipArea, layer, nullptr);
   result &= state.mImageRenderer.PrepareResult();
   if (!state.mFillArea.IsEmpty()) {
     return state.mImageRenderer.BuildWebRenderDisplayItemsForLayer(&aParams.presCtx,
-                                     aBuilder, aSc, aParentCommands, aLayer,
+                                     aBuilder, aSc, aParentCommands,
+                                     aLayer, aManager, aItem,
                                      state.mDestArea, state.mFillArea,
                                      state.mAnchor + paintBorderArea.TopLeft(),
                                      clipState.mDirtyRectInAppUnits,
                                      state.mRepeatSize, aParams.opacity);
   }
 
   return result;
 }
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -498,23 +498,27 @@ struct nsCSSRendering {
                                                               nsPresContext& aPresCtx,
                                                               nsIFrame *aFrame,
                                                               const nsStyleBackground* aBackgroundStyle,
                                                               int32_t aLayer);
   static DrawResult BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
                                                                  mozilla::wr::DisplayListBuilder& aBuilder,
                                                                  const mozilla::layers::StackingContextHelper& aSc,
                                                                  nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
-                                                                 mozilla::layers::WebRenderDisplayItemLayer* aLayer);
+                                                                 mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                                                 mozilla::layers::WebRenderLayerManager* aManager,
+                                                                 nsDisplayItem* aItem);
 
   static DrawResult BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
                                                                        mozilla::wr::DisplayListBuilder& aBuilder,
                                                                        const mozilla::layers::StackingContextHelper& aSc,
                                                                        nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
                                                                        mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                                                       mozilla::layers::WebRenderLayerManager* aManager,
+                                                                       nsDisplayItem* aItem,
                                                                        nsStyleContext *mBackgroundSC,
                                                                        const nsStyleBorder& aBorder);
 
   /**
    * Returns the rectangle covered by the given background layer image, taking
    * into account background positioning, sizing, and repetition, but not
    * clipping.
    */
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3528,31 +3528,65 @@ nsDisplayBackgroundImage::CanBuildWebRen
   return mBackgroundStyle->mImage.mLayers[mLayer].mClip != StyleGeometryBox::Text &&
          nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer(aManager,
                                                                          *StyleFrame()->PresContext(),
                                                                          StyleFrame(),
                                                                          mBackgroundStyle,
                                                                          mLayer);
 }
 
+bool
+nsDisplayBackgroundImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                                  const StackingContextHelper& aSc,
+                                                  nsTArray<WebRenderParentCommand>& aParentCommands,
+                                                  WebRenderLayerManager* aManager,
+                                                  nsDisplayListBuilder* aDisplayListBuilder)
+{
+  if (!CanBuildWebRenderDisplayItems(aManager)) {
+    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;
+  DrawResult result =
+    nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params, aBuilder, aSc, aParentCommands, nullptr, aManager, this);
+  nsDisplayBackgroundGeometry::UpdateDrawResult(this, result);
+
+  return true;
+}
+
 void
 nsDisplayBackgroundImage::CreateWebRenderCommand(wr::DisplayListBuilder& aBuilder,
                                                  const StackingContextHelper& aSc,
                                                  nsTArray<WebRenderParentCommand>& aParentCommands,
                                                  WebRenderDisplayItemLayer* aLayer)
 {
   nsCSSRendering::PaintBGParams params =
     nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
                                                   mVisibleRect, mBackgroundRect,
                                                   StyleFrame(), mImageFlags, mLayer,
                                                   CompositionOp::OP_OVER);
   params.bgClipRect = &mBounds;
 
   DrawResult result =
-    nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params, aBuilder, aSc, aParentCommands, aLayer);
+    nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params,
+                                                                 aBuilder,
+                                                                 aSc,
+                                                                 aParentCommands,
+                                                                 aLayer,
+                                                                 aLayer->WrManager(),
+                                                                 this);
 
   nsDisplayBackgroundGeometry::UpdateDrawResult(this, result);
 }
 
 void
 nsDisplayBackgroundImage::HitTest(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aRect,
                                   HitTestState* aState,
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3127,17 +3127,21 @@ public:
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
 
   virtual void CreateWebRenderCommand(mozilla::wr::DisplayListBuilder& aBuilder,
                                       const StackingContextHelper& aSc,
                                       nsTArray<WebRenderParentCommand>& aParentCommands,
                                       WebRenderDisplayItemLayer* aLayer) override;
-
+  virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                       const StackingContextHelper& aSc,
+                                       nsTArray<WebRenderParentCommand>& aParentCommands,
+                                       mozilla::layers::WebRenderLayerManager* aManager,
+                                       nsDisplayListBuilder* aDisplayListBuilder) override;
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                  nsRegion* aVisibleRegion) override;
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) override;
   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
   /**
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -585,16 +585,18 @@ nsImageRenderer::Draw(nsPresContext*    
 }
 
 DrawResult
 nsImageRenderer::BuildWebRenderDisplayItems(nsPresContext*       aPresContext,
                                             mozilla::wr::DisplayListBuilder&            aBuilder,
                                             const mozilla::layers::StackingContextHelper& aSc,
                                             nsTArray<WebRenderParentCommand>&           aParentCommands,
                                             mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                            mozilla::layers::WebRenderLayerManager* aManager,
+                                            nsDisplayItem*       aItem,
                                             const nsRect&        aDirtyRect,
                                             const nsRect&        aDest,
                                             const nsRect&        aFill,
                                             const nsPoint&       aAnchor,
                                             const nsSize&        aRepeatSize,
                                             const CSSIntRect&    aSrc,
                                             float                aOpacity)
 {
@@ -619,23 +621,26 @@ nsImageRenderer::BuildWebRenderDisplayIt
     case eStyleImageType_Image:
     {
       // XXX(aosmond): We will support downscale-on-decode in bug 1368776. Until
       // then, don't pass FLAG_HIGH_QUALITY_SCALING.
       uint32_t containerFlags = imgIContainer::FLAG_NONE;
       if (mFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
         containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
       }
-      RefPtr<layers::ImageContainer> container = mImageContainer->GetImageContainer(aLayer->WrManager(),
-                                                                                    containerFlags);
+      RefPtr<layers::ImageContainer> container =
+        mImageContainer->GetImageContainer(aManager, containerFlags);
       if (!container) {
         NS_WARNING("Failed to get image container");
         return DrawResult::NOT_READY;
       }
-      Maybe<wr::ImageKey> key = aLayer->SendImageContainer(container, aParentCommands);
+
+      gfx::IntSize size;
+      Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aSc, size);
+
       if (key.isNothing()) {
         return DrawResult::BAD_IMAGE;
       }
 
       const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
       LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
           aDest, appUnitsPerDevPixel);
 
@@ -725,33 +730,35 @@ nsImageRenderer::DrawLayer(nsPresContext
 }
 
 DrawResult
 nsImageRenderer::BuildWebRenderDisplayItemsForLayer(nsPresContext*       aPresContext,
                                                     mozilla::wr::DisplayListBuilder& aBuilder,
                                                     const mozilla::layers::StackingContextHelper& aSc,
                                                     nsTArray<WebRenderParentCommand>& aParentCommands,
                                                     WebRenderDisplayItemLayer*       aLayer,
+                                                    mozilla::layers::WebRenderLayerManager* aManager,
+                                                    nsDisplayItem*       aItem,
                                                     const nsRect&        aDest,
                                                     const nsRect&        aFill,
                                                     const nsPoint&       aAnchor,
                                                     const nsRect&        aDirty,
                                                     const nsSize&        aRepeatSize,
                                                     float                aOpacity)
 {
   if (!IsReady()) {
     NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
     return mPrepareResult;
   }
   if (aDest.IsEmpty() || aFill.IsEmpty() ||
       mSize.width <= 0 || mSize.height <= 0) {
     return DrawResult::SUCCESS;
   }
-
-  return BuildWebRenderDisplayItems(aPresContext, aBuilder, aSc, aParentCommands, aLayer,
+  return BuildWebRenderDisplayItems(aPresContext, aBuilder, aSc, aParentCommands,
+                                    aLayer, aManager, aItem,
                                     aDirty, aDest, aFill, aAnchor, aRepeatSize,
                                     CSSIntRect(0, 0,
                                                nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
                                                nsPresContext::AppUnitsToIntCSSPixels(mSize.height)),
                                     aOpacity);
 }
 
 /**
--- a/layout/painting/nsImageRenderer.h
+++ b/layout/painting/nsImageRenderer.h
@@ -12,16 +12,17 @@
 
 class gfxDrawable;
 namespace mozilla {
 
 namespace layers {
 class StackingContextHelper;
 class WebRenderParentCommand;
 class WebRenderDisplayItemLayer;
+class WebRenderLayerManager;
 } // namespace layers
 
 namespace wr {
 class DisplayListBuilder;
 } // namespace wr
 
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
 // in computing image sizes. Either or both of the width and height might be
@@ -207,16 +208,18 @@ public:
    * {background|mask}-specific arguments.
    * @see nsLayoutUtils::DrawImage() for parameters.
    */
   DrawResult BuildWebRenderDisplayItemsForLayer(nsPresContext*       aPresContext,
                                                 mozilla::wr::DisplayListBuilder& aBuilder,
                                                 const mozilla::layers::StackingContextHelper& aSc,
                                                 nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                                 mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                                mozilla::layers::WebRenderLayerManager* aManager,
+                                                nsDisplayItem*       aItem,
                                                 const nsRect&        aDest,
                                                 const nsRect&        aFill,
                                                 const nsPoint&       aAnchor,
                                                 const nsRect&        aDirty,
                                                 const nsSize&        aRepeatSize,
                                                 float                aOpacity);
 
   /**
@@ -292,16 +295,18 @@ private:
    *
    * @see nsLayoutUtils::DrawImage() for other parameters.
    */
   DrawResult BuildWebRenderDisplayItems(nsPresContext*       aPresContext,
                                         mozilla::wr::DisplayListBuilder& aBuilder,
                                         const mozilla::layers::StackingContextHelper& aSc,
                                         nsTArray<layers::WebRenderParentCommand>& aParentCommands,
                                         mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+                                        mozilla::layers::WebRenderLayerManager* aManager,
+                                        nsDisplayItem*       aItem,
                                         const nsRect&        aDirtyRect,
                                         const nsRect&        aDest,
                                         const nsRect&        aFill,
                                         const nsPoint&       aAnchor,
                                         const nsSize&        aRepeatSize,
                                         const mozilla::CSSIntRect& aSrc,
                                         float                aOpacity = 1.0);