зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1221056 - make the destroy messages for PTexture and PCompositable part of the current transaction when applicable. r=sotaro
This commit is contained in:
Родитель
d9a9a55a72
Коммит
4d9fc4395b
|
@ -7,6 +7,7 @@
|
|||
#define MOZILLA_LAYERS_IPDLACTOR_H
|
||||
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -48,32 +49,43 @@ public:
|
|||
///
|
||||
/// This will asynchronously send a Destroy message to the parent actor, whom
|
||||
/// will send the delete message.
|
||||
void Destroy()
|
||||
void Destroy(CompositableForwarder* aFwd = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
if (!mDestroyed) {
|
||||
mDestroyed = true;
|
||||
DestroyManagees();
|
||||
if (!aFwd || !aFwd->DestroyInTransaction(this, false)) {
|
||||
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()
|
||||
void DestroySynchronously(CompositableForwarder* aFwd = nullptr)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
|
|
@ -644,8 +644,6 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
|||
mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
|
||||
}
|
||||
|
||||
mForwarder->RemoveTexturesIfNecessary();
|
||||
mForwarder->RemoveCompositablesIfNecessary();
|
||||
mForwarder->SendPendingAsyncMessges();
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
|
|
|
@ -412,7 +412,6 @@ ClientTiledPaintedLayer::RenderLayer()
|
|||
|
||||
IntSize layerSize = mVisibleRegion.ToUnknownRegion().GetBounds().Size();
|
||||
if (mContentClient && !mContentClient->SupportsLayerSize(layerSize, ClientManager())) {
|
||||
ClientManager()->AsShadowForwarder()->HoldUntilTransaction(mContentClient);
|
||||
mContentClient = nullptr;
|
||||
mValidRegion.SetEmpty();
|
||||
}
|
||||
|
|
|
@ -180,13 +180,18 @@ CompositableClient::Destroy()
|
|||
if (!IsConnected()) {
|
||||
return;
|
||||
}
|
||||
// Send pending AsyncMessages before deleting CompositableChild.
|
||||
// They might have dependency to the mCompositableChild.
|
||||
mForwarder->SendPendingAsyncMessges();
|
||||
// Destroy CompositableChild.
|
||||
|
||||
mCompositableChild->mCompositableClient = nullptr;
|
||||
mCompositableChild->Destroy();
|
||||
mCompositableChild->Destroy(mForwarder);
|
||||
mCompositableChild = nullptr;
|
||||
|
||||
mForwarder->SendPendingAsyncMessges();
|
||||
}
|
||||
|
||||
bool
|
||||
CompositableClient::DestroyFallback(PCompositableChild* aActor)
|
||||
{
|
||||
return aActor->SendDestroySync();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
|
|
@ -155,6 +155,8 @@ public:
|
|||
|
||||
void Destroy();
|
||||
|
||||
static bool DestroyFallback(PCompositableChild* aActor);
|
||||
|
||||
bool IsConnected() const;
|
||||
|
||||
PCompositableChild* GetIPDLActor() const;
|
||||
|
|
|
@ -300,13 +300,13 @@ DeallocateTextureClient(TextureDeallocParams params)
|
|||
if (params.syncDeallocation) {
|
||||
MOZ_PERFORMANCE_WARNING("gfx",
|
||||
"TextureClient/Host pair requires synchronous deallocation");
|
||||
actor->DestroySynchronously();
|
||||
actor->DestroySynchronously(actor->GetForwarder());
|
||||
DestroyTextureData(params.data, params.allocator, params.clientDeallocation,
|
||||
actor->mMainThreadOnly);
|
||||
} else {
|
||||
actor->mTextureData = params.data;
|
||||
actor->mOwnsTextureData = params.clientDeallocation;
|
||||
actor->Destroy();
|
||||
actor->Destroy(actor->GetForwarder());
|
||||
// DestroyTextureData will be called by TextureChild::ActorDestroy
|
||||
}
|
||||
}
|
||||
|
@ -346,6 +346,14 @@ void TextureClient::Destroy(bool aForceSync)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -415,6 +415,8 @@ public:
|
|||
*/
|
||||
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.
|
||||
|
|
|
@ -227,6 +227,12 @@ CompositableHost::DumpTextureHost(std::stringstream& aStream, TextureHost* aText
|
|||
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;
|
||||
|
|
|
@ -176,6 +176,9 @@ public:
|
|||
}
|
||||
bool IsAttached() { return mAttached; }
|
||||
|
||||
static void
|
||||
ReceivedDestroy(PCompositableParent* aActor);
|
||||
|
||||
virtual void Dump(std::stringstream& aStream,
|
||||
const char* aPrefix="",
|
||||
bool aDumpHtml=false) { }
|
||||
|
|
|
@ -835,6 +835,12 @@ TextureParent::Destroy()
|
|||
mTextureHost = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::ReceivedDestroy(PTextureParent* aActor)
|
||||
{
|
||||
static_cast<TextureParent*>(aActor)->RecvDestroy();
|
||||
}
|
||||
|
||||
bool
|
||||
TextureParent::RecvRecycleTexture(const TextureFlags& aTextureFlags)
|
||||
{
|
||||
|
|
|
@ -463,6 +463,8 @@ public:
|
|||
*/
|
||||
static bool SendDeleteIPDLActor(PTextureParent* actor);
|
||||
|
||||
static void ReceivedDestroy(PTextureParent* actor);
|
||||
|
||||
/**
|
||||
* Get the TextureHost corresponding to the actor passed in parameter.
|
||||
*/
|
||||
|
|
|
@ -84,6 +84,9 @@ public:
|
|||
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.
|
||||
|
@ -108,40 +111,6 @@ public:
|
|||
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) {}
|
||||
|
|
|
@ -232,9 +232,34 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ protected:
|
|||
*/
|
||||
bool ReceiveCompositableUpdate(const CompositableOperation& aEdit,
|
||||
EditReplyVector& replyv);
|
||||
void DestroyActor(const OpDestroy& aOp);
|
||||
|
||||
bool IsOnCompositorSide() const override { return true; }
|
||||
|
||||
/**
|
||||
|
@ -57,6 +59,7 @@ protected:
|
|||
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
|
||||
|
||||
std::vector<AsyncParentMessageData> mPendingAsyncMessage;
|
||||
std::vector<PTextureParent*> mDestroyedTextures;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -56,6 +56,7 @@ using namespace mozilla::gfx;
|
|||
using namespace mozilla::media;
|
||||
|
||||
typedef std::vector<CompositableOperation> OpVector;
|
||||
typedef nsTArray<OpDestroy> OpDestroyVector;
|
||||
|
||||
struct CompositableTransaction
|
||||
{
|
||||
|
@ -81,10 +82,11 @@ struct CompositableTransaction
|
|||
mFinished = true;
|
||||
mSwapRequired = false;
|
||||
mOperations.clear();
|
||||
mDestroyedActors.Clear();
|
||||
}
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return mOperations.empty();
|
||||
return mOperations.empty() && mDestroyedActors.IsEmpty();
|
||||
}
|
||||
void AddNoSwapEdit(const CompositableOperation& op)
|
||||
{
|
||||
|
@ -94,10 +96,35 @@ struct CompositableTransaction
|
|||
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;
|
||||
};
|
||||
|
@ -178,6 +205,12 @@ void ReleaseImageBridgeParentSingleton() {
|
|||
sImageBridgeParentSingleton = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::FallbackDestroyActors() {
|
||||
if (mTxn && !mTxn->mDestroyedActors.IsEmpty()) {
|
||||
mTxn->FallbackDestroyActors();
|
||||
}
|
||||
}
|
||||
|
||||
// dispatched function
|
||||
static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone)
|
||||
|
@ -204,6 +237,8 @@ static void ImageBridgeShutdownStep1(ReentrantMonitor *aBarrier, bool *aDone)
|
|||
client->Destroy();
|
||||
}
|
||||
}
|
||||
sImageBridgeChildSingleton->FallbackDestroyActors();
|
||||
|
||||
sImageBridgeChildSingleton->SendWillStop();
|
||||
sImageBridgeChildSingleton->MarkShutDown();
|
||||
// From now on, no message can be sent through the image bridge from the
|
||||
|
@ -607,20 +642,6 @@ ImageBridgeChild::BeginTransaction()
|
|||
mTxn->Begin();
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoRemoveTexturesFromImageBridge
|
||||
{
|
||||
public:
|
||||
explicit AutoRemoveTexturesFromImageBridge(ImageBridgeChild* aImageBridge)
|
||||
: mImageBridge(aImageBridge) {}
|
||||
|
||||
~AutoRemoveTexturesFromImageBridge()
|
||||
{
|
||||
mImageBridge->RemoveTexturesIfNecessary();
|
||||
}
|
||||
private:
|
||||
ImageBridgeChild* mImageBridge;
|
||||
};
|
||||
|
||||
void
|
||||
ImageBridgeChild::EndTransaction()
|
||||
{
|
||||
|
@ -628,7 +649,6 @@ ImageBridgeChild::EndTransaction()
|
|||
MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
|
||||
|
||||
AutoEndTransaction _(mTxn);
|
||||
AutoRemoveTexturesFromImageBridge autoRemoveTextures(this);
|
||||
|
||||
if (mTxn->IsEmpty()) {
|
||||
return;
|
||||
|
@ -647,15 +667,17 @@ ImageBridgeChild::EndTransaction()
|
|||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
|
||||
if (mTxn->mSwapRequired) {
|
||||
if (!SendUpdate(cset, &replies)) {
|
||||
if (!SendUpdate(cset, mTxn->mDestroyedActors, &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)) {
|
||||
if (!SendUpdateNoSwap(cset, mTxn->mDestroyedActors)) {
|
||||
NS_WARNING("could not send async texture transaction (no swap)");
|
||||
mTxn->FallbackDestroyActors();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1096,6 +1118,35 @@ ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
|
|||
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)
|
||||
|
@ -1114,8 +1165,6 @@ ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositabl
|
|||
mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
|
||||
nullptr, aTexture->GetIPDLActor()));
|
||||
}
|
||||
// Hold texture until transaction complete.
|
||||
HoldUntilTransaction(aTexture);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -262,6 +262,9 @@ public:
|
|||
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;
|
||||
|
||||
|
@ -318,6 +321,8 @@ public:
|
|||
virtual void SendPendingAsyncMessges() override;
|
||||
|
||||
void MarkShutDown();
|
||||
|
||||
void FallbackDestroyActors();
|
||||
protected:
|
||||
ImageBridgeChild();
|
||||
bool DispatchAllocShmemInternal(size_t aSize,
|
||||
|
|
|
@ -129,7 +129,8 @@ private:
|
|||
};
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply)
|
||||
ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
EditReplyArray* aReply)
|
||||
{
|
||||
AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this);
|
||||
|
||||
|
@ -140,6 +141,10 @@ ImageBridgeParent::RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply)
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
|
||||
aReply->SetCapacity(replyv.size());
|
||||
if (replyv.size() > 0) {
|
||||
aReply->AppendElements(&replyv.front(), replyv.size());
|
||||
|
@ -156,10 +161,10 @@ ImageBridgeParent::RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply)
|
|||
}
|
||||
|
||||
bool
|
||||
ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits)
|
||||
ImageBridgeParent::RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy)
|
||||
{
|
||||
InfallibleTArray<EditReply> noReplies;
|
||||
bool success = RecvUpdate(Move(aEdits), &noReplies);
|
||||
bool success = RecvUpdate(Move(aEdits), Move(aToDestroy), &noReplies);
|
||||
MOZ_ASSERT(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ class ImageBridgeParent final : public PImageBridgeParent,
|
|||
{
|
||||
public:
|
||||
typedef InfallibleTArray<CompositableOperation> EditArray;
|
||||
typedef InfallibleTArray<OpDestroy> OpDestroyArray;
|
||||
typedef InfallibleTArray<EditReply> EditReplyArray;
|
||||
typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
|
||||
|
||||
|
@ -67,8 +68,9 @@ public:
|
|||
|
||||
// PImageBridge
|
||||
virtual bool RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
|
||||
virtual bool RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) override;
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& aEdits) override;
|
||||
virtual bool RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
|
||||
EditReplyArray* aReply) override;
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy) override;
|
||||
|
||||
virtual bool IsAsync() const override { return true; }
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ LayerTransactionParent::Destroy()
|
|||
|
||||
bool
|
||||
LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
|
@ -197,7 +198,8 @@ LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
|
|||
const mozilla::TimeStamp& aTransactionStart,
|
||||
const int32_t& aPaintSyncId)
|
||||
{
|
||||
return RecvUpdate(Move(cset), aTransactionId, targetConfig, Move(aPlugins), isFirstPaint,
|
||||
return RecvUpdate(Move(cset), Move(aToDestroy),
|
||||
aTransactionId, targetConfig, Move(aPlugins), isFirstPaint,
|
||||
scheduleComposite, paintSequenceNumber, isRepeatTransaction,
|
||||
aTransactionStart, aPaintSyncId, nullptr);
|
||||
}
|
||||
|
@ -219,6 +221,7 @@ private:
|
|||
|
||||
bool
|
||||
LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
||||
InfallibleTArray<OpDestroy>&& aToDestroy,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
|
@ -241,6 +244,10 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -593,6 +600,10 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& op : aToDestroy) {
|
||||
DestroyActor(op);
|
||||
}
|
||||
|
||||
mShadowLayersManager->ShadowLayersUpdated(this, aTransactionId, targetConfig,
|
||||
aPlugins, isFirstPaint, scheduleComposite,
|
||||
paintSequenceNumber, isRepeatTransaction,
|
||||
|
|
|
@ -40,6 +40,7 @@ class LayerTransactionParent final : public PLayerTransactionParent,
|
|||
{
|
||||
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;
|
||||
|
@ -93,6 +94,7 @@ protected:
|
|||
virtual bool RecvShutdown() override;
|
||||
|
||||
virtual bool RecvUpdate(EditArray&& cset,
|
||||
OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
|
@ -105,6 +107,7 @@ protected:
|
|||
EditReplyArray* reply) override;
|
||||
|
||||
virtual bool RecvUpdateNoSwap(EditArray&& cset,
|
||||
OpDestroyArray&& aToDestroy,
|
||||
const uint64_t& aTransactionId,
|
||||
const TargetConfig& targetConfig,
|
||||
PluginsArray&& aPlugins,
|
||||
|
|
|
@ -471,6 +471,12 @@ union Edit {
|
|||
CompositableOperation;
|
||||
};
|
||||
|
||||
// Operations related to destroying resources, always handled after the other
|
||||
// operations for safety.
|
||||
union OpDestroy {
|
||||
PTexture;
|
||||
PCompositable;
|
||||
};
|
||||
|
||||
// Replies to operations
|
||||
|
||||
|
|
|
@ -42,8 +42,10 @@ child:
|
|||
parent:
|
||||
async ImageBridgeThreadId(PlatformThreadId aTreahdId);
|
||||
|
||||
sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
|
||||
async UpdateNoSwap(CompositableOperation[] ops);
|
||||
sync Update(CompositableOperation[] ops, OpDestroy[] toDestroy)
|
||||
returns (EditReply[] reply);
|
||||
|
||||
async UpdateNoSwap(CompositableOperation[] ops, OpDestroy[] toDestroy);
|
||||
|
||||
// First step of the destruction sequence. This puts ImageBridge
|
||||
// in a state in which it can't send asynchronous messages
|
||||
|
|
|
@ -55,7 +55,8 @@ parent:
|
|||
|
||||
// The isFirstPaint flag can be used to indicate that this is the first update
|
||||
// for a particular document.
|
||||
sync Update(Edit[] cset, uint64_t id, TargetConfig targetConfig,
|
||||
sync Update(Edit[] cset, OpDestroy[] toDestroy,
|
||||
uint64_t id, TargetConfig targetConfig,
|
||||
PluginWindowData[] plugins, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
bool isRepeatTransaction, TimeStamp transactionStart,
|
||||
|
@ -64,7 +65,8 @@ parent:
|
|||
|
||||
// We don't need to send a sync transaction if
|
||||
// no transaction operate require a swap.
|
||||
async UpdateNoSwap(Edit[] cset, uint64_t id, TargetConfig targetConfig,
|
||||
async UpdateNoSwap(Edit[] cset, OpDestroy[] toDestroy,
|
||||
uint64_t id, TargetConfig targetConfig,
|
||||
PluginWindowData[] plugins, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
bool isRepeatTransaction, TimeStamp transactionStart,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#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
|
||||
|
@ -48,6 +49,7 @@ class ClientTiledLayerBuffer;
|
|||
typedef nsTArray<SurfaceDescriptor> BufferArray;
|
||||
typedef std::vector<Edit> EditVector;
|
||||
typedef std::set<ShadowableLayer*> ShadowableLayerSet;
|
||||
typedef nsTArray<OpDestroy> OpDestroyVector;
|
||||
|
||||
class Transaction
|
||||
{
|
||||
|
@ -118,13 +120,15 @@ public:
|
|||
mCset.clear();
|
||||
mPaints.clear();
|
||||
mMutants.clear();
|
||||
mDestroyedActors.Clear();
|
||||
mOpen = false;
|
||||
mSwapRequired = false;
|
||||
mRotationChanged = false;
|
||||
}
|
||||
|
||||
bool Empty() const {
|
||||
return mCset.empty() && mPaints.empty() && mMutants.empty();
|
||||
return mCset.empty() && mPaints.empty() && mMutants.empty()
|
||||
&& mDestroyedActors.IsEmpty();
|
||||
}
|
||||
bool RotationChanged() const {
|
||||
return mRotationChanged;
|
||||
|
@ -133,8 +137,29 @@ public:
|
|||
|
||||
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;
|
||||
|
@ -175,6 +200,9 @@ ShadowLayerForwarder::ShadowLayerForwarder()
|
|||
ShadowLayerForwarder::~ShadowLayerForwarder()
|
||||
{
|
||||
MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?");
|
||||
if (!mTxn->mDestroyedActors.IsEmpty()) {
|
||||
mTxn->FallbackDestroyActors();
|
||||
}
|
||||
delete mTxn;
|
||||
if (mShadowManager) {
|
||||
mShadowManager->SetForwarder(nullptr);
|
||||
|
@ -415,6 +443,33 @@ ShadowLayerForwarder::UseOverlaySource(CompositableClient* aCompositable,
|
|||
}
|
||||
#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)
|
||||
|
@ -433,8 +488,6 @@ ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aComposi
|
|||
if (aTexture->GetFlags() & TextureFlags::DEALLOCATE_CLIENT) {
|
||||
mTxn->MarkSyncTransaction();
|
||||
}
|
||||
// Hold texture until transaction complete.
|
||||
HoldUntilTransaction(aTexture);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -647,11 +700,13 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
|||
RenderTraceScope rendertrace3("Forward Transaction", "000093");
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdate(cset, aId, targetConfig, mPluginWindowData,
|
||||
!mShadowManager->SendUpdate(cset, mTxn->mDestroyedActors,
|
||||
aId, targetConfig, mPluginWindowData,
|
||||
mIsFirstPaint, aScheduleComposite,
|
||||
aPaintSequenceNumber, aIsRepeatTransaction,
|
||||
aTransactionStart, mPaintSyncId, aReplies)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
mTxn->FallbackDestroyActors();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -661,11 +716,13 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
|||
RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093");
|
||||
if (!HasShadowManager() ||
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdateNoSwap(cset, aId, targetConfig, mPluginWindowData,
|
||||
!mShadowManager->SendUpdateNoSwap(cset, mTxn->mDestroyedActors,
|
||||
aId, targetConfig, mPluginWindowData,
|
||||
mIsFirstPaint, aScheduleComposite,
|
||||
aPaintSequenceNumber, aIsRepeatTransaction,
|
||||
aTransactionStart, mPaintSyncId)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
mTxn->FallbackDestroyActors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,6 +214,9 @@ public:
|
|||
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче