☠☠ backed out by 0a9a4f8d79e9 ☠ ☠ | |
author | Olli Pettay <Olli.Pettay@helsinki.fi> |
Fri, 08 Feb 2019 14:46:56 +0200 | |
changeset 458721 | de5c7c2699c4 |
parent 458720 | 6cb3a502e891 |
child 458722 | aca48f57fb21 |
push id | 35546 |
push user | rmaries@mozilla.com |
push date | Wed, 13 Feb 2019 04:27:59 +0000 |
treeherder | mozilla-central@636d2c00234d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | aosmond |
bugs | 1506376 |
milestone | 67.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
|
--- 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