From cd2052eec1aa51b21c3ba7fa02f2c357b0c25447 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 10 Jul 2014 13:45:40 +0200 Subject: [PATCH] Bug 1027601 - Create and allocate TextureClient in a single step in some of the cases. r=sotaro --- gfx/layers/ImageContainer.cpp | 7 +-- gfx/layers/client/CanvasClient.cpp | 15 +++-- gfx/layers/client/CanvasClient.h | 9 +-- gfx/layers/client/CompositableClient.cpp | 15 ++--- gfx/layers/client/CompositableClient.h | 5 +- gfx/layers/client/ContentClient.cpp | 41 ++++++-------- gfx/layers/client/ImageClient.cpp | 10 ++-- gfx/layers/client/SimpleTextureClientPool.cpp | 10 ++-- gfx/layers/client/TextureClient.cpp | 55 ++++++++++++++++--- gfx/layers/client/TextureClient.h | 26 +++++++-- gfx/layers/client/TextureClientPool.cpp | 6 +- 11 files changed, 129 insertions(+), 70 deletions(-) diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index b5ac61414da..90f034b0d78 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -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; } diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 7d268050638..d6e30178b64 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -74,8 +74,11 @@ 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); bufferCreated = true; } @@ -118,16 +121,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, backend, + mTextureInfo.mTextureFlags | aFlags); #endif } diff --git a/gfx/layers/client/CanvasClient.h b/gfx/layers/client/CanvasClient.h index a2d7f5776b6..539758dbb51 100644 --- a/gfx/layers/client/CanvasClient.h +++ b/gfx/layers/client/CanvasClient.h @@ -101,10 +101,11 @@ public: } private: - TemporaryRef CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat, - gfx::IntSize aSize, - TextureFlags aFlags, - ClientCanvasLayer* aLayer); + TemporaryRef + CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat, + gfx::IntSize aSize, + TextureFlags aFlags, + ClientCanvasLayer* aLayer); RefPtr mBuffer; }; diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 2d3e17e6840..9a7793f77a5 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -191,15 +191,16 @@ CompositableClient::CreateBufferTextureClient(SurfaceFormat aFormat, } TemporaryRef -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, - aTextureFlags | mTextureFlags, - aMoz2DBackend, - aSizeHint); + return TextureClient::CreateForDrawing(GetForwarder(), + aFormat, aSize, aMoz2DBackend, + aTextureFlags | mTextureFlags, + aAllocFlags); } bool diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 6db2ad9e235..dacf9754797 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -134,9 +134,10 @@ public: TemporaryRef 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) diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index cf34aae7e75..1f450eb091c 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -189,35 +189,30 @@ bool ContentClientRemoteBuffer::CreateAndAllocateTextureClient(RefPtr& aClient, TextureFlags aFlags) { + TextureAllocationFlags allocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER; + if (aFlags & TextureFlags::ON_WHITE) { + allocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE; + } + // gfx::BackendType::NONE means fallback to the content backend - aClient = CreateTextureClientForDrawing(mSurfaceFormat, - mTextureInfo.mTextureFlags | aFlags, + 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; } - TextureAllocationFlags flags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER; - if (aFlags & TextureFlags::ON_WHITE) { - flags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE; - } - - if (!aClient->AllocateForSurface(mSize, flags)) { - aClient = CreateTextureClientForDrawing(mSurfaceFormat, - mTextureInfo.mTextureFlags | TextureFlags::ALLOC_FALLBACK | aFlags, - gfx::BackendType::NONE, - mSize); - 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; } diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 3834a2a26e2..36ebf362441 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -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; } diff --git a/gfx/layers/client/SimpleTextureClientPool.cpp b/gfx/layers/client/SimpleTextureClientPool.cpp index 2b82c1675a4..7c982491d5b 100644 --- a/gfx/layers/client/SimpleTextureClientPool.cpp +++ b/gfx/layers/client/SimpleTextureClientPool.cpp @@ -72,12 +72,12 @@ SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle) if (gfxPrefs::ForceShmemTiles()) { textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TextureFlags::IMMEDIATE_UPLOAD | TextureFlags::RECYCLE, gfx::BackendType::NONE); + if (!textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT)) { + NS_WARNING("TextureClient::AllocateForSurface failed!"); + } } 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!"); + 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()); } diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index cf5a96468b9..667e2a0586a 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -235,13 +235,13 @@ DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint) } #endif -// static +static TemporaryRef -TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, - SurfaceFormat aFormat, - TextureFlags aTextureFlags, - gfx::BackendType aMoz2DBackend, - const gfx::IntSize& aSizeHint) +CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, + SurfaceFormat aFormat, + TextureFlags aTextureFlags, + gfx::BackendType aMoz2DBackend, + const gfx::IntSize& aSizeHint) { if (aMoz2DBackend == gfx::BackendType::NONE) { aMoz2DBackend = gfxPlatform::GetPlatform()->GetContentBackend(); @@ -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::CreateForDrawing(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + gfx::IntSize aSize, + gfx::BackendType aMoz2DBackend, + TextureFlags aTextureFlags, + TextureAllocationFlags aAllocFlags) +{ + RefPtr texture = + CreateTextureClientForDrawing(aAllocator, aFormat, + aTextureFlags, aMoz2DBackend, + aSize); + if (texture) { + if (!texture->AllocateForSurface(aSize, aAllocFlags)) { + return nullptr; + } + } + return texture; +} + +// static +TemporaryRef +TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + gfx::IntSize aSize, + gfx::BackendType aMoz2DBackend, + TextureFlags aTextureFlags, + TextureAllocationFlags aAllocFlags) +{ + RefPtr texture = + CreateBufferTextureClient(aAllocator, aFormat, + aTextureFlags, aMoz2DBackend); + if (texture) { + if (!texture->AllocateForSurface(aSize, aAllocFlags)) { + return nullptr; + } + } + return texture; +} + // static TemporaryRef TextureClient::CreateBufferTextureClient(ISurfaceAllocator* aAllocator, diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 14f16236c96..34b49045245 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -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 CreateBufferTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat, TextureFlags aTextureFlags, gfx::BackendType aMoz2dBackend); + // Creates and allocates a TextureClient usable with Moz2D. static TemporaryRef - CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, - gfx::SurfaceFormat aFormat, - TextureFlags aTextureFlags, - gfx::BackendType aMoz2dBackend, - const gfx::IntSize& aSizeHint); + CreateForDrawing(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + gfx::IntSize aSize, + gfx::BackendType aMoz2dBackend, + TextureFlags aTextureFlags, + TextureAllocationFlags flags = ALLOC_DEFAULT); + + // Creates and allocates a BufferTextureClient (can beaccessed through raw + // pointers). + static TemporaryRef + CreateForRawBufferAccess(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + gfx::IntSize aSize, + gfx::BackendType aMoz2dBackend, + TextureFlags aTextureFlags, + TextureAllocationFlags flags = ALLOC_DEFAULT); virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; } diff --git a/gfx/layers/client/TextureClientPool.cpp b/gfx/layers/client/TextureClientPool.cpp index b4a93f38305..85df3cd0b58 100644 --- a/gfx/layers/client/TextureClientPool.cpp +++ b/gfx/layers/client/TextureClientPool.cpp @@ -57,11 +57,11 @@ TextureClientPool::GetTextureClient() // gfx::BackendType::NONE means use the content backend textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TextureFlags::IMMEDIATE_UPLOAD, gfx::BackendType::NONE); + textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT); } else { - textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, - mFormat, TextureFlags::IMMEDIATE_UPLOAD, gfx::BackendType::NONE, mSize); + textureClient = TextureClient::CreateForDrawing(mSurfaceAllocator, + mFormat, mSize, gfx::BackendType::NONE, TextureFlags::IMMEDIATE_UPLOAD); } - textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT); return textureClient; }