diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index 2d30fd49cea8..52e0b3477383 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -45,6 +45,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/Unused.h" #include "mozilla/DebugOnly.h" +#include "nsThreadUtils.h" #if defined(XP_WIN) # include "WinUtils.h" #endif @@ -109,6 +110,17 @@ bool CompositorBridgeChild::IsSameProcess() const { return OtherPid() == base::GetCurrentProcId(); } +void CompositorBridgeChild::PrepareFinalDestroy() { + // Because of medium high priority DidComposite, we need to repost to + // medium high priority queue to ensure the actor is destroyed after possible + // pending DidComposite message. + nsCOMPtr runnable = + NewRunnableMethod("CompositorBridgeChild::AfterDestroy", this, + &CompositorBridgeChild::AfterDestroy); + NS_DispatchToCurrentThreadQueue(runnable.forget(), + EventQueuePriority::MediumHigh); +} + 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. @@ -159,8 +171,8 @@ void CompositorBridgeChild::Destroy() { // 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; } @@ -221,8 +233,8 @@ void CompositorBridgeChild::Destroy() { // 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 diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index 25973caf831f..c215fe70f9de 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -275,6 +275,7 @@ class CompositorBridgeChild final : public PCompositorBridgeChild, // and resumes IPC. void ResumeIPCAfterAsyncPaint(); + void PrepareFinalDestroy(); void AfterDestroy(); PLayerTransactionChild* AllocPLayerTransactionChild( diff --git a/gfx/layers/ipc/PCompositorBridge.ipdl b/gfx/layers/ipc/PCompositorBridge.ipdl index 68c18caedb8c..83dfbaa8056e 100644 --- a/gfx/layers/ipc/PCompositorBridge.ipdl +++ b/gfx/layers/ipc/PCompositorBridge.ipdl @@ -120,8 +120,9 @@ child: // 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(mediumhigh) async DidComposite(LayersId id, TransactionId transactionId, + TimeStamp compositeStart, + TimeStamp compositeEnd); async NotifyFrameStats(FrameStats[] aFrameStats);