diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 19:44:37 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 19:44:37 +0000 |
commit | fdc6db2930f0df90431cdcd789666281a09d286b (patch) | |
tree | 6861cda4bb59829ac7eb219e827944f3d6a4837f /cc | |
parent | a8e8af9e020e5bc84b4a745c96d2b739943dd503 (diff) | |
download | chromium_src-fdc6db2930f0df90431cdcd789666281a09d286b.zip chromium_src-fdc6db2930f0df90431cdcd789666281a09d286b.tar.gz chromium_src-fdc6db2930f0df90431cdcd789666281a09d286b.tar.bz2 |
cc: Make IOSurfaces transportable.
IOSurfaceLayerImpl is the last client of CreateResourceFromExternalTexture(),
which creates resources that aren't transportable.
Introduce CreateResourceFromIOSurface which creates a (transportable) resource
out of an IOSurface, managing the GL texture.
Remove CreateResourceFromExternalTexture.
Update assertions and deletion logic since now "External" resources now are
always mailbox-backed.
BUG=239335
Review URL: https://codereview.chromium.org/265833010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268588 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/io_surface_layer_impl.cc | 57 | ||||
-rw-r--r-- | cc/layers/io_surface_layer_impl.h | 3 | ||||
-rw-r--r-- | cc/resources/resource_provider.cc | 50 | ||||
-rw-r--r-- | cc/resources/resource_provider.h | 7 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 52 |
5 files changed, 71 insertions, 98 deletions
diff --git a/cc/layers/io_surface_layer_impl.cc b/cc/layers/io_surface_layer_impl.cc index c40e05e..4176c26 100644 --- a/cc/layers/io_surface_layer_impl.cc +++ b/cc/layers/io_surface_layer_impl.cc @@ -21,32 +21,19 @@ IOSurfaceLayerImpl::IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), io_surface_id_(0), io_surface_changed_(false), - io_surface_texture_id_(0), io_surface_resource_id_(0) {} IOSurfaceLayerImpl::~IOSurfaceLayerImpl() { - if (!io_surface_texture_id_) - return; - - DestroyTexture(); + DestroyResource(); } -void IOSurfaceLayerImpl::DestroyTexture() { +void IOSurfaceLayerImpl::DestroyResource() { if (io_surface_resource_id_) { ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); resource_provider->DeleteResource(io_surface_resource_id_); io_surface_resource_id_ = 0; } - - if (io_surface_texture_id_) { - ContextProvider* context_provider = - layer_tree_impl()->output_surface()->context_provider().get(); - // TODO(skaslev): Implement this path for software compositing. - if (context_provider) - context_provider->ContextGL()->DeleteTextures(1, &io_surface_texture_id_); - io_surface_texture_id_ = 0; - } } scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl( @@ -64,41 +51,13 @@ void IOSurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) { bool IOSurfaceLayerImpl::WillDraw(DrawMode draw_mode, ResourceProvider* resource_provider) { - if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) + if (draw_mode != DRAW_MODE_HARDWARE) return false; if (io_surface_changed_) { - ContextProvider* context_provider = - layer_tree_impl()->output_surface()->context_provider().get(); - if (!context_provider) { - // TODO(skaslev): Implement this path for software compositing. - return false; - } - - gpu::gles2::GLES2Interface* gl = context_provider->ContextGL(); - - // TODO(ernstm): Do this in a way that we can track memory usage. - if (!io_surface_texture_id_) { - gl->GenTextures(1, &io_surface_texture_id_); - io_surface_resource_id_ = - resource_provider->CreateResourceFromExternalTexture( - GL_TEXTURE_RECTANGLE_ARB, - io_surface_texture_id_); - } - - GLC(gl, gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_texture_id_)); - gl->TexImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, - io_surface_size_.width(), - io_surface_size_.height(), - io_surface_id_, - 0); - // Do not check for error conditions. texImageIOSurface2DCHROMIUM() is - // supposed to hold on to the last good IOSurface if the new one is already - // closed. This is only a possibility during live resizing of plugins. - // However, it seems that this is not sufficient to completely guard against - // garbage being drawn. If this is found to be a significant issue, it may - // be necessary to explicitly tell the embedder when to free the surfaces it - // has allocated. + DestroyResource(); + io_surface_resource_id_ = resource_provider->CreateResourceFromIOSurface( + io_surface_size_, io_surface_id_); io_surface_changed_ = false; } @@ -130,9 +89,9 @@ void IOSurfaceLayerImpl::AppendQuads(QuadSink* quad_sink, } void IOSurfaceLayerImpl::ReleaseResources() { - // We don't have a valid texture ID in the new context; however, + // We don't have a valid resource ID in the new context; however, // the IOSurface is still valid. - DestroyTexture(); + DestroyResource(); io_surface_changed_ = true; } diff --git a/cc/layers/io_surface_layer_impl.h b/cc/layers/io_surface_layer_impl.h index efd7428..8ac9a25 100644 --- a/cc/layers/io_surface_layer_impl.h +++ b/cc/layers/io_surface_layer_impl.h @@ -37,14 +37,13 @@ class CC_EXPORT IOSurfaceLayerImpl : public LayerImpl { private: IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id); - void DestroyTexture(); + void DestroyResource(); virtual const char* LayerTypeAsString() const OVERRIDE; unsigned io_surface_id_; gfx::Size io_surface_size_; bool io_surface_changed_; - unsigned io_surface_texture_id_; unsigned io_surface_resource_id_; DISALLOW_COPY_AND_ASSIGN(IOSurfaceLayerImpl); diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index f410b7a..538e57b 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -736,34 +736,27 @@ ResourceProvider::ResourceId ResourceProvider::CreateBitmap( return id; } -ResourceProvider::ResourceId -ResourceProvider::CreateResourceFromExternalTexture( - GLuint texture_target, - GLuint texture_id) { +ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface( + const gfx::Size& size, + unsigned io_surface_id) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(texture_target); - DCHECK(texture_id); - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - GLC(gl, gl->BindTexture(texture_target, texture_id)); - GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - GLC(gl, - gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLC(gl, - gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - ResourceId id = next_id_++; - Resource resource(texture_id, + Resource resource(0, gfx::Size(), - Resource::External, - texture_target, + Resource::Internal, + GL_TEXTURE_RECTANGLE_ARB, GL_LINEAR, - 0, + GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, GL_CLAMP_TO_EDGE, TextureUsageAny, RGBA_8888); + LazyCreate(&resource); + GLES2Interface* gl = ContextGL(); + DCHECK(gl); + gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id); + gl->TexImageIOSurface2DCHROMIUM( + GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0); resource.allocated = true; resources_[id] = resource; return id; @@ -869,7 +862,8 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DCHECK(gl); GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id)); } - if (resource->mailbox.IsValid() && resource->origin == Resource::External) { + if (resource->origin == Resource::External) { + DCHECK(resource->mailbox.IsValid()); GLuint sync_point = resource->mailbox.sync_point(); if (resource->type == GLTexture) { DCHECK(resource->mailbox.IsTexture()); @@ -894,7 +888,7 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, } resource->release_callback.Run(sync_point, lost_resource); } - if (resource->gl_id && resource->origin != Resource::External) { + if (resource->gl_id) { GLES2Interface* gl = ContextGL(); DCHECK(gl); GLC(gl, gl->DeleteTextures(1, &resource->gl_id)); @@ -910,10 +904,6 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DCHECK(resource->origin == Resource::Internal); delete[] resource->pixels; } - // We should never delete the texture for a resource created by - // CreateResourceFromExternalTexture(). - DCHECK(!resource->gl_id || resource->origin == Resource::External); - resources_.erase(it); } @@ -1558,8 +1548,6 @@ void ResourceProvider::ReceiveReturnsFromParent( DCHECK(resource->gl_id); GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point)); } else { - // Because CreateResourceFromExternalTexture() never be called, - // when enabling delegated compositor. DCHECK(!resource->gl_id); resource->mailbox.set_sync_point(returned.sync_point); } @@ -1606,11 +1594,7 @@ void ResourceProvider::TransferResource(GLES2Interface* gl, Resource* source = GetResource(id); DCHECK(!source->locked_for_write); DCHECK(!source->lock_for_read_count); - // Because CreateResourceFromExternalTexture() never be called, - // when enabling delegated compositor. - DCHECK(source->origin == Resource::Internal || - source->origin == Resource::Delegated || - (source->origin == Resource::External && source->mailbox.IsValid())); + DCHECK(source->origin != Resource::External || source->mailbox.IsValid()); DCHECK(source->allocated); DCHECK_EQ(source->wrap_mode, GL_CLAMP_TO_EDGE); resource->id = id; diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index cf1bb9b..4cd9c46 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -125,10 +125,9 @@ class CC_EXPORT ResourceProvider { ResourceFormat format); ResourceId CreateBitmap(const gfx::Size& size, GLint wrap_mode); - // Wraps an external texture into a GL resource. - ResourceId CreateResourceFromExternalTexture( - unsigned texture_target, - unsigned texture_id); + // Wraps an IOSurface into a GL resource. + ResourceId CreateResourceFromIOSurface(const gfx::Size& size, + unsigned io_surface_id); // Wraps an external texture mailbox into a GL resource. ResourceId CreateResourceFromTextureMailbox( diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 1faa650..e8c629a 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -23,6 +23,8 @@ #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/output/output_surface.h" +#include "cc/quads/draw_quad.h" +#include "cc/quads/io_surface_draw_quad.h" #include "cc/resources/prioritized_resource.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/resources/resource_update_queue.h" @@ -2844,6 +2846,8 @@ class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { GLenum type, GLintptr offset)); MOCK_METHOD1(deleteTexture, void(GLenum texture)); + MOCK_METHOD2(produceTextureCHROMIUM, + void(GLenum target, const GLbyte* mailbox)); }; class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { @@ -2854,8 +2858,13 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { new MockIOSurfaceWebGraphicsContext3D); mock_context_ = mock_context_owned.get(); - return FakeOutputSurface::Create3d( - mock_context_owned.PassAs<TestWebGraphicsContext3D>()); + if (delegating_renderer()) { + return FakeOutputSurface::CreateDelegating3d( + mock_context_owned.PassAs<TestWebGraphicsContext3D>()); + } else { + return FakeOutputSurface::Create3d( + mock_context_owned.PassAs<TestWebGraphicsContext3D>()); + } } virtual void SetupTree() OVERRIDE { @@ -2870,6 +2879,7 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { io_surface_layer->SetBounds(gfx::Size(10, 10)); io_surface_layer->SetAnchorPoint(gfx::PointF()); io_surface_layer->SetIsDrawable(true); + io_surface_layer->SetContentsOpaque(true); io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_); layer_tree_host()->root_layer()->AddChild(io_surface_layer); } @@ -2877,6 +2887,7 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); // In WillDraw, the IOSurfaceLayer sets up the io surface texture. EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0); @@ -2892,6 +2903,10 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { .Times(1); EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB, + GL_TEXTURE_POOL_CHROMIUM, + GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1); + EXPECT_CALL(*mock_context_, + texParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)).Times(1); EXPECT_CALL(*mock_context_, @@ -2914,13 +2929,32 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { LayerTreeHostImpl::FrameData* frame, DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE { Mock::VerifyAndClearExpectations(&mock_context_); + ResourceProvider* resource_provider = host_impl->resource_provider(); + EXPECT_EQ(1u, resource_provider->num_resources()); + CHECK_EQ(1u, frame->render_passes.size()); + CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); + const DrawQuad* quad = frame->render_passes[0]->quad_list[0]; + CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); + const IOSurfaceDrawQuad* io_surface_draw_quad = + IOSurfaceDrawQuad::MaterialCast(quad); + EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size); + EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id); + EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), + resource_provider->TargetForTesting( + io_surface_draw_quad->io_surface_resource_id)); - // The io surface layer's texture is drawn. - EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1)) .Times(1); - EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) - .Times(AtLeast(1)); + if (delegating_renderer()) { + // The io surface layer's resource should be sent to the parent. + EXPECT_CALL(*mock_context_, + produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1); + } else { + // The io surface layer's texture is drawn. + EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1)); + EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _)) + .Times(AtLeast(1)); + } return draw_result; } @@ -2928,7 +2962,7 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { Mock::VerifyAndClearExpectations(&mock_context_); - EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1); + EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); EndTest(); } @@ -2939,9 +2973,7 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { gfx::Size io_surface_size_; }; -// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostTestIOSurfaceDrawing); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { public: |