Bug 1027601 - Create and allocate TextureClients in a single step in some cases. r=sotaro

This commit is contained in:
Nicolas Silva
2014-07-09 11:59:49 +02:00
parent d2b3407dac
commit 2b5d60e4a8
11 changed files with 129 additions and 69 deletions

View File

@@ -637,15 +637,14 @@ CairoImage::GetTextureClient(CompositableClient *aClient)
// gfx::BackendType::NONE means default to content backend
textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
TextureFlags::DEFAULT,
surface->GetSize(),
gfx::BackendType::NONE,
surface->GetSize());
TextureFlags::DEFAULT);
if (!textureClient) {
return nullptr;
}
MOZ_ASSERT(textureClient->CanExposeDrawTarget());
if (!textureClient->AllocateForSurface(surface->GetSize()) ||
!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
if (!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
return nullptr;
}

View File

@@ -74,6 +74,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
gfx::SurfaceFormat surfaceFormat = gfx::ImageFormatToSurfaceFormat(format);
mBuffer = CreateTextureClientForCanvas(surfaceFormat, aSize, flags, aLayer);
if (!mBuffer) {
NS_WARNING("Failed to allocate the TextureClient");
return;
}
MOZ_ASSERT(mBuffer->CanExposeDrawTarget());
mBuffer->AllocateForSurface(aSize);
@@ -118,16 +122,20 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
// We want a cairo backend here as we don't want to be copying into
// an accelerated backend and we like LockBits to work. This is currently
// the most effective way to make this work.
return CreateBufferTextureClient(aFormat, aFlags, BackendType::CAIRO);
return TextureClient::CreateForRawBufferAccess(GetForwarder(),
aFormat, aSize, BackendType::CAIRO,
mTextureInfo.mTextureFlags | aFlags);
}
gfx::BackendType backend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
#ifdef XP_WIN
return CreateTextureClientForDrawing(aFormat, aFlags, backend, aSize);
return CreateTextureClientForDrawing(aFormat, aSize, backend, aFlags);
#else
// XXX - We should use CreateTextureClientForDrawing, but we first need
// to use double buffering.
return CreateBufferTextureClient(aFormat, aFlags, backend);
return TextureClient::CreateForRawBufferAccess(GetForwarder(),
aFormat, aSize, BackendType::CAIRO,
mTextureInfo.mTextureFlags | aFlags);
#endif
}

View File

@@ -101,7 +101,8 @@ public:
}
private:
TemporaryRef<TextureClient> CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
TemporaryRef<TextureClient>
CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
TextureFlags aFlags,
ClientCanvasLayer* aLayer);

View File

@@ -191,15 +191,16 @@ CompositableClient::CreateBufferTextureClient(SurfaceFormat aFormat,
}
TemporaryRef<TextureClient>
CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat,
TextureFlags aTextureFlags,
CompositableClient::CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2DBackend,
const IntSize& aSizeHint)
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
return TextureClient::CreateTextureClientForDrawing(GetForwarder(), aFormat,
return TextureClient::CreateForDrawing(GetForwarder(),
aFormat, aSize, aMoz2DBackend,
aTextureFlags | mTextureFlags,
aMoz2DBackend,
aSizeHint);
aAllocFlags);
}
bool

View File

@@ -134,9 +134,10 @@ public:
TemporaryRef<TextureClient>
CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2DBackend,
TextureFlags aTextureFlags,
gfx::BackendType aMoz2dBackend,
const gfx::IntSize& aSizeHint);
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
virtual void SetDescriptorFromReply(TextureIdentifier aTextureId,
const SurfaceDescriptor& aDescriptor)

View File

@@ -189,34 +189,29 @@ bool
ContentClientRemoteBuffer::CreateAndAllocateTextureClient(RefPtr<TextureClient>& aClient,
TextureFlags aFlags)
{
// gfx::BackendType::NONE means fallback to the content backend
aClient = CreateTextureClientForDrawing(mSurfaceFormat,
mTextureInfo.mTextureFlags | aFlags,
gfx::BackendType::NONE,
mSize);
if (!aClient) {
return false;
}
TextureAllocationFlags flags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER;
TextureAllocationFlags allocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER;
if (aFlags & TextureFlags::ON_WHITE) {
flags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE;
allocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE;
}
if (!aClient->AllocateForSurface(mSize, flags)) {
aClient = CreateTextureClientForDrawing(mSurfaceFormat,
mTextureInfo.mTextureFlags | TextureFlags::ALLOC_FALLBACK | aFlags,
// gfx::BackendType::NONE means fallback to the content backend
aClient = CreateTextureClientForDrawing(mSurfaceFormat, mSize,
gfx::BackendType::NONE,
mSize);
mTextureInfo.mTextureFlags | aFlags,
allocFlags);
if (!aClient) {
// try with ALLOC_FALLBACK
aClient = CreateTextureClientForDrawing(mSurfaceFormat, mSize,
gfx::BackendType::NONE,
mTextureInfo.mTextureFlags
| TextureFlags::ALLOC_FALLBACK
| aFlags,
allocFlags);
}
if (!aClient) {
return false;
}
if (!aClient->AllocateForSurface(mSize, flags)) {
NS_WARNING("Could not allocate texture client");
aClient = nullptr;
return false;
}
}
NS_WARN_IF_FALSE(aClient->IsValid(), "Created an invalid texture client");
return true;

View File

@@ -276,14 +276,12 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
if (!mFrontBuffer) {
gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat()));
mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
mTextureFlags, gfx::BackendType::NONE, size);
MOZ_ASSERT(mFrontBuffer->CanExposeDrawTarget());
if (!mFrontBuffer->AllocateForSurface(size)) {
mFrontBuffer = nullptr;
mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format), size,
gfx::BackendType::NONE, mTextureFlags);
if (!mFrontBuffer) {
return false;
}
MOZ_ASSERT(mFrontBuffer->CanExposeDrawTarget());
bufferCreated = true;
}

View File

@@ -73,13 +73,13 @@ SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle)
if (gfxPrefs::ForceShmemTiles()) {
textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
mFormat, TextureFlags::IMMEDIATE_UPLOAD | TextureFlags::RECYCLE, gfx::BackendType::NONE);
} else {
textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
mFormat, TextureFlags::DEFAULT | TextureFlags::RECYCLE, gfx::BackendType::NONE, mSize);
}
if (!textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT)) {
NS_WARNING("TextureClient::AllocateForSurface failed!");
}
} else {
textureClient = TextureClient::CreateForDrawing(mSurfaceAllocator,
mFormat, mSize, gfx::BackendType::NONE, TextureFlags::DEFAULT | TextureFlags::RECYCLE);
}
RECYCLE_LOG("%s Must allocate (0 left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), textureClient.get());
}

View File

@@ -235,9 +235,9 @@ DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
}
#endif
// static
static
TemporaryRef<TextureClient>
TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
SurfaceFormat aFormat,
TextureFlags aTextureFlags,
gfx::BackendType aMoz2DBackend,
@@ -315,13 +315,54 @@ TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
// Can't do any better than a buffer texture client.
if (!result) {
result = CreateBufferTextureClient(aAllocator, aFormat, aTextureFlags, aMoz2DBackend);
result = TextureClient::CreateBufferTextureClient(aAllocator, aFormat, aTextureFlags, aMoz2DBackend);
}
MOZ_ASSERT(!result || result->CanExposeDrawTarget(), "texture cannot expose a DrawTarget?");
return result;
}
// static
TemporaryRef<TextureClient>
TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2DBackend,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
RefPtr<TextureClient> texture =
CreateTextureClientForDrawing(aAllocator, aFormat,
aTextureFlags, aMoz2DBackend,
aSize);
if (texture) {
if (!texture->AllocateForSurface(aSize, aAllocFlags)) {
return nullptr;
}
}
return texture;
}
// static
TemporaryRef<BufferTextureClient>
TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2DBackend,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
RefPtr<BufferTextureClient> texture =
CreateBufferTextureClient(aAllocator, aFormat,
aTextureFlags, aMoz2DBackend);
if (texture) {
if (!texture->AllocateForSurface(aSize, aAllocFlags)) {
return nullptr;
}
}
return texture;
}
// static
TemporaryRef<BufferTextureClient>
TextureClient::CreateBufferTextureClient(ISurfaceAllocator* aAllocator,

View File

@@ -120,18 +120,34 @@ public:
TextureClient(TextureFlags aFlags = TextureFlags::DEFAULT);
virtual ~TextureClient();
// Creates a TextureClient that can be accessed through a raw pointer.
// XXX - this doesn't allocate the texture data.
// Prefer CreateForRawBufferAccess which returns a BufferTextureClient
// only if allocation suceeded.
static TemporaryRef<BufferTextureClient>
CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags,
gfx::BackendType aMoz2dBackend);
// Creates and allocates a TextureClient usable with Moz2D.
static TemporaryRef<TextureClient>
CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
CreateForDrawing(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags,
gfx::IntSize aSize,
gfx::BackendType aMoz2dBackend,
const gfx::IntSize& aSizeHint);
TextureFlags aTextureFlags,
TextureAllocationFlags flags = ALLOC_DEFAULT);
// Creates and allocates a BufferTextureClient (can beaccessed through raw
// pointers).
static TemporaryRef<BufferTextureClient>
CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2dBackend,
TextureFlags aTextureFlags,
TextureAllocationFlags flags = ALLOC_DEFAULT);
virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }

View File

@@ -58,11 +58,11 @@ TextureClientPool::GetTextureClient()
// gfx::BackendType::NONE means use the content backend
textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
mFormat, TextureFlags::IMMEDIATE_UPLOAD, gfx::BackendType::NONE);
} else {
textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
mFormat, TextureFlags::IMMEDIATE_UPLOAD, gfx::BackendType::NONE, mSize);
}
textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT);
} else {
textureClient = TextureClient::CreateForDrawing(mSurfaceAllocator,
mFormat, mSize, gfx::BackendType::NONE, TextureFlags::IMMEDIATE_UPLOAD);
}
return textureClient;
}