From 6c8fec17917aa8a4d066189db2a11a1769de0f8e Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Tue, 7 Oct 2014 11:37:15 -0700 Subject: [PATCH] Bug 1076868 - Fix RemoveTextureFromCompositableAsync() call handling r=nical --- gfx/layers/client/ClientLayerManager.cpp | 2 +- gfx/layers/client/CompositableClient.cpp | 4 +++ gfx/layers/ipc/CompositableForwarder.h | 2 ++ gfx/layers/ipc/ImageBridgeChild.cpp | 4 +-- gfx/layers/ipc/ImageBridgeChild.h | 2 +- gfx/layers/ipc/LayerTransactionParent.cpp | 26 ++++++++++++++ gfx/layers/ipc/LayersMessages.ipdlh | 1 + gfx/layers/ipc/ShadowLayers.cpp | 43 +++++++++++++++++------ gfx/layers/ipc/ShadowLayers.h | 3 +- 9 files changed, 71 insertions(+), 16 deletions(-) diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index 9c735489282..52979abdb97 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -607,7 +607,7 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite) } mForwarder->RemoveTexturesIfNecessary(); - mForwarder->SendPendingAsyncMessge(); + mForwarder->SendPendingAsyncMessges(); mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 3de25025067..fca3280d280 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -171,6 +171,10 @@ CompositableClient::Destroy() if (!mCompositableChild) { return; } + // Send pending AsyncMessages before deleting CompositableChild. + // They might have dependency to the mCompositableChild. + mForwarder->SendPendingAsyncMessges(); + // Delete CompositableChild. mCompositableChild->mCompositableClient = nullptr; PCompositableChild::Send__delete__(mCompositableChild); mCompositableChild = nullptr; diff --git a/gfx/layers/ipc/CompositableForwarder.h b/gfx/layers/ipc/CompositableForwarder.h index 040c7902fef..6bac768cf63 100644 --- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -194,6 +194,8 @@ public: PTextureChild* aTexture, const FenceHandle& aFence) = 0; + virtual void SendPendingAsyncMessges() = 0; + void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier); virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index c8162382abf..b58c5c0cf3b 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -555,7 +555,7 @@ ImageBridgeChild::EndTransaction() NS_RUNTIMEABORT("not reached"); } } - SendPendingAsyncMessge(); + SendPendingAsyncMessges(); } @@ -964,7 +964,7 @@ bool ImageBridgeChild::IsSameProcess() const return OtherProcess() == ipc::kInvalidProcessHandle; } -void ImageBridgeChild::SendPendingAsyncMessge() +void ImageBridgeChild::SendPendingAsyncMessges() { if (!IsCreated() || mTransactionsToRespond.empty()) { diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index facf86d8321..6e60c10879b 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -310,7 +310,7 @@ public: virtual bool IsSameProcess() const MOZ_OVERRIDE; - void SendPendingAsyncMessge(); + virtual void SendPendingAsyncMessges(); void MarkShutDown(); protected: diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 059752f6cd6..86de8d9a8bd 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -858,6 +858,8 @@ LayerTransactionParent::DeallocPTextureParent(PTextureParent* actor) bool LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray& aMessages) { + AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this); + for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) { const AsyncChildMessageData& message = aMessages[i]; @@ -888,6 +890,30 @@ LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray tex = TextureHost::AsTextureHost(op.textureParent()); + + MOZ_ASSERT(tex.get()); + compositable->RemoveTextureHost(tex); + + // send FenceHandle if present via ImageBridge. + ImageBridgeParent::SendFenceHandleToTrackerIfPresent( + GetChildProcessId(), + op.holderId(), + op.transactionId(), + op.textureParent(), + compositable); + + // Send message back via PImageBridge. + ImageBridgeParent::ReplyRemoveTexture( + GetChildProcessId(), + OpReplyRemoveTexture(true, // isMain + op.holderId(), + op.transactionId())); + break; + } default: NS_ERROR("unknown AsyncChildMessageData type"); return false; diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 521935573b0..83722791976 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -492,6 +492,7 @@ union AsyncParentMessageData { union AsyncChildMessageData { OpDeliverFenceFromChild; OpReplyDeliverFence; + OpRemoveTextureAsync; }; } // namespace diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 15135f27385..116b8fc1567 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -135,6 +135,8 @@ public: } bool Finished() const { return !mOpen && Empty(); } + bool Opened() const { return mOpen; } + EditVector mCset; EditVector mPaints; ShadowableLayerSet mMutants; @@ -472,11 +474,19 @@ ShadowLayerForwarder::RemoveTextureFromCompositableAsync(AsyncTransactionTracker CompositableClient* aCompositable, TextureClient* aTexture) { - mTxn->AddEdit(OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()), - aAsyncTransactionTracker->GetId(), - nullptr, aCompositable->GetIPDLActor(), - nullptr, aTexture->GetIPDLActor())); - // Hold AsyncTransactionTracker until receving reply + if (mTxn->Opened()) { + mTxn->AddEdit(OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()), + aAsyncTransactionTracker->GetId(), + nullptr, aCompositable->GetIPDLActor(), + nullptr, aTexture->GetIPDLActor())); + } else { + // If the function is called outside of transaction, + // OpRemoveTextureAsync message is stored as pending message. + mPendingAsyncMessages.push_back(OpRemoveTextureAsync(CompositableClient::GetTrackersHolderId(aCompositable->GetIPDLActor()), + aAsyncTransactionTracker->GetId(), + nullptr, aCompositable->GetIPDLActor(), + nullptr, aTexture->GetIPDLActor())); + } CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(), aAsyncTransactionTracker); } @@ -821,7 +831,7 @@ void ShadowLayerForwarder::StopReceiveAsyncParentMessge() !mShadowManager->IPCOpen()) { return; } - SendPendingAsyncMessge(); + SendPendingAsyncMessges(); mShadowManager->SetForwarder(nullptr); } @@ -831,7 +841,7 @@ void ShadowLayerForwarder::ClearCachedResources() !mShadowManager->IPCOpen()) { return; } - SendPendingAsyncMessge(); + SendPendingAsyncMessges(); mShadowManager->SendClearCachedResources(); } @@ -844,20 +854,31 @@ void ShadowLayerForwarder::Composite() mShadowManager->SendForceComposite(); } -void ShadowLayerForwarder::SendPendingAsyncMessge() +void ShadowLayerForwarder::SendPendingAsyncMessges() { if (!HasShadowManager() || - !mShadowManager->IPCOpen() || - mTransactionsToRespond.empty()) { + !mShadowManager->IPCOpen()) { + mTransactionsToRespond.clear(); + mPendingAsyncMessages.clear(); return; } - // Send OpReplyDeliverFence messages + + if (mTransactionsToRespond.empty() && mPendingAsyncMessages.empty()) { + return; + } + InfallibleTArray replies; replies.SetCapacity(mTransactionsToRespond.size()); + // Prepare OpReplyDeliverFence messages. for (size_t i = 0; i < mTransactionsToRespond.size(); i++) { replies.AppendElement(OpReplyDeliverFence(mTransactionsToRespond[i])); } mTransactionsToRespond.clear(); + // Prepare pending messages. + for (size_t i = 0; i < mPendingAsyncMessages.size(); i++) { + replies.AppendElement(mPendingAsyncMessages[i]); + } + mPendingAsyncMessages.clear(); mShadowManager->SendChildAsyncMessages(replies); } diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index c01c46f1737..694c7eb4c0b 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -319,7 +319,7 @@ public: void Composite(); - void SendPendingAsyncMessge(); + virtual void SendPendingAsyncMessges(); /** * True if this is forwarding to a LayerManagerComposite. @@ -403,6 +403,7 @@ protected: private: Transaction* mTxn; + std::vector mPendingAsyncMessages; DiagnosticTypes mDiagnosticTypes; bool mIsFirstPaint; bool mWindowOverlayChanged;