Bug 1390804 - Apply WR mask to ScrollingLayersHelper for layers-free. r=kats draft
authorEthan Lin <ethlin@mozilla.com>
Thu, 17 Aug 2017 17:32:50 +0800
changeset 648155 cc17088b584e21c750677eaefff1d33333074593
parent 647355 9ab2470a3210324bc11320531b15d195aaf05051
child 726729 56107618ab4cdb64f4bd02e45d0de2c5215d5013
push id74649
push userbmo:ethlin@mozilla.com
push dateThu, 17 Aug 2017 09:50:52 +0000
reviewerskats
bugs1390804
milestone57.0a1
Bug 1390804 - Apply WR mask to ScrollingLayersHelper for layers-free. r=kats MozReview-Commit-ID: CbfQXqWtiLg
gfx/layers/wr/ScrollingLayersHelper.cpp
gfx/layers/wr/ScrollingLayersHelper.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -6,17 +6,16 @@
 #include "mozilla/layers/ScrollingLayersHelper.h"
 
 #include "FrameMetrics.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/WebRenderLayer.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "UnitTransforms.h"
-
 namespace mozilla {
 namespace layers {
 
 ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
                                              wr::DisplayListBuilder& aBuilder,
                                              const StackingContextHelper& aStackingContext)
   : mLayer(aLayer)
   , mBuilder(&aBuilder)
@@ -106,60 +105,62 @@ ScrollingLayersHelper::ScrollingLayersHe
   } else {
     PushLayerLocalClip(aStackingContext);
   }
 }
 
 ScrollingLayersHelper::ScrollingLayersHelper(nsDisplayItem* aItem,
                                              wr::DisplayListBuilder& aBuilder,
                                              const StackingContextHelper& aStackingContext,
+                                             const wr::WrImageMask* aMask,
                                              WebRenderLayerManager::ClipIdMap& aCache)
   : mLayer(nullptr)
   , mBuilder(&aBuilder)
   , mPushedLayerLocalClip(false)
   , mClipsPushed(0)
 {
   DefineAndPushChain(aItem->GetClipChain(), aBuilder, aStackingContext,
-      aItem->Frame()->PresContext()->AppUnitsPerDevPixel(), aCache);
+      aItem->Frame()->PresContext()->AppUnitsPerDevPixel(), aMask, aCache);
 }
 
 void
 ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
                                           wr::DisplayListBuilder& aBuilder,
                                           const StackingContextHelper& aStackingContext,
                                           int32_t aAppUnitsPerDevPixel,
+                                          const wr::WrImageMask* aMask,
                                           WebRenderLayerManager::ClipIdMap& aCache)
 {
   if (!aChain) {
     return;
   }
   auto it = aCache.find(aChain);
   Maybe<wr::WrClipId> clipId = (it != aCache.end() ? Some(it->second) : Nothing());
   if (clipId && clipId == aBuilder.TopmostClipId()) {
     // it was already in the cache and pushed on the WR clip stack, so we don't
     // need to recurse any further.
     return;
   }
   // Recurse up the clip chain to make sure all ancestor clips are defined and
   // pushed onto the WR clip stack. Note that the recursion can invalidate the
   // iterator `it`.
-  DefineAndPushChain(aChain->mParent, aBuilder, aStackingContext, aAppUnitsPerDevPixel, aCache);
+  DefineAndPushChain(aChain->mParent, aBuilder, aStackingContext, aAppUnitsPerDevPixel, aMask, aCache);
 
   if (!aChain->mClip.HasClip()) {
     // This item in the chain is a no-op, skip over it
     return;
   }
   if (!clipId) {
     // If we don't have a clip id for this chain item yet, define the clip in WR
     // and save the id
     LayoutDeviceRect clip = LayoutDeviceRect::FromAppUnits(
         aChain->mClip.GetClipRect(), aAppUnitsPerDevPixel);
     nsTArray<wr::WrComplexClipRegion> wrRoundedRects;
     aChain->mClip.ToWrComplexClipRegions(aAppUnitsPerDevPixel, aStackingContext, wrRoundedRects);
-    clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects));
+    clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip), &wrRoundedRects, aMask));
     aCache[aChain] = clipId.value();
   }
   // Finally, push the clip onto the WR stack
   MOZ_ASSERT(clipId);
   aBuilder.PushClip(clipId.value());
   mClipsPushed++;
 }
 
--- a/gfx/layers/wr/ScrollingLayersHelper.h
+++ b/gfx/layers/wr/ScrollingLayersHelper.h
@@ -27,24 +27,26 @@ class MOZ_RAII ScrollingLayersHelper
 {
 public:
   ScrollingLayersHelper(WebRenderLayer* aLayer,
                         wr::DisplayListBuilder& aBuilder,
                         const StackingContextHelper& aSc);
   ScrollingLayersHelper(nsDisplayItem* aItem,
                         wr::DisplayListBuilder& aBuilder,
                         const StackingContextHelper& aStackingContext,
+                        const wr::WrImageMask* aMask,
                         WebRenderLayerManager::ClipIdMap& aCache);
   ~ScrollingLayersHelper();
 
 private:
   void DefineAndPushChain(const DisplayItemClipChain* aChain,
                           wr::DisplayListBuilder& aBuilder,
                           const StackingContextHelper& aStackingContext,
                           int32_t aAppUnitsPerDevPixel,
+                          const wr::WrImageMask* aMask,
                           WebRenderLayerManager::ClipIdMap& aCache);
   void PushLayerLocalClip(const StackingContextHelper& aStackingContext);
   void PushLayerClip(const LayerClip& aClip,
                      const StackingContextHelper& aSc);
 
   WebRenderLayer* mLayer;
   wr::DisplayListBuilder* mBuilder;
   bool mPushedLayerLocalClip;
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -188,17 +188,18 @@ PopulateScrollData(WebRenderScrollData& 
   aTarget.GetLayerDataMutable(index)->Initialize(aTarget, aLayer, descendants);
   return descendants + 1;
 }
 
 void
 WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
                                                               nsDisplayListBuilder* aDisplayListBuilder,
                                                               const StackingContextHelper& aSc,
-                                                              wr::DisplayListBuilder& aBuilder)
+                                                              wr::DisplayListBuilder& aBuilder,
+                                                              const wr::WrImageMask* aMask)
 {
   bool apzEnabled = AsyncPanZoomEnabled();
   const ActiveScrolledRoot* lastAsr = nullptr;
 
   nsDisplayList savedItems;
   nsDisplayItem* item;
   while ((item = aDisplayList->RemoveBottom()) != nullptr) {
     DisplayItemType itemType = item->GetType();
@@ -260,17 +261,17 @@ WebRenderLayerManager::CreateWebRenderCo
       // ASR so that if we recurse into a sublist they will know where to stop
       // walking up their ASR chain when building scroll metadata.
       if (forceNewLayerData) {
         mAsrStack.push_back(asr);
       }
     }
 
     { // scope the ScrollingLayersHelper
-      ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache);
+      ScrollingLayersHelper clip(item, aBuilder, aSc, aMask, mClipIdCache);
 
       // Note: this call to CreateWebRenderCommands can recurse back into
       // this function if the |item| is a wrapper for a sublist.
       if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this,
                                          aDisplayListBuilder)) {
         PushItemAsImage(item, aBuilder, aSc, aDisplayListBuilder);
       }
     }
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -82,17 +82,18 @@ public:
                                           const LayerRect& aBounds);
   bool PushItemAsImage(nsDisplayItem* aItem,
                        wr::DisplayListBuilder& aBuilder,
                        const StackingContextHelper& aSc,
                        nsDisplayListBuilder* aDisplayListBuilder);
   void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
                                               nsDisplayListBuilder* aDisplayListBuilder,
                                               const StackingContextHelper& aSc,
-                                              wr::DisplayListBuilder& aBuilder);
+                                              wr::DisplayListBuilder& aBuilder,
+                                              const wr::WrImageMask* aMask = nullptr);
   void EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
                                   nsDisplayListBuilder* aDisplayListBuilder);
   bool IsLayersFreeTransaction() { return mEndTransactionWithoutLayers; }
   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT) override;
 
   virtual LayersBackend GetBackendType() override { return LayersBackend::LAYERS_WR; }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8990,27 +8990,21 @@ nsDisplayMask::CreateWebRenderCommands(m
 {
   bool snap;
   float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsRect displayBound = GetBounds(aDisplayListBuilder, &snap);
   LayerRect bounds = ViewAs<LayerPixel>(LayoutDeviceRect::FromAppUnits(displayBound, appUnitsPerDevPixel),
                                         PixelCastJustification::WebRenderHasUnitResolution);
 
   Maybe<wr::WrImageMask> mask = aManager->BuildWrMaskImage(this, aBuilder, aSc, aDisplayListBuilder, bounds);
-  if (mask) {
-    aBuilder.PushClip(aBuilder.DefineClip(
-        aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr()));
-  }
-
-  nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aSc, aParentCommands, aManager, aDisplayListBuilder);
-
-  if (mask) {
-    aBuilder.PopClip();
-  }
-
+  aManager->CreateWebRenderCommandsFromDisplayList(GetChildren(),
+                                                   aDisplayListBuilder,
+                                                   aSc,
+                                                   aBuilder,
+                                                   mask.ptrOr(nullptr));
   return true;
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayMask::PrintEffects(nsACString& aTo)
 {
   nsIFrame* firstFrame =