Bug 1393376 - (Part 2) Retain BasicLayerManager in WebRenderFallbackData for layer invalidation computation; r?jrmuizel draft
authorKevin Chen <kechen@mozilla.com>
Thu, 07 Sep 2017 15:04:30 +0800
changeset 668843 0f16bf455c991586cd5a52e19e78c30b1fc6487f
parent 668842 dcc64110691ab02e620ae1df1ce595f72d9d494f
child 732786 ac2b8c60c2a8c8bcef6ffb1b64604a97442dd3e5
push id81134
push userbmo:kechen@mozilla.com
push dateFri, 22 Sep 2017 02:59:02 +0000
reviewersjrmuizel
bugs1393376
milestone57.0a1
Bug 1393376 - (Part 2) Retain BasicLayerManager in WebRenderFallbackData for layer invalidation computation; r?jrmuizel MozReview-Commit-ID: 6rmJkXzLubX
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
gfx/layers/wr/WebRenderUserData.h
layout/painting/nsDisplayList.cpp
layout/reftests/bugs/reftest.list
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -454,46 +454,70 @@ WebRenderLayerManager::PushImage(nsDispl
   return true;
 }
 
 static void
 PaintItemByDrawTarget(nsDisplayItem* aItem,
                       DrawTarget* aDT,
                       const LayerRect& aImageRect,
                       const LayerPoint& aOffset,
-                      nsDisplayListBuilder* aDisplayListBuilder)
+                      nsDisplayListBuilder* aDisplayListBuilder,
+                      RefPtr<BasicLayerManager>& aManager,
+                      WebRenderLayerManager* aWrManager)
 {
   MOZ_ASSERT(aDT);
 
   aDT->ClearRect(aImageRect.ToUnknownRect());
   RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
   MOZ_ASSERT(context);
 
   context->SetMatrix(gfxMatrix::Translation(-aOffset.x, -aOffset.y));
   switch (aItem->GetType()) {
   case DisplayItemType::TYPE_MASK:
     static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
     break;
   case DisplayItemType::TYPE_FILTER:
     {
-      RefPtr<BasicLayerManager> tempManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
-      FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
-      layerBuilder->Init(aDisplayListBuilder, tempManager);
-
-      tempManager->BeginTransactionWithTarget(context);
-      ContainerLayerParameters param;
-      RefPtr<Layer> layer = aItem->BuildLayer(aDisplayListBuilder, tempManager, param);
-      if (layer) {
-        tempManager->SetRoot(layer);
-        static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder, context, tempManager);
+      if (aManager == nullptr) {
+        aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
       }
 
-      if (tempManager->InTransaction()) {
-        tempManager->AbortTransaction();
+      FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
+      layerBuilder->Init(aDisplayListBuilder, aManager);
+      layerBuilder->DidBeginRetainedLayerTransaction(aManager);
+
+      aManager->BeginTransactionWithTarget(context);
+
+      ContainerLayerParameters param;
+      RefPtr<Layer> layer =
+        static_cast<nsDisplayFilter*>(aItem)->BuildLayer(aDisplayListBuilder,
+                                                         aManager, param);
+
+      if (layer) {
+        UniquePtr<LayerProperties> props;
+        props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
+
+        aManager->SetRoot(layer);
+        layerBuilder->WillEndTransaction();
+
+        nsIntRegion invalid;
+        props->ComputeDifferences(layer, invalid, nullptr);
+
+        static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
+                                                           context, aManager);
+
+        if (!invalid.IsEmpty()) {
+          aWrManager->SetNotifyInvalidation(true);
+        }
       }
+
+      if (aManager->InTransaction()) {
+        aManager->AbortTransaction();
+      }
+      aManager->SetTarget(nullptr);
       break;
     }
   default:
     aItem->Paint(aDisplayListBuilder, context);
     break;
   }
 
   if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
@@ -586,17 +610,18 @@ WebRenderLayerManager::GenerateFallbackD
       bool snapped;
       bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
 
       RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
       // TODO: should use 'format' to replace gfx::SurfaceFormat::B8G8R8A8. Currently blob image doesn't support A8 format.
       RefPtr<gfx::DrawTarget> dummyDt =
         gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8);
       RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
-      PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
+      PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder,
+                            fallbackData->mBasicLayerManager, this);
       recorder->Finish();
 
       Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
       wr::ImageKey key = WrBridge()->GetNextImageKey();
       wr::ImageDescriptor descriptor(imageSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
       aResources.AddBlobImage(key, descriptor, bytes);
       fallbackData->SetKey(key);
     } else {
@@ -606,17 +631,19 @@ WebRenderLayerManager::GenerateFallbackD
 
       {
         UpdateImageHelper helper(imageContainer, imageClient, imageSize.ToUnknownSize(), format);
         {
           RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
           if (!dt) {
             return nullptr;
           }
-          PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
+          PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset,
+                                aDisplayListBuilder,
+                                fallbackData->mBasicLayerManager, this);
         }
         if (!helper.UpdateImage()) {
           return nullptr;
         }
       }
 
       // Force update the key in fallback data since we repaint the image in this path.
       // If not force update, fallbackData may reuse the original key because it
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -226,16 +226,17 @@ public:
     if (T::Type() == WebRenderUserData::UserDataType::eCanvas) {
       mLastCanvasDatas.PutEntry(data->AsCanvasData());
     }
     RefPtr<T> res = static_cast<T*>(data.get());
     return res.forget();
   }
 
   bool ShouldNotifyInvalidation() const { return mShouldNotifyInvalidation; }
+  void SetNotifyInvalidation(bool aShouldNotifyInvalidation) { mShouldNotifyInvalidation = aShouldNotifyInvalidation; }
 
 private:
   /**
    * Take a snapshot of the parent context, and copy
    * it into mTarget.
    */
   void MakeSnapshotIfRequired(LayoutDeviceIntSize aSize);
 
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_WEBRENDERUSERDATA_H
 #define GFX_WEBRENDERUSERDATA_H
 
+#include "BasicLayers.h"                // for BasicLayerManager
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/layers/AnimationInfo.h"
 
 class nsDisplayItemGeometry;
 
 namespace mozilla {
 namespace layers {
@@ -102,16 +103,17 @@ public:
   static UserDataType Type() { return UserDataType::eFallback; }
   nsAutoPtr<nsDisplayItemGeometry> GetGeometry();
   void SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry);
   nsRect GetBounds() { return mBounds; }
   void SetBounds(const nsRect& aRect) { mBounds = aRect; }
   void SetInvalid(bool aInvalid) { mInvalid = aInvalid; }
   bool IsInvalid() { return mInvalid; }
 
+  RefPtr<BasicLayerManager> mBasicLayerManager;
 protected:
   nsAutoPtr<nsDisplayItemGeometry> mGeometry;
   nsRect mBounds;
   bool mInvalid;
 };
 
 class WebRenderAnimationData : public WebRenderUserData
 {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9141,17 +9141,16 @@ nsDisplayFilter::BuildLayer(nsDisplayLis
              "By getting here, we must have valid CSS filters.");
 
   ContainerLayerParameters newContainerParameters = aContainerParameters;
   newContainerParameters.mDisableSubpixelAntialiasingInDescendants = true;
 
   RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
                            newContainerParameters, nullptr);
-
   LayerState state = this->GetLayerState(aBuilder, aManager, newContainerParameters);
   if (container && state != LAYER_SVG_EFFECTS) {
     const nsTArray<nsStyleFilter>& filters = mFrame->StyleEffects()->mFilters;
     nsTArray<layers::CSSFilter> cssFilters = nsTArray<layers::CSSFilter>(filters.Length());
     for (const nsStyleFilter& filter : filters) {
       cssFilters.AppendElement(ToCSSFilter(filter));
     }
 
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1744,17 +1744,17 @@ fuzzy-if(true,17,5886) fuzzy-if(skiaCont
 == 776265-2a.html 776265-2-ref.html
 == 776265-2b.html 776265-2-ref.html
 == 776265-2c.html 776265-2-ref.html
 == 776265-2d.html 776265-2-ref.html
 == 776443-1.html 776443-1-ref.html
 == 776443-2.html 776443-2-ref.html
 == 786254-1.html 786254-1-ref.html
 == 787947-1.html 787947-1-ref.html
-== 796847-1.svg 796847-1-ref.svg
+pref(gfx.webrender.layers-free,true) == 796847-1.svg 796847-1-ref.svg
 fuzzy(40,875) fuzzy-if(skiaContent,1,2500) == 797797-1.html 797797-1-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 fuzzy(40,850) fuzzy-if(skiaContent,2,2310) == 797797-2.html 797797-2-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 == 801994-1.html 801994-1-ref.html
 == 804323-1.html 804323-1-ref.html
 fuzzy-if(Android,8,608) == 811301-1.html 811301-1-ref.html
 == 812824-1.html 812824-1-ref.html
 == 814677.html 814677-ref.html
 == 814952-1.html 814952-1-ref.html