diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index c8eceae423c2..dc93b6928dfe 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -672,7 +672,8 @@ CairoImage::GetTextureClient(CompositableClient *aClient) MOZ_ASSERT(surface); textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(), - TEXTURE_FLAGS_DEFAULT); + TEXTURE_FLAGS_DEFAULT, + surface->GetSize()); MOZ_ASSERT(textureClient->AsTextureClientDrawTarget()); if (!textureClient->AsTextureClientDrawTarget()->AllocateForSurface(surface->GetSize()) || !textureClient->Lock(OPEN_WRITE_ONLY)) { diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index aef32af1ed57..e91ae94b1cc6 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -177,10 +177,12 @@ CompositableClient::CreateBufferTextureClient(SurfaceFormat aFormat, TemporaryRef CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat, - TextureFlags aTextureFlags) + TextureFlags aTextureFlags, + const IntSize& aSizeHint) { return TextureClient::CreateTextureClientForDrawing(GetForwarder(), aFormat, - aTextureFlags | mTextureFlags); + aTextureFlags | mTextureFlags, + aSizeHint); } bool diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 6fe442274965..df2dd1dc6cb0 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -93,7 +93,8 @@ public: // always be non-null. TemporaryRef CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat, - TextureFlags aTextureFlags); + TextureFlags aTextureFlags, + const gfx::IntSize& aSizeHint); virtual void SetDescriptorFromReply(TextureIdentifier aTextureId, const SurfaceDescriptor& aDescriptor) diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 2864d55a6882..fc17b7581ad6 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -169,14 +169,16 @@ ContentClientRemoteBuffer::CreateAndAllocateTextureClient(RefPtr& TextureFlags aFlags) { aClient = CreateTextureClientForDrawing(mSurfaceFormat, - mTextureInfo.mTextureFlags | aFlags); + mTextureInfo.mTextureFlags | aFlags, + mSize); if (!aClient) { return false; } if (!aClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_CLEAR_BUFFER)) { aClient = CreateTextureClientForDrawing(mSurfaceFormat, - mTextureInfo.mTextureFlags | TEXTURE_ALLOC_FALLBACK | aFlags); + mTextureInfo.mTextureFlags | TEXTURE_ALLOC_FALLBACK | aFlags, + mSize); if (!aClient) { return false; } diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 0bd982ae92c3..9f738612a427 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -240,7 +240,7 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer, gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(gfx::ContentForFormat(surface->GetFormat())); mFrontBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format), - mTextureFlags); + mTextureFlags, size); MOZ_ASSERT(mFrontBuffer->AsTextureClientDrawTarget()); if (!mFrontBuffer->AsTextureClientDrawTarget()->AllocateForSurface(size)) { mFrontBuffer = nullptr; diff --git a/gfx/layers/client/SimpleTextureClientPool.cpp b/gfx/layers/client/SimpleTextureClientPool.cpp index 8ce93375e7a6..2fb4c56e3cd2 100644 --- a/gfx/layers/client/SimpleTextureClientPool.cpp +++ b/gfx/layers/client/SimpleTextureClientPool.cpp @@ -72,7 +72,7 @@ SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle) if (gfxPrefs::ForceShmemTiles()) { textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD | TEXTURE_RECYCLE); } else { - textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_FLAGS_DEFAULT | TEXTURE_RECYCLE); + textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_FLAGS_DEFAULT | TEXTURE_RECYCLE, mSize); } if (!textureClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_DEFAULT)) { NS_WARNING("TextureClient::AllocateForSurface failed!"); diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index a22ffb0ed543..c40fbc991ca1 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -278,7 +278,8 @@ DisableGralloc(SurfaceFormat aFormat) TemporaryRef TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, SurfaceFormat aFormat, - TextureFlags aTextureFlags) + TextureFlags aTextureFlags, + const gfx::IntSize& aSizeHint) { RefPtr result; @@ -327,7 +328,12 @@ TextureClient::CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, #ifdef MOZ_WIDGET_GONK if (!DisableGralloc(aFormat)) { - result = new GrallocTextureClientOGL(aAllocator, aFormat, aTextureFlags); + // Don't allow Gralloc texture clients to exceed the maximum texture size. + // BufferTextureClients have code to handle tiling the surface client-side. + int32_t maxTextureSize = aAllocator->GetMaxTextureSize(); + if (aSizeHint.width <= maxTextureSize && aSizeHint.height <= maxTextureSize) { + result = new GrallocTextureClientOGL(aAllocator, aFormat, aTextureFlags); + } } #endif diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 6aeddb08b40d..9b62f88e2326 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -207,7 +207,8 @@ public: static TemporaryRef CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat, - TextureFlags aTextureFlags); + TextureFlags aTextureFlags, + const gfx::IntSize& aSizeHint); virtual TextureClientSurface* AsTextureClientSurface() { return nullptr; } virtual TextureClientDrawTarget* AsTextureClientDrawTarget() { return nullptr; } diff --git a/gfx/layers/client/TextureClientPool.cpp b/gfx/layers/client/TextureClientPool.cpp index 5591cd0f1fd8..a02a82ac005c 100644 --- a/gfx/layers/client/TextureClientPool.cpp +++ b/gfx/layers/client/TextureClientPool.cpp @@ -51,7 +51,7 @@ TextureClientPool::GetTextureClient() if (gfxPrefs::ForceShmemTiles()) { textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD); } else { - textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD); + textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator, mFormat, TEXTURE_IMMEDIATE_UPLOAD, mSize); } textureClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_DEFAULT); diff --git a/gfx/layers/ipc/CompositableForwarder.h b/gfx/layers/ipc/CompositableForwarder.h index 8b0958ce02a9..26b989cd2732 100644 --- a/gfx/layers/ipc/CompositableForwarder.h +++ b/gfx/layers/ipc/CompositableForwarder.h @@ -213,10 +213,10 @@ public: void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier); - /** - * Returns the maximum texture size supported by the compositor. - */ - virtual int32_t GetMaxTextureSize() const { return mTextureFactoryIdentifier.mMaxTextureSize; } + virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE + { + return mTextureFactoryIdentifier.mMaxTextureSize; + } bool IsOnCompositorSide() const MOZ_OVERRIDE { return false; } diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h index 89547c34f1d4..1e12017c610f 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.h +++ b/gfx/layers/ipc/ISurfaceAllocator.h @@ -125,6 +125,11 @@ public: uint32_t aCaps, SurfaceDescriptor* aBuffer); + /** + * Returns the maximum texture size supported by the compositor. + */ + virtual int32_t GetMaxTextureSize() const { return INT32_MAX; } + virtual void DestroySharedSurface(SurfaceDescriptor* aSurface); // method that does the actual allocation work