зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1272600 - Part 3 - Move the ReadUnlock logic from compositable to texture. r=sotaro
This commit is contained in:
Родитель
0a313355f8
Коммит
1d7c8451c8
|
@ -7,6 +7,7 @@
|
|||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "gfx2DGlue.h"
|
||||
|
@ -23,6 +24,35 @@ namespace mozilla {
|
|||
|
||||
namespace layers {
|
||||
|
||||
Compositor::Compositor(widget::CompositorWidgetProxy* aWidget,
|
||||
CompositorBridgeParent* aParent)
|
||||
: mCompositorID(0)
|
||||
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
||||
, mParent(aParent)
|
||||
, mPixelsPerFrame(0)
|
||||
, mPixelsFilled(0)
|
||||
, mScreenRotation(ROTATION_0)
|
||||
, mWidget(aWidget)
|
||||
{
|
||||
}
|
||||
|
||||
Compositor::~Compositor()
|
||||
{
|
||||
for (auto& lock : mUnlockAfterComposition) {
|
||||
lock->ReadUnlock();
|
||||
}
|
||||
mUnlockAfterComposition.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
Compositor::EndFrame()
|
||||
{
|
||||
for (auto& lock : mUnlockAfterComposition) {
|
||||
lock->ReadUnlock();
|
||||
}
|
||||
mUnlockAfterComposition.Clear();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Compositor::AssertOnCompositorThread()
|
||||
{
|
||||
|
|
|
@ -133,6 +133,7 @@ class CompositorOGL;
|
|||
class CompositorD3D9;
|
||||
class CompositorD3D11;
|
||||
class BasicCompositor;
|
||||
class TextureReadLock;
|
||||
|
||||
enum SurfaceInitMode
|
||||
{
|
||||
|
@ -185,22 +186,13 @@ enum SurfaceInitMode
|
|||
class Compositor
|
||||
{
|
||||
protected:
|
||||
virtual ~Compositor() {}
|
||||
virtual ~Compositor();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(Compositor)
|
||||
|
||||
explicit Compositor(widget::CompositorWidgetProxy* aWidget,
|
||||
CompositorBridgeParent* aParent = nullptr)
|
||||
: mCompositorID(0)
|
||||
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
||||
, mParent(aParent)
|
||||
, mPixelsPerFrame(0)
|
||||
, mPixelsFilled(0)
|
||||
, mScreenRotation(ROTATION_0)
|
||||
, mWidget(aWidget)
|
||||
{
|
||||
}
|
||||
CompositorBridgeParent* aParent = nullptr);
|
||||
|
||||
virtual already_AddRefed<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
|
||||
|
||||
|
@ -388,8 +380,10 @@ public:
|
|||
|
||||
/**
|
||||
* Flush the current frame to the screen and tidy up.
|
||||
*
|
||||
* Derived class overriding this should call Compositor::EndFrame.
|
||||
*/
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void EndFrame();
|
||||
|
||||
virtual void SetDispAcquireFence(Layer* aLayer);
|
||||
|
||||
|
@ -539,6 +533,11 @@ public:
|
|||
return mParent;
|
||||
}
|
||||
|
||||
void UnlockAfterComposition(already_AddRefed<TextureReadLock> aLock)
|
||||
{
|
||||
mUnlockAfterComposition.AppendElement(aLock);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
|
||||
const gfx::Rect& aVisibleRect,
|
||||
|
@ -563,6 +562,11 @@ protected:
|
|||
gfx::Matrix4x4* aOutTransform,
|
||||
gfx::Rect* aOutLayerQuad = nullptr);
|
||||
|
||||
/**
|
||||
* An array of locks that will need to be unlocked after the next composition.
|
||||
*/
|
||||
nsTArray<RefPtr<TextureReadLock>> mUnlockAfterComposition;
|
||||
|
||||
/**
|
||||
* Render time for the current composition.
|
||||
*/
|
||||
|
|
|
@ -436,6 +436,8 @@ DIBTextureHost::UpdatedInternal(const nsIntRegion* aRegion)
|
|||
if (!mTextureSource->Update(surf, const_cast<nsIntRegion*>(aRegion))) {
|
||||
mTextureSource = nullptr;
|
||||
}
|
||||
|
||||
ReadUnlock();
|
||||
}
|
||||
|
||||
TextureHostFileMapping::TextureHostFileMapping(TextureFlags aFlags,
|
||||
|
@ -484,6 +486,8 @@ TextureHostFileMapping::UpdatedInternal(const nsIntRegion* aRegion)
|
|||
} else {
|
||||
mTextureSource = nullptr;
|
||||
}
|
||||
|
||||
ReadUnlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
|
|
@ -650,6 +650,8 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
void
|
||||
BasicCompositor::EndFrame()
|
||||
{
|
||||
Compositor::EndFrame();
|
||||
|
||||
// Pop aClipRectIn/bounds rect
|
||||
mRenderTarget->mDrawTarget->PopClip();
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ GrallocTextureHostBasic::BindTextureSource(CompositableTextureSourceRef& aTextur
|
|||
void
|
||||
GrallocTextureHostBasic::UnbindTextureSource()
|
||||
{
|
||||
TextureHost::UnbindTextureSource();
|
||||
ClearTextureSource();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
|
|
@ -30,11 +30,6 @@ SingleTiledContentClient::ClearCachedResources()
|
|||
void
|
||||
SingleTiledContentClient::UpdatedBuffer(TiledBufferType aType)
|
||||
{
|
||||
// Take a ReadLock on behalf of the TiledContentHost. This
|
||||
// reference will be adopted when the descriptor is opened in
|
||||
// TiledLayerBufferComposite.
|
||||
mTiledBuffer->ReadLock();
|
||||
|
||||
mForwarder->UseTiledLayerBuffer(this, mTiledBuffer->GetSurfaceDescriptorTiles());
|
||||
mTiledBuffer->ClearPaintedRegion();
|
||||
}
|
||||
|
@ -56,13 +51,6 @@ ClientSingleTiledLayerBuffer::ClientSingleTiledLayerBuffer(ClientTiledPaintedLay
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClientSingleTiledLayerBuffer::ReadLock() {
|
||||
if (!mTile.IsPlaceholderTile()) {
|
||||
mTile.ReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientSingleTiledLayerBuffer::ReleaseTiles()
|
||||
{
|
||||
|
|
|
@ -70,8 +70,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void ReadLock();
|
||||
|
||||
void ReleaseTiles();
|
||||
|
||||
void DiscardBuffers();
|
||||
|
|
|
@ -452,7 +452,7 @@ TextureClient::UnlockActor() const
|
|||
bool
|
||||
TextureClient::IsReadLocked() const
|
||||
{
|
||||
return mReadLock && mReadLock->GetReadCount() > 1;
|
||||
return mReadLock && mReadLock->GetReadCount() > 1 && !mPendingReadUnlock;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -528,6 +528,15 @@ TextureClient::Unlock()
|
|||
mBorrowedDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
if (mOpenMode & OpenMode::OPEN_WRITE) {
|
||||
if (mReadLock && !mPendingReadUnlock) {
|
||||
// Take a read lock on behalf of the TextureHost. The latter will unlock
|
||||
// after the shared data is available again for drawing.
|
||||
mReadLock->ReadLock();
|
||||
}
|
||||
mPendingReadUnlock = true;
|
||||
}
|
||||
|
||||
mData->Unlock();
|
||||
mIsLocked = false;
|
||||
mOpenMode = OpenMode::OPEN_NONE;
|
||||
|
@ -535,8 +544,43 @@ TextureClient::Unlock()
|
|||
UnlockActor();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::EnableReadLock()
|
||||
{
|
||||
if (!mReadLock) {
|
||||
mReadLock = TextureReadLock::Create(mAllocator);
|
||||
if (mPendingReadUnlock) {
|
||||
// We would have done this during TextureClient::Unlock if the ReadLock
|
||||
// had been there, need to account for this here.
|
||||
mReadLock->ReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SetReadLock(TextureReadLock* aLock)
|
||||
{
|
||||
MOZ_ASSERT(!mReadLock);
|
||||
mReadLock = aLock;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClient::SerializeReadLock(ReadLockDescriptor& aDescriptor)
|
||||
{
|
||||
if (mReadLock && mPendingReadUnlock) {
|
||||
mReadLock->Serialize(aDescriptor);
|
||||
mPendingReadUnlock = false;
|
||||
} else {
|
||||
aDescriptor = null_t();
|
||||
}
|
||||
}
|
||||
|
||||
TextureClient::~TextureClient()
|
||||
{
|
||||
if (mPendingReadUnlock && mReadLock) {
|
||||
mReadLock->ReadUnlock();
|
||||
mReadLock = nullptr;
|
||||
}
|
||||
Destroy(false);
|
||||
}
|
||||
|
||||
|
@ -1044,6 +1088,7 @@ TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCA
|
|||
, mExpectedDtRefs(0)
|
||||
#endif
|
||||
, mIsLocked(false)
|
||||
, mPendingReadUnlock(false)
|
||||
, mInUse(false)
|
||||
, mAddedToCompositableClient(false)
|
||||
, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
|
||||
|
@ -1174,11 +1219,19 @@ public:
|
|||
|
||||
virtual bool IsValid() const override { return true; };
|
||||
|
||||
virtual bool Serialize(TileLock& aOutput) override;
|
||||
virtual bool Serialize(ReadLockDescriptor& aOutput) override;
|
||||
|
||||
int32_t mReadCount;
|
||||
};
|
||||
|
||||
// The cross-prcess implementation of TextureReadLock.
|
||||
//
|
||||
// Since we don't use cross-process reference counting for the ReadLock objects,
|
||||
// we use the lock's internal counter as a way to know when to deallocate the
|
||||
// underlying shmem section: when the counter is equal to 1, it means that the
|
||||
// lock is not "held" (the texture is writable), when the counter is equal to 0
|
||||
// it means that we can safely deallocate the shmem section without causing a race
|
||||
// condition with the other process.
|
||||
class ShmemTextureReadLock : public TextureReadLock {
|
||||
public:
|
||||
struct ShmReadLockInfo {
|
||||
|
@ -1199,7 +1252,7 @@ public:
|
|||
|
||||
virtual LockType GetType() override { return TYPE_SHMEM; }
|
||||
|
||||
virtual bool Serialize(TileLock& aOutput) override;
|
||||
virtual bool Serialize(ReadLockDescriptor& aOutput) override;
|
||||
|
||||
mozilla::layers::ShmemSection& GetShmemSection() { return mShmemSection; }
|
||||
|
||||
|
@ -1224,31 +1277,43 @@ public:
|
|||
|
||||
// static
|
||||
already_AddRefed<TextureReadLock>
|
||||
TextureReadLock::Open(const TileLock& aDescriptor, ISurfaceAllocator* aAllocator)
|
||||
TextureReadLock::Deserialize(const ReadLockDescriptor& aDescriptor, ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
RefPtr<TextureReadLock> lock;
|
||||
if (aDescriptor.type() == TileLock::TShmemSection) {
|
||||
switch (aDescriptor.type()) {
|
||||
case ReadLockDescriptor::TShmemSection: {
|
||||
const ShmemSection& section = aDescriptor.get_ShmemSection();
|
||||
MOZ_RELEASE_ASSERT(section.shmem().IsReadable());
|
||||
lock = new ShmemTextureReadLock(aAllocator, section);
|
||||
} else {
|
||||
return MakeAndAddRef<ShmemTextureReadLock>(aAllocator, section);
|
||||
}
|
||||
case ReadLockDescriptor::Tuintptr_t: {
|
||||
if (!aAllocator->IsSameProcess()) {
|
||||
// Trying to use a memory based lock instead of a shmem based one in
|
||||
// the cross-process case is a bad security violation.
|
||||
NS_ERROR("A client process may be trying to peek at the host's address space!");
|
||||
return nullptr;
|
||||
}
|
||||
lock = reinterpret_cast<MemoryTextureReadLock*>(aDescriptor.get_uintptr_t());
|
||||
RefPtr<TextureReadLock> lock = reinterpret_cast<MemoryTextureReadLock*>(
|
||||
aDescriptor.get_uintptr_t()
|
||||
);
|
||||
|
||||
MOZ_ASSERT(lock);
|
||||
if (lock) {
|
||||
// The corresponding AddRef is in MemoryTextureReadLock::Serialize
|
||||
lock.get()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return lock.forget();
|
||||
}
|
||||
case ReadLockDescriptor::Tnull_t: {
|
||||
return nullptr;
|
||||
}
|
||||
default: {
|
||||
// Invalid descriptor.
|
||||
MOZ_DIAGNOSTIC_ASSERT(false);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TextureReadLock>
|
||||
TextureReadLock::Create(ClientIPCAllocator* aAllocator)
|
||||
|
@ -1276,13 +1341,13 @@ MemoryTextureReadLock::~MemoryTextureReadLock()
|
|||
}
|
||||
|
||||
bool
|
||||
MemoryTextureReadLock::Serialize(TileLock& aOutput)
|
||||
MemoryTextureReadLock::Serialize(ReadLockDescriptor& aOutput)
|
||||
{
|
||||
// AddRef here and Release when receiving on the host side to make sure the
|
||||
// reference count doesn't go to zero before the host receives the message.
|
||||
// see TextureReadLock::Open
|
||||
// see TextureReadLock::Deserialize
|
||||
this->AddRef();
|
||||
aOutput = TileLock(uintptr_t(this));
|
||||
aOutput = ReadLockDescriptor(uintptr_t(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1339,9 +1404,9 @@ ShmemTextureReadLock::~ShmemTextureReadLock()
|
|||
}
|
||||
|
||||
bool
|
||||
ShmemTextureReadLock::Serialize(TileLock& aOutput)
|
||||
ShmemTextureReadLock::Serialize(ReadLockDescriptor& aOutput)
|
||||
{
|
||||
aOutput = TileLock(GetShmemSection());
|
||||
aOutput = ReadLockDescriptor(GetShmemSection());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,9 +177,27 @@ struct MappedYCbCrTextureData {
|
|||
}
|
||||
};
|
||||
|
||||
class TileLock;
|
||||
class ReadLockDescriptor;
|
||||
|
||||
// A class to help implement copy-on-write semantics for shared tiles.
|
||||
// A class to help implement copy-on-write semantics for shared textures.
|
||||
//
|
||||
// A TextureClient/Host pair can opt into using a ReadLock by calling
|
||||
// TextureClient::EnableReadLock. This will equip the TextureClient with a
|
||||
// ReadLock object that will be automatically ReadLock()'ed by the texture itself
|
||||
// when it is written into (see TextureClient::Unlock).
|
||||
// A TextureReadLock's counter starts at 1 and is expected to be equal to 1 when the
|
||||
// lock is destroyed. See ShmemTextureReadLock for explanations about why we use
|
||||
// 1 instead of 0 as the initial state.
|
||||
// TextureReadLock is mostly internally managed by the TextureClient/Host pair,
|
||||
// and the compositable only has to forward it during updates. If an update message
|
||||
// contains a null_t lock, it means that the texture was not written into on the
|
||||
// content side, and there is no synchronization required on the compositor side
|
||||
// (or it means that the texture pair did not opt into using ReadLocks).
|
||||
// On the compositor side, the TextureHost can receive a ReadLock during a
|
||||
// transaction, and will both ReadUnlock() it and drop it as soon as the shared
|
||||
// data is available again for writing (the texture upload is done, or the compositor
|
||||
// not reading the texture anymore). The lock is dropped to make sure it is
|
||||
// ReadUnlock()'ed only once.
|
||||
class TextureReadLock {
|
||||
protected:
|
||||
virtual ~TextureReadLock() {}
|
||||
|
@ -196,9 +214,9 @@ public:
|
|||
Create(ClientIPCAllocator* aAllocator);
|
||||
|
||||
static already_AddRefed<TextureReadLock>
|
||||
Open(const TileLock& aDescriptor, ISurfaceAllocator* aAllocator);
|
||||
Deserialize(const ReadLockDescriptor& aDescriptor, ISurfaceAllocator* aAllocator);
|
||||
|
||||
virtual bool Serialize(TileLock& aOutput) = 0;
|
||||
virtual bool Serialize(ReadLockDescriptor& aOutput) = 0;
|
||||
|
||||
enum LockType {
|
||||
TYPE_MEMORY,
|
||||
|
@ -632,12 +650,17 @@ public:
|
|||
virtual void RemoveFromCompositable(CompositableClient* aCompositable,
|
||||
AsyncTransactionWaiter* aWaiter = nullptr);
|
||||
|
||||
void SetReadLock(already_AddRefed<TextureReadLock> aLock) { mReadLock = aLock; }
|
||||
|
||||
void EnableReadLock();
|
||||
|
||||
void SetReadLock(TextureReadLock* aLock);
|
||||
|
||||
TextureReadLock* GetReadLock() { return mReadLock; }
|
||||
|
||||
bool IsReadLocked() const;
|
||||
|
||||
void SerializeReadLock(ReadLockDescriptor& aDescriptor);
|
||||
|
||||
private:
|
||||
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);
|
||||
|
||||
|
@ -687,6 +710,10 @@ protected:
|
|||
uint32_t mExpectedDtRefs;
|
||||
#endif
|
||||
bool mIsLocked;
|
||||
// True when there has been a modification of the texture that hasn't been sent
|
||||
// to the compositor yet. We keep track of this to avoid sending the texture's
|
||||
// ReadLock twice after a single update.
|
||||
bool mPendingReadUnlock;
|
||||
bool mInUse;
|
||||
|
||||
bool mAddedToCompositableClient;
|
||||
|
|
|
@ -119,11 +119,6 @@ MultiTiledContentClient::UpdatedBuffer(TiledBufferType aType)
|
|||
|
||||
MOZ_ASSERT(aType != LOW_PRECISION_TILED_BUFFER || mHasLowPrecision);
|
||||
|
||||
// Take a ReadLock on behalf of the TiledContentHost. This
|
||||
// reference will be adopted when the descriptor is opened in
|
||||
// TiledLayerBufferComposite.
|
||||
buffer->ReadLock();
|
||||
|
||||
mForwarder->UseTiledLayerBuffer(this, buffer->GetSurfaceDescriptorTiles());
|
||||
buffer->ClearPaintedRegion();
|
||||
}
|
||||
|
@ -570,10 +565,6 @@ TileClient::DiscardFrontBuffer()
|
|||
|
||||
mAllocator->ReturnTextureClientDeferred(mFrontBuffer);
|
||||
if (mFrontBufferOnWhite) {
|
||||
// TODO: right now we use he same ReadLock for the texture on black and
|
||||
// the texture on white, but we may change that in the near future.
|
||||
RefPtr<TextureReadLock> lock = mFrontBuffer->GetReadLock();
|
||||
mFrontBuffer->SetReadLock(lock.forget());
|
||||
mFrontBufferOnWhite->RemoveFromCompositable(mCompositableClient);
|
||||
mAllocator->ReturnTextureClientDeferred(mFrontBufferOnWhite);
|
||||
}
|
||||
|
@ -588,36 +579,61 @@ TileClient::DiscardFrontBuffer()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TileClient::DiscardBackBuffer()
|
||||
static void
|
||||
DiscardTexture(TextureClient* aTexture, TextureClientAllocator* aAllocator)
|
||||
{
|
||||
if (mBackBuffer) {
|
||||
MOZ_ASSERT(mBackBuffer->GetReadLock());
|
||||
if (!mBackBuffer->HasSynchronization() && mBackBuffer->IsReadLocked()) {
|
||||
if (aTexture) {
|
||||
MOZ_ASSERT(aTexture->GetReadLock());
|
||||
if (!aTexture->HasSynchronization() && aTexture->IsReadLocked()) {
|
||||
// Our current back-buffer is still locked by the compositor. This can occur
|
||||
// when the client is producing faster than the compositor can consume. In
|
||||
// this case we just want to drop it and not return it to the pool.
|
||||
mAllocator->ReportClientLost();
|
||||
if (mBackBufferOnWhite) {
|
||||
mAllocator->ReportClientLost();
|
||||
}
|
||||
aAllocator->ReportClientLost();
|
||||
} else {
|
||||
mAllocator->ReturnTextureClientDeferred(mBackBuffer);
|
||||
if (mBackBufferOnWhite) {
|
||||
RefPtr<TextureReadLock> lock = mBackBuffer->GetReadLock();
|
||||
mBackBufferOnWhite->SetReadLock(lock.forget());
|
||||
mAllocator->ReturnTextureClientDeferred(mBackBufferOnWhite);
|
||||
aAllocator->ReturnTextureClientDeferred(aTexture);
|
||||
}
|
||||
if (aTexture->IsLocked()) {
|
||||
aTexture->Unlock();
|
||||
}
|
||||
}
|
||||
if (mBackBuffer->IsLocked()) {
|
||||
mBackBuffer->Unlock();
|
||||
}
|
||||
if (mBackBufferOnWhite && mBackBufferOnWhite->IsLocked()) {
|
||||
mBackBufferOnWhite->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TileClient::DiscardBackBuffer()
|
||||
{
|
||||
DiscardTexture(mBackBuffer, mAllocator);
|
||||
mBackBuffer.Set(this, nullptr);
|
||||
DiscardTexture(mBackBufferOnWhite, mAllocator);
|
||||
mBackBufferOnWhite = nullptr;
|
||||
}
|
||||
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateBackBufferTexture(TextureClient* aCurrentTexture,
|
||||
CompositableClient* aCompositable,
|
||||
TextureClientAllocator* aAllocator)
|
||||
{
|
||||
if (aCurrentTexture) {
|
||||
// Our current back-buffer is still locked by the compositor. This can occur
|
||||
// when the client is producing faster than the compositor can consume. In
|
||||
// this case we just want to drop it and not return it to the pool.
|
||||
aAllocator->ReportClientLost();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
TextureClient*
|
||||
|
@ -627,49 +643,53 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
|
|||
nsIntRegion& aAddPaintedRegion,
|
||||
RefPtr<TextureClient>* aBackBufferOnWhite)
|
||||
{
|
||||
if (aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||
// It can happen that a component-alpha layer stops being on component alpha
|
||||
// on the next frame, just drop the buffers on white if that happens.
|
||||
if (mBackBufferOnWhite) {
|
||||
mAllocator->ReportClientLost();
|
||||
mBackBufferOnWhite = nullptr;
|
||||
}
|
||||
if (mFrontBufferOnWhite) {
|
||||
mAllocator->ReportClientLost();
|
||||
mFrontBufferOnWhite = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to re-use the front-buffer if possible
|
||||
bool createdTextureClient = false;
|
||||
if (mFrontBuffer &&
|
||||
mFrontBuffer->HasIntermediateBuffer() &&
|
||||
!mFrontBuffer->IsReadLocked() &&
|
||||
!(aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA && !mFrontBufferOnWhite)) {
|
||||
(aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA || (
|
||||
mFrontBufferOnWhite && !mFrontBufferOnWhite->IsReadLocked()))) {
|
||||
// If we had a backbuffer we no longer care about it since we'll
|
||||
// re-use the front buffer.
|
||||
DiscardBackBuffer();
|
||||
Flip();
|
||||
} else {
|
||||
if (!mBackBuffer || mBackBuffer->IsReadLocked()) {
|
||||
|
||||
if (mBackBuffer) {
|
||||
// Our current back-buffer is still locked by the compositor. This can occur
|
||||
// when the client is producing faster than the compositor can consume. In
|
||||
// this case we just want to drop it and not return it to the pool.
|
||||
mAllocator->ReportClientLost();
|
||||
}
|
||||
if (mBackBufferOnWhite) {
|
||||
mAllocator->ReportClientLost();
|
||||
mBackBufferOnWhite = nullptr;
|
||||
}
|
||||
|
||||
mBackBuffer.Set(this, mAllocator->GetTextureClient());
|
||||
if (!mBackBuffer) {
|
||||
gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient (B)";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||
mBackBufferOnWhite = mAllocator->GetTextureClient();
|
||||
if (!mBackBufferOnWhite) {
|
||||
mBackBuffer.Set(this, nullptr);
|
||||
gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient (W)";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mBackBuffer->SetReadLock(TextureReadLock::Create(mManager->AsShadowForwarder()));
|
||||
|
||||
createdTextureClient = true;
|
||||
mBackBuffer.Set(this,
|
||||
CreateBackBufferTexture(mBackBuffer, mCompositableClient, mAllocator)
|
||||
);
|
||||
mInvalidBack = IntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
|
||||
if (!mBackBuffer) {
|
||||
DiscardBackBuffer();
|
||||
DiscardFrontBuffer();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA
|
||||
&& (!mBackBufferOnWhite || mBackBufferOnWhite->IsReadLocked())) {
|
||||
mBackBufferOnWhite = CreateBackBufferTexture(
|
||||
mBackBufferOnWhite, mCompositableClient, mAllocator
|
||||
);
|
||||
mInvalidBack = IntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
|
||||
if (!mBackBufferOnWhite) {
|
||||
DiscardBackBuffer();
|
||||
DiscardFrontBuffer();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ValidateBackBufferFromFront(aDirtyRegion, aAddPaintedRegion);
|
||||
|
@ -693,21 +713,6 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
|
|||
}
|
||||
}
|
||||
|
||||
if (createdTextureClient) {
|
||||
if (!mCompositableClient->AddTextureClient(mBackBuffer)) {
|
||||
gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (a)";
|
||||
DiscardFrontBuffer();
|
||||
DiscardBackBuffer();
|
||||
return nullptr;
|
||||
}
|
||||
if (mBackBufferOnWhite && !mCompositableClient->AddTextureClient(mBackBufferOnWhite)) {
|
||||
gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (b)";
|
||||
DiscardFrontBuffer();
|
||||
DiscardBackBuffer();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
*aBackBufferOnWhite = mBackBufferOnWhite;
|
||||
return mBackBuffer;
|
||||
}
|
||||
|
@ -722,25 +727,21 @@ TileClient::GetTileDescriptor()
|
|||
bool wasPlaceholder = mWasPlaceholder;
|
||||
mWasPlaceholder = false;
|
||||
|
||||
TileLock lock;
|
||||
mFrontBuffer->GetReadLock()->Serialize(lock);
|
||||
ReadLockDescriptor lock;
|
||||
mFrontBuffer->SerializeReadLock(lock);
|
||||
|
||||
ReadLockDescriptor lockOnWhite = null_t();
|
||||
if (mFrontBufferOnWhite) {
|
||||
mFrontBufferOnWhite->SerializeReadLock(lockOnWhite);
|
||||
}
|
||||
|
||||
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
|
||||
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
|
||||
mUpdateRect,
|
||||
lock,
|
||||
lock, lockOnWhite,
|
||||
wasPlaceholder);
|
||||
}
|
||||
|
||||
void
|
||||
ClientMultiTiledLayerBuffer::ReadLock() {
|
||||
for (TileClient& tile : mRetainedTiles) {
|
||||
if (!tile.IsPlaceholderTile()) {
|
||||
tile.ReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientMultiTiledLayerBuffer::DiscardBuffers()
|
||||
{
|
||||
|
|
|
@ -90,22 +90,6 @@ struct TileClient
|
|||
return mBackBuffer == nullptr && mFrontBuffer == nullptr;
|
||||
}
|
||||
|
||||
void ReadUnlock()
|
||||
{
|
||||
MOZ_ASSERT(mFrontBuffer && mFrontBuffer->GetReadLock());
|
||||
if (mFrontBuffer && mFrontBuffer->GetReadLock()) {
|
||||
mFrontBuffer->GetReadLock()->ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
void ReadLock()
|
||||
{
|
||||
MOZ_ASSERT(mFrontBuffer && mFrontBuffer->GetReadLock());
|
||||
if (mFrontBuffer && mFrontBuffer->GetReadLock()) {
|
||||
mFrontBuffer->GetReadLock()->ReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
void DiscardBuffers()
|
||||
{
|
||||
DiscardFrontBuffer();
|
||||
|
|
|
@ -324,6 +324,26 @@ void TextureHost::Finalize()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::UnbindTextureSource()
|
||||
{
|
||||
if (mReadLock) {
|
||||
auto compositor = GetCompositor();
|
||||
// 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 (compositor) {
|
||||
compositor->UnlockAfterComposition(mReadLock.forget());
|
||||
} else {
|
||||
// GetCompositor returned null which means no compositor can be using this
|
||||
// texture. We can ReadUnlock right away.
|
||||
ReadUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextureHost::RecycleTexture(TextureFlags aFlags)
|
||||
{
|
||||
|
@ -503,9 +523,18 @@ BufferTextureHost::Unlock()
|
|||
}
|
||||
|
||||
void
|
||||
TextureHost::SetReadLock(already_AddRefed<TextureReadLock> aLock)
|
||||
TextureHost::DeserializeReadLock(const ReadLockDescriptor& aDesc,
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
mReadLock = aLock;
|
||||
RefPtr<TextureReadLock> lock = TextureReadLock::Deserialize(aDesc, aAllocator);
|
||||
if (!lock) {
|
||||
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();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace layers {
|
|||
class BufferDescriptor;
|
||||
class Compositor;
|
||||
class CompositableParentManager;
|
||||
class ReadLockDescriptor;
|
||||
class CompositorBridgeParent;
|
||||
class SurfaceDescriptor;
|
||||
class HostIPCAllocator;
|
||||
|
@ -409,7 +410,7 @@ public:
|
|||
/**
|
||||
* Called when another TextureHost will take over.
|
||||
*/
|
||||
virtual void UnbindTextureSource() {}
|
||||
virtual void UnbindTextureSource();
|
||||
|
||||
/**
|
||||
* Is called before compositing if the shared data has changed since last
|
||||
|
@ -575,12 +576,15 @@ public:
|
|||
|
||||
virtual FenceHandle GetCompositorReleaseFence() { return FenceHandle(); }
|
||||
|
||||
void SetReadLock(already_AddRefed<TextureReadLock> aLock);
|
||||
void DeserializeReadLock(const ReadLockDescriptor& aDesc,
|
||||
ISurfaceAllocator* aAllocator);
|
||||
|
||||
TextureReadLock* GetReadLock() { return mReadLock; }
|
||||
|
||||
void ReadUnlock();
|
||||
|
||||
virtual Compositor* GetCompositor() = 0;
|
||||
|
||||
protected:
|
||||
FenceHandle mReleaseFenceHandle;
|
||||
|
||||
|
@ -634,6 +638,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
/**
|
||||
* Return the format that is exposed to the compositor when calling
|
||||
* BindTextureSource.
|
||||
|
|
|
@ -186,23 +186,6 @@ UseTileTexture(CompositableTextureHostRef& aTexture,
|
|||
aTexture->PrepareTextureSource(aTextureSource);
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::MarkTilesForUnlock()
|
||||
{
|
||||
// Tiles without an internal buffer will have internal locks
|
||||
// held by the gpu driver until the previous draw operation has finished.
|
||||
// We don't know when that will be exactly, so wait until we start the
|
||||
// next composite before unlocking.
|
||||
for (TileHost& tile : mRetainedTiles) {
|
||||
// Tile with an internal buffer get unlocked as soon as we've uploaded,
|
||||
// so won't have a lock at this point.
|
||||
if (tile.mTextureHost && tile.mTextureHost->GetReadLock()) {
|
||||
mDelayedUnlocks.AppendElement(tile.mTextureHost->GetReadLock());
|
||||
tile.mTextureHost->SetReadLock(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TextureSourceRecycler
|
||||
{
|
||||
public:
|
||||
|
@ -297,15 +280,10 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
|
||||
const InfallibleTArray<TileDescriptor>& tileDescriptors = aTiles.tiles();
|
||||
|
||||
// Step 1, unlock all the old tiles that haven't been unlocked yet. Any tiles that
|
||||
// exist in both the old and new sets will have been locked again by content, so this
|
||||
// doesn't result in the surface being writeable again.
|
||||
MarkTilesForUnlock();
|
||||
|
||||
TextureSourceRecycler oldRetainedTiles(Move(mRetainedTiles));
|
||||
mRetainedTiles.SetLength(tileDescriptors.Length());
|
||||
|
||||
// Step 2, deserialize the incoming set of tiles into mRetainedTiles, and attempt
|
||||
// Step 1, deserialize the incoming set of tiles into mRetainedTiles, and attempt
|
||||
// to recycle the TextureSource for any repeated tiles.
|
||||
//
|
||||
// Since we don't have any retained 'tile' object, we have to search for instances
|
||||
|
@ -327,16 +305,15 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
|
||||
tile.mTextureHost = TextureHost::AsTextureHost(texturedDesc.textureParent());
|
||||
tile.mTextureHost->SetCompositor(aCompositor);
|
||||
|
||||
tile.mTextureHost->SetReadLock(TextureReadLock::Open(texturedDesc.sharedLock(), aAllocator));
|
||||
|
||||
if (!tile.mTextureHost->GetReadLock()) {
|
||||
return false;
|
||||
}
|
||||
tile.mTextureHost->DeserializeReadLock(texturedDesc.sharedLock(), aAllocator);
|
||||
|
||||
if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) {
|
||||
tile.mTextureHostOnWhite =
|
||||
TextureHost::AsTextureHost(texturedDesc.textureOnWhite().get_PTextureParent());
|
||||
tile.mTextureHostOnWhite = TextureHost::AsTextureHost(
|
||||
texturedDesc.textureOnWhite().get_PTextureParent()
|
||||
);
|
||||
tile.mTextureHostOnWhite->DeserializeReadLock(
|
||||
texturedDesc.sharedLockOnWhite(), aAllocator
|
||||
);
|
||||
}
|
||||
|
||||
tile.mTilePosition = newTiles.TilePosition(i);
|
||||
|
@ -360,7 +337,7 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
}
|
||||
}
|
||||
|
||||
// Step 3, attempt to recycle unused texture sources from the old tile set into new tiles.
|
||||
// Step 2, attempt to recycle unused texture sources from the old tile set into new tiles.
|
||||
//
|
||||
// For gralloc, binding a new TextureHost to the existing TextureSource is the fastest way
|
||||
// to ensure that any implicit locking on the old gralloc image is released.
|
||||
|
@ -371,7 +348,7 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
oldRetainedTiles.RecycleTextureSource(tile);
|
||||
}
|
||||
|
||||
// Step 4, handle the texture uploads, texture source binding and release the
|
||||
// Step 3, handle the texture uploads, texture source binding and release the
|
||||
// copy-on-write locks for textures with an internal buffer.
|
||||
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
|
||||
TileHost& tile = mRetainedTiles[i];
|
||||
|
@ -393,12 +370,6 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
texturedDesc.updateRect(),
|
||||
aCompositor);
|
||||
}
|
||||
|
||||
if (tile.mTextureHost->HasIntermediateBuffer()) {
|
||||
// Now that we did the texture upload (in UseTileTexture), we can release
|
||||
// the lock.
|
||||
tile.ReadUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
mTiles = newTiles;
|
||||
|
@ -412,23 +383,10 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::ProcessDelayedUnlocks()
|
||||
{
|
||||
for (TextureReadLock* lock : mDelayedUnlocks) {
|
||||
lock->ReadUnlock();
|
||||
}
|
||||
mDelayedUnlocks.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
TiledLayerBufferComposite::Clear()
|
||||
{
|
||||
for (TileHost& tile : mRetainedTiles) {
|
||||
tile.ReadUnlock();
|
||||
}
|
||||
mRetainedTiles.Clear();
|
||||
ProcessDelayedUnlocks();
|
||||
mTiles.mFirst = TileIntPoint();
|
||||
mTiles.mSize = TileIntSize();
|
||||
mValidRegion = nsIntRegion();
|
||||
|
@ -490,8 +448,6 @@ TiledContentHost::Composite(LayerComposite* aLayer,
|
|||
aFilter, aClipRect, *renderRegion, aTransform);
|
||||
RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aFilter,
|
||||
aClipRect, *renderRegion, aTransform);
|
||||
mLowPrecisionTiledBuffer.ProcessDelayedUnlocks();
|
||||
mTiledBuffer.ProcessDelayedUnlocks();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -140,9 +140,6 @@ public:
|
|||
|
||||
void Clear();
|
||||
|
||||
void MarkTilesForUnlock();
|
||||
void ProcessDelayedUnlocks();
|
||||
|
||||
TileHost GetPlaceholderTile() const { return TileHost(); }
|
||||
|
||||
// Stores the absolute resolution of the containing frame, calculated
|
||||
|
@ -155,7 +152,6 @@ public:
|
|||
protected:
|
||||
|
||||
CSSToParentLayerScale2D mFrameResolution;
|
||||
nsTArray<RefPtr<TextureReadLock>> mDelayedUnlocks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
|
|
@ -1205,6 +1205,8 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
void
|
||||
CompositorD3D11::EndFrame()
|
||||
{
|
||||
Compositor::EndFrame();
|
||||
|
||||
if (!mDefaultRT) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -684,6 +684,12 @@ DXGITextureHostD3D11::SetCompositor(Compositor* aCompositor)
|
|||
}
|
||||
}
|
||||
|
||||
Compositor*
|
||||
DXGITextureHostD3D11::GetCompositor()
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
||||
bool
|
||||
DXGITextureHostD3D11::Lock()
|
||||
{
|
||||
|
@ -807,6 +813,12 @@ DXGIYCbCrTextureHostD3D11::SetCompositor(Compositor* aCompositor)
|
|||
}
|
||||
}
|
||||
|
||||
Compositor*
|
||||
DXGIYCbCrTextureHostD3D11::GetCompositor()
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
||||
bool
|
||||
DXGIYCbCrTextureHostD3D11::Lock()
|
||||
{
|
||||
|
|
|
@ -281,6 +281,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
@ -320,6 +322,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override{ return gfx::SurfaceFormat::YUV; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
|
|
@ -716,6 +716,8 @@ CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
void
|
||||
CompositorD3D9::EndFrame()
|
||||
{
|
||||
Compositor::EndFrame();
|
||||
|
||||
if (mDeviceManager) {
|
||||
device()->EndScene();
|
||||
|
||||
|
|
|
@ -935,6 +935,8 @@ TextureHostD3D9::UpdatedInternal(const nsIntRegion* aRegion)
|
|||
if (!mTextureSource->UpdateFromTexture(mTexture, regionToUpdate)) {
|
||||
gfxCriticalNote << "[D3D9] DataTextureSourceD3D9::UpdateFromTexture failed";
|
||||
}
|
||||
|
||||
ReadUnlock();
|
||||
}
|
||||
|
||||
IDirect3DDevice9*
|
||||
|
@ -959,6 +961,12 @@ TextureHostD3D9::SetCompositor(Compositor* aCompositor)
|
|||
}
|
||||
}
|
||||
|
||||
Compositor*
|
||||
TextureHostD3D9::GetCompositor()
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
||||
bool
|
||||
TextureHostD3D9::BindTextureSource(CompositableTextureSourceRef& aTexture)
|
||||
{
|
||||
|
@ -1085,6 +1093,12 @@ DXGITextureHostD3D9::SetCompositor(Compositor* aCompositor)
|
|||
}
|
||||
}
|
||||
|
||||
Compositor*
|
||||
DXGITextureHostD3D9::GetCompositor()
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
||||
void
|
||||
DXGITextureHostD3D9::DeallocateDeviceData()
|
||||
{
|
||||
|
@ -1124,6 +1138,12 @@ DXGIYCbCrTextureHostD3D9::SetCompositor(Compositor* aCompositor)
|
|||
}
|
||||
}
|
||||
|
||||
Compositor*
|
||||
DXGIYCbCrTextureHostD3D9::GetCompositor()
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
||||
bool
|
||||
DXGIYCbCrTextureHostD3D9::Lock()
|
||||
{
|
||||
|
|
|
@ -276,6 +276,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
@ -317,6 +319,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
@ -354,6 +358,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return gfx::SurfaceFormat::YUV; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
|
|
@ -312,9 +312,10 @@ struct ShmemSection {
|
|||
size_t size;
|
||||
};
|
||||
|
||||
union TileLock {
|
||||
union ReadLockDescriptor {
|
||||
ShmemSection;
|
||||
uintptr_t;
|
||||
null_t;
|
||||
};
|
||||
|
||||
union MaybeTexture {
|
||||
|
@ -326,7 +327,8 @@ struct TexturedTileDescriptor {
|
|||
PTexture texture;
|
||||
MaybeTexture textureOnWhite;
|
||||
IntRect updateRect;
|
||||
TileLock sharedLock;
|
||||
ReadLockDescriptor sharedLock;
|
||||
ReadLockDescriptor sharedLockOnWhite;
|
||||
bool wasPlaceholder;
|
||||
};
|
||||
|
||||
|
|
|
@ -1460,6 +1460,8 @@ CompositorOGL::EndFrame()
|
|||
|
||||
MOZ_ASSERT(mCurrentRenderTarget == mWindowRenderTarget, "Rendering target not properly restored");
|
||||
|
||||
Compositor::EndFrame();
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (gfxEnv::DumpCompositorTextures()) {
|
||||
LayoutDeviceIntSize size;
|
||||
|
|
|
@ -259,6 +259,7 @@ GrallocTextureHostOGL::GetAsSurface() {
|
|||
void
|
||||
GrallocTextureHostOGL::UnbindTextureSource()
|
||||
{
|
||||
TextureHost::UnbindTextureSource();
|
||||
// Clear the reference to the TextureSource (if any), because we know that
|
||||
// another TextureHost is being bound to the TextureSource. This means that
|
||||
// we will have to re-do gl->fEGLImageTargetTexture2D next time we go through
|
||||
|
|
|
@ -30,6 +30,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual void DeallocateSharedData() override;
|
||||
|
||||
virtual void ForgetSharedData() override;
|
||||
|
|
|
@ -73,6 +73,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
|
|
@ -298,6 +298,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
@ -393,6 +395,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
@ -489,6 +493,8 @@ public:
|
|||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче