Bug 1506376 - Make PCompositorBridge::DidComposite high priority message, r=aosmond
☠☠ backed out by 0a9a4f8d79e9 ☠ ☠
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 08 Feb 2019 14:46:56 +0200
changeset 458721 de5c7c2699c4
parent 458720 6cb3a502e891
child 458722 aca48f57fb21
push id35546
push userrmaries@mozilla.com
push dateWed, 13 Feb 2019 04:27:59 +0000
treeherdermozilla-central@636d2c00234d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaosmond
bugs1506376
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1506376 - Make PCompositorBridge::DidComposite high priority message, r=aosmond
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/PCompositorBridge.ipdl
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -38,16 +38,17 @@
 #include "nsTArray.h"         // for nsTArray, nsTArray_Impl
 #include "nsXULAppAPI.h"      // for XRE_GetIOMessageLoop, etc
 #include "FrameLayerBuilder.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Unused.h"
 #include "mozilla/DebugOnly.h"
+#include "nsThreadUtils.h"
 #if defined(XP_WIN)
 #  include "WinUtils.h"
 #endif
 #include "mozilla/widget/CompositorWidget.h"
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
 #  include "mozilla/widget/CompositorWidgetChild.h"
 #endif
 #include "VsyncSource.h"
@@ -103,16 +104,26 @@ CompositorBridgeChild::~CompositorBridge
     gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
   }
 }
 
 bool CompositorBridgeChild::IsSameProcess() const {
   return OtherPid() == base::GetCurrentProcId();
 }
 
+void CompositorBridgeChild::PrepareFinalDestroy() {
+  // Because of high priority DidComposite, we need to repost to
+  // high priority queue to ensure the actor is destroyed after possible
+  // pending DidComposite message.
+  nsCOMPtr<nsIRunnable> runnable =
+      NewRunnableMethod("CompositorBridgeChild::AfterDestroy", this,
+                        &CompositorBridgeChild::AfterDestroy);
+  NS_DispatchToCurrentThreadQueue(runnable.forget(), EventQueuePriority::High);
+}
+
 void CompositorBridgeChild::AfterDestroy() {
   // Note that we cannot rely upon mCanSend here because we already set that to
   // false to prevent normal IPDL calls from being made after SendWillClose.
   // The only time we should not issue Send__delete__ is if the actor is already
   // destroyed, e.g. the compositor process crashed.
   if (!mActorDestroyed) {
     Send__delete__(this);
     mActorDestroyed = true;
@@ -149,18 +160,18 @@ void CompositorBridgeChild::Destroy() {
   // Flush async paints before we destroy texture data.
   FlushAsyncPaints();
 
   if (!mCanSend) {
     // We may have already called destroy but still have lingering references
     // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our
     // post destroy clean up no matter what. It is safe to call multiple times.
     MessageLoop::current()->PostTask(
-        NewRunnableMethod("CompositorBridgeChild::AfterDestroy", selfRef,
-                          &CompositorBridgeChild::AfterDestroy));
+        NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef,
+                          &CompositorBridgeChild::PrepareFinalDestroy));
     return;
   }
 
   AutoTArray<PLayerTransactionChild*, 16> transactions;
   ManagedPLayerTransactionChild(transactions);
   for (int i = transactions.Length() - 1; i >= 0; --i) {
     RefPtr<LayerTransactionChild> layers =
         static_cast<LayerTransactionChild*>(transactions[i]);
@@ -196,18 +207,18 @@ void CompositorBridgeChild::Destroy() {
   // destruction of shared memory). We need to ensure this gets processed by the
   // CompositorBridgeChild before it gets destroyed. It suffices to ensure that
   // events already in the MessageLoop get processed before the
   // CompositorBridgeChild is destroyed, so we add a task to the MessageLoop to
   // handle compositor destruction.
 
   // From now on we can't send any message message.
   MessageLoop::current()->PostTask(
-      NewRunnableMethod("CompositorBridgeChild::AfterDestroy", selfRef,
-                        &CompositorBridgeChild::AfterDestroy));
+      NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef,
+                        &CompositorBridgeChild::PrepareFinalDestroy));
 }
 
 // static
 void CompositorBridgeChild::ShutDown() {
   if (sCompositorBridge) {
     sCompositorBridge->Destroy();
     SpinEventLoopUntil([&]() { return !sCompositorBridge; });
   }
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -253,16 +253,17 @@ class CompositorBridgeChild final : publ
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
   // Must only be called from the paint thread. If the main thread is delaying
   // IPC messages, this forwards all such delayed IPC messages to the I/O thread
   // and resumes IPC.
   void ResumeIPCAfterAsyncPaint();
 
+  void PrepareFinalDestroy();
   void AfterDestroy();
 
   PLayerTransactionChild* AllocPLayerTransactionChild(
       const nsTArray<LayersBackend>& aBackendHints, const LayersId& aId);
 
   bool DeallocPLayerTransactionChild(PLayerTransactionChild* aChild);
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -108,18 +108,18 @@ child:
   // TextureSources are recreated.
   async InvalidateLayers(LayersId layersId);
 
   // The compositor completed a layers transaction. id is the layers id
   // of the child layer tree that was composited (or 0 when notifying
   // the root layer tree).
   // transactionId is the id of the transaction before this composite, or 0
   // if there was no transaction since the last composite.
-  async DidComposite(LayersId id, TransactionId transactionId,
-                     TimeStamp compositeStart, TimeStamp compositeEnd);
+  prio(high) async DidComposite(LayersId id, TransactionId transactionId,
+                                TimeStamp compositeStart, TimeStamp compositeEnd);
 
   async NotifyFrameStats(FrameStats[] aFrameStats);
 
   /**
    * Parent informs the child that the graphics objects are ready for
    * compositing.  This usually means that the graphics objects (textures
    * and the like) are available on the GPU.  This is used for chrome UI.
    * @see RequestNotifyAfterRemotePaint