mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1340117 - Batch ReadLock intializer into a separate IDPL message to avoid hitting the file descriptor limit. r=dvander
This commit is contained in:
parent
ebf572da48
commit
ef5a44cc58
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -578,6 +578,7 @@ public:
|
||||
|
||||
void DeserializeReadLock(const ReadLockDescriptor& aDesc,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
void SetReadLock(TextureReadLock* aReadLock);
|
||||
|
||||
TextureReadLock* GetReadLock() { return mReadLock; }
|
||||
|
||||
|
@ -114,6 +114,8 @@ public:
|
||||
MOZ_ASSERT(InForwarderThread());
|
||||
}
|
||||
|
||||
static uint32_t GetMaxFileDescriptorsPerMessage();
|
||||
|
||||
protected:
|
||||
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
|
||||
nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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])) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user