Bug 1221056 - make the destroy messages for PTexture and PCompositable part of the current transaction when applicable. r=sotaro

This commit is contained in:
Nicolas Silva 2016-01-05 14:03:26 +01:00
Родитель d9a9a55a72
Коммит 4d9fc4395b
25 изменённых файлов: 269 добавлений и 84 удалений

Просмотреть файл

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