From 95dafbe6316f9c77a1210af211f9eba8136496e4 Mon Sep 17 00:00:00 2001 From: Randall Barker Date: Tue, 7 Feb 2017 14:44:43 -0800 Subject: [PATCH] Bug 1336929 - Have UiCompositorControllerChild cache surface resize when not yet initialized. r=jchen,dvander --- .../ipc/UiCompositorControllerChild.cpp | 56 +++++++++++++++++++ gfx/layers/ipc/UiCompositorControllerChild.h | 3 +- widget/android/nsWindow.cpp | 8 ++- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/gfx/layers/ipc/UiCompositorControllerChild.cpp b/gfx/layers/ipc/UiCompositorControllerChild.cpp index 1c902e093735..ec4d914a0605 100644 --- a/gfx/layers/ipc/UiCompositorControllerChild.cpp +++ b/gfx/layers/ipc/UiCompositorControllerChild.cpp @@ -18,6 +18,50 @@ static bool sInitialized = false; static StaticRefPtr sChild; static StaticRefPtr sParent; +namespace { + +struct SurfaceResizeCache { + int32_t mSurfaceWidth; + int32_t mSurfaceHeight; + + SurfaceResizeCache(int32_t aWidth, int32_t aHeight) : + mSurfaceWidth(aWidth), + mSurfaceHeight(aHeight) {} + + SurfaceResizeCache(const SurfaceResizeCache& value) + { + *this = value; + } + + SurfaceResizeCache& operator=(const SurfaceResizeCache& value) + { + mSurfaceWidth = value.mSurfaceWidth; + mSurfaceHeight = value.mSurfaceHeight; + return *this; + } + + SurfaceResizeCache() : + mSurfaceWidth(0), + mSurfaceHeight(0) {} +}; + +static std::map sResizeCache; + +static void +DoCachedResize() +{ + MOZ_ASSERT(sChild); + MOZ_ASSERT(sChild->IsOnUiThread()); + + for (auto& cache : sResizeCache) { + sChild->SendResumeAndResize(cache.first, cache.second.mSurfaceWidth, cache.second.mSurfaceHeight); + } + + sResizeCache.empty(); +} + +} // namespace + UiCompositorControllerChild::UiCompositorControllerChild(RefPtr aThread, const uint64_t& aProcessToken) : mUiThread(aThread), mProcessToken(aProcessToken) @@ -83,6 +127,16 @@ UiCompositorControllerChild::InitWithGPUProcess(RefPtr aThread, aThread->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL); } +/* static */ void +UiCompositorControllerChild::CacheSurfaceResize(int64_t aId, int32_t aWidth, int32_t aHeight) +{ + // This should only be called if the sChild has not been set yet. + // It should also only be called from the UI thread but since the sChild hasn't been set + // yet, there isn't a good way to verify this. + MOZ_ASSERT(!sChild); + sResizeCache[aId] = SurfaceResizeCache{aWidth, aHeight}; +} + void UiCompositorControllerChild::OpenForSameProcess() { @@ -99,6 +153,7 @@ UiCompositorControllerChild::OpenForSameProcess() AddRef(); sChild = this; + DoCachedResize(); } void @@ -118,6 +173,7 @@ UiCompositorControllerChild::OpenForGPUProcess(Endpoint&& aEndpoint); + static void CacheSurfaceResize(int64_t aId, int32_t aWidth, int32_t aHeight); void Close(); void ActorDestroy(ActorDestroyReason aWhy) override; @@ -34,12 +35,12 @@ public: virtual void HandleFatalError(const char* aName, const char* aMsg) const override; + bool IsOnUiThread() const; private: UiCompositorControllerChild(RefPtr aThread, const uint64_t& aProcessToken); ~UiCompositorControllerChild(); void OpenForSameProcess(); void OpenForGPUProcess(Endpoint&& aEndpoint); - bool IsOnUiThread() const; RefPtr mUiThread; uint64_t mProcessToken; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 204a1eacffe7..b5f9f10e380d 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1176,11 +1176,13 @@ public: RefPtr child = UiCompositorControllerChild::Get(); if (!child) { - return; + // When starting, sometimes the UiCompositorControllerChild is still initializing + // so cache the resized surface dimensions until it has initialized. + UiCompositorControllerChild::CacheSurfaceResize(id, aWidth, aHeight); + } else { + child->SendResumeAndResize(id, aWidth, aHeight); } - child->SendResumeAndResize(id, aWidth, aHeight); - mCompositorPaused = false; class OnResumedEvent : public nsAppShell::Event