summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-06 19:44:37 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-06 19:44:37 +0000
commitfdc6db2930f0df90431cdcd789666281a09d286b (patch)
tree6861cda4bb59829ac7eb219e827944f3d6a4837f /cc
parenta8e8af9e020e5bc84b4a745c96d2b739943dd503 (diff)
downloadchromium_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.cc57
-rw-r--r--cc/layers/io_surface_layer_impl.h3
-rw-r--r--cc/resources/resource_provider.cc50
-rw-r--r--cc/resources/resource_provider.h7
-rw-r--r--cc/trees/layer_tree_host_unittest.cc52
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: