diff options
author | rosca@adobe.com <rosca@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 09:55:48 +0000 |
---|---|---|
committer | rosca@adobe.com <rosca@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 09:55:48 +0000 |
commit | e56f261b227e7963bb40369ee3c3ca25e20f074f (patch) | |
tree | 5169acdb2c7679571f047f72fb7b5c3b93226150 /cc | |
parent | 7ce884a98758ea78ebc8a56dbbbcced86587a2ad (diff) | |
download | chromium_src-e56f261b227e7963bb40369ee3c3ca25e20f074f.zip chromium_src-e56f261b227e7963bb40369ee3c3ca25e20f074f.tar.gz chromium_src-e56f261b227e7963bb40369ee3c3ca25e20f074f.tar.bz2 |
ResourceProvider should be able to avoid allocating immutable textures.
copyTexImage2D will fail when called on a texture having immutable
storage, allocated using texStorage2DEXT.
I encountered this problem while working on mix-blend-mode in cc:
http://crrev.com/23455060#msg51.
This problem is valid for background filters as well. Background filters
unittests pass because the test framework uses mesa, which does not
support texture storage. I couldn't create cc_unittests for the same
reason.
Texture storage currently is supported on windows using angle by
default.
BUG=243223
Review URL: https://codereview.chromium.org/79603002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236482 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/output/gl_renderer.cc | 10 | ||||
-rw-r--r-- | cc/resources/resource_provider.cc | 3 | ||||
-rw-r--r-- | cc/resources/resource_provider_unittest.cc | 83 | ||||
-rw-r--r-- | cc/test/test_web_graphics_context_3d.h | 3 |
4 files changed, 95 insertions, 4 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index ea2d2b5..10014f8 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -616,9 +616,13 @@ scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters( scoped_ptr<ScopedResource> device_background_texture = ScopedResource::create(resource_provider_); - if (!device_background_texture->Allocate(window_rect.size(), - ResourceProvider::TextureUsageAny, - RGBA_8888)) { + // The TextureUsageFramebuffer hint makes ResourceProvider avoid immutable + // storage allocation (texStorage2DEXT) for this texture. copyTexImage2D fails + // when called on a texture having immutable storage. + if (!device_background_texture->Allocate( + window_rect.size(), + ResourceProvider::TextureUsageFramebuffer, + RGBA_8888)) { return scoped_ptr<ScopedResource>(); } else { ResourceProvider::ScopedWriteLockGL lock(resource_provider_, diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index a6c59cc..c0d56ef 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -1692,7 +1692,8 @@ void ResourceProvider::LazyAllocate(Resource* resource) { DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D)); ResourceFormat format = resource->format; GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->gl_id)); - if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format)) { + if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format) && + resource->hint != TextureUsageFramebuffer) { GLenum storage_format = TextureToStorageFormat(format); GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 33cfa5c..5bf9fc9 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -2375,6 +2375,12 @@ class AllocationTrackingContext3D : public TestWebGraphicsContext3D { MOCK_METHOD0(NextTextureId, WebGLId()); MOCK_METHOD1(RetireTextureId, void(WebGLId id)); MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture)); + MOCK_METHOD5(texStorage2DEXT, + void(WGC3Denum target, + WGC3Dint levels, + WGC3Duint internalformat, + WGC3Dint width, + WGC3Dint height)); MOCK_METHOD9(texImage2D, void(WGC3Denum target, WGC3Dint level, @@ -2515,6 +2521,83 @@ TEST_P(ResourceProviderTest, TextureAllocation) { Mock::VerifyAndClearExpectations(context); } +TEST_P(ResourceProviderTest, TextureAllocationStorageUsageAny) { + // Only for GL textures. + if (GetParam() != ResourceProvider::GLTexture) + return; + scoped_ptr<AllocationTrackingContext3D> context_owned( + new StrictMock<AllocationTrackingContext3D>); + AllocationTrackingContext3D* context = context_owned.get(); + context->set_support_texture_storage(true); + + FakeOutputSurfaceClient output_surface_client; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( + context_owned.PassAs<TestWebGraphicsContext3D>())); + CHECK(output_surface->BindToClient(&output_surface_client)); + + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), NULL, 0, false, 1)); + + gfx::Size size(2, 2); + ResourceFormat format = RGBA_8888; + ResourceProvider::ResourceId id = 0; + int texture_id = 123; + + // Lazy allocation. Don't allocate when creating the resource. + id = resource_provider->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + + EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); + EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); + EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2)).Times(1); + resource_provider->AllocateForTesting(id); + + EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1); + resource_provider->DeleteResource(id); + + Mock::VerifyAndClearExpectations(context); +} + +TEST_P(ResourceProviderTest, TextureAllocationStorageUsageFramebuffer) { + // Only for GL textures. + if (GetParam() != ResourceProvider::GLTexture) + return; + scoped_ptr<AllocationTrackingContext3D> context_owned( + new StrictMock<AllocationTrackingContext3D>); + AllocationTrackingContext3D* context = context_owned.get(); + context->set_support_texture_storage(true); + + FakeOutputSurfaceClient output_surface_client; + scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( + context_owned.PassAs<TestWebGraphicsContext3D>())); + CHECK(output_surface->BindToClient(&output_surface_client)); + + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), NULL, 0, false, 1)); + + gfx::Size size(2, 2); + ResourceFormat format = RGBA_8888; + ResourceProvider::ResourceId id = 0; + int texture_id = 123; + + // Lazy allocation. Don't allocate when creating the resource. + id = resource_provider->CreateResource( + size, + GL_CLAMP_TO_EDGE, + ResourceProvider::TextureUsageFramebuffer, + format); + + EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); + EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); + EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1); + resource_provider->AllocateForTesting(id); + + EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1); + resource_provider->DeleteResource(id); + + Mock::VerifyAndClearExpectations(context); +} + TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { if (GetParam() != ResourceProvider::GLTexture) return; diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h index 4828720..f8d17c7 100644 --- a/cc/test/test_web_graphics_context_3d.h +++ b/cc/test/test_web_graphics_context_3d.h @@ -213,6 +213,9 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { void set_support_compressed_texture_etc1(bool support) { test_capabilities_.texture_format_etc1 = support; } + void set_support_texture_storage(bool support) { + test_capabilities_.texture_storage = support; + } // When this context is lost, all contexts in its share group are also lost. void add_share_group_context(blink::WebGraphicsContext3D* context3d) { |