Bug 1340117 - Batch ReadLock intializer into a separate IDPL message to avoid hitting the file descriptor limit. r=dvander

This commit is contained in:
Matt Woodrow 2017-02-27 16:12:12 +13:00
parent ebf572da48
commit ef5a44cc58
24 changed files with 277 additions and 47 deletions

View File

@ -728,6 +728,19 @@ struct ParamTraits<mozilla::layers::CompositableHandle>
}
};
template<>
struct ParamTraits<mozilla::layers::ReadLockHandle>
{
typedef mozilla::layers::ReadLockHandle paramType;
static void Write(Message* msg, const paramType& param) {
WriteParam(msg, param.mHandle);
}
static bool Read(const Message* msg, PickleIterator* iter, paramType* result) {
return ReadParam(msg, iter, &result->mHandle);
}
};
// Helper class for reading bitfields.
// If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>.
template <typename ParamType>

View File

@ -274,6 +274,32 @@ private:
uint64_t mHandle;
};
class ReadLockHandle
{
friend struct IPC::ParamTraits<mozilla::layers::ReadLockHandle>;
public:
ReadLockHandle() : mHandle(0)
{}
ReadLockHandle(const ReadLockHandle& aOther) : mHandle(aOther.mHandle)
{}
explicit ReadLockHandle(uint64_t aHandle) : mHandle(aHandle)
{}
bool IsValid() const {
return mHandle != 0;
}
explicit operator bool() const {
return IsValid();
}
bool operator ==(const ReadLockHandle& aOther) const {
return mHandle == aOther.mHandle;
}
uint64_t Value() const {
return mHandle;
}
private:
uint64_t mHandle;
};
enum class ScrollDirection : uint32_t {
NONE,
VERTICAL,

View File

@ -582,7 +582,7 @@ TextureClient::EnableReadLock()
}
}
void
bool
TextureClient::SerializeReadLock(ReadLockDescriptor& aDescriptor)
{
if (mReadLock && mUpdated) {
@ -591,8 +591,10 @@ TextureClient::SerializeReadLock(ReadLockDescriptor& aDescriptor)
mReadLock->ReadLock();
mReadLock->Serialize(aDescriptor, GetAllocator()->GetParentPid());
mUpdated = false;
return true;
} else {
aDescriptor = null_t();
return false;
}
}

View File

@ -651,7 +651,7 @@ public:
bool TryReadLock();
void ReadUnlock();
void SerializeReadLock(ReadLockDescriptor& aDescriptor);
bool SerializeReadLock(ReadLockDescriptor& aDescriptor);
private:
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);

View File

@ -559,6 +559,18 @@ TextureHost::DeserializeReadLock(const ReadLockDescriptor& aDesc,
mReadLock = lock.forget();
}
void
TextureHost::SetReadLock(TextureReadLock* aReadLock)
{
if (!aReadLock) {
return;
}
// If mReadLock is not null it means we haven't unlocked it yet and the content
// side should not have been able to write into this texture and send a new lock!
MOZ_ASSERT(!mReadLock);
mReadLock = aReadLock;
}
void
TextureHost::ReadUnlock()
{

View File

@ -578,6 +578,7 @@ public:
void DeserializeReadLock(const ReadLockDescriptor& aDesc,
ISurfaceAllocator* aAllocator);
void SetReadLock(TextureReadLock* aReadLock);
TextureReadLock* GetReadLock() { return mReadLock; }

View File

@ -114,6 +114,8 @@ public:
MOZ_ASSERT(InForwarderThread());
}
static uint32_t GetMaxFileDescriptorsPerMessage();
protected:
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;

View File

@ -160,7 +160,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
t->mPictureRect = timedTexture.picture();
t->mFrameID = timedTexture.frameID();
t->mProducerID = timedTexture.producerID();
t->mTexture->DeserializeReadLock(timedTexture.sharedLock(), this);
t->mTexture->SetReadLock(FindReadLock(timedTexture.sharedLock()));
}
if (textures.Length() > 0) {
compositable->UseTextureHost(textures);
@ -185,8 +185,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
const OpUseComponentAlphaTextures& op = aEdit.detail().get_OpUseComponentAlphaTextures();
RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
texOnBlack->DeserializeReadLock(op.sharedLockBlack(), this);
texOnWhite->DeserializeReadLock(op.sharedLockWhite(), this);
texOnBlack->SetReadLock(FindReadLock(op.sharedLockBlack()));
texOnWhite->SetReadLock(FindReadLock(op.sharedLockWhite()));
MOZ_ASSERT(texOnBlack && texOnWhite);
compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
@ -283,6 +283,29 @@ CompositableParentManager::ReleaseCompositable(const CompositableHandle& aHandle
host->Detach(nullptr, CompositableHost::FORCE_DETACH);
}
bool
CompositableParentManager::AddReadLocks(ReadLockArray&& aReadLocks)
{
for (ReadLockInit& r : aReadLocks) {
if (mReadLocks.find(r.handle().Value()) != mReadLocks.end()) {
NS_ERROR("Duplicate read lock handle!");
return false;
}
mReadLocks[r.handle().Value()] = TextureReadLock::Deserialize(r.sharedLock(), this);
}
return true;
}
TextureReadLock*
CompositableParentManager::FindReadLock(const ReadLockHandle& aHandle)
{
auto iter = mReadLocks.find(aHandle.Value());
if (iter == mReadLocks.end()) {
return nullptr;
}
return iter->second.get();
}
} // namespace layers
} // namespace mozilla

View File

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h" // for override
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc
#include "mozilla/layers/TextureClient.h"
#include "CompositableHost.h"
namespace mozilla {
@ -24,6 +25,8 @@ namespace layers {
class CompositableParentManager : public HostIPCAllocator
{
public:
typedef InfallibleTArray<ReadLockInit> ReadLockArray;
CompositableParentManager() {}
void DestroyActor(const OpDestroy& aOp);
@ -41,6 +44,9 @@ public:
const TextureInfo& aInfo);
RefPtr<CompositableHost> FindCompositable(const CompositableHandle& aHandle);
bool AddReadLocks(ReadLockArray&& aReadLocks);
TextureReadLock* FindReadLock(const ReadLockHandle& aLockHandle);
protected:
/**
* Handle the IPDL messages that affect PCompositable actors.
@ -55,6 +61,22 @@ protected:
* Mapping form IDs to CompositableHosts.
*/
std::map<uint64_t, RefPtr<CompositableHost>> mCompositables;
std::map<uint64_t, RefPtr<TextureReadLock>> mReadLocks;
};
struct AutoClearReadLocks {
explicit AutoClearReadLocks(std::map<uint64_t, RefPtr<TextureReadLock>>& aReadLocks)
: mReadLocks(aReadLocks)
{}
~AutoClearReadLocks()
{
mReadLocks.clear();
}
std::map<uint64_t, RefPtr<TextureReadLock>>& mReadLocks;
};
} // namespace layers

View File

@ -11,6 +11,7 @@
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
#include "mozilla/layers/TextureHost.h" // for TextureHost
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/CompositableForwarder.h"
namespace mozilla {
namespace layers {
@ -19,6 +20,17 @@ NS_IMPL_ISUPPORTS(GfxMemoryImageReporter, nsIMemoryReporter)
mozilla::Atomic<ptrdiff_t> GfxMemoryImageReporter::sAmount(0);
/* static */ uint32_t
CompositableForwarder::GetMaxFileDescriptorsPerMessage() {
#if defined(OS_POSIX)
static const uint32_t kMaxFileDescriptors = FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE;
#else
// default number that works everywhere else
static const uint32_t kMaxFileDescriptors = 250;
#endif
return kMaxFileDescriptors;
}
mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType()
{
return ipc::SharedMemory::SharedMemoryType::TYPE_BASIC;

View File

@ -58,11 +58,13 @@ using namespace mozilla::media;
typedef std::vector<CompositableOperation> OpVector;
typedef nsTArray<OpDestroy> OpDestroyVector;
typedef nsTArray<ReadLockInit> ReadLockVector;
struct CompositableTransaction
{
CompositableTransaction()
: mFinished(true)
: mReadLockSequenceNumber(0)
, mFinished(true)
{}
~CompositableTransaction()
{
@ -76,12 +78,15 @@ struct CompositableTransaction
{
MOZ_ASSERT(mFinished);
mFinished = false;
mReadLockSequenceNumber = 0;
mReadLocks.AppendElement();
}
void End()
{
mFinished = true;
mOperations.clear();
mDestroyedActors.Clear();
mReadLocks.Clear();
}
bool IsEmpty() const
{
@ -93,8 +98,21 @@ struct CompositableTransaction
mOperations.push_back(op);
}
ReadLockHandle AddReadLock(const ReadLockDescriptor& aReadLock)
{
ReadLockHandle handle(++mReadLockSequenceNumber);
if (mReadLocks.LastElement().Length() >= CompositableForwarder::GetMaxFileDescriptorsPerMessage()) {
mReadLocks.AppendElement();
}
mReadLocks.LastElement().AppendElement(ReadLockInit(aReadLock, handle));
return handle;
}
OpVector mOperations;
OpDestroyVector mDestroyedActors;
nsTArray<ReadLockVector> mReadLocks;
uint64_t mReadLockSequenceNumber;
bool mFinished;
};
@ -123,10 +141,13 @@ ImageBridgeChild::UseTextures(CompositableClient* aCompositable,
}
ReadLockDescriptor readLock;
t.mTextureClient->SerializeReadLock(readLock);
ReadLockHandle readLockHandle;
if (t.mTextureClient->SerializeReadLock(readLock)) {
readLockHandle = mTxn->AddReadLock(readLock);
}
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
readLock,
readLockHandle,
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID));
@ -142,32 +163,7 @@ ImageBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
TextureClient* aTextureOnBlack,
TextureClient* aTextureOnWhite)
{
MOZ_ASSERT(aCompositable);
MOZ_ASSERT(aTextureOnWhite);
MOZ_ASSERT(aTextureOnBlack);
MOZ_ASSERT(aCompositable->IsConnected());
MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
ReadLockDescriptor readLockW;
ReadLockDescriptor readLockB;
aTextureOnBlack->SerializeReadLock(readLockB);
aTextureOnWhite->SerializeReadLock(readLockW);
HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
mTxn->AddNoSwapEdit(
CompositableOperation(
aCompositable->GetIPCHandle(),
OpUseComponentAlphaTextures(
nullptr, aTextureOnBlack->GetIPDLActor(),
nullptr, aTextureOnWhite->GetIPDLActor(),
readLockB, readLockW
)
)
);
MOZ_CRASH("should not be called");
}
void
@ -543,6 +539,15 @@ ImageBridgeChild::EndTransaction()
ShadowLayerForwarder::PlatformSyncBeforeUpdate();
}
for (ReadLockVector& locks : mTxn->mReadLocks) {
if (locks.Length()) {
if (!SendInitReadLocks(locks)) {
NS_WARNING("[LayersForwarder] WARNING: sending read locks failed!");
return;
}
}
}
if (!SendUpdate(cset, mTxn->mDestroyedActors, GetFwdTransactionId())) {
NS_WARNING("could not send async texture transaction");
return;

View File

@ -152,6 +152,15 @@ private:
InfallibleTArray<OpDestroy>* mToDestroy;
};
mozilla::ipc::IPCResult
ImageBridgeParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
{
if (!AddReadLocks(Move(aReadLocks))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
const uint64_t& aFwdTransactionId)
@ -160,6 +169,7 @@ ImageBridgeParent::RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
// to early-return from RecvUpdate without doing so.
AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
UpdateFwdTransactionId(aFwdTransactionId);
AutoClearReadLocks clearLocks(mReadLocks);
for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
if (!ReceiveCompositableUpdate(aEdits[i])) {

View File

@ -70,6 +70,7 @@ public:
// PImageBridge
virtual mozilla::ipc::IPCResult RecvImageBridgeThreadId(const PlatformThreadId& aThreadId) override;
virtual mozilla::ipc::IPCResult RecvInitReadLocks(ReadLockArray&& aReadLocks) override;
virtual mozilla::ipc::IPCResult RecvUpdate(EditArray&& aEdits, OpDestroyArray&& aToDestroy,
const uint64_t& aFwdTransactionId) override;

View File

@ -132,6 +132,15 @@ LayerTransactionParent::RecvPaintTime(const uint64_t& aTransactionId,
return IPC_OK();
}
mozilla::ipc::IPCResult
LayerTransactionParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
{
if (!AddReadLocks(Move(aReadLocks))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
{
@ -146,6 +155,7 @@ LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
MOZ_LAYERS_LOG(("[ParentSide] received txn with %" PRIuSIZE " edits", aInfo.cset().Length()));
UpdateFwdTransactionId(aInfo.fwdTransactionId());
AutoClearReadLocks clearLocks(mReadLocks);
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
for (const auto& op : aInfo.toDestroy()) {

View File

@ -43,6 +43,7 @@ class LayerTransactionParent final : public PLayerTransactionParent,
typedef InfallibleTArray<Edit> EditArray;
typedef InfallibleTArray<OpDestroy> OpDestroyArray;
typedef InfallibleTArray<PluginWindowData> PluginsArray;
typedef InfallibleTArray<ReadLockInit> ReadLockArray;
public:
LayerTransactionParent(HostLayerManager* aManager,
@ -111,6 +112,7 @@ protected:
virtual mozilla::ipc::IPCResult RecvPaintTime(const uint64_t& aTransactionId,
const TimeDuration& aPaintTime) override;
virtual mozilla::ipc::IPCResult RecvInitReadLocks(ReadLockArray&& aReadLocks) override;
virtual mozilla::ipc::IPCResult RecvUpdate(const TransactionInfo& aInfo) override;
virtual mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;

View File

@ -50,6 +50,7 @@ using mozilla::layers::BorderCorners from "mozilla/layers/LayersTypes.h";
using mozilla::layers::BorderWidths from "mozilla/layers/LayersTypes.h";
using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
using mozilla::layers::ReadLockHandle from "mozilla/layers/LayersTypes.h";
using mozilla::layers::SimpleLayerAttributes from "mozilla/layers/LayerAttributes.h";
using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
@ -348,6 +349,11 @@ union ReadLockDescriptor {
null_t;
};
struct ReadLockInit {
ReadLockDescriptor sharedLock;
ReadLockHandle handle;
};
union MaybeTexture {
PTexture;
null_t;
@ -403,7 +409,7 @@ struct OpRemoveTexture {
struct TimedTexture {
PTexture texture;
ReadLockDescriptor sharedLock;
ReadLockHandle sharedLock;
TimeStamp timeStamp;
IntRect picture;
uint32_t frameID;
@ -427,8 +433,8 @@ struct OpUseTexture {
struct OpUseComponentAlphaTextures {
PTexture textureOnBlack;
PTexture textureOnWhite;
ReadLockDescriptor sharedLockBlack;
ReadLockDescriptor sharedLockWhite;
ReadLockHandle sharedLockBlack;
ReadLockHandle sharedLockWhite;
};
union MaybeRegion {

View File

@ -38,6 +38,11 @@ child:
parent:
async ImageBridgeThreadId(PlatformThreadId aTreahdId);
// Creates a set of mappings between TextureReadLocks and an associated
// ReadLockHandle that can be used in Update, and persist until the
// next Update call.
async InitReadLocks(ReadLockInit[] locks);
async Update(CompositableOperation[] ops, OpDestroy[] toDestroy, uint64_t fwdTransactionId);
// First step of the destruction sequence. This puts ImageBridge

View File

@ -50,6 +50,11 @@ sync protocol PLayerTransaction {
manager PCompositorBridge;
parent:
// Creates a set of mappings between TextureReadLocks and an associated
// ReadLockHandle that can be used in Update, and persist until the
// next Update call.
async InitReadLocks(ReadLockInit[] locks);
// The isFirstPaint flag can be used to indicate that this is the first update
// for a particular document.
async Update(TransactionInfo txn);

View File

@ -32,6 +32,11 @@ parent:
async NewCompositable(CompositableHandle handle, TextureInfo info);
async ReleaseCompositable(CompositableHandle compositable);
// Creates a set of mappings between TextureReadLocks and an associated
// ReadLockHandle that can be used in Update, and persist until the
// next Update call.
async InitReadLocks(ReadLockInit[] locks);
sync Create(IntSize aSize);
sync AddImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
SurfaceFormat aFormat, ByteBuffer aBytes);

View File

@ -54,12 +54,14 @@ typedef nsTArray<SurfaceDescriptor> BufferArray;
typedef nsTArray<Edit> EditVector;
typedef nsTHashtable<nsPtrHashKey<ShadowableLayer>> ShadowableLayerSet;
typedef nsTArray<OpDestroy> OpDestroyVector;
typedef nsTArray<ReadLockInit> ReadLockVector;
class Transaction
{
public:
Transaction()
: mTargetRotation(ROTATION_0)
: mReadLockSequenceNumber(0)
, mTargetRotation(ROTATION_0)
, mOpen(false)
, mRotationChanged(false)
{}
@ -78,6 +80,8 @@ public:
}
mTargetRotation = aRotation;
mTargetOrientation = aOrientation;
mReadLockSequenceNumber = 0;
mReadLocks.AppendElement();
}
void AddEdit(const Edit& aEdit)
{
@ -104,6 +108,15 @@ public:
MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
mSimpleMutants.PutEntry(aLayer);
}
ReadLockHandle AddReadLock(const ReadLockDescriptor& aReadLock)
{
ReadLockHandle handle(++mReadLockSequenceNumber);
if (mReadLocks.LastElement().Length() >= CompositableForwarder::GetMaxFileDescriptorsPerMessage()) {
mReadLocks.AppendElement();
}
mReadLocks.LastElement().AppendElement(ReadLockInit(aReadLock, handle));
return handle;
}
void End()
{
mCset.Clear();
@ -111,6 +124,7 @@ public:
mMutants.Clear();
mSimpleMutants.Clear();
mDestroyedActors.Clear();
mReadLocks.Clear();
mOpen = false;
mRotationChanged = false;
}
@ -134,6 +148,8 @@ public:
OpDestroyVector mDestroyedActors;
ShadowableLayerSet mMutants;
ShadowableLayerSet mSimpleMutants;
nsTArray<ReadLockVector> mReadLocks;
uint64_t mReadLockSequenceNumber;
gfx::IntRect mTargetBounds;
ScreenRotation mTargetRotation;
dom::ScreenOrientationInternal mTargetOrientation;
@ -420,9 +436,12 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
ReadLockDescriptor readLock;
t.mTextureClient->SerializeReadLock(readLock);
ReadLockHandle readLockHandle;
if (t.mTextureClient->SerializeReadLock(readLock)) {
readLockHandle = mTxn->AddReadLock(readLock);
}
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
readLock,
readLockHandle,
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID));
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
@ -451,10 +470,16 @@ ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositabl
MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
ReadLockDescriptor readLockW;
ReadLockDescriptor readLockB;
aTextureOnBlack->SerializeReadLock(readLockB);
aTextureOnWhite->SerializeReadLock(readLockW);
ReadLockHandle readLockHandleB;
ReadLockDescriptor readLockW;
ReadLockHandle readLockHandleW;
if (aTextureOnBlack->SerializeReadLock(readLockB)) {
readLockHandleB = mTxn->AddReadLock(readLockB);
}
if (aTextureOnWhite->SerializeReadLock(readLockW)) {
readLockHandleW = mTxn->AddReadLock(readLockW);
}
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
@ -465,7 +490,7 @@ ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositabl
OpUseComponentAlphaTextures(
nullptr, aTextureOnBlack->GetIPDLActor(),
nullptr, aTextureOnWhite->GetIPDLActor(),
readLockB, readLockW)
readLockHandleB, readLockHandleW)
)
);
}
@ -698,6 +723,15 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
PlatformSyncBeforeUpdate();
}
for (ReadLockVector& locks : mTxn->mReadLocks) {
if (locks.Length()) {
if (!mShadowManager->SendInitReadLocks(locks)) {
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending read locks failed!"));
return false;
}
}
}
MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
RenderTraceScope rendertrace3("Forward Transaction", "000093");
if (!mShadowManager->SendUpdate(info)) {

View File

@ -17,7 +17,8 @@ namespace mozilla {
namespace layers {
WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId)
: mIsInTransaction(false)
: mReadLockSequenceNumber(0)
, mIsInTransaction(false)
, mIdNamespace(0)
, mResourceId(0)
, mPipelineId(aPipelineId)
@ -82,6 +83,8 @@ WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
UpdateFwdTransactionId();
this->SendDPBegin(aSize);
mIsInTransaction = true;
mReadLockSequenceNumber = 0;
mReadLocks.AppendElement();
return true;
}
@ -197,6 +200,15 @@ WebRenderBridgeChild::DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aT
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
for (nsTArray<ReadLockInit>& locks : mReadLocks) {
if (locks.Length()) {
if (!SendInitReadLocks(locks)) {
NS_WARNING("WARNING: sending read locks failed!");
return;
}
}
}
wr::BuiltDisplayList dl = ProcessWebrenderCommands(aSize, mCommands);
ByteBuffer dlData(Move(dl.dl));
ByteBuffer auxData(Move(dl.aux));
@ -212,6 +224,7 @@ WebRenderBridgeChild::DPEnd(const gfx::IntSize& aSize, bool aIsSync, uint64_t aT
mCommands.Clear();
mParentCommands.Clear();
mDestroyedActors.Clear();
mReadLocks.Clear();
mIsInTransaction = false;
}
@ -376,9 +389,16 @@ WebRenderBridgeChild::UseTextures(CompositableClient* aCompositable,
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == GetIPCChannel());
ReadLockDescriptor readLock;
t.mTextureClient->SerializeReadLock(readLock);
ReadLockHandle readLockHandle;
if (t.mTextureClient->SerializeReadLock(readLock)) {
readLockHandle = ReadLockHandle(++mReadLockSequenceNumber);
if (mReadLocks.LastElement().Length() >= GetMaxFileDescriptorsPerMessage()) {
mReadLocks.AppendElement();
}
mReadLocks.LastElement().AppendElement(ReadLockInit(readLock, readLockHandle));
}
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
readLock,
readLockHandle,
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID));
GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);

View File

@ -114,6 +114,8 @@ private:
nsTArray<WebRenderParentCommand> mParentCommands;
nsTArray<OpDestroy> mDestroyedActors;
nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
nsTArray<nsTArray<ReadLockInit>> mReadLocks;
uint64_t mReadLockSequenceNumber;
bool mIsInTransaction;
uint32_t mIdNamespace;
uint32_t mResourceId;

View File

@ -226,6 +226,7 @@ WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
const WrAuxiliaryListsDescriptor& auxDesc)
{
UpdateFwdTransactionId(aFwdTransactionId);
AutoClearReadLocks clearLocks(mReadLocks);
if (mDestroyed) {
for (const auto& op : aToDestroy) {
@ -653,6 +654,15 @@ WebRenderBridgeParent::RecvReleaseCompositable(const CompositableHandle& aHandle
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
{
if (!AddReadLocks(Move(aReadLocks))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
void
WebRenderBridgeParent::SetWebRenderProfilerEnabled(bool aEnabled)
{

View File

@ -59,6 +59,8 @@ public:
const TextureInfo& aInfo) override;
mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
mozilla::ipc::IPCResult RecvInitReadLocks(ReadLockArray&& aReadLocks) override;
mozilla::ipc::IPCResult RecvCreate(const gfx::IntSize& aSize) override;
mozilla::ipc::IPCResult RecvShutdown() override;
mozilla::ipc::IPCResult RecvAddImage(const wr::ImageKey& aImageKey,