--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -68,19 +68,23 @@ enum class TextureFlags : uint32_t {
COMPONENT_ALPHA = 1 << 11,
// The texture is being allocated for a compositor that no longer exists.
// This flag is only used in the parent process.
INVALID_COMPOSITOR = 1 << 12,
// The texture was created by converting from YCBCR to RGB
RGB_FROM_YCBCR = 1 << 13,
// The texture is used for snapshot.
SNAPSHOT = 1 << 14,
+ // Enable a non blocking read lock.
+ NON_BLOCKING_READ_LOCK = 1 << 15,
+ // Enable a blocking read lock.
+ BLOCKING_READ_LOCK = 1 << 16,
// OR union of all valid bits
- ALL_BITS = (1 << 15) - 1,
+ ALL_BITS = (1 << 17) - 1,
// the default flags
DEFAULT = NO_FLAGS
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TextureFlags)
static inline bool
TextureRequiresLocking(TextureFlags aFlags)
{
--- a/gfx/layers/PersistentBufferProvider.cpp
+++ b/gfx/layers/PersistentBufferProvider.cpp
@@ -101,17 +101,17 @@ PersistentBufferProviderShared::Create(g
{
if (!aKnowsCompositor || !aKnowsCompositor->GetTextureForwarder()->IPCOpen()) {
return nullptr;
}
RefPtr<TextureClient> texture = TextureClient::CreateForDrawing(
aKnowsCompositor, aFormat, aSize,
BackendSelector::Canvas,
- TextureFlags::DEFAULT,
+ TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK,
TextureAllocationFlags::ALLOC_DEFAULT
);
if (!texture) {
return nullptr;
}
RefPtr<PersistentBufferProviderShared> provider =
@@ -185,17 +185,17 @@ PersistentBufferProviderShared::SetKnows
// Get rid of everything else
Destroy();
if (prevTexture) {
RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing(
aKnowsCompositor, mFormat, mSize,
BackendSelector::Canvas,
- TextureFlags::DEFAULT,
+ TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK,
TextureAllocationFlags::ALLOC_DEFAULT
);
MOZ_ASSERT(newTexture);
if (!newTexture) {
return false;
}
@@ -317,17 +317,17 @@ PersistentBufferProviderShared::BorrowDr
// Give up now. The caller can fall-back to a non-shared buffer provider.
return nullptr;
}
}
RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing(
mKnowsCompositor, mFormat, mSize,
BackendSelector::Canvas,
- TextureFlags::DEFAULT,
+ TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK,
TextureAllocationFlags::ALLOC_DEFAULT
);
MOZ_ASSERT(newTexture);
if (newTexture) {
if (mTextures.append(newTexture)) {
tex = newTexture;
mBack = Some<uint32_t>(mTextures.length() - 1);
@@ -378,19 +378,17 @@ PersistentBufferProviderShared::ReturnDr
}
TextureClient*
PersistentBufferProviderShared::GetTextureClient()
{
// Can't access the front buffer while drawing.
MOZ_ASSERT(!mDrawTarget);
TextureClient* texture = GetTexture(mFront);
- if (texture) {
- texture->EnableReadLock();
- } else {
+ if (!texture) {
gfxCriticalNote << "PersistentBufferProviderShared: front buffer unavailable";
}
return texture;
}
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderShared::BorrowSnapshot()
{
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -106,23 +106,23 @@ CanvasClient2D::Update(gfx::IntSize aSiz
gfxContentType contentType =
aCanvasRenderer->IsOpaque() ? gfxContentType::COLOR : gfxContentType::COLOR_ALPHA;
gfx::SurfaceFormat surfaceFormat
= gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType);
TextureFlags flags = TextureFlags::DEFAULT;
if (mTextureFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) {
flags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
}
+ flags |= TextureFlags::NON_BLOCKING_READ_LOCK;
mBackBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aCanvasRenderer);
if (!mBackBuffer) {
NS_WARNING("Failed to allocate the TextureClient");
return;
}
- mBackBuffer->EnableReadLock();
MOZ_ASSERT(mBackBuffer->CanExposeDrawTarget());
bufferCreated = true;
}
bool updated = false;
{
TextureClientAutoLock autoLock(mBackBuffer, OpenMode::OPEN_WRITE_ONLY);
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -745,30 +745,29 @@ ContentClientRemoteBuffer::CreateBufferI
{
TextureAllocationFlags textureAllocFlags
= (aFlags & TextureFlags::COMPONENT_ALPHA) ?
TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK :
TextureAllocationFlags::ALLOC_CLEAR_BUFFER;
RefPtr<TextureClient> textureClient = CreateTextureClientForDrawing(
aFormat, aRect.Size(), BackendSelector::Content,
- aFlags | ExtraTextureFlags(),
+ aFlags | ExtraTextureFlags() | TextureFlags::BLOCKING_READ_LOCK,
textureAllocFlags
);
if (!textureClient || !AddTextureClient(textureClient)) {
return nullptr;
}
- textureClient->EnableBlockingReadLock();
RefPtr<TextureClient> textureClientOnWhite;
if (aFlags & TextureFlags::COMPONENT_ALPHA) {
textureClientOnWhite = textureClient->CreateSimilar(
mForwarder->GetCompositorBackendType(),
- aFlags | ExtraTextureFlags(),
+ aFlags | ExtraTextureFlags() | TextureFlags::BLOCKING_READ_LOCK,
TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE
);
if (!textureClientOnWhite || !AddTextureClient(textureClientOnWhite)) {
return nullptr;
}
// We don't enable the readlock for the white buffer since we always
// use them together and waiting on the lock for the black
// should be sufficient.
--- a/gfx/layers/client/SingleTiledContentClient.cpp
+++ b/gfx/layers/client/SingleTiledContentClient.cpp
@@ -92,17 +92,17 @@ ClientSingleTiledLayerBuffer::GetSurface
}
already_AddRefed<TextureClient>
ClientSingleTiledLayerBuffer::GetTextureClient()
{
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN);
return mCompositableClient.CreateTextureClientForDrawing(
gfx::ImageFormatToSurfaceFormat(mFormat), mSize, BackendSelector::Content,
- TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD);
+ TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD | TextureFlags::NON_BLOCKING_READ_LOCK);
}
void
ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
const nsIntRegion& aPaintRegion,
const nsIntRegion& aDirtyRegion,
LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData,
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -592,33 +592,30 @@ void
TextureClient::EnableReadLock()
{
if (!mReadLock) {
mReadLock = NonBlockingTextureReadLock::Create(mAllocator);
}
}
bool
-TextureClient::SerializeReadLock(ReadLockDescriptor& aDescriptor)
+TextureClient::OnForwardedToHost()
{
if (mData) {
mData->OnForwardedToHost();
}
if (mReadLock && mUpdated) {
// Take a read lock on behalf of the TextureHost. The latter will unlock
// after the shared data is available again for drawing.
mReadLock->ReadLock();
mUpdated = false;
- if (mReadLock->Serialize(aDescriptor, GetAllocator()->GetParentPid())) {
- return true;
- }
+ return true;
}
- aDescriptor = null_t();
return false;
}
TextureClient::~TextureClient()
{
// TextureClients should be kept alive while there are references on the
// paint thread.
MOZ_ASSERT(mPaintThreadRefs == 0);
@@ -923,18 +920,24 @@ TextureClient::InitIPDLActor(Compositabl
mExternalImageId = aForwarder->GetTextureForwarder()->GetNextExternalImageId();
nsIEventTarget* target = nullptr;
// Get the layers id if the forwarder is a ShadowLayerForwarder.
if (ShadowLayerForwarder* forwarder = aForwarder->AsLayerForwarder()) {
target = forwarder->GetEventTarget();
}
+ ReadLockDescriptor readLockDescriptor = null_t();
+ if (mReadLock) {
+ mReadLock->Serialize(readLockDescriptor, GetAllocator()->GetParentPid());
+ }
+
PTextureChild* actor = aForwarder->GetTextureForwarder()->CreateTexture(
desc,
+ readLockDescriptor,
aForwarder->GetCompositorBackendType(),
GetFlags(),
mSerial,
mExternalImageId,
target);
if (!actor) {
gfxCriticalNote << static_cast<int32_t>(desc.type()) << ", "
@@ -985,18 +988,24 @@ TextureClient::InitIPDLActor(KnowsCompos
SurfaceDescriptor desc;
if (!ToSurfaceDescriptor(desc)) {
return false;
}
// Try external image id allocation.
mExternalImageId = aForwarder->GetTextureForwarder()->GetNextExternalImageId();
+ ReadLockDescriptor readLockDescriptor = null_t();
+ if (mReadLock) {
+ mReadLock->Serialize(readLockDescriptor, GetAllocator()->GetParentPid());
+ }
+
PTextureChild* actor = fwd->CreateTexture(
desc,
+ readLockDescriptor,
aForwarder->GetCompositorBackendType(),
GetFlags(),
mSerial,
mExternalImageId);
if (!actor) {
gfxCriticalNote << static_cast<int32_t>(desc.type()) << ", "
<< static_cast<int32_t>(aForwarder->GetCompositorBackendType()) << ", "
<< static_cast<uint32_t>(GetFlags())
@@ -1345,16 +1354,22 @@ TextureClient::TextureClient(TextureData
, mFwdTransactionId(0)
, mSerial(++sSerialCounter)
#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
, mPoolTracker(nullptr)
#endif
{
mData->FillInfo(mInfo);
mFlags |= mData->GetTextureFlags();
+
+ if (mFlags & TextureFlags::NON_BLOCKING_READ_LOCK) {
+ EnableReadLock();
+ } else if (mFlags & TextureFlags::BLOCKING_READ_LOCK) {
+ EnableBlockingReadLock();
+ }
}
bool TextureClient::CopyToTextureClient(TextureClient* aTarget,
const gfx::IntRect* aRect,
const gfx::IntPoint* aPoint)
{
MOZ_ASSERT(IsLocked());
MOZ_ASSERT(aTarget->IsLocked());
@@ -1508,19 +1523,21 @@ public:
bool mAllocSuccess;
};
class CrossProcessSemaphoreReadLock : public TextureReadLock
{
public:
CrossProcessSemaphoreReadLock()
: mSemaphore(CrossProcessSemaphore::Create("TextureReadLock", 1))
+ , mShared(false)
{}
explicit CrossProcessSemaphoreReadLock(CrossProcessSemaphoreHandle aHandle)
: mSemaphore(CrossProcessSemaphore::Create(aHandle))
+ , mShared(false)
{}
virtual bool ReadLock() override
{
if (!IsValid()) {
return false;
}
return mSemaphore->Wait();
@@ -1542,16 +1559,17 @@ public:
}
virtual bool IsValid() const override { return !!mSemaphore; }
virtual bool Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther) override;
virtual LockType GetType() override { return TYPE_CROSS_PROCESS_SEMAPHORE; }
UniquePtr<CrossProcessSemaphore> mSemaphore;
+ bool mShared;
};
// static
already_AddRefed<TextureReadLock>
TextureReadLock::Deserialize(const ReadLockDescriptor& aDescriptor, ISurfaceAllocator* aAllocator)
{
switch (aDescriptor.type()) {
case ReadLockDescriptor::TShmemSection: {
@@ -1723,21 +1741,23 @@ ShmemTextureReadLock::GetReadCount() {
}
ShmReadLockInfo* info = GetShmReadLockInfoPtr();
return info->readCount;
}
bool
CrossProcessSemaphoreReadLock::Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther)
{
- if (IsValid()) {
+ if (!mShared && IsValid()) {
aOutput = ReadLockDescriptor(CrossProcessSemaphoreDescriptor(mSemaphore->ShareToProcess(aOther)));
+ mSemaphore->CloseHandle();
+ mShared = true;
return true;
} else {
- return false;
+ return mShared;
}
}
void
TextureClient::EnableBlockingReadLock()
{
if (!mReadLock) {
mReadLock = new CrossProcessSemaphoreReadLock();
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -630,27 +630,24 @@ public:
void SetLastFwdTransactionId(uint64_t aTransactionId)
{
MOZ_ASSERT(mFwdTransactionId <= aTransactionId);
mFwdTransactionId = aTransactionId;
}
uint64_t GetLastFwdTransactionId() { return mFwdTransactionId; }
- void EnableReadLock();
- void EnableBlockingReadLock();
-
TextureReadLock* GetReadLock() { return mReadLock; }
bool IsReadLocked() const;
bool TryReadLock();
void ReadUnlock();
- bool SerializeReadLock(ReadLockDescriptor& aDescriptor);
+ bool OnForwardedToHost();
// Mark that the TextureClient will be used by the paint thread, and should not
// free its underlying texture data. This must only be called from the main
// thread.
void AddPaintThreadRef();
// Mark that the TextureClient is no longer in use by the PaintThread. This
// must only be called from the PaintThread.
@@ -678,16 +675,19 @@ private:
CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2dBackend,
LayersBackend aLayersBackend,
TextureFlags aTextureFlags,
TextureAllocationFlags flags = ALLOC_DEFAULT);
+ void EnableReadLock();
+ void EnableBlockingReadLock();
+
/**
* Called once, during the destruction of the Texture, on the thread in which
* texture's reference count reaches 0 (could be any thread).
*
* Here goes the shut-down code that uses virtual methods.
* Must only be called by Release().
*/
void Finalize() {}
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -637,18 +637,16 @@ CreateBackBufferTexture(TextureClient* a
RefPtr<TextureClient> texture = aAllocator->GetTextureClient();
if (!texture) {
gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient";
return nullptr;
}
- texture->EnableReadLock();
-
if (!aCompositable.AddTextureClient(texture)) {
gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient";
return nullptr;
}
return texture.forget();
}
@@ -749,28 +747,27 @@ TileClient::GetTileDescriptor()
{
if (IsPlaceholderTile()) {
mWasPlaceholder = true;
return PlaceholderTileDescriptor();
}
bool wasPlaceholder = mWasPlaceholder;
mWasPlaceholder = false;
- ReadLockDescriptor lock;
- mFrontBuffer->SerializeReadLock(lock);
+ bool readLocked = mFrontBuffer->OnForwardedToHost();
+ bool readLockedOnWhite = false;
- ReadLockDescriptor lockOnWhite = null_t();
if (mFrontBufferOnWhite) {
- mFrontBufferOnWhite->SerializeReadLock(lockOnWhite);
+ readLockedOnWhite = mFrontBufferOnWhite->OnForwardedToHost();
}
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
mUpdateRect,
- lock, lockOnWhite,
+ readLocked, readLockedOnWhite,
wasPlaceholder);
}
void
ClientMultiTiledLayerBuffer::DiscardBuffers()
{
for (TileClient& tile : mRetainedTiles) {
tile.DiscardBuffers();
@@ -1114,17 +1111,17 @@ ClientMultiTiledLayerBuffer::ValidateTil
SurfaceMode mode;
gfxContentType content = GetContentType(&mode);
if (!aTile.mAllocator) {
aTile.SetTextureAllocator(mManager->GetCompositorBridgeChild()->GetTexturePool(
mManager->AsShadowForwarder(),
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content),
- TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD));
+ TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD | TextureFlags::NON_BLOCKING_READ_LOCK));
MOZ_ASSERT(aTile.mAllocator);
}
nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
std::vector<CapturedTiledPaintState::Copy> asyncPaintCopies;
std::vector<RefPtr<TextureClient>> asyncPaintClients;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -69,16 +69,17 @@ namespace layers {
class TextureParent : public ParentActor<PTextureParent>
{
public:
explicit TextureParent(HostIPCAllocator* aAllocator, uint64_t aSerial, const wr::MaybeExternalImageId& aExternalImageId);
~TextureParent();
bool Init(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags);
void NotifyNotUsed(uint64_t aTransactionId);
virtual mozilla::ipc::IPCResult RecvRecycleTexture(const TextureFlags& aTextureFlags) override;
TextureHost* GetTextureHost() { return mTextureHost; }
@@ -106,23 +107,24 @@ WrapWithWebRenderTextureHost(ISurfaceAll
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
PTextureParent*
TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
TextureParent* actor = new TextureParent(aAllocator, aSerial, aExternalImageId);
- if (!actor->Init(aSharedData, aLayersBackend, aFlags)) {
+ if (!actor->Init(aSharedData, aReadLock, aLayersBackend, aFlags)) {
actor->ActorDestroy(ipc::IProtocol::ActorDestroyReason::FailedConstructor);
delete actor;
return nullptr;
}
return actor;
}
// static
@@ -188,16 +190,17 @@ already_AddRefed<TextureHost> CreateText
// implemented in TextureD3D11.cpp
already_AddRefed<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
already_AddRefed<TextureHost>
TextureHost::Create(const SurfaceDescriptor& aDesc,
+ const ReadLockDescriptor& aReadLock,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags,
wr::MaybeExternalImageId& aExternalImageId)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
@@ -247,16 +250,20 @@ TextureHost::Create(const SurfaceDescrip
MOZ_CRASH("GFX: Unsupported Surface type host");
}
if (result && WrapWithWebRenderTextureHost(aDeallocator, aBackend, aFlags)) {
MOZ_ASSERT(aExternalImageId.isSome());
result = new WebRenderTextureHost(aDesc, aFlags, result, aExternalImageId.ref());
}
+ if (result) {
+ result->DeserializeReadLock(aReadLock, aDeallocator);
+ }
+
return result.forget();
}
already_AddRefed<TextureHost>
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
@@ -350,16 +357,17 @@ CreateBackendIndependentTextureHost(cons
}
TextureHost::TextureHost(TextureFlags aFlags)
: AtomicRefCountedWithFinalize("TextureHost")
, mActor(nullptr)
, mFlags(aFlags)
, mCompositableCount(0)
, mFwdTransactionId(0)
+ , mReadLocked(false)
{
}
TextureHost::~TextureHost()
{
// If we still have a ReadLock, unlock it. At this point we don't care about
// the texture client being written into on the other side since it should be
// destroyed by now. But we will hit assertions if we don't ReadUnlock before
@@ -373,17 +381,17 @@ void TextureHost::Finalize()
DeallocateSharedData();
DeallocateDeviceData();
}
}
void
TextureHost::UnbindTextureSource()
{
- if (mReadLock) {
+ if (mReadLocked) {
// This TextureHost is not used anymore. Since most compositor backends are
// working asynchronously under the hood a compositor could still be using
// this texture, so it is generally best to wait until the end of the next
// composition before calling ReadUnlock. We ask the compositor to take care
// of that for us.
if (mProvider) {
mProvider->UnlockAfterComposition(this);
} else {
@@ -669,45 +677,41 @@ BufferTextureHost::PushDisplayItems(wr::
aFilter);
}
}
void
TextureHost::DeserializeReadLock(const ReadLockDescriptor& aDesc,
ISurfaceAllocator* aAllocator)
{
- RefPtr<TextureReadLock> lock = TextureReadLock::Deserialize(aDesc, aAllocator);
- if (!lock) {
+ if (mReadLock) {
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 = lock.forget();
+ mReadLock = TextureReadLock::Deserialize(aDesc, aAllocator);
}
void
-TextureHost::SetReadLock(TextureReadLock* aReadLock)
+TextureHost::SetReadLocked()
{
- if (!aReadLock) {
+ if (!mReadLock) {
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;
+ // If mReadLocked is true it means we haven't read unlocked yet and the content
+ // side should not have been able to write into this texture and read lock again!
+ MOZ_ASSERT(!mReadLocked);
+ mReadLocked = true;
}
void
TextureHost::ReadUnlock()
{
- if (mReadLock) {
+ if (mReadLock && mReadLocked) {
mReadLock->ReadUnlock();
- mReadLock = nullptr;
+ mReadLocked = false;
}
}
bool
BufferTextureHost::EnsureWrappingTextureSource()
{
MOZ_ASSERT(!mHasIntermediateBuffer);
@@ -1243,20 +1247,22 @@ TextureParent::NotifyNotUsed(uint64_t aT
if (!mTextureHost) {
return;
}
mSurfaceAllocator->NotifyNotUsed(this, aTransactionId);
}
bool
TextureParent::Init(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aBackend,
const TextureFlags& aFlags)
{
mTextureHost = TextureHost::Create(aSharedData,
+ aReadLock,
mSurfaceAllocator,
aBackend,
aFlags,
mExternalImageId);
if (mTextureHost) {
mTextureHost->mActor = this;
}
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -396,16 +396,17 @@ protected:
virtual ~TextureHost();
public:
/**
* Factory method.
*/
static already_AddRefed<TextureHost> Create(
const SurfaceDescriptor& aDesc,
+ const ReadLockDescriptor& aReadLock,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags,
wr::MaybeExternalImageId& aExternalImageId);
/**
* Lock the texture host for compositing.
*/
@@ -543,16 +544,17 @@ public:
*
* TextureParent< is an implementation detail of TextureHost that is not
* exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
* are for use with the managing IPDL protocols only (so that they can
* implement AllocPTextureParent and DeallocPTextureParent).
*/
static PTextureParent* CreateIPDLActor(HostIPCAllocator* aAllocator,
const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aDescriptor,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
const wr::MaybeExternalImageId& aExternalImageId);
static bool DestroyIPDLActor(PTextureParent* actor);
/**
* Destroy the TextureChild/Parent pair.
@@ -607,17 +609,17 @@ public:
}
int NumCompositableRefs() const { return mCompositableCount; }
void SetLastFwdTransactionId(uint64_t aTransactionId);
void DeserializeReadLock(const ReadLockDescriptor& aDesc,
ISurfaceAllocator* aAllocator);
- void SetReadLock(TextureReadLock* aReadLock);
+ void SetReadLocked();
TextureReadLock* GetReadLock() { return mReadLock; }
virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() { return nullptr; }
virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
// Create the corresponding RenderTextureHost type of this texture, and
@@ -676,16 +678,17 @@ protected:
void CallNotifyNotUsed();
PTextureParent* mActor;
RefPtr<TextureSourceProvider> mProvider;
RefPtr<TextureReadLock> mReadLock;
TextureFlags mFlags;
int mCompositableCount;
uint64_t mFwdTransactionId;
+ bool mReadLocked;
friend class Compositor;
friend class TextureParent;
friend class TiledLayerBufferComposite;
friend class TextureSourceProvider;
};
/**
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -316,25 +316,27 @@ TiledLayerBufferComposite::UseTiles(cons
"Unrecognised tile descriptor type");
continue;
}
const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
tile.mTextureHost = TextureHost::AsTextureHost(texturedDesc.textureParent());
tile.mTextureHost->SetTextureSourceProvider(aLayerManager->GetCompositor());
- tile.mTextureHost->DeserializeReadLock(texturedDesc.sharedLock(), aAllocator);
+ if (texturedDesc.readLocked()) {
+ tile.mTextureHost->SetReadLocked();
+ }
if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) {
tile.mTextureHostOnWhite = TextureHost::AsTextureHost(
texturedDesc.textureOnWhite().get_PTextureParent()
);
- tile.mTextureHostOnWhite->DeserializeReadLock(
- texturedDesc.sharedLockOnWhite(), aAllocator
- );
+ if (texturedDesc.readLockedOnWhite()) {
+ tile.mTextureHostOnWhite->SetReadLocked();
+ }
}
tile.mTilePosition = newTiles.TilePosition(i);
// If this same tile texture existed in the old tile set then this will move the texture
// source into our new tile.
oldRetainedTiles.RecycleTextureSourceForTile(tile);
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -156,17 +156,19 @@ CompositableParentManager::ReceiveCompos
CompositableHost::TimedTexture* t = textures.AppendElement();
t->mTexture =
TextureHost::AsTextureHost(timedTexture.textureParent());
MOZ_ASSERT(t->mTexture);
t->mTimeStamp = timedTexture.timeStamp();
t->mPictureRect = timedTexture.picture();
t->mFrameID = timedTexture.frameID();
t->mProducerID = timedTexture.producerID();
- t->mTexture->SetReadLock(FindReadLock(timedTexture.sharedLock()));
+ if (timedTexture.readLocked()) {
+ t->mTexture->SetReadLocked();
+ }
}
if (textures.Length() > 0) {
compositable->UseTextureHost(textures);
for (auto& timedTexture : op.textures()) {
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(timedTexture.textureParent());
if (texture) {
texture->SetLastFwdTransactionId(mFwdTransactionId);
@@ -181,18 +183,22 @@ CompositableParentManager::ReceiveCompos
ScheduleComposition(compositable);
}
break;
}
case CompositableOperationDetail::TOpUseComponentAlphaTextures: {
const OpUseComponentAlphaTextures& op = aEdit.detail().get_OpUseComponentAlphaTextures();
RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());
- texOnBlack->SetReadLock(FindReadLock(op.sharedLockBlack()));
- texOnWhite->SetReadLock(FindReadLock(op.sharedLockWhite()));
+ if (op.readLockedBlack()) {
+ texOnBlack->SetReadLocked();
+ }
+ if (op.readLockedWhite()) {
+ texOnWhite->SetReadLocked();
+ }
MOZ_ASSERT(texOnBlack && texOnWhite);
compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
if (texOnBlack) {
texOnBlack->SetLastFwdTransactionId(mFwdTransactionId);
// Make sure that each texture was handled by the compositable
// because the recycling logic depends on it.
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -847,16 +847,17 @@ CompositorBridgeChild::SendAllPluginsCap
if (!mCanSend) {
return false;
}
return PCompositorBridgeChild::SendAllPluginsCaptured();
}
PTextureChild*
CompositorBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
+ const ReadLockDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t&,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
return TextureClient::CreateIPDLActor();
}
@@ -999,32 +1000,33 @@ CompositorBridgeChild::GetTileLockAlloca
if (!mSectionAllocator) {
mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
}
return mSectionAllocator;
}
PTextureChild*
CompositorBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget)
{
PTextureChild* textureChild = AllocPTextureChild(
- aSharedData, aLayersBackend, aFlags, 0 /* FIXME */, aSerial, aExternalImageId);
+ aSharedData, aReadLock, aLayersBackend, aFlags, 0 /* FIXME */, aSerial, aExternalImageId);
// Do the DOM labeling.
if (aTarget) {
SetEventTargetForActor(textureChild, aTarget);
}
return SendPTextureConstructor(
- textureChild, aSharedData, aLayersBackend, aFlags, 0 /* FIXME? */, aSerial, aExternalImageId);
+ textureChild, aSharedData, aReadLock, aLayersBackend, aFlags, 0 /* FIXME? */, aSerial, aExternalImageId);
}
bool
CompositorBridgeChild::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
ShmemAllocated(this);
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -99,27 +99,29 @@ public:
virtual mozilla::ipc::IPCResult
RecvCaptureAllPlugins(const uintptr_t& aParentWidget) override;
virtual mozilla::ipc::IPCResult
RecvHideAllPlugins(const uintptr_t& aParentWidget) override;
virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureChild(PTextureChild* actor) override;
virtual mozilla::ipc::IPCResult
RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget) override;
/**
* Request that the parent tell us when graphics are ready on GPU.
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -2221,23 +2221,24 @@ CompositorBridgeParent::GetGeckoContentC
MonitorAutoLock lock(*sIndirectLayerTreesLock);
CompositorBridgeParent::LayerTreeState* state =
GetStateForRoot(aContentLayersId, lock);
return state ? state->mController.get() : nullptr;
}
PTextureParent*
CompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
- return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
+ return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool
CompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
{
return TextureHost::DestroyIPDLActor(actor);
}
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -263,16 +263,17 @@ public:
void GetAPZTestData(const uint64_t& aLayersId,
APZTestData* aOutData) override;
void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
const uint64_t& aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) override;
AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) override { return mCompositionManager; }
PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
bool DeallocPTextureParent(PTextureParent* actor) override;
bool IsSameProcess() const override;
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -566,16 +566,17 @@ CrossProcessCompositorBridgeParent::Defe
CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
{
MOZ_ASSERT(XRE_GetIOMessageLoop());
}
PTextureParent*
CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
CompositorBridgeParent::LayerTreeState* state = nullptr;
@@ -597,17 +598,17 @@ CrossProcessCompositorBridgeParent::Allo
// return null because this will mess up deserialization later and we'll
// kill the content process. Instead, we signal that the underlying
// TextureHost should not attempt to access the compositor.
flags |= TextureFlags::INVALID_COMPOSITOR;
} else if (actualBackend != LayersBackend::LAYERS_NONE && aLayersBackend != actualBackend) {
gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
}
- return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
+ return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool
CrossProcessCompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
{
return TextureHost::DestroyIPDLActor(actor);
}
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -117,16 +117,17 @@ public:
void DidCompositeLocked(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd);
void DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd) override;
PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aId,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
bool DeallocPTextureParent(PTextureParent* actor) override;
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -136,26 +136,21 @@ ImageBridgeChild::UseTextures(Compositab
for (auto& t : aTextures) {
MOZ_ASSERT(t.mTextureClient);
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
if (!t.mTextureClient->IsSharedWithCompositor()) {
return;
}
- ReadLockDescriptor readLock;
- ReadLockHandle readLockHandle;
- if (t.mTextureClient->SerializeReadLock(readLock)) {
- readLockHandle = mTxn->AddReadLock(readLock);
- }
-
+ bool readLocked = t.mTextureClient->OnForwardedToHost();
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
- readLockHandle,
t.mTimeStamp, t.mPictureRect,
- t.mFrameID, t.mProducerID));
+ t.mFrameID, t.mProducerID,
+ readLocked));
// Wait end of usage on host side if TextureFlags::RECYCLE is set
HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
}
mTxn->AddNoSwapEdit(CompositableOperation(aCompositable->GetIPCHandle(),
OpUseTexture(textures)));
}
@@ -960,16 +955,17 @@ ImageBridgeChild::DeallocShmem(ipc::Shme
GetMessageLoop()->PostTask(runnable.forget());
task.Wait();
return result;
}
PTextureChild*
ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
+ const ReadLockDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
MOZ_ASSERT(CanSend());
return TextureClient::CreateIPDLActor();
}
@@ -1030,24 +1026,25 @@ ImageBridgeChild::RecvDidComposite(Infal
listener->NotifyComposite(n);
}
}
return IPC_OK();
}
PTextureChild*
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget)
{
MOZ_ASSERT(CanSend());
- return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
+ return SendPTextureConstructor(aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
static bool
IBCAddOpDestroy(CompositableTransaction* aTxn, const OpDestroy& op)
{
if (aTxn->Finished()) {
return false;
}
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -168,16 +168,17 @@ public:
* Can be called from any thread.
*/
virtual MessageLoop * GetMessageLoop() const override;
virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
virtual PTextureChild*
AllocPTextureChild(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool
DeallocPTextureChild(PTextureChild* actor) override;
@@ -326,16 +327,17 @@ public:
* Can be used from any thread.
* If used outside the ImageBridgeChild thread, it will proxy a synchronous
* call on the ImageBridgeChild thread.
*/
virtual bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
virtual PTextureChild* CreateTexture(
const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget = nullptr) override;
virtual bool IsSameProcess() const override;
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -315,22 +315,23 @@ mozilla::ipc::IPCResult
ImageBridgeParent::RecvReleaseCompositable(const CompositableHandle& aHandle)
{
ReleaseCompositable(aHandle);
return IPC_OK();
}
PTextureParent*
ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId)
{
- return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, aExternalImageId);
+ return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
}
bool
ImageBridgeParent::DeallocPTextureParent(PTextureParent* actor)
{
return TextureHost::DestroyIPDLActor(actor);
}
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -77,16 +77,17 @@ 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;
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial,
const wr::MaybeExternalImageId& aExternalImageId) override;
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
virtual mozilla::ipc::IPCResult RecvNewCompositable(const CompositableHandle& aHandle,
const TextureInfo& aInfo,
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -388,18 +388,18 @@ union MaybeTexture {
PTexture;
null_t;
};
struct TexturedTileDescriptor {
PTexture texture;
MaybeTexture textureOnWhite;
IntRect updateRect;
- ReadLockDescriptor sharedLock;
- ReadLockDescriptor sharedLockOnWhite;
+ bool readLocked;
+ bool readLockedOnWhite;
bool wasPlaceholder;
};
struct PlaceholderTileDescriptor {
};
union TileDescriptor {
TexturedTileDescriptor;
@@ -434,21 +434,21 @@ struct OpPaintTextureRegion {
* Tells the CompositableHost to remove the corresponding TextureHost
*/
struct OpRemoveTexture {
PTexture texture;
};
struct TimedTexture {
PTexture texture;
- ReadLockHandle sharedLock;
TimeStamp timeStamp;
IntRect picture;
uint32_t frameID;
uint32_t producerID;
+ bool readLocked;
};
/**
* Tells the compositor-side which textures to use (for example, as front buffer
* if there are several textures for double buffering).
* This provides a list of textures with timestamps, ordered by timestamp.
* The newest texture whose timestamp is <= the current time is rendered
* (where null is considered less than every other timestamp). If there is no
@@ -458,18 +458,18 @@ struct TimedTexture {
*/
struct OpUseTexture {
TimedTexture[] textures;
};
struct OpUseComponentAlphaTextures {
PTexture textureOnBlack;
PTexture textureOnWhite;
- ReadLockHandle sharedLockBlack;
- ReadLockHandle sharedLockWhite;
+ bool readLockedBlack;
+ bool readLockedWhite;
};
union MaybeRegion {
nsIntRegion;
null_t;
};
struct OpNotifyNotUsed {
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -241,17 +241,17 @@ parent:
// We visualize this information in the APZ minimap.
async NotifyApproximatelyVisibleRegion(ScrollableLayerGuid guid, CSSIntRegion region);
/**
* Sent when the child has finished CaptureAllPlugins.
*/
async AllPluginsCaptured();
- async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
+ async PTexture(SurfaceDescriptor aSharedData, ReadLockDescriptor aReadLock, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t id, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
sync SyncWithCompositor();
// The pipelineId is the same as the layersId
sync PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize)
returns (TextureFactoryIdentifier textureFactoryIdentifier, IdNamespace idNamespace);
sync CheckContentOnlyTDR(uint32_t sequenceNum)
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -52,17 +52,17 @@ parent:
// in a state in which it can't send asynchronous messages
// so as to not race with the channel getting closed.
// In the child side, the Closing the channel does not happen right after WillClose,
// it is scheduled in the ImageBridgeChild's message queue in order to ensure
// that all of the messages from the parent side have been received and processed
// before sending closing the channel.
sync WillClose();
- async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
+ async PTexture(SurfaceDescriptor aSharedData, ReadLockDescriptor aReadLock, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
async PMediaSystemResourceManager();
sync NewCompositable(CompositableHandle aHandle, TextureInfo aInfo, LayersBackend aBackend);
async ReleaseCompositable(CompositableHandle aHandle);
};
} // namespace
--- a/gfx/layers/ipc/PVideoBridge.ipdl
+++ b/gfx/layers/ipc/PVideoBridge.ipdl
@@ -19,15 +19,15 @@ namespace layers {
* The PVideoBridge protocol is used to share textures from the video decoders
* to the compositor.
*/
sync protocol PVideoBridge
{
manages PTexture;
parent:
- async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend,
+ async PTexture(SurfaceDescriptor aSharedData, ReadLockDescriptor aReadLock, LayersBackend aBackend,
TextureFlags aTextureFlags, uint64_t aSerial);
};
} // namespace
} // namespace
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -488,25 +488,21 @@ ShadowLayerForwarder::UseTextures(Compos
}
AutoTArray<TimedTexture,4> textures;
for (auto& t : aTextures) {
MOZ_ASSERT(t.mTextureClient);
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
- ReadLockDescriptor readLock;
- ReadLockHandle readLockHandle;
- if (t.mTextureClient->SerializeReadLock(readLock)) {
- readLockHandle = mTxn->AddReadLock(readLock);
- }
+ bool readLocked = t.mTextureClient->OnForwardedToHost();
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
- readLockHandle,
t.mTimeStamp, t.mPictureRect,
- t.mFrameID, t.mProducerID));
+ t.mFrameID, t.mProducerID,
+ readLocked));
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
}
mTxn->AddEdit(CompositableOperation(aCompositable->GetIPCHandle(),
OpUseTexture(textures)));
}
void
ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositable,
@@ -523,37 +519,29 @@ ShadowLayerForwarder::UseComponentAlphaT
MOZ_ASSERT(aTextureOnBlack);
MOZ_ASSERT(aCompositable->GetIPCHandle());
MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
- ReadLockDescriptor readLockB;
- ReadLockHandle readLockHandleB;
- ReadLockDescriptor readLockW;
- ReadLockHandle readLockHandleW;
- if (aTextureOnBlack->SerializeReadLock(readLockB)) {
- readLockHandleB = mTxn->AddReadLock(readLockB);
- }
- if (aTextureOnWhite->SerializeReadLock(readLockW)) {
- readLockHandleW = mTxn->AddReadLock(readLockW);
- }
+ bool readLockedB = aTextureOnBlack->OnForwardedToHost();
+ bool readLockedW = aTextureOnWhite->OnForwardedToHost();
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
mClientLayerManager->GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
mTxn->AddEdit(
CompositableOperation(
aCompositable->GetIPCHandle(),
OpUseComponentAlphaTextures(
nullptr, aTextureOnBlack->GetIPDLActor(),
nullptr, aTextureOnWhite->GetIPDLActor(),
- readLockHandleB, readLockHandleW)
+ readLockedB, readLockedW)
)
);
}
static bool
AddOpDestroy(Transaction* aTxn, const OpDestroy& op)
{
if (!aTxn->Opened()) {
--- a/gfx/layers/ipc/TextureForwarder.h
+++ b/gfx/layers/ipc/TextureForwarder.h
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_LAYERS_TEXTUREFORWARDER
#define MOZILLA_LAYERS_TEXTUREFORWARDER
#include <stdint.h> // for int32_t, uint64_t
#include "gfxTypes.h"
+#include "mozilla/layers/LayersMessages.h" // for Edit, etc
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/layers/KnowsCompositor.h"
namespace mozilla {
namespace ipc {
class IShmemAllocator;
}
@@ -64,16 +65,17 @@ protected:
*/
class TextureForwarder : public LayersIPCChannel {
public:
/**
* Create a TextureChild/Parent pair as as well as the TextureHost on the parent side.
*/
virtual PTextureChild* CreateTexture(
const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget = nullptr) = 0;
};
} // namespace layers
--- a/gfx/layers/ipc/VideoBridgeChild.cpp
+++ b/gfx/layers/ipc/VideoBridgeChild.cpp
@@ -73,16 +73,17 @@ VideoBridgeChild::AllocShmem(size_t aSiz
bool
VideoBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
{
return PVideoBridgeChild::DeallocShmem(aShmem);
}
PTextureChild*
VideoBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
+ const ReadLockDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t& aSerial)
{
MOZ_ASSERT(CanSend());
return TextureClient::CreateIPDLActor();
}
@@ -101,24 +102,25 @@ VideoBridgeChild::ActorDestroy(ActorDest
void
VideoBridgeChild::DeallocPVideoBridgeChild()
{
mIPDLSelfRef = nullptr;
}
PTextureChild*
VideoBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget)
{
MOZ_ASSERT(CanSend());
- return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);
+ return SendPTextureConstructor(aSharedData, aReadLock, aLayersBackend, aFlags, aSerial);
}
bool VideoBridgeChild::IsSameProcess() const
{
return OtherPid() == base::GetCurrentProcId();
}
} // namespace layers
--- a/gfx/layers/ipc/VideoBridgeChild.h
+++ b/gfx/layers/ipc/VideoBridgeChild.h
@@ -22,16 +22,17 @@ public:
static void Startup();
static void Shutdown();
static VideoBridgeChild* GetSingleton();
// PVideoBridgeChild
PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial) override;
bool DeallocPTextureChild(PTextureChild* actor) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void DeallocPVideoBridgeChild() override;
@@ -42,16 +43,17 @@ public:
mozilla::ipc::Shmem* aShmem) override;
bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
// TextureForwarder
PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial,
wr::MaybeExternalImageId& aExternalImageId,
nsIEventTarget* aTarget = nullptr) override;
// ClientIPCAllocator
base::ProcessId GetParentPid() const override { return OtherPid(); }
--- a/gfx/layers/ipc/VideoBridgeParent.cpp
+++ b/gfx/layers/ipc/VideoBridgeParent.cpp
@@ -52,22 +52,23 @@ void
VideoBridgeParent::DeallocPVideoBridgeParent()
{
mCompositorThreadRef = nullptr;
mSelfRef = nullptr;
}
PTextureParent*
VideoBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial)
{
PTextureParent* parent =
- TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, Nothing());
+ TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, Nothing());
mTextureMap[aSerial] = parent;
return parent;
}
bool
VideoBridgeParent::DeallocPTextureParent(PTextureParent* actor)
{
mTextureMap.erase(TextureHost::GetTextureSerial(actor));
--- a/gfx/layers/ipc/VideoBridgeParent.h
+++ b/gfx/layers/ipc/VideoBridgeParent.h
@@ -24,16 +24,17 @@ public:
~VideoBridgeParent();
static VideoBridgeParent* GetSingleton();
TextureHost* LookupTexture(uint64_t aSerial);
// PVideoBridgeParent
void ActorDestroy(ActorDestroyReason aWhy) override;
PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
+ const ReadLockDescriptor& aReadLock,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial) override;
bool DeallocPTextureParent(PTextureParent* actor) override;
// HostIPCAllocator
base::ProcessId GetChildProcessId() override
{
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -534,29 +534,22 @@ WebRenderBridgeChild::UseTextures(Compos
}
AutoTArray<TimedTexture,4> textures;
for (auto& t : aTextures) {
MOZ_ASSERT(t.mTextureClient);
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == GetIPCChannel());
- ReadLockDescriptor readLock;
- ReadLockHandle readLockHandle;
- if (t.mTextureClient->SerializeReadLock(readLock)) {
- readLockHandle = ReadLockHandle(++mReadLockSequenceNumber);
- if (mReadLocks.LastElement().Length() >= GetMaxFileDescriptorsPerMessage()) {
- mReadLocks.AppendElement();
- }
- mReadLocks.LastElement().AppendElement(ReadLockInit(readLock, readLockHandle));
- }
+ bool readLocked = t.mTextureClient->OnForwardedToHost();
+
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
- readLockHandle,
t.mTimeStamp, t.mPictureRect,
- t.mFrameID, t.mProducerID));
+ t.mFrameID, t.mProducerID,
+ readLocked));
GetCompositorBridgeChild()->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
}
AddWebRenderParentCommand(CompositableOperation(aCompositable->GetIPCHandle(),
OpUseTexture(textures)));
}
void
WebRenderBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
--- a/gfx/tests/gtest/TextureHelper.h
+++ b/gfx/tests/gtest/TextureHelper.h
@@ -144,19 +144,20 @@ CreateTextureHostWithBackend(TextureClie
LayersBackend& aLayersBackend)
{
if (!aClient) {
return nullptr;
}
// client serialization
SurfaceDescriptor descriptor;
+ ReadLockDescriptor readLock = null_t();
RefPtr<TextureHost> textureHost;
aClient->ToSurfaceDescriptor(descriptor);
wr::MaybeExternalImageId id = Nothing();
- return TextureHost::Create(descriptor, aDeallocator, aLayersBackend,
+ return TextureHost::Create(descriptor, readLock, aDeallocator, aLayersBackend,
aClient->GetFlags(), id);
}
} // namespace layers
} // namespace mozilla
--- a/ipc/glue/CrossProcessSemaphore.h
+++ b/ipc/glue/CrossProcessSemaphore.h
@@ -73,16 +73,18 @@ public:
* ShareToProcess
* This function is called to generate a serializable structure that can
* be sent to the specified process and opened on the other side.
*
* @returns A handle that can be shared to another process
*/
CrossProcessSemaphoreHandle ShareToProcess(base::ProcessId aTargetPid);
+ void CloseHandle();
+
private:
friend struct IPC::ParamTraits<CrossProcessSemaphore>;
CrossProcessSemaphore();
CrossProcessSemaphore(const CrossProcessSemaphore&);
CrossProcessSemaphore &operator=(const CrossProcessSemaphore&);
#if defined(OS_WIN)
--- a/ipc/glue/CrossProcessSemaphore_posix.cpp
+++ b/ipc/glue/CrossProcessSemaphore_posix.cpp
@@ -71,16 +71,18 @@ CrossProcessSemaphore::Create(CrossProce
if (!sharedBuffer->SetHandle(aHandle, ipc::SharedMemory::RightsReadWrite)) {
return nullptr;
}
if (!sharedBuffer->Map(sizeof(SemaphoreData))) {
return nullptr;
}
+ sharedBuffer->CloseHandle();
+
SemaphoreData* data = static_cast<SemaphoreData*>(sharedBuffer->memory());
if (!data) {
return nullptr;
}
int32_t oldCount = data->mRefCount++;
if (oldCount == 0) {
@@ -157,9 +159,15 @@ CrossProcessSemaphore::ShareToProcess(ba
if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
MOZ_CRASH();
}
return result;
}
+void
+CrossProcessSemaphore::CloseHandle()
+{
+ mSharedBuffer->CloseHandle();
+}
+
} // namespace mozilla
--- a/ipc/glue/CrossProcessSemaphore_unimplemented.cpp
+++ b/ipc/glue/CrossProcessSemaphore_unimplemented.cpp
@@ -49,9 +49,15 @@ CrossProcessSemaphore::Signal()
CrossProcessSemaphoreHandle
CrossProcessSemaphore::ShareToProcess(base::ProcessId aTargetPid)
{
MOZ_CRASH("Cross-process semaphores not allowed on this platform - woah! We should've aborted by now!");
return 0;
}
+void
+CrossProcessSemaphore::CloseHandle()
+{
+ MOZ_CRASH("Cross-process semaphores not allowed on this platform - woah! We should've aborted by now!");
}
+
+}
--- a/ipc/glue/CrossProcessSemaphore_windows.cpp
+++ b/ipc/glue/CrossProcessSemaphore_windows.cpp
@@ -80,9 +80,14 @@ CrossProcessSemaphore::ShareToProcess(ba
if (!succeeded) {
return nullptr;
}
return newHandle;
}
+void
+CrossProcessSemaphore::CloseHandle()
+{
}
+
+}