Bug 1350828 - Label CompositorForwarder; r?bevistseng, kats draft
authorKevin Chen <kechen@mozilla.com>
Wed, 29 Mar 2017 13:49:20 +0800
changeset 562501 c0c85c506c4e7f669a38dbf70bb45bac0e2c9cbe
parent 562500 74c853a70973239b637d8c4b0aa2e2345443c0f8
child 562702 32bf1a72fb9c324afec3b999364b4a2aa554aef1
child 562743 6153d54bd285dd0908f66be15e1d47edfcbdc2c1
push id54034
push userbmo:kechen@mozilla.com
push dateFri, 14 Apr 2017 01:54:43 +0000
reviewersbevistseng, kats
bugs1350828
milestone55.0a1
Bug 1350828 - Label CompositorForwarder; r?bevistseng, kats MozReview-Commit-ID: 714oc4O8MNs
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -5,16 +5,17 @@
 
 #include "ClientLayerManager.h"
 #include "GeckoProfiler.h"              // for PROFILER_LABEL
 #include "gfxPrefs.h"                   // for gfxPrefs::LayersTile...
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Hal.h"
 #include "mozilla/dom/ScreenOrientation.h"  // for ScreenOrientation
 #include "mozilla/dom/TabChild.h"       // for TabChild
+#include "mozilla/dom/TabGroup.h"       // for TabGroup
 #include "mozilla/hal_sandbox/PHal.h"   // for ScreenConfiguration
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositorBridgeChild.h" // for CompositorBridgeChild
 #include "mozilla/layers/FrameUniformityData.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/LayerTransactionChild.h"
@@ -149,16 +150,27 @@ ClientLayerManager::Destroy()
     });
     NS_DispatchToMainThread(task.forget());
   }
 
   // Forget the widget pointer in case we outlive our owning widget.
   mWidget = nullptr;
 }
 
+TabGroup*
+ClientLayerManager::GetTabGroup()
+{
+  if (mWidget) {
+    if (TabChild* tabChild = mWidget->GetOwningTabChild()) {
+      return tabChild->TabGroup();
+    }
+  }
+  return nullptr;
+}
+
 int32_t
 ClientLayerManager::GetMaxTextureSize() const
 {
   return mForwarder->GetMaxTextureSize();
 }
 
 void
 ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -24,18 +24,24 @@
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsAString
 #include "mozilla/layers/TransactionIdAllocator.h"
 #include "nsIWidget.h"                  // For plugin window configuration information structs
 
 class nsDisplayListBuilder;
 
 namespace mozilla {
+
+namespace dom {
+class TabGroup;
+}
 namespace layers {
 
+using dom::TabGroup;
+
 class ClientPaintedLayer;
 class CompositorBridgeChild;
 class ImageLayer;
 class FrameUniformityData;
 
 class ClientLayerManager final : public LayerManager
 {
   typedef nsTArray<RefPtr<Layer> > LayerRefArray;
@@ -59,16 +65,18 @@ public:
     return mForwarder;
   }
 
   virtual ClientLayerManager* AsClientLayerManager() override
   {
     return this;
   }
 
+  TabGroup* GetTabGroup();
+
   virtual int32_t GetMaxTextureSize() const override;
 
   virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation);
   virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override;
   virtual bool BeginTransaction() override;
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override;
   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
                               void* aCallbackData,
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -15,16 +15,17 @@
 #include "RenderTrace.h"                // for RenderTraceScope
 #include "gfx2DGlue.h"                  // for Moz2D transition helpers
 #include "gfxPlatform.h"                // for gfxImageFormat, gfxPlatform
 #include "gfxPrefs.h"
 //#include "gfxSharedImageSurface.h"      // for gfxSharedImageSurface
 #include "ipc/IPCMessageUtils.h"        // for gfxContentType, null_t
 #include "IPDLActor.h"
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
+#include "mozilla/dom/TabGroup.h"
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient, etc
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/ContentClient.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
@@ -189,17 +190,22 @@ ShadowLayerForwarder::ShadowLayerForward
  , mMessageLoop(MessageLoop::current())
  , mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
  , mIsFirstPaint(false)
  , mWindowOverlayChanged(false)
  , mPaintSyncId(0)
  , mNextLayerHandle(1)
 {
   mTxn = new Transaction();
-  mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(1000, "CompositableForwarder");
+  if (TabGroup* tabGroup = mClientLayerManager->GetTabGroup()) {
+    mEventTarget = tabGroup->EventTargetFor(TaskCategory::Other);
+  }
+  MOZ_ASSERT(mEventTarget || !XRE_IsContentProcess());
+  mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
+    1000, "CompositableForwarder", mEventTarget);
 }
 
 template<typename T>
 struct ReleaseOnMainThreadTask : public Runnable
 {
   UniquePtr<T> mObj;
 
   explicit ReleaseOnMainThreadTask(UniquePtr<T>& aObj)
@@ -216,24 +222,37 @@ ShadowLayerForwarder::~ShadowLayerForwar
 {
   MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?");
   delete mTxn;
   if (mShadowManager) {
     mShadowManager->SetForwarder(nullptr);
     if (NS_IsMainThread()) {
       mShadowManager->Destroy();
     } else {
-      NS_DispatchToMainThread(
-        NewRunnableMethod(mShadowManager, &LayerTransactionChild::Destroy));
+      if (mEventTarget) {
+        mEventTarget->Dispatch(
+          NewRunnableMethod("LayerTransactionChild::Destroy", mShadowManager,
+                            &LayerTransactionChild::Destroy),
+          nsIEventTarget::DISPATCH_NORMAL);
+      } else {
+        NS_DispatchToMainThread(
+          NewRunnableMethod(mShadowManager, &LayerTransactionChild::Destroy));
+      }
     }
   }
 
   if (!NS_IsMainThread()) {
-    NS_DispatchToMainThread(
-      new ReleaseOnMainThreadTask<ActiveResourceTracker>(mActiveResourceTracker));
+    RefPtr<ReleaseOnMainThreadTask<ActiveResourceTracker>> event =
+      new ReleaseOnMainThreadTask<ActiveResourceTracker>(mActiveResourceTracker);
+    if (mEventTarget) {
+      event->SetName("ActiveResourceTracker::~ActiveResourceTracker");
+      mEventTarget->Dispatch(event.forget(), nsIEventTarget::DISPATCH_NORMAL);
+    } else {
+      NS_DispatchToMainThread(event);
+    }
   }
 }
 
 void
 ShadowLayerForwarder::BeginTransaction(const gfx::IntRect& aTargetBounds,
                                        ScreenRotation aRotation,
                                        dom::ScreenOrientationInternal aOrientation)
 {
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -59,18 +59,19 @@ private:
 };
 
 /**
  * A convenience class on top of nsExpirationTracker
  */
 class ActiveResourceTracker : public nsExpirationTracker<ActiveResource, 3>
 {
 public:
-  ActiveResourceTracker(uint32_t aExpirationCycle, const char* aName)
-  : nsExpirationTracker(aExpirationCycle, aName)
+  ActiveResourceTracker(uint32_t aExpirationCycle, const char* aName,
+                        nsIEventTarget* aEventTarget)
+  : nsExpirationTracker(aExpirationCycle, aName, aEventTarget)
   {}
 
   virtual void NotifyExpired(ActiveResource* aResource) override
   {
     RemoveObject(aResource);
     aResource->NotifyInactive();
   }
 };
@@ -442,16 +443,22 @@ private:
   bool mIsFirstPaint;
   bool mWindowOverlayChanged;
   int32_t mPaintSyncId;
   InfallibleTArray<PluginWindowData> mPluginWindowData;
   UniquePtr<ActiveResourceTracker> mActiveResourceTracker;
   uint64_t mNextLayerHandle;
   nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
   PaintTiming mPaintTiming;
+  /**
+   * ShadowLayerForwarder might dispatch tasks to main while puppet widget and
+   * tabChild don't exist anymore; therefore we hold the event target since its
+   *  lifecycle is independent of these objects.
+   */
+  nsCOMPtr<nsIEventTarget> mEventTarget;
 };
 
 class CompositableClient;
 
 /**
  * A ShadowableLayer is a Layer can be shared with a parent context
  * through a ShadowLayerForwarder.  A ShadowableLayer maps to a
  * Shadow*Layer in a parent context.