From 5c26b0762633394cdb7617782d5a9b53401a9bf6 Mon Sep 17 00:00:00 2001 From: Randall Barker Date: Mon, 8 May 2017 12:06:10 -0700 Subject: [PATCH] Bug 1363123 - Queue compositor messages that are sent before UiCompositorControllerParent has been initialized r=botond MozReview-Commit-ID: LNmCv9D6bS6 --- .../apz/src/AndroidDynamicToolbarAnimator.cpp | 34 +++++++++++++++++++ .../apz/src/AndroidDynamicToolbarAnimator.h | 14 ++++++++ 2 files changed, 48 insertions(+) diff --git a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp index 0d9ca3a56e35..e3aee9e3bbea 100644 --- a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp +++ b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.cpp @@ -73,10 +73,17 @@ AndroidDynamicToolbarAnimator::AndroidDynamicToolbarAnimator() void AndroidDynamicToolbarAnimator::Initialize(uint64_t aRootLayerTreeId) { + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); mRootLayerTreeId = aRootLayerTreeId; RefPtr uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeId); MOZ_ASSERT(uiController); uiController->RegisterAndroidDynamicToolbarAnimator(this); + + // Send queued messages that were posted before Initialize() was called. + for (QueuedMessage* message = mCompositorQueuedMessages.getFirst(); message != nullptr; message = message->getNext()) { + uiController->ToolbarAnimatorMessageFromCompositor(message->mMessage); + } + mCompositorQueuedMessages.clear(); } static bool @@ -461,6 +468,7 @@ AndroidDynamicToolbarAnimator::Shutdown() mCompositorShutdown = true; mCompositorToolbarEffect = nullptr; mCompositorToolbarTexture = nullptr; + mCompositorQueuedMessages.clear(); if (mCompositorToolbarPixels) { RefPtr uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeId); uiController->DeallocShmem(mCompositorToolbarPixels.ref()); @@ -620,11 +628,19 @@ AndroidDynamicToolbarAnimator::HandleTouchEnd(StaticToolbarState aCurrentToolbar void AndroidDynamicToolbarAnimator::PostMessage(int32_t aMessage) { + // if the root layer tree id is zero then Initialize() has not been called yet + // so queue the message until Initialize() is called. + if (mRootLayerTreeId == 0) { + QueueMessage(aMessage); + return; + } + RefPtr uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeId); if (!uiController) { // Looks like IPC may be shutdown. return; } + // ToolbarAnimatorMessageFromCompositor may be called from any thread. uiController->ToolbarAnimatorMessageFromCompositor(aMessage); } @@ -958,5 +974,23 @@ AndroidDynamicToolbarAnimator::CheckForResetOnNextMove(ScreenIntCoord aCurrentTo } } +void +AndroidDynamicToolbarAnimator::QueueMessage(int32_t aMessage) +{ + if (!CompositorThreadHolder::IsInCompositorThread()) { + CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod(this, &AndroidDynamicToolbarAnimator::QueueMessage, aMessage)); + return; + } + + // If the root layer tree id is no longer zero, Initialize() was called before QueueMessage was processed + // so just post the message now. + if (mRootLayerTreeId != 0) { + PostMessage(aMessage); + return; + } + + mCompositorQueuedMessages.insertBack(new QueuedMessage(aMessage)); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h index 0896d9194897..dac2b6a6d57b 100644 --- a/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h +++ b/gfx/layers/apz/src/AndroidDynamicToolbarAnimator.h @@ -13,6 +13,7 @@ #include "mozilla/ipc/Shmem.h" #include "mozilla/layers/Effects.h" #include "mozilla/layers/TextureHost.h" +#include "mozilla/LinkedList.h" #include "mozilla/Maybe.h" #include "mozilla/TimeStamp.h" #include "nsISupports.h" @@ -151,6 +152,7 @@ protected: ScreenIntCoord GetFixedLayerMarginsBottom(); void NotifyControllerSnapshotFailed(); void CheckForResetOnNextMove(ScreenIntCoord aCurrentTouch); + void QueueMessage(int32_t aMessage); // Read only Compositor and Controller threads after Initialize() uint64_t mRootLayerTreeId; @@ -195,6 +197,17 @@ protected: // Controller thread only FrameMetricsState mControllerFrameMetrics; + class QueuedMessage : public LinkedListElement { + public: + explicit QueuedMessage(int32_t aMessage) : + mMessage(aMessage) {} + int32_t mMessage; + private: + QueuedMessage() = delete; + QueuedMessage(const QueuedMessage&) = delete; + QueuedMessage& operator=(const QueuedMessage&) = delete; + }; + // Compositor thread only bool mCompositorShutdown; bool mCompositorAnimationDeferred; // An animation has been deferred until the toolbar is unlocked @@ -211,6 +224,7 @@ protected: RefPtr mCompositorToolbarTexture; // The OGL texture used to render the snapshot in the compositor RefPtr mCompositorToolbarEffect; // Effect used to render the snapshot in the compositor TimeStamp mCompositorAnimationStartTimeStamp; // Time stamp when the current animation started + AutoCleanLinkedList mCompositorQueuedMessages; // Queue to contain messages sent before Initialize() called }; } // namespace layers