Bug 1281780 - Forward ShadowLayerForwarder texture-related methods to CompositorBridgeChild. r=gw280

This commit is contained in:
Nicolas Silva 2016-06-29 11:18:30 +02:00
parent 6a5154d31f
commit 93024c0a86
17 changed files with 156 additions and 81 deletions

View File

@ -19,7 +19,7 @@ namespace layers {
class D3D11RecycleAllocator : public TextureClientRecycleAllocator
{
public:
explicit D3D11RecycleAllocator(TextureForwarder* aAllocator,
explicit D3D11RecycleAllocator(CompositableForwarder* aAllocator,
ID3D11Device* aDevice)
: TextureClientRecycleAllocator(aAllocator)
, mDevice(aDevice)

View File

@ -19,7 +19,7 @@ class TextureClient;
class D3D9RecycleAllocator : public TextureClientRecycleAllocator
{
public:
explicit D3D9RecycleAllocator(TextureForwarder* aAllocator,
explicit D3D9RecycleAllocator(CompositableForwarder* aAllocator,
IDirect3DDevice9* aDevice)
: TextureClientRecycleAllocator(aAllocator)
, mDevice(aDevice)

View File

@ -11,6 +11,7 @@
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "mozilla/layers/PCompositableChild.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h"
#ifdef XP_WIN
#include "gfxWindowsPlatform.h" // for gfxWindowsPlatform
#include "mozilla/layers/TextureD3D11.h"

View File

@ -16,7 +16,6 @@
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayersTypes.h" // for LayersBackend, TextureDumpMode
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/layers/TextureClientRecycleAllocator.h" // for TextureClientRecycleAllocator
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
namespace mozilla {
@ -28,6 +27,7 @@ class ImageContainer;
class CompositableForwarder;
class CompositableChild;
class PCompositableChild;
class TextureClientRecycleAllocator;
/**
* Handle RemoveTextureFromCompositableAsync() transaction.

View File

@ -103,7 +103,7 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild)
TextureChild()
: mForwarder(nullptr)
: mCompositableForwarder(nullptr)
, mTextureForwarder(nullptr)
, mTextureClient(nullptr)
, mTextureData(nullptr)
@ -115,18 +115,15 @@ public:
bool Recv__delete__() override { return true; }
CompositableForwarder* GetForwarder() { return mForwarder; }
TextureForwarder* GetTextureForwarder() { return mTextureForwarder; }
ClientIPCAllocator* GetAllocator() { return mTextureForwarder; }
void ActorDestroy(ActorDestroyReason why) override;
bool IPCOpen() const { return mIPCOpen; }
void Lock() const { if (mForwarder->UsesImageBridge()) { mLock.Enter(); } }
void Lock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Enter(); } }
void Unlock() const { if (mForwarder->UsesImageBridge()) { mLock.Leave(); } }
void Unlock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Leave(); } }
private:
@ -210,7 +207,7 @@ private:
// in the texture's producer thread to avoid deadlocks.
mutable gfx::CriticalSection mLock;
RefPtr<CompositableForwarder> mForwarder;
RefPtr<CompositableForwarder> mCompositableForwarder;
RefPtr<TextureForwarder> mTextureForwarder;
TextureClient* mTextureClient;
@ -350,13 +347,13 @@ DeallocateTextureClient(TextureDeallocParams params)
if (params.syncDeallocation) {
MOZ_PERFORMANCE_WARNING("gfx",
"TextureClient/Host pair requires synchronous deallocation");
actor->DestroySynchronously(actor->GetForwarder());
actor->DestroySynchronously(actor->mCompositableForwarder);
DestroyTextureData(params.data, params.allocator, params.clientDeallocation,
actor->mMainThreadOnly);
} else {
actor->mTextureData = params.data;
actor->mOwnsTextureData = params.clientDeallocation;
actor->Destroy(actor->GetForwarder());
actor->Destroy(actor->mCompositableForwarder);
// DestroyTextureData will be called by TextureChild::ActorDestroy
}
}
@ -869,8 +866,23 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
{
MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
if (mActor && !mActor->mDestroyed) {
if (mActor->GetForwarder() != aForwarder) {
mActor->mForwarder = aForwarder;
CompositableForwarder* currentFwd = mActor->mCompositableForwarder;
TextureForwarder* currentTexFwd = mActor->mTextureForwarder;
if (currentFwd != aForwarder) {
// It's a bit iffy but right now ShadowLayerForwarder inherits TextureForwarder
// even though it should not. ShadowLayerForwarder::AsTextureForwarder actually
// returns a pointer to the CompositorBridgeChild.
// It's Ok for a texture to move from a ShadowLayerForwarder to another, but
// not form a CompositorBridgeChild to another (they use different channels).
if (currentTexFwd && currentTexFwd != aForwarder->AsTextureForwarder()) {
gfxCriticalError() << "Attempt to move a texture to a different channel.";
return false;
}
if (currentFwd && currentFwd->GetCompositorBackendType() != aForwarder->GetCompositorBackendType()) {
gfxCriticalError() << "Attempt to move a texture to different compositor backend.";
return false;
}
mActor->mCompositableForwarder = aForwarder;
}
return true;
}
@ -886,7 +898,8 @@ TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
GetFlags(),
mSerial));
MOZ_ASSERT(mActor);
mActor->mForwarder = aForwarder;
mActor->mCompositableForwarder = aForwarder;
mActor->mTextureForwarder = aForwarder->AsTextureForwarder();
mActor->mTextureClient = this;
mActor->mMainThreadOnly = !!(mFlags & TextureFlags::DEALLOCATE_MAIN_THREAD);
@ -921,13 +934,42 @@ BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSel
// static
already_AddRefed<TextureClient>
TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
LayersBackend layersBackend = aAllocator->GetCompositorBackendType();
return TextureClient::CreateForDrawing(aAllocator->AsTextureForwarder(),
aFormat, aSize,
layersBackend,
aSelector,
aTextureFlags,
aAllocFlags);
}
// static
already_AddRefed<TextureClient>
TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
LayersBackend aLayersBackend,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
// What we want here is the "real" TextureForwarder. ShadowLayerForwarder,
// while inheriting TextureForwarder, actually forwards all of its TF methods
// to CompositorBridgeChild. In order to avoid odd situations where some
// textures point to a ShadowLayerForwarder and some point directly to the
// CompositorBridgeChild, we just get the actual TextureForwarder which is
// returned by AsTextureForwarder...
aAllocator = aAllocator->AsTextureForwarder();
gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(aLayersBackend, aSelector);
// also test the validity of aAllocator
MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
if (!aAllocator || !aAllocator->IPCOpen()) {
@ -938,9 +980,6 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
return nullptr;
}
LayersBackend parentBackend = aAllocator->GetCompositorBackendType();
gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(parentBackend, aSelector);
TextureData* data = nullptr;
#if defined(XP_WIN)
@ -948,7 +987,7 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
#endif
#ifdef XP_WIN
if (parentBackend == LayersBackend::LAYERS_D3D11 &&
if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
(moz2DBackend == gfx::BackendType::DIRECT2D ||
moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
(!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
@ -958,7 +997,7 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
{
data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
}
if (parentBackend == LayersBackend::LAYERS_D3D9 &&
if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
moz2DBackend == gfx::BackendType::CAIRO &&
aAllocator->IsSameProcess() &&
aSize.width <= maxTextureSize &&
@ -979,14 +1018,14 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
gfxSurfaceType type =
gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
if (!data && parentBackend == LayersBackend::LAYERS_BASIC &&
if (!data && aLayersBackend == LayersBackend::LAYERS_BASIC &&
moz2DBackend == gfx::BackendType::CAIRO &&
type == gfxSurfaceType::Xlib)
{
data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
}
#ifdef GL_PROVIDER_GLX
if (!data && parentBackend == LayersBackend::LAYERS_OPENGL &&
if (!data && aLayersBackend == LayersBackend::LAYERS_OPENGL &&
type == gfxSurfaceType::Xlib &&
aFormat != SurfaceFormat::A8 &&
gl::sGLXLibrary.UseTextureFromPixmap())

View File

@ -338,6 +338,16 @@ public:
// Creates and allocates a TextureClient usable with Moz2D.
static already_AddRefed<TextureClient>
CreateForDrawing(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
LayersBackend aLayersBackend,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
// TODO: remove this one and use the one above instead.
static already_AddRefed<TextureClient>
CreateForDrawing(CompositableForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
BackendSelector aSelector,

View File

@ -25,15 +25,17 @@ ShrinkCallback(nsITimer *aTimer, void *aClosure)
static_cast<TextureClientPool*>(aClosure)->ShrinkToMinimumSize();
}
TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat,
TextureFlags aFlags,
TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
TextureFlags aFlags,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
TextureForwarder* aAllocator)
: mFormat(aFormat)
, mFlags(aFlags)
: mBackend(aLayersBackend)
, mFormat(aFormat)
, mSize(aSize)
, mFlags(aFlags)
, mMaxTextureClients(aMaxTextureClients)
, mShrinkTimeoutMsec(aShrinkTimeoutMsec)
, mOutstandingClients(0)
@ -115,7 +117,7 @@ TextureClientPool::GetTextureClient()
mFlags, ALLOC_DEFAULT);
} else {
textureClient = TextureClient::CreateForDrawing(mSurfaceAllocator,
mFormat, mSize, BackendSelector::Content, mFlags);
mFormat, mSize, mBackend, BackendSelector::Content, mFlags);
}
mOutstandingClients++;

View File

@ -44,9 +44,10 @@ class TextureClientPool final : public TextureClientAllocator
~TextureClientPool();
public:
TextureClientPool(gfx::SurfaceFormat aFormat,
TextureFlags aFlags,
TextureClientPool(LayersBackend aBackend,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
TextureFlags aFlags,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
TextureForwarder* aAllocator);
@ -104,6 +105,7 @@ public:
*/
void Clear();
LayersBackend GetBackend() const { return mBackend; }
gfx::SurfaceFormat GetFormat() { return mFormat; }
TextureFlags GetFlags() const { return mFlags; }
@ -119,15 +121,18 @@ private:
// shrinking).
static const uint32_t sMinCacheSize = 0;
/// Backend passed to the TextureClient for buffer creation.
LayersBackend mBackend;
/// Format is passed to the TextureClient for buffer creation.
gfx::SurfaceFormat mFormat;
/// Flags passed to the TextureClient for buffer creation.
const TextureFlags mFlags;
/// The width and height of the tiles to be used.
gfx::IntSize mSize;
/// Flags passed to the TextureClient for buffer creation.
const TextureFlags mFlags;
// The maximum number of texture clients managed by this pool that we want
// to remain active.
uint32_t mMaxTextureClients;

View File

@ -5,7 +5,7 @@
#include "gfxPlatform.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "TextureClientRecycleAllocator.h"
namespace mozilla {
@ -58,7 +58,7 @@ public:
return true;
}
already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) override
already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) override
{
return mAllocator->Allocate(mFormat,
mSize,
@ -71,7 +71,7 @@ protected:
TextureClientRecycleAllocator* mAllocator;
};
TextureClientRecycleAllocator::TextureClientRecycleAllocator(TextureForwarder* aAllocator)
TextureClientRecycleAllocator::TextureClientRecycleAllocator(CompositableForwarder* aAllocator)
: mSurfaceAllocator(aAllocator)
, mMaxPooledSize(kMaxPooledSized)
, mLock("TextureClientRecycleAllocatorImp.mLock")

View File

@ -9,7 +9,7 @@
#include <map>
#include <stack>
#include "mozilla/gfx/Types.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/RefPtr.h"
#include "TextureClient.h"
#include "mozilla/Mutex.h"
@ -47,7 +47,7 @@ public:
, mAllocationFlags(aAllocationFlags)
{}
virtual already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) = 0;
virtual already_AddRefed<TextureClient> Allocate(CompositableForwarder* aAllocator) = 0;
virtual bool IsCompatible(TextureClient* aTextureClient) = 0;
const gfx::SurfaceFormat mFormat;
@ -72,7 +72,7 @@ protected:
virtual ~TextureClientRecycleAllocator();
public:
explicit TextureClientRecycleAllocator(TextureForwarder* aAllocator);
explicit TextureClientRecycleAllocator(CompositableForwarder* aAllocator);
void SetMaxPoolSize(uint32_t aMax);
@ -97,7 +97,7 @@ protected:
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags);
RefPtr<TextureForwarder> mSurfaceAllocator;
RefPtr<CompositableForwarder> mSurfaceAllocator;
friend class DefaultTextureClientAllocationHelper;
void RecycleTextureClient(TextureClient* aClient) override;

View File

@ -1100,6 +1100,7 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
if (aTile.IsPlaceholderTile()) {
aTile.SetLayerManager(mManager);
aTile.SetTextureAllocator(mManager->GetCompositorBridgeChild()->GetTexturePool(
mManager->GetCompositorBackendType(),
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content),
TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD));
}

View File

@ -139,7 +139,39 @@ public:
virtual CompositableForwarder* AsCompositableForwarder() override { return this; }
virtual int32_t GetMaxTextureSize() const override
{
return mTextureFactoryIdentifier.mMaxTextureSize;
}
/**
* Returns the type of backend that is used off the main thread.
* We only don't allow changing the backend type at runtime so this value can
* be queried once and will not change until Gecko is restarted.
*/
LayersBackend GetCompositorBackendType() const
{
return mTextureFactoryIdentifier.mParentBackend;
}
bool SupportsTextureBlitting() const
{
return mTextureFactoryIdentifier.mSupportsTextureBlitting;
}
bool SupportsPartialUploads() const
{
return mTextureFactoryIdentifier.mSupportsPartialUploads;
}
const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
{
return mTextureFactoryIdentifier;
}
protected:
TextureFactoryIdentifier mTextureFactoryIdentifier;
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
nsTArray<RefPtr<CompositableClient>> mCompositableClientsToRemove;
RefPtr<SyncObject> mSyncObject;

View File

@ -882,19 +882,23 @@ CompositorBridgeChild::CancelWaitForRecycle(uint64_t aTextureId)
}
TextureClientPool*
CompositorBridgeChild::GetTexturePool(SurfaceFormat aFormat, TextureFlags aFlags)
CompositorBridgeChild::GetTexturePool(LayersBackend aBackend,
SurfaceFormat aFormat,
TextureFlags aFlags)
{
for (size_t i = 0; i < mTexturePools.Length(); i++) {
if (mTexturePools[i]->GetFormat() == aFormat &&
if (mTexturePools[i]->GetBackend() == aBackend &&
mTexturePools[i]->GetFormat() == aFormat &&
mTexturePools[i]->GetFlags() == aFlags) {
return mTexturePools[i];
}
}
mTexturePools.AppendElement(
new TextureClientPool(aFormat, aFlags,
new TextureClientPool(aBackend, aFormat,
IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
gfxPlatform::GetPlatform()->GetTileHeight()),
aFlags,
gfxPrefs::LayersTileMaxPoolSize(),
gfxPrefs::LayersTileShrinkPoolTimeout(),
this));

View File

@ -174,7 +174,9 @@ public:
virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
TextureClientPool* GetTexturePool(gfx::SurfaceFormat aFormat, TextureFlags aFlags);
TextureClientPool* GetTexturePool(LayersBackend aBackend,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags);
void ClearTexturePool();
void HandleMemoryPressure();

View File

@ -795,7 +795,7 @@ ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize,
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocUnsafeShmem(aSize, aShmType, aShmem);
return GetCompositorBridgeChild()->AllocUnsafeShmem(aSize, aShmType, aShmem);
}
bool
@ -809,7 +809,7 @@ ShadowLayerForwarder::AllocShmem(size_t aSize,
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocShmem(aSize, aShmType, aShmem);
return GetCompositorBridgeChild()->AllocShmem(aSize, aShmType, aShmem);
}
void
@ -817,7 +817,7 @@ ShadowLayerForwarder::DeallocShmem(ipc::Shmem& aShmem)
{
MOZ_ASSERT(HasShadowManager(), "no shadow manager");
if (HasShadowManager() && mShadowManager->IPCOpen()) {
mShadowManager->DeallocShmem(aShmem);
GetCompositorBridgeChild()->DeallocShmem(aShmem);
}
}
@ -1117,9 +1117,15 @@ ShadowLayerForwarder::GetCompositorBridgeChild()
if (mCompositorBridgeChild) {
return mCompositorBridgeChild;
}
mCompositorBridgeChild = mClientLayerManager->GetCompositorBridgeChild();
mCompositorBridgeChild = static_cast<CompositorBridgeChild*>(mShadowManager->Manager());
return mCompositorBridgeChild;
}
TextureForwarder*
ShadowLayerForwarder::AsTextureForwarder()
{
return GetCompositorBridgeChild();
}
} // namespace layers
} // namespace mozilla

View File

@ -129,6 +129,12 @@ public:
virtual ShadowLayerForwarder* AsLayerForwarder() override { return this; }
// TODO: confusingly, this returns a pointer to the CompositorBridgeChild.
// Right now ShadowLayerForwarder inherits TextureForwarder but it would
// probably be best if it didn't, since it forwards all of the relevent
// methods to CompositorBridgeChild.
virtual TextureForwarder* AsTextureForwarder() override;
virtual LegacySurfaceDescriptorAllocator*
AsLegacySurfaceDescriptorAllocator() override { return this; }

View File

@ -38,41 +38,8 @@ public:
virtual TextureForwarder* AsTextureForwarder() override { return this; }
virtual int32_t GetMaxTextureSize() const override
{
return mTextureFactoryIdentifier.mMaxTextureSize;
}
/**
* Returns the type of backend that is used off the main thread.
* We only don't allow changing the backend type at runtime so this value can
* be queried once and will not change until Gecko is restarted.
*/
LayersBackend GetCompositorBackendType() const
{
return mTextureFactoryIdentifier.mParentBackend;
}
bool SupportsTextureBlitting() const
{
return mTextureFactoryIdentifier.mSupportsTextureBlitting;
}
bool SupportsPartialUploads() const
{
return mTextureFactoryIdentifier.mSupportsPartialUploads;
}
const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const
{
return mTextureFactoryIdentifier;
}
virtual FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator();
protected:
TextureFactoryIdentifier mTextureFactoryIdentifier;
private:
FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
};