author | Johan Lorenzo <jlorenzo@mozilla.com> |
Wed, 06 Jan 2016 14:59:35 +0100 | |
changeset 278766 | ec25e284ca6fd536484fbb7252fbb1791b71d95f |
parent 278628 | 9d6ffc7a08b6b47056eefe1e652710a3849adbf7 |
child 278767 | 9b1f767c564bb2c7325ec1ef81b54e4e81f7f30b |
push id | 69865 |
push user | ryanvm@gmail.com |
push date | Wed, 06 Jan 2016 14:50:58 +0000 |
treeherder | mozilla-inbound@d004c480a389 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sotaro |
bugs | 1221056, 1237197 |
milestone | 46.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/IPDLActor.h +++ b/gfx/layers/IPDLActor.h @@ -2,17 +2,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_LAYERS_IPDLACTOR_H #define MOZILLA_LAYERS_IPDLACTOR_H #include "mozilla/ipc/ProtocolUtils.h" -#include "mozilla/layers/CompositableForwarder.h" #include "mozilla/unused.h" namespace mozilla { namespace layers { /// A base class to facilitate the deallocation of IPDL actors. /// /// This class implements a simple deallocation protocol that avoids races @@ -44,54 +43,43 @@ public: /// Check the return of CanSend before sending any message! bool CanSend() const { return !mDestroyed; } /// The normal way to destroy the actor. /// /// This will asynchronously send a Destroy message to the parent actor, whom /// will send the delete message. - void Destroy(CompositableForwarder* aFwd = nullptr) + void Destroy() { MOZ_ASSERT(!mDestroyed); if (!mDestroyed) { mDestroyed = true; DestroyManagees(); - if (!aFwd || !aFwd->DestroyInTransaction(this, false)) { - this->SendDestroy(); - } + this->SendDestroy(); } } /// The ugly and slow way to destroy the actor. /// /// This will block until the Parent actor has handled the Destroy message, /// and then start the asynchronous handshake (and destruction will already /// be done on the parent side, when the async part happens). - void DestroySynchronously(CompositableForwarder* aFwd = nullptr) + void DestroySynchronously() { MOZ_PERFORMANCE_WARNING("gfx", "IPDL actor requires synchronous deallocation"); MOZ_ASSERT(!mDestroyed); if (!mDestroyed) { DestroyManagees(); mDestroyed = true; - if (!aFwd || !aFwd->DestroyInTransaction(this, true)) { - this->SendDestroySync(); - this->SendDestroy(); - } + this->SendDestroySync(); + this->SendDestroy(); } } - /// If the transaction that was supposed to destroy the texture fails for - /// whatever reason, fallback to destroying the actor synchronously. - static bool DestroyFallback(Protocol* aActor) - { - return aActor->SendDestroySync(); - } - /// Override this if the protocol manages other protocols, and destroy the /// managees from there virtual void DestroyManagees() {} private: bool mDestroyed; };
--- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -639,16 +639,18 @@ ClientLayerManager::ForwardTransaction(b if (!sent) { // Clear the transaction id so that it doesn't get returned // unless we forwarded to somewhere that doesn't actually // have a compositor. mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId); } + mForwarder->RemoveTexturesIfNecessary(); + mForwarder->RemoveCompositablesIfNecessary(); mForwarder->SendPendingAsyncMessges(); mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); TabChild* window = mWidget->GetOwningTabChild();
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -407,16 +407,17 @@ void ClientTiledPaintedLayer::RenderLayer() { LayerManager::DrawPaintedLayerCallback callback = ClientManager()->GetPaintedLayerCallback(); void *data = ClientManager()->GetPaintedLayerCallbackData(); IntSize layerSize = mVisibleRegion.ToUnknownRegion().GetBounds().Size(); if (mContentClient && !mContentClient->SupportsLayerSize(layerSize, ClientManager())) { + ClientManager()->AsShadowForwarder()->HoldUntilTransaction(mContentClient); mContentClient = nullptr; mValidRegion.SetEmpty(); } if (!mContentClient) { if (mCreationHint == LayerManager::NONE && SingleTiledContentClient::ClientSupportsLayerSize(layerSize, ClientManager()) && gfxPrefs::LayersSingleTileEnabled()) {
--- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -175,28 +175,23 @@ CompositableClient::IsConnected() const } void CompositableClient::Destroy() { if (!IsConnected()) { return; } - - mCompositableChild->mCompositableClient = nullptr; - mCompositableChild->Destroy(mForwarder); - mCompositableChild = nullptr; - + // Send pending AsyncMessages before deleting CompositableChild. + // They might have dependency to the mCompositableChild. mForwarder->SendPendingAsyncMessges(); -} - -bool -CompositableClient::DestroyFallback(PCompositableChild* aActor) -{ - return aActor->SendDestroySync(); + // Destroy CompositableChild. + mCompositableChild->mCompositableClient = nullptr; + mCompositableChild->Destroy(); + mCompositableChild = nullptr; } uint64_t CompositableClient::GetAsyncID() const { if (mCompositableChild) { return mCompositableChild->mAsyncID; }
--- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -150,18 +150,16 @@ public: /** * Establishes the connection with compositor side through IPDL */ virtual bool Connect(ImageContainer* aImageContainer = nullptr); void Destroy(); - static bool DestroyFallback(PCompositableChild* aActor); - bool IsConnected() const; PCompositableChild* GetIPDLActor() const; // should only be called by a CompositableForwarder virtual void SetIPDLActor(CompositableChild* aChild); CompositableForwarder* GetForwarder() const
--- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -295,23 +295,23 @@ DeallocateTextureClient(TextureDeallocPa // race causing this function to be called concurrently which is bad! gfxCriticalError() << "Racy texture deallocation"; return; } if (params.syncDeallocation) { MOZ_PERFORMANCE_WARNING("gfx", "TextureClient/Host pair requires synchronous deallocation"); - actor->DestroySynchronously(actor->GetForwarder()); + actor->DestroySynchronously(); DestroyTextureData(params.data, params.allocator, params.clientDeallocation, actor->mMainThreadOnly); } else { actor->mTextureData = params.data; actor->mOwnsTextureData = params.clientDeallocation; - actor->Destroy(actor->GetForwarder()); + actor->Destroy(); // DestroyTextureData will be called by TextureChild::ActorDestroy } } void TextureClient::Destroy(bool aForceSync) { MOZ_ASSERT(!IsLocked()); @@ -342,24 +342,16 @@ void TextureClient::Destroy(bool aForceS // client side, but having asynchronous deallocate in some of the cases will // be a worthwhile optimization. params.syncDeallocation = !!(mFlags & TextureFlags::DEALLOCATE_CLIENT) || aForceSync; DeallocateTextureClient(params); } } bool -TextureClient::DestroyFallback(PTextureChild* aActor) -{ - // should not end up here so crash debug builds. - MOZ_ASSERT(false); - return aActor->SendDestroySync(); -} - -bool TextureClient::Lock(OpenMode aMode) { MOZ_ASSERT(IsValid()); MOZ_ASSERT(!mIsLocked); if (mIsLocked) { return mOpenMode == aMode; }
--- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -410,18 +410,16 @@ public: * * TextureChild is an implementation detail of TextureClient that is not * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor * are for use with the managing IPDL protocols only (so that they can * implement AllocPextureChild and DeallocPTextureChild). */ static PTextureChild* CreateIPDLActor(); static bool DestroyIPDLActor(PTextureChild* actor); - // call this if the transaction that was supposed to destroy the actor failed. - static bool DestroyFallback(PTextureChild* actor); /** * Get the TextureClient corresponding to the actor passed in parameter. */ static TextureClient* AsTextureClient(PTextureChild* actor); gfx::IntSize GetSize() const;
--- a/gfx/layers/composite/CompositableHost.cpp +++ b/gfx/layers/composite/CompositableHost.cpp @@ -222,22 +222,16 @@ CompositableHost::DumpTextureHost(std::s } RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface(); if (!dSurf) { return; } aStream << gfxUtils::GetAsDataURI(dSurf).get(); } -void -CompositableHost::ReceivedDestroy(PCompositableParent* aActor) -{ - static_cast<CompositableParent*>(aActor)->RecvDestroy(); -} - namespace CompositableMap { typedef std::map<uint64_t, PCompositableParent*> CompositableMap_t; static CompositableMap_t* sCompositableMap = nullptr; bool IsCreated() { return sCompositableMap != nullptr; } PCompositableParent* Get(uint64_t aID)
--- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -171,19 +171,16 @@ public: aFlags & FORCE_DETACH) { SetLayer(nullptr); mAttached = false; mKeepAttached = false; } } bool IsAttached() { return mAttached; } - static void - ReceivedDestroy(PCompositableParent* aActor); - virtual void Dump(std::stringstream& aStream, const char* aPrefix="", bool aDumpHtml=false) { } static void DumpTextureHost(std::stringstream& aStream, TextureHost* aTexture); virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() { return nullptr; } virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0;
--- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -830,22 +830,16 @@ TextureParent::Destroy() // Clear recycle callback. mTextureHost->ClearRecycleCallback(); mWaitForClientRecycle = nullptr; mTextureHost->mActor = nullptr; mTextureHost = nullptr; } -void -TextureHost::ReceivedDestroy(PTextureParent* aActor) -{ - static_cast<TextureParent*>(aActor)->RecvDestroy(); -} - bool TextureParent::RecvRecycleTexture(const TextureFlags& aTextureFlags) { if (!mTextureHost) { return true; } mTextureHost->RecycleTexture(aTextureFlags); return true;
--- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -458,18 +458,16 @@ public: TextureFlags aFlags); static bool DestroyIPDLActor(PTextureParent* actor); /** * Destroy the TextureChild/Parent pair. */ static bool SendDeleteIPDLActor(PTextureParent* actor); - static void ReceivedDestroy(PTextureParent* actor); - /** * Get the TextureHost corresponding to the actor passed in parameter. */ static TextureHost* AsTextureHost(PTextureParent* actor); /** * Return a pointer to the IPDLActor. *
--- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -79,19 +79,16 @@ public: const nsIntRegion& aUpdatedRegion) = 0; #ifdef MOZ_WIDGET_GONK virtual void UseOverlaySource(CompositableClient* aCompositabl, const OverlaySource& aOverlay, const gfx::IntRect& aPictureRect) = 0; #endif - virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) = 0; - virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) = 0; - /** * Tell the CompositableHost on the compositor side to remove the texture * from the CompositableHost. * This function does not delete the TextureHost corresponding to the * TextureClient passed in parameter. * When the TextureClient has TEXTURE_DEALLOCATE_CLIENT flag, * the transaction becomes synchronous. */ @@ -106,16 +103,50 @@ public: * TextureClient passed in parameter. * It is used when the TextureClient recycled. * Only ImageBridge implements it. */ virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker, CompositableClient* aCompositable, TextureClient* aTexture) {} + /** + * Holds a reference to a TextureClient until after the next + * compositor transaction, and then drops it. + */ + virtual void HoldUntilTransaction(TextureClient* aClient) + { + if (aClient) { + mTexturesToRemove.AppendElement(aClient); + } + } + + /** + * Forcibly remove texture data from TextureClient + * This function needs to be called after a tansaction with Compositor. + */ + virtual void RemoveTexturesIfNecessary() + { + mTexturesToRemove.Clear(); + } + + /** + * The same as above, but for CompositableClients. + */ + void HoldUntilTransaction(CompositableClient* aClient) + { + if (aClient) { + mCompositableClientsToRemove.AppendElement(aClient); + } + } + void RemoveCompositablesIfNecessary() + { + mCompositableClientsToRemove.Clear(); + } + struct TimedTextureClient { TimedTextureClient() : mTextureClient(nullptr), mFrameID(0), mProducerID(0) {} TextureClient* mTextureClient; TimeStamp mTimeStamp; nsIntRect mPictureRect; int32_t mFrameID;
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp @@ -228,43 +228,18 @@ CompositableParentManager::ReceiveCompos MOZ_ASSERT(false, "bad type"); } } return true; } void -CompositableParentManager::DestroyActor(const OpDestroy& aOp) -{ - switch (aOp.type()) { - case OpDestroy::TPTextureParent: { - auto actor = aOp.get_PTextureParent(); - TextureHost::ReceivedDestroy(actor); - break; - } - case OpDestroy::TPCompositableParent: { - auto actor = aOp.get_PCompositableParent(); - CompositableHost::ReceivedDestroy(actor); - break; - } - default: { - MOZ_ASSERT(false, "unsupported type"); - } - } -} - -void CompositableParentManager::SendPendingAsyncMessages() { - for (auto& actor : mDestroyedTextures) { - TextureHost::SendDeleteIPDLActor(actor); - } - mDestroyedTextures.clear(); - if (mPendingAsyncMessage.empty()) { return; } // Some type of AsyncParentMessageData message could have // one file descriptor (e.g. OpDeliverFence). // A number of file descriptors per gecko ipc message have a limitation // on OS_POSIX (MACOSX or LINUX).
--- a/gfx/layers/ipc/CompositableTransactionParent.h +++ b/gfx/layers/ipc/CompositableTransactionParent.h @@ -41,28 +41,25 @@ public: virtual base::ProcessId GetChildProcessId() = 0; protected: /** * Handle the IPDL messages that affect PCompositable actors. */ bool ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv); - void DestroyActor(const OpDestroy& aOp); - bool IsOnCompositorSide() const override { return true; } /** * Return true if this protocol is asynchronous with respect to the content * thread (ImageBridge for instance). */ virtual bool IsAsync() const { return false; } virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {} std::vector<AsyncParentMessageData> mPendingAsyncMessage; - std::vector<PTextureParent*> mDestroyedTextures; }; } // namespace layers } // namespace mozilla #endif
--- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -51,17 +51,16 @@ namespace layers { using base::Thread; using base::ProcessId; using namespace mozilla::ipc; using namespace mozilla::gfx; using namespace mozilla::media; typedef std::vector<CompositableOperation> OpVector; -typedef nsTArray<OpDestroy> OpDestroyVector; struct CompositableTransaction { CompositableTransaction() : mSwapRequired(false) , mFinished(true) {} ~CompositableTransaction() @@ -77,59 +76,33 @@ struct CompositableTransaction MOZ_ASSERT(mFinished); mFinished = false; } void End() { mFinished = true; mSwapRequired = false; mOperations.clear(); - mDestroyedActors.Clear(); } bool IsEmpty() const { - return mOperations.empty() && mDestroyedActors.IsEmpty(); + return mOperations.empty(); } void AddNoSwapEdit(const CompositableOperation& op) { MOZ_ASSERT(!Finished(), "forgot BeginTransaction?"); mOperations.push_back(op); } void AddEdit(const CompositableOperation& op) { AddNoSwapEdit(op); - MarkSyncTransaction(); - } - void MarkSyncTransaction() - { mSwapRequired = true; } - void FallbackDestroyActors() - { - for (auto& actor : mDestroyedActors) { - switch (actor.type()) { - case OpDestroy::TPTextureChild: { - DebugOnly<bool> ok = TextureClient::DestroyFallback(actor.get_PTextureChild()); - MOZ_ASSERT(ok); - break; - } - case OpDestroy::TPCompositableChild: { - DebugOnly<bool> ok = CompositableClient::DestroyFallback(actor.get_PCompositableChild()); - MOZ_ASSERT(ok); - break; - } - default: MOZ_CRASH(); - } - } - mDestroyedActors.Clear(); - } - OpVector mOperations; - OpDestroyVector mDestroyedActors; bool mSwapRequired; bool mFinished; }; struct AutoEndTransaction { explicit AutoEndTransaction(CompositableTransaction* aTxn) : mTxn(aTxn) {} ~AutoEndTransaction() { mTxn->End(); } CompositableTransaction* mTxn; @@ -200,22 +173,16 @@ ImageBridgeChild::UseOverlaySource(Compo static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton; static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton; static Thread *sImageBridgeChildThread = nullptr; void ReleaseImageBridgeParentSingleton() { sImageBridgeParentSingleton = nullptr; } -void -ImageBridgeChild::FallbackDestroyActors() { - if (mTxn && !mTxn->mDestroyedActors.IsEmpty()) { - mTxn->FallbackDestroyActors(); - } -} // dispatched function static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone) { ReentrantMonitorAutoEnter autoMon(*aBarrier); MOZ_ASSERT(InImageBridgeChildThread(), "Should be in ImageBridgeChild thread."); @@ -232,18 +199,16 @@ static void ImageBridgeShutdownStep1(Ree InfallibleTArray<PTextureChild*> textures; sImageBridgeChildSingleton->ManagedPTextureChild(textures); for (int i = textures.Length() - 1; i >= 0; --i) { RefPtr<TextureClient> client = TextureClient::AsTextureClient(textures[i]); if (client) { client->Destroy(); } } - sImageBridgeChildSingleton->FallbackDestroyActors(); - sImageBridgeChildSingleton->SendWillStop(); sImageBridgeChildSingleton->MarkShutDown(); // From now on, no message can be sent through the image bridge from the // client side except the final Stop message. } *aDone = true; aBarrier->NotifyAll(); @@ -637,23 +602,38 @@ void ImageBridgeChild::FlushAllImages(Im void ImageBridgeChild::BeginTransaction() { MOZ_ASSERT(!mShuttingDown); MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?"); mTxn->Begin(); } +class MOZ_STACK_CLASS AutoRemoveTexturesFromImageBridge +{ +public: + explicit AutoRemoveTexturesFromImageBridge(ImageBridgeChild* aImageBridge) + : mImageBridge(aImageBridge) {} + + ~AutoRemoveTexturesFromImageBridge() + { + mImageBridge->RemoveTexturesIfNecessary(); + } +private: + ImageBridgeChild* mImageBridge; +}; + void ImageBridgeChild::EndTransaction() { MOZ_ASSERT(!mShuttingDown); MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?"); AutoEndTransaction _(mTxn); + AutoRemoveTexturesFromImageBridge autoRemoveTextures(this); if (mTxn->IsEmpty()) { return; } AutoInfallibleTArray<CompositableOperation, 10> cset; cset.SetCapacity(mTxn->mOperations.size()); if (!mTxn->mOperations.empty()) { @@ -662,27 +642,25 @@ ImageBridgeChild::EndTransaction() if (!IsSameProcess()) { ShadowLayerForwarder::PlatformSyncBeforeUpdate(); } AutoInfallibleTArray<EditReply, 10> replies; if (mTxn->mSwapRequired) { - if (!SendUpdate(cset, mTxn->mDestroyedActors, &replies)) { + if (!SendUpdate(cset, &replies)) { NS_WARNING("could not send async texture transaction"); - mTxn->FallbackDestroyActors(); return; } } else { // If we don't require a swap we can call SendUpdateNoSwap which // assumes that aReplies is empty (DEBUG assertion) - if (!SendUpdateNoSwap(cset, mTxn->mDestroyedActors)) { + if (!SendUpdateNoSwap(cset)) { NS_WARNING("could not send async texture transaction (no swap)"); - mTxn->FallbackDestroyActors(); return; } } for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { NS_RUNTIMEABORT("not reached"); } SendPendingAsyncMessges(); } @@ -1113,45 +1091,16 @@ PTextureChild* ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData, LayersBackend aLayersBackend, TextureFlags aFlags) { MOZ_ASSERT(!mShuttingDown); return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags); } -static bool -IBCAddOpDestroy(CompositableTransaction* aTxn, const OpDestroy& op, bool synchronously) -{ - if (aTxn->Finished()) { - return false; - } - - aTxn->mDestroyedActors.AppendElement(op); - - if (synchronously) { - aTxn->MarkSyncTransaction(); - } - - return true; -} - -bool -ImageBridgeChild::DestroyInTransaction(PTextureChild* aTexture, bool synchronously) -{ - return IBCAddOpDestroy(mTxn, OpDestroy(aTexture), synchronously); -} - -bool -ImageBridgeChild::DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) -{ - return IBCAddOpDestroy(mTxn, OpDestroy(aCompositable), synchronously); -} - - void ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) { MOZ_ASSERT(!mShuttingDown); MOZ_ASSERT(aTexture); MOZ_ASSERT(aTexture->IsSharedWithCompositor()); MOZ_ASSERT(aCompositable->IsConnected()); @@ -1160,16 +1109,18 @@ ImageBridgeChild::RemoveTextureFromCompo } if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) { mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), nullptr, aTexture->GetIPDLActor())); } else { mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), nullptr, aTexture->GetIPDLActor())); } + // Hold texture until transaction complete. + HoldUntilTransaction(aTexture); } void ImageBridgeChild::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker, CompositableClient* aCompositable, TextureClient* aTexture) { MOZ_ASSERT(!mShuttingDown);
--- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -257,19 +257,16 @@ public: TextureClient* aClientOnBlack, TextureClient* aClientOnWhite) override; #ifdef MOZ_WIDGET_GONK virtual void UseOverlaySource(CompositableClient* aCompositable, const OverlaySource& aOverlay, const nsIntRect& aPictureRect) override; #endif - virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) override; - virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) override; - virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) override; virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker, CompositableClient* aCompositable, TextureClient* aTexture) override; virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, @@ -316,18 +313,16 @@ public: LayersBackend aLayersBackend, TextureFlags aFlags) override; virtual bool IsSameProcess() const override; virtual void SendPendingAsyncMessges() override; void MarkShutDown(); - - void FallbackDestroyActors(); protected: ImageBridgeChild(); bool DispatchAllocShmemInternal(size_t aSize, SharedMemory::SharedMemoryType aType, Shmem* aShmem, bool aUnsafe); CompositableTransaction* mTxn;
--- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -124,52 +124,47 @@ public: { mImageBridge->SendPendingAsyncMessages(); } private: ImageBridgeParent* mImageBridge; }; bool -ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy, - EditReplyArray* aReply) +ImageBridgeParent::RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) { AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this); EditReplyVector replyv; for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) { if (!ReceiveCompositableUpdate(aEdits[i], replyv)) { return false; } } - for (const auto& op : aToDestroy) { - DestroyActor(op); - } - aReply->SetCapacity(replyv.size()); if (replyv.size() > 0) { aReply->AppendElements(&replyv.front(), replyv.size()); } if (!IsSameProcess()) { // Ensure that any pending operations involving back and front // buffers have completed, so that neither process stomps on the // other's buffer contents. LayerManagerComposite::PlatformSyncBeforeReplyUpdate(); } return true; } bool -ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy) +ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits) { InfallibleTArray<EditReply> noReplies; - bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), &noReplies); + bool success = RecvUpdate(Move(aEdits), &noReplies); MOZ_ASSERT(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits"); return success; } static void ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge, Transport* aTransport, base::ProcessId aOtherPid)
--- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -38,17 +38,16 @@ namespace layers { * It's purpose is mainly to setup the IPDL connection. Most of the * interesting stuff is in ImageContainerParent. */ class ImageBridgeParent final : public PImageBridgeParent, public CompositableParentManager { public: typedef InfallibleTArray<CompositableOperation> EditArray; - typedef InfallibleTArray<OpDestroy> OpDestroyArray; typedef InfallibleTArray<EditReply> EditReplyArray; typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray; ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId); ~ImageBridgeParent(); virtual void ActorDestroy(ActorDestroyReason aWhy) override; @@ -63,19 +62,18 @@ public: virtual base::ProcessId GetChildProcessId() override { return OtherPid(); } // PImageBridge virtual bool RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override; - virtual bool RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy, - EditReplyArray* aReply) override; - virtual bool RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy) override; + virtual bool RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) override; + virtual bool RecvUpdateNoSwap(EditArray&& aEdits) override; virtual bool IsAsync() const override { return true; } PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo, PImageContainerParent* aImageContainer, uint64_t*) override; bool DeallocPCompositableParent(PCompositableParent* aActor) override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -182,29 +182,27 @@ LayerTransactionParent::Destroy() RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]); tex->DeallocateDeviceData(); } mDestroyed = true; } bool LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset, - InfallibleTArray<OpDestroy>&& aToDestroy, const uint64_t& aTransactionId, const TargetConfig& targetConfig, PluginsArray&& aPlugins, const bool& isFirstPaint, const bool& scheduleComposite, const uint32_t& paintSequenceNumber, const bool& isRepeatTransaction, const mozilla::TimeStamp& aTransactionStart, const int32_t& aPaintSyncId) { - return RecvUpdate(Move(cset), Move(aToDestroy), - aTransactionId, targetConfig, Move(aPlugins), isFirstPaint, + return RecvUpdate(Move(cset), aTransactionId, targetConfig, Move(aPlugins), isFirstPaint, scheduleComposite, paintSequenceNumber, isRepeatTransaction, aTransactionStart, aPaintSyncId, nullptr); } class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender { public: explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction) @@ -216,17 +214,16 @@ public: ImageBridgeParent::SendPendingAsyncMessages(mLayerTransaction->GetChildProcessId()); } private: LayerTransactionParent* mLayerTransaction; }; bool LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset, - InfallibleTArray<OpDestroy>&& aToDestroy, const uint64_t& aTransactionId, const TargetConfig& targetConfig, PluginsArray&& aPlugins, const bool& isFirstPaint, const bool& scheduleComposite, const uint32_t& paintSequenceNumber, const bool& isRepeatTransaction, const mozilla::TimeStamp& aTransactionStart, @@ -239,20 +236,16 @@ LayerTransactionParent::RecvUpdate(Infal #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeStamp updateStart = TimeStamp::Now(); #endif MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length())); if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { - for (const auto& op : aToDestroy) { - DestroyActor(op); - } - return true; } EditReplyVector replyv; AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this); { AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this)); @@ -595,20 +588,16 @@ LayerTransactionParent::RecvUpdate(Infal host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID()); break; } default: NS_RUNTIMEABORT("not reached"); } } - for (const auto& op : aToDestroy) { - DestroyActor(op); - } - mShadowLayersManager->ShadowLayersUpdated(this, aTransactionId, targetConfig, aPlugins, isFirstPaint, scheduleComposite, paintSequenceNumber, isRepeatTransaction, aPaintSyncId); { AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this)); layer_manager()->EndTransaction(TimeStamp(), LayerManager::END_NO_IMMEDIATE_REDRAW);
--- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -35,17 +35,16 @@ class ShadowLayerParent; class CompositableParent; class ShadowLayersManager; class LayerTransactionParent final : public PLayerTransactionParent, public CompositableParentManager { typedef mozilla::layout::RenderFrameParent RenderFrameParent; typedef InfallibleTArray<Edit> EditArray; - typedef InfallibleTArray<OpDestroy> OpDestroyArray; typedef InfallibleTArray<EditReply> EditReplyArray; typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray; typedef InfallibleTArray<PluginWindowData> PluginsArray; public: LayerTransactionParent(LayerManagerComposite* aManager, ShadowLayersManager* aLayersManager, uint64_t aId); @@ -89,30 +88,28 @@ public: } virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override; protected: virtual bool RecvShutdown() override; virtual bool RecvUpdate(EditArray&& cset, - OpDestroyArray&& aToDestroy, const uint64_t& aTransactionId, const TargetConfig& targetConfig, PluginsArray&& aPlugins, const bool& isFirstPaint, const bool& scheduleComposite, const uint32_t& paintSequenceNumber, const bool& isRepeatTransaction, const mozilla::TimeStamp& aTransactionStart, const int32_t& aPaintSyncId, EditReplyArray* reply) override; virtual bool RecvUpdateNoSwap(EditArray&& cset, - OpDestroyArray&& aToDestroy, const uint64_t& aTransactionId, const TargetConfig& targetConfig, PluginsArray&& aPlugins, const bool& isFirstPaint, const bool& scheduleComposite, const uint32_t& paintSequenceNumber, const bool& isRepeatTransaction, const mozilla::TimeStamp& aTransactionStart,
--- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -466,22 +466,16 @@ union Edit { OpRaiseToTopChild; OpAttachCompositable; OpAttachAsyncCompositable; CompositableOperation; }; -// Operations related to destroying resources, always handled after the other -// operations for safety. -union OpDestroy { - PTexture; - PCompositable; -}; // Replies to operations struct OpContentBufferSwap { PCompositable compositable; nsIntRegion frontUpdatedRegion; };
--- a/gfx/layers/ipc/PImageBridge.ipdl +++ b/gfx/layers/ipc/PImageBridge.ipdl @@ -37,20 +37,18 @@ sync protocol PImageBridge child: async ParentAsyncMessages(AsyncParentMessageData[] aMessages); async DidComposite(ImageCompositeNotification[] aNotifications); parent: async ImageBridgeThreadId(PlatformThreadId aTreahdId); - sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy) - returns (EditReply[] reply); - - async UpdateNoSwap(CompositableOperation[] ops, OpDestroy[] toDestroy); + sync Update(CompositableOperation[] ops) returns (EditReply[] reply); + async UpdateNoSwap(CompositableOperation[] ops); // First step of the destruction sequence. This puts ImageBridge // in a state in which it can't send asynchronous messages // so as to not race with the upcomming Stop message and destruction. // In the child side, the Stop message is not sent right after WillStop, // it is scheduled in the ImageBridgeChild's message queue in order to ensure // that all of the messages from the parent side have been received and processed // before sending Stop, and that after Stop returns, there is no message in
--- a/gfx/layers/ipc/PLayerTransaction.ipdl +++ b/gfx/layers/ipc/PLayerTransaction.ipdl @@ -50,28 +50,26 @@ child: parent: async PLayer(); async PCompositable(TextureInfo aTextureInfo); async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags); // The isFirstPaint flag can be used to indicate that this is the first update // for a particular document. - sync Update(Edit[] cset, OpDestroy[] toDestroy, - uint64_t id, TargetConfig targetConfig, + sync Update(Edit[] cset, uint64_t id, TargetConfig targetConfig, PluginWindowData[] plugins, bool isFirstPaint, bool scheduleComposite, uint32_t paintSequenceNumber, bool isRepeatTransaction, TimeStamp transactionStart, int32_t paintSyncId) returns (EditReply[] reply); // We don't need to send a sync transaction if // no transaction operate require a swap. - async UpdateNoSwap(Edit[] cset, OpDestroy[] toDestroy, - uint64_t id, TargetConfig targetConfig, + async UpdateNoSwap(Edit[] cset, uint64_t id, TargetConfig targetConfig, PluginWindowData[] plugins, bool isFirstPaint, bool scheduleComposite, uint32_t paintSequenceNumber, bool isRepeatTransaction, TimeStamp transactionStart, int32_t paintSyncId); // Testing APIs // Enter test mode, set the sample time to sampleTime, and resample
--- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -12,17 +12,16 @@ #include "ISurfaceAllocator.h" // for IsSurfaceDescriptorValid #include "Layers.h" // for Layer #include "RenderTrace.h" // for RenderTraceScope #include "ShadowLayerChild.h" // for ShadowLayerChild #include "gfx2DGlue.h" // for Moz2D transition helpers #include "gfxPlatform.h" // for gfxImageFormat, gfxPlatform #include "gfxSharedImageSurface.h" // for gfxSharedImageSurface #include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t -#include "IPDLActor.h" #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc #include "mozilla/layers/LayersMessages.h" // for Edit, etc #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG #include "mozilla/layers/LayerTransactionChild.h" #include "ShadowLayerUtils.h" @@ -44,17 +43,16 @@ using namespace mozilla::gfx; using namespace mozilla::gl; using namespace mozilla::ipc; class ClientTiledLayerBuffer; typedef nsTArray<SurfaceDescriptor> BufferArray; typedef std::vector<Edit> EditVector; typedef std::set<ShadowableLayer*> ShadowableLayerSet; -typedef nsTArray<OpDestroy> OpDestroyVector; class Transaction { public: Transaction() : mTargetRotation(ROTATION_0) , mSwapRequired(false) , mOpen(false) @@ -115,56 +113,33 @@ public: MOZ_ASSERT(!Finished(), "forgot BeginTransaction?"); mMutants.insert(aLayer); } void End() { mCset.clear(); mPaints.clear(); mMutants.clear(); - mDestroyedActors.Clear(); mOpen = false; mSwapRequired = false; mRotationChanged = false; } bool Empty() const { - return mCset.empty() && mPaints.empty() && mMutants.empty() - && mDestroyedActors.IsEmpty(); + return mCset.empty() && mPaints.empty() && mMutants.empty(); } bool RotationChanged() const { return mRotationChanged; } bool Finished() const { return !mOpen && Empty(); } bool Opened() const { return mOpen; } - void FallbackDestroyActors() - { - for (auto& actor : mDestroyedActors) { - switch (actor.type()) { - case OpDestroy::TPTextureChild: { - DebugOnly<bool> ok = TextureClient::DestroyFallback(actor.get_PTextureChild()); - MOZ_ASSERT(ok); - break; - } - case OpDestroy::TPCompositableChild: { - DebugOnly<bool> ok = CompositableClient::DestroyFallback(actor.get_PCompositableChild()); - MOZ_ASSERT(ok); - break; - } - default: MOZ_CRASH(); - } - } - mDestroyedActors.Clear(); - } - EditVector mCset; EditVector mPaints; - OpDestroyVector mDestroyedActors; ShadowableLayerSet mMutants; gfx::IntRect mTargetBounds; ScreenRotation mTargetRotation; dom::ScreenOrientationInternal mTargetOrientation; bool mSwapRequired; private: bool mOpen; @@ -195,19 +170,16 @@ ShadowLayerForwarder::ShadowLayerForward , mPaintSyncId(0) { mTxn = new Transaction(); } ShadowLayerForwarder::~ShadowLayerForwarder() { MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?"); - if (!mTxn->mDestroyedActors.IsEmpty()) { - mTxn->FallbackDestroyActors(); - } delete mTxn; if (mShadowManager) { mShadowManager->SetForwarder(nullptr); mShadowManager->Destroy(); } } void @@ -438,43 +410,16 @@ ShadowLayerForwarder::UseOverlaySource(C MOZ_ASSERT(aCompositable); MOZ_ASSERT(aCompositable->IsConnected()); mTxn->AddEdit(OpUseOverlaySource(nullptr, aCompositable->GetIPDLActor(), aOverlay, aPictureRect)); } #endif -static bool -AddOpDestroy(Transaction* aTxn, const OpDestroy& op, bool synchronously) -{ - if (!aTxn->Opened()) { - return false; - } - - aTxn->mDestroyedActors.AppendElement(op); - if (synchronously) { - aTxn->MarkSyncTransaction(); - } - - return true; -} - -bool -ShadowLayerForwarder::DestroyInTransaction(PTextureChild* aTexture, bool synchronously) -{ - return AddOpDestroy(mTxn, OpDestroy(aTexture), synchronously); -} - -bool -ShadowLayerForwarder::DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) -{ - return AddOpDestroy(mTxn, OpDestroy(aCompositable), synchronously); -} - void ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) { MOZ_ASSERT(aCompositable); MOZ_ASSERT(aTexture); MOZ_ASSERT(aCompositable->IsConnected()); MOZ_ASSERT(aTexture->GetIPDLActor()); @@ -483,16 +428,18 @@ ShadowLayerForwarder::RemoveTextureFromC return; } mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), nullptr, aTexture->GetIPDLActor())); if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) { mTxn->MarkSyncTransaction(); } + // Hold texture until transaction complete. + HoldUntilTransaction(aTexture); } void ShadowLayerForwarder::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker, CompositableClient* aCompositable, TextureClient* aTexture) { MOZ_ASSERT(aCompositable); @@ -695,39 +642,35 @@ ShadowLayerForwarder::EndTransaction(Inf } profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END); if (mTxn->mSwapRequired) { MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); RenderTraceScope rendertrace3("Forward Transaction", "000093"); if (!HasShadowManager() || !mShadowManager->IPCOpen() || - !mShadowManager->SendUpdate(cset, mTxn->mDestroyedActors, - aId, targetConfig, mPluginWindowData, + !mShadowManager->SendUpdate(cset, aId, targetConfig, mPluginWindowData, mIsFirstPaint, aScheduleComposite, aPaintSequenceNumber, aIsRepeatTransaction, aTransactionStart, mPaintSyncId, aReplies)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); - mTxn->FallbackDestroyActors(); return false; } } else { // If we don't require a swap we can call SendUpdateNoSwap which // assumes that aReplies is empty (DEBUG assertion) MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction...")); RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); if (!HasShadowManager() || !mShadowManager->IPCOpen() || - !mShadowManager->SendUpdateNoSwap(cset, mTxn->mDestroyedActors, - aId, targetConfig, mPluginWindowData, + !mShadowManager->SendUpdateNoSwap(cset, aId, targetConfig, mPluginWindowData, mIsFirstPaint, aScheduleComposite, aPaintSequenceNumber, aIsRepeatTransaction, aTransactionStart, mPaintSyncId)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); - mTxn->FallbackDestroyActors(); return false; } } *aSent = true; mIsFirstPaint = false; mPaintSyncId = 0; MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
--- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -209,19 +209,16 @@ public: ShadowableLayer* aMaskLayer); /** * See CompositableForwarder::UseTiledLayerBuffer */ virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, const SurfaceDescriptorTiles& aTileLayerDescriptor) override; - virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) override; - virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) override; - virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) override; virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker, CompositableClient* aCompositable, TextureClient* aTexture) override; /**