From 535bbba72dcd9538864fcf9d490847438c29d46d Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 6 May 2014 17:26:13 -0400 Subject: [PATCH] Bug 961289 - Assign sequence numbers to paints on the client side and forward them to the compositor. r=BenWa,kats --HG-- extra : source : d5331eaed1c789ac0248e8710a7b4a167ae349b6 --- gfx/layers/apz/src/APZCTreeManager.cpp | 13 ++++++++---- gfx/layers/apz/src/APZCTreeManager.h | 11 ++++++++-- gfx/layers/client/ClientLayerManager.cpp | 9 +++++++- gfx/layers/client/ClientLayerManager.h | 4 ++++ gfx/layers/ipc/CompositorParent.cpp | 21 ++++++++++++------- gfx/layers/ipc/CompositorParent.h | 6 ++++-- gfx/layers/ipc/LayerTransactionParent.cpp | 10 ++++++--- gfx/layers/ipc/LayerTransactionParent.h | 4 +++- gfx/layers/ipc/PLayerTransaction.ipdl | 6 ++++-- gfx/layers/ipc/ShadowLayers.cpp | 7 +++++-- gfx/layers/ipc/ShadowLayers.h | 1 + gfx/layers/ipc/ShadowLayersManager.h | 3 ++- .../gtest/TestAsyncPanZoomController.cpp | 10 +++++---- layout/ipc/RenderFrameParent.cpp | 3 ++- layout/ipc/RenderFrameParent.h | 3 ++- 15 files changed, 80 insertions(+), 31 deletions(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 5b85400f7619..a6a8b632b69b 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -95,8 +95,11 @@ Collect(AsyncPanZoomController* aApzc, nsTArray< nsRefPtr >* aApzcsToDestroy) { mTreeLock.AssertCurrentThreadOwns(); @@ -298,7 +302,8 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) { gfx::TreeAutoIndent indent(mApzcTreeLog); next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, aTransform, aParent, next, - aIsFirstPaint, aFirstPaintLayersId, aApzcsToDestroy); + aIsFirstPaint, aFirstPaintLayersId, + aPaintSequenceNumber, aApzcsToDestroy); } // Return the APZC that should be the sibling of other APZCs as we continue diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index a14d37d1eb74..3022d0473894 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -104,9 +104,16 @@ public: * to included a first-paint. If this is true, the part of * the tree that is affected by the first-paint flag is * indicated by the aFirstPaintLayersId parameter. + * @param aPaintSequenceNumber The sequence number of the paint that triggered + * this layer update. Note that every layer child + * process' layer subtree has its own sequence + * numbers. */ - void UpdatePanZoomControllerTree(CompositorParent* aCompositor, Layer* aRoot, - bool aIsFirstPaint, uint64_t aFirstPaintLayersId); + void UpdatePanZoomControllerTree(CompositorParent* aCompositor, + Layer* aRoot, + bool aIsFirstPaint, + uint64_t aFirstPaintLayersId, + uint32_t aPaintSequenceNumber); /** * General handler for incoming input events. Manipulates the frame metrics diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index 396ffd16dc9e..113684344161 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -47,6 +47,7 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget) , mTransactionIncomplete(false) , mCompositorMightResample(false) , mNeedsComposite(false) + , mPaintSequenceNumber(0) , mForwarder(new ShadowLayerForwarder) { MOZ_COUNT_CTOR(ClientLayerManager); @@ -159,6 +160,11 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget) if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) { mShadowTarget = aTarget; } + + // If this is a new paint, increment the paint sequence number. + if (!mIsRepeatTransaction) { + ++mPaintSequenceNumber; + } } void @@ -405,7 +411,8 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite) // forward this transaction's changeset to our LayerManagerComposite bool sent; AutoInfallibleTArray replies; - if (HasShadowManager() && mForwarder->EndTransaction(&replies, mRegionToClear, aScheduleComposite, &sent)) { + if (HasShadowManager() && mForwarder->EndTransaction(&replies, mRegionToClear, + aScheduleComposite, mPaintSequenceNumber, &sent)) { for (nsTArray::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index d0c45d6c754b..9eb36aff101c 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -232,6 +232,10 @@ private: bool mCompositorMightResample; bool mNeedsComposite; + // An incrementing sequence number for paints. + // Incremented in BeginTransaction(), but not for repeat transactions. + uint32_t mPaintSequenceNumber; + RefPtr mForwarder; nsAutoTArray,2> mTexturePools; nsAutoTArray mOverfillCallbacks; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 5877d1b76f52..5eee1e51133c 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -521,13 +521,15 @@ CompositorParent::ScheduleTask(CancelableTask* task, int time) } void -CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, bool aScheduleComposite) +CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, + bool aScheduleComposite, uint32_t aPaintSequenceNumber) { if (mApzcTreeManager && mLayerManager && mLayerManager->GetRoot()) { AutoResolveRefLayers resolve(mCompositionManager); - mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId); + mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), + aIsFirstPaint, aId, aPaintSequenceNumber); mLayerManager->NotifyShadowTreeTransaction(); } @@ -768,7 +770,8 @@ void CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) { ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint); @@ -784,7 +787,8 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, if (mApzcTreeManager) { AutoResolveRefLayers resolve(mCompositionManager); - mApzcTreeManager->UpdatePanZoomControllerTree(this, root, aIsFirstPaint, mRootLayerTreeID); + mApzcTreeManager->UpdatePanZoomControllerTree(this, root, aIsFirstPaint, + mRootLayerTreeID, aPaintSequenceNumber); } if (root) { @@ -1131,7 +1135,8 @@ public: virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) MOZ_OVERRIDE; + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) MOZ_OVERRIDE; virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, const TimeStamp& aTime) MOZ_OVERRIDE; @@ -1291,7 +1296,8 @@ CrossProcessCompositorParent::ShadowLayersUpdated( LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) { uint64_t id = aLayerTree->GetId(); @@ -1310,7 +1316,8 @@ CrossProcessCompositorParent::ShadowLayersUpdated( } UpdateIndirectTree(id, shadowRoot, aTargetConfig); - state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite); + state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite, + aPaintSequenceNumber); } void diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 4f66240818cb..0969dc8a3fd3 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -97,7 +97,8 @@ public: virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) MOZ_OVERRIDE; + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) MOZ_OVERRIDE; virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, const TimeStamp& aTime) MOZ_OVERRIDE; @@ -128,7 +129,8 @@ public: bool ScheduleResumeOnCompositorThread(int width, int height); virtual void ScheduleComposition(); - void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, bool aScheduleComposite); + void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, + bool aScheduleComposite, uint32_t aPaintSequenceNumber); /** * Check rotation info and schedule a rendering task if needed. diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 32621d0d8944..60fce36fd070 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -179,9 +179,11 @@ bool LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray& cset, const TargetConfig& targetConfig, const bool& isFirstPaint, - const bool& scheduleComposite) + const bool& scheduleComposite, + const uint32_t& paintSequenceNumber) { - return RecvUpdate(cset, targetConfig, isFirstPaint, scheduleComposite, nullptr); + return RecvUpdate(cset, targetConfig, isFirstPaint, scheduleComposite, + paintSequenceNumber, nullptr); } bool @@ -189,6 +191,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray& cset, const TargetConfig& targetConfig, const bool& isFirstPaint, const bool& scheduleComposite, + const uint32_t& paintSequenceNumber, InfallibleTArray* reply) { profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START); @@ -547,7 +550,8 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray& cset, // other's buffer contents. LayerManagerComposite::PlatformSyncBeforeReplyUpdate(); - mShadowLayersManager->ShadowLayersUpdated(this, targetConfig, isFirstPaint, scheduleComposite); + mShadowLayersManager->ShadowLayersUpdated(this, targetConfig, isFirstPaint, + scheduleComposite, paintSequenceNumber); #ifdef COMPOSITOR_PERFORMANCE_WARNING int compositeTime = (int)(mozilla::TimeStamp::Now() - updateStart).ToMilliseconds(); diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 73419f6b42ad..722e16cfb40f 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -89,12 +89,14 @@ protected: const TargetConfig& targetConfig, const bool& isFirstPaint, const bool& scheduleComposite, + const uint32_t& paintSequenceNumber, EditReplyArray* reply) MOZ_OVERRIDE; virtual bool RecvUpdateNoSwap(const EditArray& cset, const TargetConfig& targetConfig, const bool& isFirstPaint, - const bool& scheduleComposite) MOZ_OVERRIDE; + const bool& scheduleComposite, + const uint32_t& paintSequenceNumber) MOZ_OVERRIDE; virtual bool RecvClearCachedResources() MOZ_OVERRIDE; virtual bool RecvForceComposite() MOZ_OVERRIDE; diff --git a/gfx/layers/ipc/PLayerTransaction.ipdl b/gfx/layers/ipc/PLayerTransaction.ipdl index 73229bb62aec..449e59122239 100644 --- a/gfx/layers/ipc/PLayerTransaction.ipdl +++ b/gfx/layers/ipc/PLayerTransaction.ipdl @@ -51,7 +51,8 @@ parent: // The isFirstPaint flag can be used to indicate that this is the first update // for a particular document. - sync Update(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint, bool scheduleComposite) + sync Update(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint, + bool scheduleComposite, uint32_t paintSequenceNumber) returns (EditReply[] reply); // Testing APIs @@ -78,7 +79,8 @@ parent: // We don't need to send a sync transaction if // no transaction operate require a swap. - async UpdateNoSwap(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint, bool scheduleComposite); + async UpdateNoSwap(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint, + bool scheduleComposite, uint32_t paintSequenceNumber); // Drop any front buffers that might be retained on the compositor // side. diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 01ff2039e4ef..803c6016d7e1 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -439,6 +439,7 @@ bool ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, const nsIntRegion& aRegionToClear, bool aScheduleComposite, + uint32_t aPaintSequenceNumber, bool* aSent) { *aSent = false; @@ -549,7 +550,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, if (!HasShadowManager() || !mShadowManager->IPCOpen() || !mShadowManager->SendUpdate(cset, targetConfig, mIsFirstPaint, - aScheduleComposite, aReplies)) { + aScheduleComposite, aPaintSequenceNumber, + aReplies)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } @@ -560,7 +562,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); if (!HasShadowManager() || !mShadowManager->IPCOpen() || - !mShadowManager->SendUpdateNoSwap(cset, targetConfig, mIsFirstPaint, aScheduleComposite)) { + !mShadowManager->SendUpdateNoSwap(cset, targetConfig, mIsFirstPaint, + aPaintSequenceNumber, aScheduleComposite)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index d91c555e7f0c..38ef68e1ef25 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -292,6 +292,7 @@ public: bool EndTransaction(InfallibleTArray* aReplies, const nsIntRegion& aRegionToClear, bool aScheduleComposite, + uint32_t aPaintSequenceNumber, bool* aSent); /** diff --git a/gfx/layers/ipc/ShadowLayersManager.h b/gfx/layers/ipc/ShadowLayersManager.h index 95566682dd54..7a695908ba19 100644 --- a/gfx/layers/ipc/ShadowLayersManager.h +++ b/gfx/layers/ipc/ShadowLayersManager.h @@ -20,7 +20,8 @@ public: virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) = 0; + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) = 0; virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; } diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 04a351150925..149b1bfb0b0a 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -1130,9 +1130,11 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { EXPECT_EQ(gfx3DMatrix(), transformToApzc); EXPECT_EQ(gfx3DMatrix(), transformToGecko); + uint32_t paintSequenceNumber = 0; + // Now we have a root APZC that will match the page SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID); - manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) @@ -1141,7 +1143,7 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { // Now we have a sub APZC with a better fit SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1); - manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController()); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); @@ -1153,7 +1155,7 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2); - manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) @@ -1206,7 +1208,7 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80)); SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80)); - manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, 0); // At this point, the following holds (all coordinates in screen pixels): // layers[0] has content from (0,0)-(200,200), clipped by composition bounds (0,0)-(100,100) diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 2b0d4126ebdc..3ea0663cc660 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -811,7 +811,8 @@ void RenderFrameParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) { // View map must only contain views that are associated with the current // shadow layer tree. We must always update the map when shadow layers diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 7af1ce40f771..3135ea4a1e2d 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -81,7 +81,8 @@ public: virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const TargetConfig& aTargetConfig, bool aIsFirstPaint, - bool aScheduleComposite) MOZ_OVERRIDE; + bool aScheduleComposite, + uint32_t aPaintSequenceNumber) MOZ_OVERRIDE; void BuildDisplayList(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame,