diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 6d18f0b5a44..5e31c4e6b16 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -64,7 +64,9 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Laye if (aRoot) { UpdatePanZoomControllerTree(aCompositor, - aRoot, CompositorParent::ROOT_LAYER_TREE_ID, + aRoot, + // aCompositor is null in gtest scenarios + aCompositor ? aCompositor->RootLayerTreeId() : 0, nullptr, nullptr, aIsFirstPaint, aFirstPaintLayersId, &apzcsToDestroy); diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 05a7eb207c9..c3ce7bfb5fb 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -154,6 +154,9 @@ CompositorParent::CompositorParent(nsIWidget* aWidget, CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&AddCompositor, this, &mCompositorID)); + mRootLayerTreeID = AllocateLayerTreeId(); + sIndirectLayerTrees[mRootLayerTreeID].mParent = this; + mApzcTreeManager = new APZCTreeManager(); ++sCompositorThreadRefCount; } @@ -170,11 +173,16 @@ CompositorParent::IsInCompositorThread() return CompositorThreadID() == PlatformThread::CurrentId(); } +uint64_t +CompositorParent::RootLayerTreeId() +{ + return mRootLayerTreeID; +} + CompositorParent::~CompositorParent() { MOZ_COUNT_DTOR(CompositorParent); - mApzcTreeManager->ClearTree(); ReleaseCompositorThread(); } @@ -187,6 +195,9 @@ CompositorParent::Destroy() // Ensure that the layer manager is destructed on the compositor thread. mLayerManager = nullptr; mCompositionManager = nullptr; + mApzcTreeManager->ClearTree(); + mApzcTreeManager = nullptr; + sIndirectLayerTrees.erase(mRootLayerTreeID); } void @@ -568,7 +579,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, if (mApzcTreeManager) { AutoResolveRefLayers resolve(mCompositionManager); - mApzcTreeManager->UpdatePanZoomControllerTree(this, root, isFirstPaint, ROOT_LAYER_TREE_ID); + mApzcTreeManager->UpdatePanZoomControllerTree(this, root, isFirstPaint, mRootLayerTreeID); } if (root) { @@ -709,17 +720,12 @@ CompositorParent::NotifyChildCreated(uint64_t aChild) sIndirectLayerTrees[aChild].mParent = this; } -// Ensure all layer tree IDs are greater than zero, so if we -// ever see a zero-valued layer tree id we know it's actually -// uninitialized and/or garbage. -uint64_t CompositorParent::ROOT_LAYER_TREE_ID = 1; - /*static*/ uint64_t CompositorParent::AllocateLayerTreeId() { MOZ_ASSERT(CompositorLoop()); MOZ_ASSERT(NS_IsMainThread()); - static uint64_t ids = ROOT_LAYER_TREE_ID; + static uint64_t ids = 0; return ++ids; } diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 0522fbe4414..392687f4276 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -103,6 +103,12 @@ public: virtual void ScheduleComposition(); void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint); + /** + * Returns the unique layer tree identifier that corresponds to the root + * tree of this compositor. + */ + uint64_t RootLayerTreeId(); + /** * Returns a pointer to the compositor corresponding to the given ID. */ @@ -125,11 +131,6 @@ public: */ static void ShutDown(); - /** - * The reserved layer tree ID for the root of the layer tree. - */ - static uint64_t ROOT_LAYER_TREE_ID; - /** * Allocate an ID that can be used to refer to a layer tree and * associated resources that live only on the compositor thread. @@ -287,6 +288,7 @@ private: mozilla::Monitor mResumeCompositionMonitor; uint64_t mCompositorID; + uint64_t mRootLayerTreeID; bool mOverrideComposeReadiness; CancelableTask* mForceCompositionTask; diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index f8283bb0f24..885a79e5ee4 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -373,7 +373,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { TimeStamp testStartTime = TimeStamp::Now(); AsyncPanZoomController::SetFrameTime(testStartTime); nsRefPtr mcc = new MockContentController(); - ScopedLayerTreeRegistration controller(CompositorParent::ROOT_LAYER_TREE_ID, root, mcc); + ScopedLayerTreeRegistration controller(0, root, mcc); nsRefPtr manager = new TestAPZCTreeManager(); @@ -384,14 +384,14 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { // Now we have a root APZC that will match the page SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); hit = manager->GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) // Now we have a sub APZC with a better fit SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController()); hit = manager->GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); @@ -401,7 +401,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { hit = manager->GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); hit = manager->GetTargetAPZC(ScreenPoint(15, 15)); EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) @@ -422,7 +422,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { transform.ScalePost(0.1, 0.1, 1); root->SetBaseTransform(transform); root->ComputeEffectiveTransforms(gfx3DMatrix()); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); hit = manager->GetTargetAPZC(ScreenPoint(50, 50)); // This point is now outside the root layer EXPECT_EQ(nullAPZC, hit.get()); @@ -435,7 +435,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { // layer 4 effective visible screenrect: (0.05, 0.05, 0.2, 0.2) // Does not contain (2, 2) root->ComputeEffectiveTransforms(gfx3DMatrix()); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); hit = manager->GetTargetAPZC(ScreenPoint(2, 2)); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerPoint(20, 20) @@ -456,7 +456,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { layers[7]->SetBaseTransform(translateTransform3); root->ComputeEffectiveTransforms(gfx3DMatrix()); - manager->UpdatePanZoomControllerTree(nullptr, root, CompositorParent::ROOT_LAYER_TREE_ID, false); + manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); // layer 7 effective visible screenrect (0,16,4,60) but clipped by parent layers hit = manager->GetTargetAPZC(ScreenPoint(1, 45)); EXPECT_EQ(layers[7]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index 737f441896b..e7a5c91f412 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -847,9 +847,9 @@ Java_org_mozilla_gecko_GeckoJavaSampler_getProfilerTime(JNIEnv *jenv, jclass jc) NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_abortAnimation(JNIEnv* env, jobject instance) { - APZCTreeManager *controller = CompositorParent::GetAPZCTreeManager(CompositorParent::ROOT_LAYER_TREE_ID); + APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) { - controller->CancelAnimation(ScrollableLayerGuid(CompositorParent::ROOT_LAYER_TREE_ID)); + controller->CancelAnimation(ScrollableLayerGuid(nsWindow::RootLayerTreeId())); } } @@ -865,13 +865,12 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject ins MOZ_ASSERT(false, "Registering a new NPZC when we already have one"); env->DeleteGlobalRef(oldRef); } - CompositorParent::SetControllerForLayerTree(CompositorParent::ROOT_LAYER_TREE_ID, AndroidBridge::Bridge()); } NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, jobject instance, jobject event) { - APZCTreeManager *controller = CompositorParent::GetAPZCTreeManager(CompositorParent::ROOT_LAYER_TREE_ID); + APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) { AndroidGeckoEvent* wrapper = AndroidGeckoEvent::MakeFromJavaObject(env, event); const MultiTouchInput& input = wrapper->MakeMultiTouchInput(nsWindow::TopWindow()); @@ -916,9 +915,9 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv* env, jobject instance, jboolean prevented) { - APZCTreeManager *controller = CompositorParent::GetAPZCTreeManager(CompositorParent::ROOT_LAYER_TREE_ID); + APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) { - controller->ContentReceivedTouch(ScrollableLayerGuid(CompositorParent::ROOT_LAYER_TREE_ID), prevented); + controller->ContentReceivedTouch(ScrollableLayerGuid(nsWindow::RootLayerTreeId()), prevented); } } @@ -945,9 +944,9 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_getOverScrollMode(JNIEnv* env NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_updateScrollOffset(JNIEnv* env, jobject instance, jfloat cssX, jfloat cssY) { - APZCTreeManager *controller = CompositorParent::GetAPZCTreeManager(CompositorParent::ROOT_LAYER_TREE_ID); + APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) { - controller->UpdateScrollOffset(ScrollableLayerGuid(CompositorParent::ROOT_LAYER_TREE_ID), CSSPoint(cssX, cssY)); + controller->UpdateScrollOffset(ScrollableLayerGuid(nsWindow::RootLayerTreeId()), CSSPoint(cssX, cssY)); } } diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 4b97f75d49a..4a688296d35 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -2417,6 +2417,7 @@ nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) // off-main-thread compositor fields and functions +nsRefPtr nsWindow::sApzcTreeManager = 0; nsRefPtr nsWindow::sLayerManager = 0; nsRefPtr nsWindow::sCompositorParent = 0; nsRefPtr nsWindow::sCompositorChild = 0; @@ -2500,3 +2501,25 @@ nsWindow::NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight) { return new CompositorParent(this, true, aSurfaceWidth, aSurfaceHeight); } + +mozilla::layers::APZCTreeManager* +nsWindow::GetAPZCTreeManager() +{ + if (!sApzcTreeManager) { + CompositorParent* compositor = sCompositorParent; + if (!compositor) { + return nullptr; + } + uint64_t rootLayerTreeId = compositor->RootLayerTreeId(); + CompositorParent::SetControllerForLayerTree(rootLayerTreeId, AndroidBridge::Bridge()); + sApzcTreeManager = CompositorParent::GetAPZCTreeManager(rootLayerTreeId); + } + return sApzcTreeManager; +} + +uint64_t +nsWindow::RootLayerTreeId() +{ + MOZ_ASSERT(sCompositorParent); + return sCompositorParent->RootLayerTreeId(); +} diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index cf444372bb7..bce79a77299 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -155,6 +155,9 @@ public: static void ScheduleResumeComposition(int width, int height); static void ForceIsFirstPaint(); static float ComputeRenderIntegrity(); + static mozilla::layers::APZCTreeManager* GetAPZCTreeManager(); + /* RootLayerTreeId() can only be called when GetAPZCTreeManager() returns non-null */ + static uint64_t RootLayerTreeId(); virtual bool WidgetPaintsBackground(); @@ -229,6 +232,7 @@ private: mozilla::AndroidLayerRendererFrame mLayerRendererFrame; + static nsRefPtr sApzcTreeManager; static nsRefPtr sLayerManager; static nsRefPtr sCompositorParent; static nsRefPtr sCompositorChild;