Bug 866232 - Break assumption of a single global root layer tree. r=BenWa, mattwoodrow

This commit is contained in:
Kartikaya Gupta 2013-07-30 14:03:43 -04:00
parent e0f930eb52
commit 8a21c3e5f3
7 changed files with 65 additions and 29 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -373,7 +373,7 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
TimeStamp testStartTime = TimeStamp::Now();
AsyncPanZoomController::SetFrameTime(testStartTime);
nsRefPtr<MockContentController> mcc = new MockContentController();
ScopedLayerTreeRegistration controller(CompositorParent::ROOT_LAYER_TREE_ID, root, mcc);
ScopedLayerTreeRegistration controller(0, root, mcc);
nsRefPtr<APZCTreeManager> 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());

View File

@ -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));
}
}

View File

@ -2417,6 +2417,7 @@ nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
// off-main-thread compositor fields and functions
nsRefPtr<mozilla::layers::APZCTreeManager> nsWindow::sApzcTreeManager = 0;
nsRefPtr<mozilla::layers::LayerManager> nsWindow::sLayerManager = 0;
nsRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent = 0;
nsRefPtr<mozilla::layers::CompositorChild> 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();
}

View File

@ -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<mozilla::layers::APZCTreeManager> sApzcTreeManager;
static nsRefPtr<mozilla::layers::LayerManager> sLayerManager;
static nsRefPtr<mozilla::layers::CompositorParent> sCompositorParent;
static nsRefPtr<mozilla::layers::CompositorChild> sCompositorChild;