diff options
Diffstat (limited to 'cc')
41 files changed, 1022 insertions, 550 deletions
@@ -360,6 +360,9 @@ 'resources/scoped_resource.h', 'resources/scoped_ui_resource.cc', 'resources/scoped_ui_resource.h', + 'resources/shared_bitmap.cc', + 'resources/shared_bitmap.h', + 'resources/shared_bitmap_manager.h', 'resources/single_release_callback.cc', 'resources/single_release_callback.h', 'resources/skpicture_content_layer_updater.cc', diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 3a7a1c1..c66eb85 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -39,7 +39,7 @@ namespace { class MockLayerTreeHost : public LayerTreeHost { public: explicit MockLayerTreeHost(LayerTreeHostClient* client) - : LayerTreeHost(client, LayerTreeSettings()) { + : LayerTreeHost(client, NULL, LayerTreeSettings()) { Initialize(NULL); } @@ -803,11 +803,12 @@ class LayerTreeHostFactory { : client_(FakeLayerTreeHostClient::DIRECT_3D) {} scoped_ptr<LayerTreeHost> Create() { - return LayerTreeHost::Create(&client_, LayerTreeSettings(), NULL).Pass(); + return LayerTreeHost::Create(&client_, NULL, LayerTreeSettings(), NULL) + .Pass(); } scoped_ptr<LayerTreeHost> Create(LayerTreeSettings settings) { - return LayerTreeHost::Create(&client_, settings, NULL).Pass(); + return LayerTreeHost::Create(&client_, NULL, settings, NULL).Pass(); } private: diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc index f616560..7213a51 100644 --- a/cc/layers/nine_patch_layer_unittest.cc +++ b/cc/layers/nine_patch_layer_unittest.cc @@ -32,7 +32,7 @@ namespace { class MockLayerTreeHost : public LayerTreeHost { public: explicit MockLayerTreeHost(LayerTreeHostClient* client) - : LayerTreeHost(client, LayerTreeSettings()) { + : LayerTreeHost(client, NULL, LayerTreeSettings()) { Initialize(NULL); } }; diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 250d610..0423cdc 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -514,7 +514,7 @@ class MockLayerTreeHost : public LayerTreeHost { public: MockLayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) - : LayerTreeHost(client, settings), + : LayerTreeHost(client, NULL, settings), next_id_(1), total_ui_resource_created_(0), total_ui_resource_deleted_(0) { diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index bdb1358..c576341 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc @@ -44,7 +44,7 @@ namespace { class MockLayerTreeHost : public LayerTreeHost { public: explicit MockLayerTreeHost(LayerTreeHostClient* client) - : LayerTreeHost(client, LayerTreeSettings()) { + : LayerTreeHost(client, NULL, LayerTreeSettings()) { Initialize(NULL); } diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc index 47d694b..9bdb907 100644 --- a/cc/layers/tiled_layer_unittest.cc +++ b/cc/layers/tiled_layer_unittest.cc @@ -60,6 +60,7 @@ class TiledLayerTest : public testing::Test { virtual void SetUp() { impl_thread_.Start(); layer_tree_host_ = LayerTreeHost::Create(&fake_layer_tree_host_client_, + NULL, settings_, impl_thread_.message_loop_proxy()); proxy_ = layer_tree_host_->proxy(); @@ -73,7 +74,7 @@ class TiledLayerTest : public testing::Test { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(proxy_); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_)); } diff --git a/cc/layers/ui_resource_layer_unittest.cc b/cc/layers/ui_resource_layer_unittest.cc index 1720b81..a2c75c1 100644 --- a/cc/layers/ui_resource_layer_unittest.cc +++ b/cc/layers/ui_resource_layer_unittest.cc @@ -32,7 +32,7 @@ namespace { class MockLayerTreeHost : public LayerTreeHost { public: explicit MockLayerTreeHost(LayerTreeHostClient* client) - : LayerTreeHost(client, LayerTreeSettings()) { + : LayerTreeHost(client, NULL, LayerTreeSettings()) { Initialize(NULL); } }; diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc index 772a16a..7d95550 100644 --- a/cc/output/delegating_renderer.cc +++ b/cc/output/delegating_renderer.cc @@ -60,7 +60,8 @@ bool DelegatingRenderer::Initialize() { capabilities_.using_offscreen_context3d = false; if (!output_surface_->context_provider()) { - // TODO(danakj): Make software compositing work. + capabilities_.using_shared_memory_resources = true; + capabilities_.using_map_image = settings_->use_map_image; return true; } diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 7f60c2d..8b71ca4 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -221,7 +221,7 @@ class GLRendererTest : public testing::Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false).Pass(); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass(); renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_, &settings_, output_surface_.get(), @@ -312,8 +312,8 @@ class GLRendererShaderTest : public testing::Test { new ShaderCreatorMockGraphicsContext())).Pass(); CHECK(output_surface_->BindToClient(&output_surface_client_)); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), 0, false).Pass(); + resource_provider_ = + ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass(); renderer_.reset(new FakeRendererGL(&renderer_client_, &settings_, output_surface_.get(), @@ -634,7 +634,7 @@ TEST(GLRendererTest2, InitializationDoesNotMakeSynchronousCalls) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -679,7 +679,7 @@ TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -714,7 +714,7 @@ TEST(GLRendererTest2, OpaqueBackground) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -752,7 +752,7 @@ TEST(GLRendererTest2, TransparentBackground) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -784,7 +784,7 @@ TEST(GLRendererTest2, OffscreenOutputSurface) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -860,7 +860,7 @@ TEST(GLRendererTest2, VisibilityChangeIsLastCall) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -920,7 +920,7 @@ TEST(GLRendererTest2, ActiveTextureState) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -1007,7 +1007,7 @@ TEST(GLRendererTest2, ShouldClearRootRenderPass) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; settings.should_clear_root_render_pass = false; @@ -1095,7 +1095,7 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -1181,7 +1181,7 @@ TEST(GLRendererTest2, NoDiscardOnPartialUpdates) { output_surface->set_fixed_size(gfx::Size(100, 100)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; settings.partial_swap_enabled = true; @@ -1360,7 +1360,7 @@ TEST(GLRendererTest2, ScissorAndViewportWithinNonreshapableSurface) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -1714,7 +1714,7 @@ class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { CHECK(output_surface_.BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(&output_surface_, 0, false).Pass(); + ResourceProvider::Create(&output_surface_, NULL, 0, false).Pass(); renderer_.reset(new FakeRendererGL( this, &settings_, &output_surface_, resource_provider_.get())); diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index f88a9ee..450d1fe 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc @@ -34,7 +34,7 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); renderer_ = SoftwareRenderer::Create( this, &settings_, output_surface_.get(), resource_provider()); } diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc index 231e378..c0d6f0d 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -66,7 +66,7 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider = - ResourceProvider::Create(output_surface.get(), 0, false); + ResourceProvider::Create(output_surface.get(), NULL, 0, false); FakePictureLayerTilingClient client; client.SetTileSize(gfx::Size(256, 256)); diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc index fb71533..21cafd1 100644 --- a/cc/resources/prioritized_resource_unittest.cc +++ b/cc/resources/prioritized_resource_unittest.cc @@ -24,7 +24,7 @@ class PrioritizedResourceTest : public testing::Test { DebugScopedSetImplThread impl_thread(&proxy_); CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - cc::ResourceProvider::Create(output_surface_.get(), 0, false); + cc::ResourceProvider::Create(output_surface_.get(), NULL, 0, false); } virtual ~PrioritizedResourceTest() { diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc index 37c9cc1..4bf27fb 100644 --- a/cc/resources/prioritized_tile_set_unittest.cc +++ b/cc/resources/prioritized_tile_set_unittest.cc @@ -57,9 +57,9 @@ class PrioritizedTileSetTest : public testing::Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false).Pass(); - tile_manager_.reset(new FakeTileManager(&tile_manager_client_, - resource_provider_.get())); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass(); + tile_manager_.reset( + new FakeTileManager(&tile_manager_client_, resource_provider_.get())); picture_pile_ = FakePicturePileImpl::CreatePile(); } diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index 61cb324..023be79 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -68,7 +68,7 @@ class RasterWorkerPoolTest : public testing::Test, CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false).Pass(); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass(); } virtual ~RasterWorkerPoolTest() { resource_provider_.reset(); diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index d76fc4b..0a214a4 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -8,6 +8,7 @@ #include <limits> #include "base/containers/hash_tables.h" +#include "base/debug/trace_event.h" #include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -15,6 +16,7 @@ #include "cc/output/gl_renderer.h" // For the GLC() macro. #include "cc/resources/platform_color.h" #include "cc/resources/returned_resource.h" +#include "cc/resources/shared_bitmap_manager.h" #include "cc/resources/transferable_resource.h" #include "cc/scheduler/texture_uploader.h" #include "gpu/GLES2/gl2extchromium.h" @@ -118,7 +120,8 @@ ResourceProvider::Resource::Resource() lost(false), hint(TextureUsageAny), type(static_cast<ResourceType>(0)), - format(RGBA_8888) {} + format(RGBA_8888), + shared_bitmap(NULL) {} ResourceProvider::Resource::~Resource() {} @@ -159,11 +162,13 @@ ResourceProvider::Resource::Resource(unsigned texture_id, lost(false), hint(hint), type(GLTexture), - format(format) { + format(format), + shared_bitmap(NULL) { DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); } ResourceProvider::Resource::Resource(uint8_t* pixels, + SharedBitmap* bitmap, gfx::Size size, GLenum filter, GLint wrap_mode) @@ -196,7 +201,8 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, lost(false), hint(TextureUsageAny), type(Bitmap), - format(RGBA_8888) { + format(RGBA_8888), + shared_bitmap(bitmap) { DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); } @@ -206,10 +212,12 @@ ResourceProvider::Child::~Child() {} scoped_ptr<ResourceProvider> ResourceProvider::Create( OutputSurface* output_surface, + SharedBitmapManager* shared_bitmap_manager, int highp_threshold_min, bool use_rgba_4444_texture_format) { scoped_ptr<ResourceProvider> resource_provider( new ResourceProvider(output_surface, + shared_bitmap_manager, highp_threshold_min, use_rgba_4444_texture_format)); @@ -311,10 +319,19 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture( ResourceProvider::ResourceId ResourceProvider::CreateBitmap(gfx::Size size) { DCHECK(thread_checker_.CalledOnValidThread()); - uint8_t* pixels = new uint8_t[4 * size.GetArea()]; + scoped_ptr<SharedBitmap> bitmap; + if (shared_bitmap_manager_) + bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size); + + uint8_t* pixels; + if (bitmap) + pixels = bitmap->pixels(); + else + pixels = new uint8_t[4 * size.GetArea()]; ResourceId id = next_id_++; - Resource resource(pixels, size, GL_LINEAR, GL_CLAMP_TO_EDGE); + Resource resource( + pixels, bitmap.release(), size, GL_LINEAR, GL_CLAMP_TO_EDGE); resource.allocated = true; resources_[id] = resource; return id; @@ -375,8 +392,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( base::SharedMemory* shared_memory = mailbox.shared_memory(); DCHECK(shared_memory->memory()); uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory()); - resource = Resource( - pixels, mailbox.shared_memory_size(), GL_LINEAR, GL_CLAMP_TO_EDGE); + scoped_ptr<SharedBitmap> shared_bitmap; + if (shared_bitmap_manager_) { + shared_bitmap = + shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory); + } + resource = Resource(pixels, + shared_bitmap.release(), + mailbox.shared_memory_size(), + GL_LINEAR, + GL_CLAMP_TO_EDGE); } resource.external = true; resource.allocated = true; @@ -407,8 +432,9 @@ void ResourceProvider::DeleteResource(ResourceId id) { void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style) { + TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal"); Resource* resource = &it->second; - bool lost_resource = lost_output_surface_ || resource->lost; + bool lost_resource = resource->lost; DCHECK(resource->exported_count == 0 || style != Normal); if (style == ForShutdown && resource->exported_count > 0) @@ -438,6 +464,7 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, if (resource->mailbox.IsValid() && resource->external) { unsigned sync_point = resource->mailbox.sync_point(); if (resource->mailbox.IsTexture()) { + lost_resource |= lost_output_surface_; WebGraphicsContext3D* context3d = Context3d(); DCHECK(context3d); if (resource->gl_id) @@ -450,10 +477,16 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, if (resource->pixels && shared_memory) { DCHECK(shared_memory->memory() == resource->pixels); resource->pixels = NULL; + delete resource->shared_bitmap; + resource->shared_bitmap = NULL; } } resource->release_callback.Run(sync_point, lost_resource); } + if (resource->shared_bitmap) { + delete resource->shared_bitmap; + resource->pixels = NULL; + } if (resource->pixels) delete[] resource->pixels; if (resource->pixel_buffer) @@ -754,9 +787,11 @@ ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() { } ResourceProvider::ResourceProvider(OutputSurface* output_surface, + SharedBitmapManager* shared_bitmap_manager, int highp_threshold_min, bool use_rgba_4444_texture_format) : output_surface_(output_surface), + shared_bitmap_manager_(shared_bitmap_manager), lost_output_surface_(false), highp_threshold_min_(highp_threshold_min), next_id_(1), @@ -876,17 +911,15 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources, TransferableResourceArray* list) { DCHECK(thread_checker_.CalledOnValidThread()); WebGraphicsContext3D* context3d = Context3d(); - if (!context3d || !context3d->makeContextCurrent()) { - // TODO(skaslev): Implement this path for software compositing. - return; - } + if (context3d) + context3d->makeContextCurrent(); bool need_sync_point = false; for (ResourceIdArray::const_iterator it = resources.begin(); it != resources.end(); ++it) { TransferableResource resource; TransferResource(context3d, *it, &resource); - if (!resource.sync_point) + if (!resource.sync_point && !resource.is_software) need_sync_point = true; ++resources_.find(*it)->second.exported_count; list->push_back(resource); @@ -906,10 +939,8 @@ void ResourceProvider::ReceiveFromChild( int child, const TransferableResourceArray& resources) { DCHECK(thread_checker_.CalledOnValidThread()); WebGraphicsContext3D* context3d = Context3d(); - if (!context3d || !context3d->makeContextCurrent()) { - // TODO(skaslev): Implement this path for software compositing. - return; - } + if (context3d) + context3d->makeContextCurrent(); Child& child_info = children_.find(child)->second; for (TransferableResourceArray::const_iterator it = resources.begin(); it != resources.end(); @@ -920,34 +951,58 @@ void ResourceProvider::ReceiveFromChild( resources_[resource_in_map_it->second].imported_count++; continue; } - unsigned texture_id; - // NOTE: If the parent is a browser and the child a renderer, the parent - // is not supposed to have its context wait, because that could induce - // deadlocks and/or security issues. The caller is responsible for - // waiting asynchronously, and resetting sync_point before calling this. - // However if the parent is a renderer (e.g. browser tag), it may be ok - // (and is simpler) to wait. - if (it->sync_point) - GLC(context3d, context3d->waitSyncPoint(it->sync_point)); - GLC(context3d, texture_id = context3d->createTexture()); - GLC(context3d, context3d->bindTexture(it->target, texture_id)); - GLC(context3d, - context3d->consumeTextureCHROMIUM(it->target, it->mailbox.name)); + + scoped_ptr<SharedBitmap> bitmap; + uint8_t* pixels = NULL; + if (it->is_software) { + if (shared_bitmap_manager_) + bitmap = shared_bitmap_manager_->GetSharedBitmapFromId(it->size, + it->mailbox); + if (bitmap) + pixels = bitmap->pixels(); + } + + if ((!it->is_software && !context3d) || (it->is_software && !pixels)) { + TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid"); + ReturnedResourceArray to_return; + to_return.push_back(it->ToReturnedResource()); + child_info.return_callback.Run(to_return); + continue; + } + ResourceId local_id = next_id_++; - Resource resource(texture_id, - it->size, - it->target, - it->filter, - 0, - GL_CLAMP_TO_EDGE, - TextureUsageAny, - it->format); - resource.mailbox.SetName(it->mailbox); + Resource& resource = resources_[local_id]; + if (it->is_software) { + resource = Resource( + pixels, bitmap.release(), it->size, GL_LINEAR, GL_CLAMP_TO_EDGE); + } else { + unsigned texture_id; + // NOTE: If the parent is a browser and the child a renderer, the parent + // is not supposed to have its context wait, because that could induce + // deadlocks and/or security issues. The caller is responsible for + // waiting asynchronously, and resetting sync_point before calling this. + // However if the parent is a renderer (e.g. browser tag), it may be ok + // (and is simpler) to wait. + if (it->sync_point) + GLC(context3d, context3d->waitSyncPoint(it->sync_point)); + GLC(context3d, texture_id = context3d->createTexture()); + GLC(context3d, context3d->bindTexture(it->target, texture_id)); + GLC(context3d, + context3d->consumeTextureCHROMIUM(it->target, it->mailbox.name)); + resource = Resource(texture_id, + it->size, + it->target, + it->filter, + 0, + GL_CLAMP_TO_EDGE, + TextureUsageAny, + it->format); + resource.mailbox.SetName(it->mailbox); + } resource.child_id = child; // Don't allocate a texture for a child. resource.allocated = true; resource.imported_count = 1; - resources_[local_id] = resource; child_info.parent_to_child_map[local_id] = it->id; child_info.child_to_parent_map[it->id] = local_id; } @@ -997,10 +1052,8 @@ void ResourceProvider::ReceiveReturnsFromParent( const ReturnedResourceArray& resources) { DCHECK(thread_checker_.CalledOnValidThread()); WebGraphicsContext3D* context3d = Context3d(); - if (!context3d || !context3d->makeContextCurrent()) { - // TODO(skaslev): Implement this path for software compositing. - return; - } + if (context3d) + context3d->makeContextCurrent(); int child_id = 0; Child* child_info = NULL; @@ -1043,7 +1096,7 @@ void ResourceProvider::ReceiveReturnsFromParent( if (resource->gl_id) { if (returned.sync_point) GLC(context3d, context3d->waitSyncPoint(returned.sync_point)); - } else { + } else if (!resource->shared_bitmap) { resource->mailbox = TextureMailbox(resource->mailbox.name(), returned.sync_point); } @@ -1096,10 +1149,10 @@ void ResourceProvider::TransferResource(WebGraphicsContext3D* context, resource->filter = source->filter; resource->size = source->size; - // TODO(skaslev) Implement this path for shared memory resources. - DCHECK(!source->mailbox.IsSharedMemory()); - - if (!source->mailbox.IsTexture()) { + if (source->shared_bitmap) { + resource->mailbox = source->shared_bitmap->id(); + resource->is_software = true; + } else if (!source->mailbox.IsValid()) { // This is a resource allocated by the compositor, we need to produce it. // Don't set a sync point, the caller will do it. DCHECK(source->gl_id); @@ -1110,6 +1163,7 @@ void ResourceProvider::TransferResource(WebGraphicsContext3D* context, resource->mailbox.name)); source->mailbox.SetName(resource->mailbox); } else { + DCHECK(source->mailbox.IsTexture()); // This is either an external resource, or a compositor resource that we // already exported. Make sure to forward the sync point that we were given. resource->mailbox = source->mailbox.name(); @@ -1129,10 +1183,8 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( return; WebGraphicsContext3D* context3d = Context3d(); - if (!context3d || !context3d->makeContextCurrent()) { - // TODO(skaslev): Implement this path for software compositing. - return; - } + if (context3d) + context3d->makeContextCurrent(); ReturnedResourceArray to_return; @@ -1152,7 +1204,8 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( ResourceId child_id = child_info->parent_to_child_map[local_id]; DCHECK(child_info->child_to_parent_map.count(child_id)); - bool is_lost = resource.lost || lost_output_surface_; + bool is_lost = + resource.lost || (!resource.shared_bitmap && lost_output_surface_); if (resource.exported_count > 0) { if (style != ForShutdown) { // Defer this until we receive the resource back from the parent. @@ -1164,7 +1217,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( is_lost = true; } - if (resource.filter != resource.original_filter) { + if (context3d && resource.filter != resource.original_filter) { DCHECK(resource.target); DCHECK(resource.gl_id); @@ -1182,7 +1235,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( ReturnedResource returned; returned.id = child_id; returned.sync_point = resource.mailbox.sync_point(); - if (!returned.sync_point) + if (!returned.sync_point && !resource.shared_bitmap) need_sync_point = true; returned.count = resource.imported_count; returned.lost = is_lost; @@ -1194,6 +1247,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( DeleteResourceInternal(it, style); } if (need_sync_point) { + DCHECK(context3d); unsigned int sync_point = context3d->insertSyncPoint(); for (size_t i = 0; i < to_return.size(); ++i) { if (!to_return[i].sync_point) @@ -1646,6 +1700,16 @@ int ResourceProvider::GetImageStride(ResourceId id) { return stride; } +base::SharedMemory* ResourceProvider::GetSharedMemory(ResourceId id) { + Resource* resource = GetResource(id); + DCHECK(!resource->external); + DCHECK_EQ(resource->exported_count, 0); + + if (!resource->shared_bitmap) + return NULL; + return resource->shared_bitmap->memory(); +} + GLint ResourceProvider::GetActiveTextureUnit(WebGraphicsContext3D* context) { GLint active_unit = 0; context->getIntegerv(GL_ACTIVE_TEXTURE, &active_unit); diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index b8cb399..3b9e8e0 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -39,6 +39,8 @@ class Vector2d; } namespace cc { +class SharedBitmap; +class SharedBitmapManager; class TextureUploader; // This class is not thread-safe and can only be called from the thread it was @@ -59,9 +61,11 @@ class CC_EXPORT ResourceProvider { Bitmap, }; - static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface, - int highp_threshold_min, - bool use_rgba_4444_texture_format); + static scoped_ptr<ResourceProvider> Create( + OutputSurface* output_surface, + SharedBitmapManager* shared_bitmap_manager, + int highp_threshold_min, + bool use_rgba_4444_texture_format); virtual ~ResourceProvider(); void InitializeSoftware(); @@ -320,6 +324,8 @@ class CC_EXPORT ResourceProvider { // Returns the stride for the image. int GetImageStride(ResourceId id); + base::SharedMemory* GetSharedMemory(ResourceId id); + // For tests only! This prevents detecting uninitialized reads. // Use SetPixels or LockForWrite to allocate implicitly. void AllocateForTesting(ResourceId id); @@ -359,6 +365,7 @@ class CC_EXPORT ResourceProvider { TextureUsageHint hint, ResourceFormat format); Resource(uint8_t* pixels, + SharedBitmap* bitmap, gfx::Size size, GLenum filter, GLint wrap_mode); @@ -398,6 +405,7 @@ class CC_EXPORT ResourceProvider { TextureUsageHint hint; ResourceType type; ResourceFormat format; + SharedBitmap* shared_bitmap; }; typedef base::hash_map<ResourceId, Resource> ResourceMap; @@ -422,6 +430,7 @@ class CC_EXPORT ResourceProvider { } ResourceProvider(OutputSurface* output_surface, + SharedBitmapManager* shared_bitmap_manager, int highp_threshold_min, bool use_rgba_4444_texture_format); @@ -461,6 +470,7 @@ class CC_EXPORT ResourceProvider { WebKit::WebGraphicsContext3D* Context3d() const; OutputSurface* output_surface_; + SharedBitmapManager* shared_bitmap_manager_; bool lost_output_surface_; int highp_threshold_min_; ResourceId next_id_; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 05a10a2..23da024 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -15,6 +15,7 @@ #include "cc/debug/test_web_graphics_context_3d.h" #include "cc/output/output_surface.h" #include "cc/resources/returned_resource.h" +#include "cc/resources/shared_bitmap_manager.h" #include "cc/resources/single_release_callback.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" @@ -44,6 +45,41 @@ namespace { static void EmptyReleaseCallback(unsigned sync_point, bool lost_resource) {} +static void SharedMemoryReleaseCallback(scoped_ptr<base::SharedMemory> memory, + unsigned sync_point, + bool lost_resource) {} + +static void ReleaseTextureMailbox(unsigned* release_sync_point, + bool* release_lost_resource, + unsigned sync_point, + bool lost_resource) { + *release_sync_point = sync_point; + *release_lost_resource = lost_resource; +} + +static void ReleaseSharedMemoryCallback( + scoped_ptr<base::SharedMemory> shared_memory, + bool* release_called, + unsigned* release_sync_point, + bool* lost_resource_result, + unsigned sync_point, + bool lost_resource) { + *release_called = true; + *release_sync_point = sync_point; + *lost_resource_result = lost_resource; +} + +static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory( + gfx::Size size, + uint32_t value) { + scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory); + CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea())); + uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory()); + CHECK(pixels); + std::fill_n(pixels, size.GetArea(), value); + return shared_memory.Pass(); +} + class TextureStateTrackingContext : public TestWebGraphicsContext3D { public: MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture)); @@ -323,6 +359,55 @@ class ResourceProviderContext : public TestWebGraphicsContext3D { PendingProduceTextureList pending_produce_textures_; }; +void FreeSharedBitmap(SharedBitmap* shared_bitmap) { + delete shared_bitmap->memory(); +} + +void IgnoreSharedBitmap(SharedBitmap* shared_bitmap) {} + +class TestSharedBitmapManager : public SharedBitmapManager { + public: + TestSharedBitmapManager() : count_(0) {} + virtual ~TestSharedBitmapManager() {} + + virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(gfx::Size size) + OVERRIDE { + scoped_ptr<base::SharedMemory> memory(new base::SharedMemory); + memory->CreateAndMapAnonymous(size.GetArea() * 4); + int8 name[64] = { 0 }; + name[0] = count_++; + SharedBitmapId id; + id.SetName(name); + bitmap_map_[id] = memory.get(); + return scoped_ptr<SharedBitmap>( + new SharedBitmap(memory.release(), id, base::Bind(&FreeSharedBitmap))); + } + + virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId( + gfx::Size, + const SharedBitmapId& id) OVERRIDE { + if (bitmap_map_.find(id) == bitmap_map_.end()) + return scoped_ptr<SharedBitmap>(); + return scoped_ptr<SharedBitmap>( + new SharedBitmap(bitmap_map_[id], id, base::Bind(&IgnoreSharedBitmap))); + } + + virtual scoped_ptr<SharedBitmap> GetBitmapForSharedMemory( + base::SharedMemory* memory) OVERRIDE { + int8 name[64] = { 0 }; + name[0] = count_++; + SharedBitmapId id; + id.SetName(name); + bitmap_map_[id] = memory; + return scoped_ptr<SharedBitmap>( + new SharedBitmap(memory, id, base::Bind(&IgnoreSharedBitmap))); + } + + private: + int count_; + std::map<SharedBitmapId, base::SharedMemory*> bitmap_map_; +}; + void GetResourcePixels(ResourceProvider* resource_provider, ResourceProviderContext* context, ResourceProvider::ResourceId id, @@ -356,7 +441,8 @@ class ResourceProviderTest public: ResourceProviderTest() : shared_data_(ContextSharedData::Create()), - context3d_(NULL) { + context3d_(NULL), + child_context_(NULL) { switch (GetParam()) { case ResourceProvider::GLTexture: { scoped_ptr<ResourceProviderContext> context3d( @@ -368,19 +454,33 @@ class ResourceProviderTest context3d.PassAs<TestWebGraphicsContext3D>()); output_surface_ = FakeOutputSurface::Create3d(context_provider); + + scoped_ptr<ResourceProviderContext> child_context_owned = + ResourceProviderContext::Create(shared_data_.get()); + child_context_ = child_context_owned.get(); + child_output_surface_ = FakeOutputSurface::Create3d( + child_context_owned.PassAs<TestWebGraphicsContext3D>()); break; } case ResourceProvider::Bitmap: output_surface_ = FakeOutputSurface::CreateSoftware( make_scoped_ptr(new SoftwareOutputDevice)); + child_output_surface_ = FakeOutputSurface::CreateSoftware( + make_scoped_ptr(new SoftwareOutputDevice)); break; case ResourceProvider::InvalidType: NOTREACHED(); break; } CHECK(output_surface_->BindToClient(&output_surface_client_)); + CHECK(child_output_surface_->BindToClient(&child_output_surface_client_)); + + shared_bitmap_manager_.reset(new TestSharedBitmapManager()); + resource_provider_ = ResourceProvider::Create( - output_surface_.get(), 0, false); + output_surface_.get(), shared_bitmap_manager_.get(), 0, false); + child_resource_provider_ = ResourceProvider::Create( + child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false); } static void CollectResources(ReturnedResourceArray* array, @@ -401,12 +501,56 @@ class ResourceProviderTest ResourceProviderContext* context() { return context3d_; } + ResourceProvider::ResourceId CreateChildMailbox(unsigned* release_sync_point, + bool* lost_resource, + bool* release_called, + unsigned* sync_point) { + if (GetParam() == ResourceProvider::GLTexture) { + unsigned texture = child_context_->createTexture(); + gpu::Mailbox gpu_mailbox; + child_context_->bindTexture(GL_TEXTURE_2D, texture); + child_context_->genMailboxCHROMIUM(gpu_mailbox.name); + child_context_->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name); + *sync_point = child_context_->insertSyncPoint(); + EXPECT_LT(0u, *sync_point); + + scoped_ptr<base::SharedMemory> shared_memory; + scoped_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback, + base::Passed(&shared_memory), + release_called, + release_sync_point, + lost_resource)); + return child_resource_provider_->CreateResourceFromTextureMailbox( + TextureMailbox(gpu_mailbox, *sync_point), callback.Pass()); + } else { + gfx::Size size(64, 64); + scoped_ptr<base::SharedMemory> shared_memory( + CreateAndFillSharedMemory(size, 0)); + + base::SharedMemory* shared_memory_ptr = shared_memory.get(); + scoped_ptr<SingleReleaseCallback> callback = + SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback, + base::Passed(&shared_memory), + release_called, + release_sync_point, + lost_resource)); + return child_resource_provider_->CreateResourceFromTextureMailbox( + TextureMailbox(shared_memory_ptr, size), callback.Pass()); + } + } + protected: scoped_ptr<ContextSharedData> shared_data_; ResourceProviderContext* context3d_; + ResourceProviderContext* child_context_; FakeOutputSurfaceClient output_surface_client_; + FakeOutputSurfaceClient child_output_surface_client_; scoped_ptr<OutputSurface> output_surface_; + scoped_ptr<OutputSurface> child_output_surface_; scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<ResourceProvider> child_resource_provider_; + scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_; }; void CheckCreateResource(ResourceProvider::ResourceType expected_default_type, @@ -512,50 +656,35 @@ TEST_P(ResourceProviderTest, Upload) { resource_provider_->DeleteResource(id); } -TEST_P(ResourceProviderTest, TransferResources) { - // Resource transfer is only supported with GL textures for now. +TEST_P(ResourceProviderTest, TransferGLResources) { if (GetParam() != ResourceProvider::GLTexture) return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - ResourceProviderContext* child_context = child_context_owned.get(); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface( - FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; size_t pixel_size = TextureSizeBytes(size, format); ASSERT_EQ(4U, pixel_size); - ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource( + ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data1[4] = { 1, 2, 3, 4 }; gfx::Rect rect(size); - child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); - ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource( + ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data2[4] = { 5, 5, 5, 5 }; - child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); - WebGLId external_texture_id = child_context->createExternalTexture(); - child_context->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id); + WebGLId external_texture_id = child_context_->createExternalTexture(); + child_context_->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id); gpu::Mailbox external_mailbox; - child_context->genMailboxCHROMIUM(external_mailbox.name); - child_context->produceTextureCHROMIUM(GL_TEXTURE_EXTERNAL_OES, - external_mailbox.name); - const unsigned external_sync_point = child_context->insertSyncPoint(); + child_context_->genMailboxCHROMIUM(external_mailbox.name); + child_context_->produceTextureCHROMIUM(GL_TEXTURE_EXTERNAL_OES, + external_mailbox.name); + const unsigned external_sync_point = child_context_->insertSyncPoint(); ResourceProvider::ResourceId id3 = - child_resource_provider->CreateResourceFromTextureMailbox( + child_resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox( external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point), SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback))); @@ -570,8 +699,8 @@ TEST_P(ResourceProviderTest, TransferResources) { resource_ids_to_transfer.push_back(id2); resource_ids_to_transfer.push_back(id3); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); ASSERT_EQ(3u, list.size()); EXPECT_NE(0u, list[0].sync_point); EXPECT_NE(0u, list[1].sync_point); @@ -579,9 +708,9 @@ TEST_P(ResourceProviderTest, TransferResources) { EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[1].target); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), list[2].target); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id3)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3)); resource_provider_->ReceiveFromChild(child_id, list); resource_provider_->DeclareUsedResourcesFromChild(child_id, resource_ids_to_transfer); @@ -615,17 +744,17 @@ TEST_P(ResourceProviderTest, TransferResources) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(id1); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(1u, list.size()); EXPECT_EQ(id1, list[0].id); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target); ReturnedResourceArray returned; TransferableResource::ReturnResources(list, &returned); - child_resource_provider->ReceiveReturnsFromParent(returned); + child_resource_provider_->ReceiveReturnsFromParent(returned); // id1 was exported twice, we returned it only once, it should still be // in-use. - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); } { EXPECT_EQ(0u, returned_to_child.size()); @@ -642,25 +771,27 @@ TEST_P(ResourceProviderTest, TransferResources) { EXPECT_FALSE(returned_to_child[0].lost); EXPECT_FALSE(returned_to_child[1].lost); EXPECT_FALSE(returned_to_child[2].lost); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); returned_to_child.clear(); } - EXPECT_FALSE(child_resource_provider->InUseByConsumer(id1)); - EXPECT_FALSE(child_resource_provider->InUseByConsumer(id2)); - EXPECT_FALSE(child_resource_provider->InUseByConsumer(id3)); + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3)); { - ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id1); + ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(), + id1); ASSERT_NE(0U, lock.texture_id()); - child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id()); - child_context->GetPixels(size, format, result); + child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id()); + child_context_->GetPixels(size, format, result); EXPECT_EQ(0, memcmp(data1, result, pixel_size)); } { - ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id2); + ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(), + id2); ASSERT_NE(0U, lock.texture_id()); - child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id()); - child_context->GetPixels(size, format, result); + child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id()); + child_context_->GetPixels(size, format, result); EXPECT_EQ(0, memcmp(data2, result, pixel_size)); } { @@ -670,8 +801,8 @@ TEST_P(ResourceProviderTest, TransferResources) { resource_ids_to_transfer.push_back(id2); resource_ids_to_transfer.push_back(id3); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); ASSERT_EQ(3u, list.size()); EXPECT_EQ(id1, list[0].id); EXPECT_EQ(id2, list[1].id); @@ -682,9 +813,9 @@ TEST_P(ResourceProviderTest, TransferResources) { EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[1].target); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), list[2].target); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id3)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3)); resource_provider_->ReceiveFromChild(child_id, list); resource_provider_->DeclareUsedResourcesFromChild(child_id, resource_ids_to_transfer); @@ -705,9 +836,234 @@ TEST_P(ResourceProviderTest, TransferResources) { EXPECT_FALSE(returned_to_child[2].lost); } -TEST_P(ResourceProviderTest, DeleteExportedResources) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) +TEST_P(ResourceProviderTest, TransferSoftwareResources) { + if (GetParam() != ResourceProvider::Bitmap) + return; + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + size_t pixel_size = TextureSizeBytes(size, format); + ASSERT_EQ(4U, pixel_size); + + ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + uint8_t data1[4] = { 1, 2, 3, 4 }; + gfx::Rect rect(size); + child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + + ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + uint8_t data2[4] = { 5, 5, 5, 5 }; + child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); + + scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); + shared_memory->CreateAndMapAnonymous(1); + base::SharedMemory* shared_memory_ptr = shared_memory.get(); + ResourceProvider::ResourceId id3 = + child_resource_provider_->CreateResourceFromTextureMailbox( + TextureMailbox(shared_memory_ptr, gfx::Size(1, 1)), + SingleReleaseCallback::Create(base::Bind( + &SharedMemoryReleaseCallback, base::Passed(&shared_memory)))); + + ReturnedResourceArray returned_to_child; + int child_id = + resource_provider_->CreateChild(GetReturnCallback(&returned_to_child)); + { + // Transfer some resources to the parent. + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + resource_ids_to_transfer.push_back(id2); + resource_ids_to_transfer.push_back(id3); + TransferableResourceArray list; + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(0u, list[0].sync_point); + EXPECT_EQ(0u, list[1].sync_point); + EXPECT_EQ(0u, list[2].sync_point); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3)); + resource_provider_->ReceiveFromChild(child_id, list); + resource_provider_->DeclareUsedResourcesFromChild(child_id, + resource_ids_to_transfer); + } + + EXPECT_EQ(3u, resource_provider_->num_resources()); + ResourceProvider::ResourceIdMap resource_map = + resource_provider_->GetChildToParentMap(child_id); + ResourceProvider::ResourceId mapped_id1 = resource_map[id1]; + ResourceProvider::ResourceId mapped_id2 = resource_map[id2]; + ResourceProvider::ResourceId mapped_id3 = resource_map[id3]; + EXPECT_NE(0u, mapped_id1); + EXPECT_NE(0u, mapped_id2); + EXPECT_NE(0u, mapped_id3); + EXPECT_FALSE(resource_provider_->InUseByConsumer(id1)); + EXPECT_FALSE(resource_provider_->InUseByConsumer(id2)); + EXPECT_FALSE(resource_provider_->InUseByConsumer(id3)); + + uint8_t result[4] = { 0 }; + GetResourcePixels( + resource_provider_.get(), context(), mapped_id1, size, format, result); + EXPECT_EQ(0, memcmp(data1, result, pixel_size)); + + GetResourcePixels( + resource_provider_.get(), context(), mapped_id2, size, format, result); + EXPECT_EQ(0, memcmp(data2, result, pixel_size)); + + { + // Check that transfering again the same resource from the child to the + // parent works. + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + TransferableResourceArray list; + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); + EXPECT_EQ(1u, list.size()); + EXPECT_EQ(id1, list[0].id); + ReturnedResourceArray returned; + TransferableResource::ReturnResources(list, &returned); + child_resource_provider_->ReceiveReturnsFromParent(returned); + // id1 was exported twice, we returned it only once, it should still be + // in-use. + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + } + { + EXPECT_EQ(0u, returned_to_child.size()); + + // Transfer resources back from the parent to the child. Set no resources as + // being in use. + ResourceProvider::ResourceIdArray no_resources; + resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources); + + ASSERT_EQ(3u, returned_to_child.size()); + EXPECT_EQ(0u, returned_to_child[0].sync_point); + EXPECT_EQ(0u, returned_to_child[1].sync_point); + EXPECT_EQ(0u, returned_to_child[2].sync_point); + EXPECT_EQ(id1, returned_to_child[0].id); + EXPECT_EQ(id2, returned_to_child[1].id); + EXPECT_EQ(id3, returned_to_child[2].id); + EXPECT_FALSE(returned_to_child[0].lost); + EXPECT_FALSE(returned_to_child[1].lost); + EXPECT_FALSE(returned_to_child[2].lost); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); + returned_to_child.clear(); + } + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3)); + + { + ResourceProvider::ScopedReadLockSoftware lock( + child_resource_provider_.get(), id1); + const SkBitmap* sk_bitmap = lock.sk_bitmap(); + EXPECT_EQ(sk_bitmap->width(), size.width()); + EXPECT_EQ(sk_bitmap->height(), size.height()); + EXPECT_EQ(0, memcmp(data1, sk_bitmap->getPixels(), pixel_size)); + } + { + ResourceProvider::ScopedReadLockSoftware lock( + child_resource_provider_.get(), id2); + const SkBitmap* sk_bitmap = lock.sk_bitmap(); + EXPECT_EQ(sk_bitmap->width(), size.width()); + EXPECT_EQ(sk_bitmap->height(), size.height()); + EXPECT_EQ(0, memcmp(data2, sk_bitmap->getPixels(), pixel_size)); + } + { + // Transfer resources to the parent again. + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + resource_ids_to_transfer.push_back(id2); + resource_ids_to_transfer.push_back(id3); + TransferableResourceArray list; + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); + ASSERT_EQ(3u, list.size()); + EXPECT_EQ(id1, list[0].id); + EXPECT_EQ(id2, list[1].id); + EXPECT_EQ(id3, list[2].id); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3)); + resource_provider_->ReceiveFromChild(child_id, list); + resource_provider_->DeclareUsedResourcesFromChild(child_id, + resource_ids_to_transfer); + } + + EXPECT_EQ(0u, returned_to_child.size()); + + EXPECT_EQ(3u, resource_provider_->num_resources()); + resource_provider_->DestroyChild(child_id); + EXPECT_EQ(0u, resource_provider_->num_resources()); + + ASSERT_EQ(3u, returned_to_child.size()); + EXPECT_EQ(0u, returned_to_child[0].sync_point); + EXPECT_EQ(0u, returned_to_child[1].sync_point); + EXPECT_EQ(0u, returned_to_child[2].sync_point); + EXPECT_EQ(id1, returned_to_child[0].id); + EXPECT_EQ(id2, returned_to_child[1].id); + EXPECT_EQ(id3, returned_to_child[2].id); + EXPECT_FALSE(returned_to_child[0].lost); + EXPECT_FALSE(returned_to_child[1].lost); + EXPECT_FALSE(returned_to_child[2].lost); +} + +TEST_P(ResourceProviderTest, TransferSoftwareToNonUber) { + // TODO(jbauman): Remove test when shared bitmap manager available + // everywhere. + if (GetParam() != ResourceProvider::Bitmap) + return; + + scoped_ptr<FakeOutputSurface> parent_output_surface = + FakeOutputSurface::CreateSoftware( + make_scoped_ptr(new SoftwareOutputDevice)); + FakeOutputSurfaceClient parent_output_surface_client; + CHECK(parent_output_surface->BindToClient(&parent_output_surface_client)); + + scoped_ptr<ResourceProvider> parent_resource_provider( + ResourceProvider::Create(parent_output_surface.get(), NULL, 0, false)); + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + size_t pixel_size = TextureSizeBytes(size, format); + ASSERT_EQ(4U, pixel_size); + + ResourceProvider::ResourceId id1 = resource_provider_->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + uint8_t data1[4] = { 1, 2, 3, 4 }; + gfx::Rect rect(size); + resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + + ReturnedResourceArray returned_to_child; + int child_id = parent_resource_provider->CreateChild( + GetReturnCallback(&returned_to_child)); + { + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + TransferableResourceArray list; + resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list); + ASSERT_EQ(1u, list.size()); + EXPECT_TRUE(resource_provider_->InUseByConsumer(id1)); + parent_resource_provider->ReceiveFromChild(child_id, list); + } + + EXPECT_EQ(0u, parent_resource_provider->num_resources()); + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_EQ(returned_to_child[0].id, id1); + ResourceProvider::ResourceIdMap resource_map = + parent_resource_provider->GetChildToParentMap(child_id); + ResourceProvider::ResourceId mapped_id1 = resource_map[id1]; + EXPECT_EQ(0u, mapped_id1); + + parent_resource_provider->DestroyChild(child_id); + EXPECT_EQ(0u, parent_resource_provider->num_resources()); + + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_FALSE(returned_to_child[0].lost); +} + +TEST_P(ResourceProviderTest, TransferGLToSoftware) { + if (GetParam() != ResourceProvider::Bitmap) return; scoped_ptr<ResourceProviderContext> child_context_owned( @@ -719,7 +1075,7 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) { CHECK(child_output_surface->BindToClient(&child_output_surface_client)); scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); + ResourceProvider::Create(child_output_surface.get(), NULL, 0, false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -728,14 +1084,103 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) { ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - uint8_t data1[4] = {1, 2, 3, 4}; + uint8_t data1[4] = { 1, 2, 3, 4 }; gfx::Rect rect(size); child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); - ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource( + ReturnedResourceArray returned_to_child; + int child_id = + resource_provider_->CreateChild(GetReturnCallback(&returned_to_child)); + { + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + TransferableResourceArray list; + child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, + &list); + ASSERT_EQ(1u, list.size()); + EXPECT_NE(0u, list[0].sync_point); + EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target); + EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); + resource_provider_->ReceiveFromChild(child_id, list); + } + + EXPECT_EQ(0u, resource_provider_->num_resources()); + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_EQ(returned_to_child[0].id, id1); + ResourceProvider::ResourceIdMap resource_map = + resource_provider_->GetChildToParentMap(child_id); + ResourceProvider::ResourceId mapped_id1 = resource_map[id1]; + EXPECT_EQ(0u, mapped_id1); + + resource_provider_->DestroyChild(child_id); + EXPECT_EQ(0u, resource_provider_->num_resources()); + + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_FALSE(returned_to_child[0].lost); +} + +TEST_P(ResourceProviderTest, TransferInvalidSoftware) { + if (GetParam() != ResourceProvider::Bitmap) + return; + + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + size_t pixel_size = TextureSizeBytes(size, format); + ASSERT_EQ(4U, pixel_size); + + ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + uint8_t data1[4] = { 1, 2, 3, 4 }; + gfx::Rect rect(size); + child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + + ReturnedResourceArray returned_to_child; + int child_id = + resource_provider_->CreateChild(GetReturnCallback(&returned_to_child)); + { + ResourceProvider::ResourceIdArray resource_ids_to_transfer; + resource_ids_to_transfer.push_back(id1); + TransferableResourceArray list; + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); + ASSERT_EQ(1u, list.size()); + // Make invalid. + list[0].mailbox.name[1] = 5; + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + resource_provider_->ReceiveFromChild(child_id, list); + } + + EXPECT_EQ(0u, resource_provider_->num_resources()); + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_EQ(returned_to_child[0].id, id1); + ResourceProvider::ResourceIdMap resource_map = + resource_provider_->GetChildToParentMap(child_id); + ResourceProvider::ResourceId mapped_id1 = resource_map[id1]; + EXPECT_EQ(0u, mapped_id1); + + resource_provider_->DestroyChild(child_id); + EXPECT_EQ(0u, resource_provider_->num_resources()); + + ASSERT_EQ(1u, returned_to_child.size()); + EXPECT_FALSE(returned_to_child[0].lost); +} + +TEST_P(ResourceProviderTest, DeleteExportedResources) { + gfx::Size size(1, 1); + ResourceFormat format = RGBA_8888; + size_t pixel_size = TextureSizeBytes(size, format); + ASSERT_EQ(4U, pixel_size); + + ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource( + size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); + uint8_t data1[4] = { 1, 2, 3, 4 }; + gfx::Rect rect(size); + child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + + ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data2[4] = {5, 5, 5, 5}; - child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); ReturnedResourceArray returned_to_child; int child_id = @@ -746,13 +1191,15 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) { resource_ids_to_transfer.push_back(id1); resource_ids_to_transfer.push_back(id2); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); ASSERT_EQ(2u, list.size()); - EXPECT_NE(0u, list[0].sync_point); - EXPECT_NE(0u, list[1].sync_point); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2)); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, list[0].sync_point); + EXPECT_NE(0u, list[1].sync_point); + } + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); resource_provider_->ReceiveFromChild(child_id, list); resource_provider_->DeclareUsedResourcesFromChild(child_id, resource_ids_to_transfer); @@ -777,8 +1224,10 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) { resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list); ASSERT_EQ(2u, list.size()); - EXPECT_NE(0u, list[0].sync_point); - EXPECT_NE(0u, list[1].sync_point); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, list[0].sync_point); + EXPECT_NE(0u, list[1].sync_point); + } EXPECT_TRUE(resource_provider_->InUseByConsumer(id1)); EXPECT_TRUE(resource_provider_->InUseByConsumer(id2)); @@ -801,44 +1250,31 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) { EXPECT_EQ(0u, resource_provider_->num_resources()); ASSERT_EQ(2u, returned_to_child.size()); - EXPECT_NE(0u, returned_to_child[0].sync_point); - EXPECT_NE(0u, returned_to_child[1].sync_point); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, returned_to_child[0].sync_point); + EXPECT_NE(0u, returned_to_child[1].sync_point); + } EXPECT_FALSE(returned_to_child[0].lost); EXPECT_FALSE(returned_to_child[1].lost); } } TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; size_t pixel_size = TextureSizeBytes(size, format); ASSERT_EQ(4U, pixel_size); - ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource( + ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data1[4] = {1, 2, 3, 4}; gfx::Rect rect(size); - child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d()); - ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource( + ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data2[4] = {5, 5, 5, 5}; - child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d()); ReturnedResourceArray returned_to_child; int child_id = @@ -849,13 +1285,15 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) { resource_ids_to_transfer.push_back(id1); resource_ids_to_transfer.push_back(id2); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); ASSERT_EQ(2u, list.size()); - EXPECT_NE(0u, list[0].sync_point); - EXPECT_NE(0u, list[1].sync_point); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1)); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2)); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, list[0].sync_point); + EXPECT_NE(0u, list[1].sync_point); + } + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2)); resource_provider_->ReceiveFromChild(child_id, list); resource_provider_->DeclareUsedResourcesFromChild(child_id, resource_ids_to_transfer); @@ -880,8 +1318,10 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) { resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list); ASSERT_EQ(2u, list.size()); - EXPECT_NE(0u, list[0].sync_point); - EXPECT_NE(0u, list[1].sync_point); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, list[0].sync_point); + EXPECT_NE(0u, list[1].sync_point); + } EXPECT_TRUE(resource_provider_->InUseByConsumer(id1)); EXPECT_TRUE(resource_provider_->InUseByConsumer(id2)); @@ -899,8 +1339,10 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) { EXPECT_EQ(0u, resource_provider_->num_resources()); ASSERT_EQ(2u, returned_to_child.size()); - EXPECT_NE(0u, returned_to_child[0].sync_point); - EXPECT_NE(0u, returned_to_child[1].sync_point); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_NE(0u, returned_to_child[0].sync_point); + EXPECT_NE(0u, returned_to_child[1].sync_point); + } EXPECT_TRUE(returned_to_child[0].lost); EXPECT_TRUE(returned_to_child[1].lost); returned_to_child.clear(); @@ -919,32 +1361,16 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) { } TEST_P(ResourceProviderTest, DeleteTransferredResources) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface( - FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; size_t pixel_size = TextureSizeBytes(size, format); ASSERT_EQ(4U, pixel_size); - ResourceProvider::ResourceId id = child_resource_provider->CreateResource( + ResourceProvider::ResourceId id = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); uint8_t data[4] = { 1, 2, 3, 4 }; gfx::Rect rect(size); - child_resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d()); + child_resource_provider_->SetPixels(id, data, rect, rect, gfx::Vector2d()); ReturnedResourceArray returned_to_child; int child_id = @@ -954,19 +1380,20 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(id); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); ASSERT_EQ(1u, list.size()); - EXPECT_NE(0u, list[0].sync_point); - EXPECT_TRUE(child_resource_provider->InUseByConsumer(id)); + if (GetParam() == ResourceProvider::GLTexture) + EXPECT_NE(0u, list[0].sync_point); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id)); resource_provider_->ReceiveFromChild(child_id, list); resource_provider_->DeclareUsedResourcesFromChild(child_id, resource_ids_to_transfer); } // Delete textures in the child, while they are transfered. - child_resource_provider->DeleteResource(id); - EXPECT_EQ(1u, child_resource_provider->num_resources()); + child_resource_provider_->DeleteResource(id); + EXPECT_EQ(1u, child_resource_provider_->num_resources()); { EXPECT_EQ(0u, returned_to_child.size()); @@ -976,10 +1403,11 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) { resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources); ASSERT_EQ(1u, returned_to_child.size()); - EXPECT_NE(0u, returned_to_child[0].sync_point); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + if (GetParam() == ResourceProvider::GLTexture) + EXPECT_NE(0u, returned_to_child[0].sync_point); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); } - EXPECT_EQ(0u, child_resource_provider->num_resources()); + EXPECT_EQ(0u, child_resource_provider_->num_resources()); } class ResourceProviderTestTextureFilters : public ResourceProviderTest { @@ -995,7 +1423,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest { CHECK(child_output_surface->BindToClient(&child_output_surface_client)); scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); + ResourceProvider::Create(child_output_surface.get(), NULL, 0, false)); scoped_ptr<TextureStateTrackingContext> parent_context_owned( new TextureStateTrackingContext); @@ -1007,7 +1435,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest { CHECK(parent_output_surface->BindToClient(&parent_output_surface_client)); scoped_ptr<ResourceProvider> parent_resource_provider( - ResourceProvider::Create(parent_output_surface.get(), 0, false)); + ResourceProvider::Create(parent_output_surface.get(), NULL, 0, false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1150,16 +1578,8 @@ TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) { ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST); } -void ReleaseTextureMailbox(unsigned* release_sync_point, - bool* release_lost_resource, - unsigned sync_point, - bool lost_resource) { - *release_sync_point = sync_point; - *release_lost_resource = lost_resource; -} - TEST_P(ResourceProviderTest, TransferMailboxResources) { - // Resource transfer is only supported with GL textures for now. + // Other mailbox transfers tested elsewhere. if (GetParam() != ResourceProvider::GLTexture) return; unsigned texture = context()->createTexture(); @@ -1279,27 +1699,14 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { } TEST_P(ResourceProviderTest, LostResourceInParent) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; ResourceProvider::ResourceId resource = - child_resource_provider->CreateResource( + child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - child_resource_provider->AllocateForTesting(resource); + child_resource_provider_->AllocateForTesting(resource); + // Expect a GL resource to be lost. + bool should_lose_resource = GetParam() == ResourceProvider::GLTexture; ReturnedResourceArray returned_to_child; int child_id = @@ -1309,8 +1716,8 @@ TEST_P(ResourceProviderTest, LostResourceInParent) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(resource); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(1u, list.size()); resource_provider_->ReceiveFromChild(child_id, list); @@ -1329,42 +1736,28 @@ TEST_P(ResourceProviderTest, LostResourceInParent) { ResourceProvider::ResourceIdArray no_resources; resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources); - // Expect the resource to be lost. + // Expect a GL resource to be lost. ASSERT_EQ(1u, returned_to_child.size()); - EXPECT_TRUE(returned_to_child[0].lost); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + EXPECT_EQ(should_lose_resource, returned_to_child[0].lost); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); returned_to_child.clear(); } - // The resource should be lost. - EXPECT_TRUE(child_resource_provider->IsLost(resource)); + // A GL resource should be lost. + EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(resource)); // Lost resources stay in use in the parent forever. - EXPECT_TRUE(child_resource_provider->InUseByConsumer(resource)); + EXPECT_EQ(should_lose_resource, + child_resource_provider_->InUseByConsumer(resource)); } TEST_P(ResourceProviderTest, LostResourceInGrandParent) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; ResourceProvider::ResourceId resource = - child_resource_provider->CreateResource( + child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - child_resource_provider->AllocateForTesting(resource); + child_resource_provider_->AllocateForTesting(resource); ReturnedResourceArray returned_to_child; int child_id = @@ -1374,8 +1767,8 @@ TEST_P(ResourceProviderTest, LostResourceInGrandParent) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(resource); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(1u, list.size()); resource_provider_->ReceiveFromChild(child_id, list); @@ -1423,47 +1816,24 @@ TEST_P(ResourceProviderTest, LostResourceInGrandParent) { // Expect the resource to be lost. ASSERT_EQ(1u, returned_to_child.size()); EXPECT_TRUE(returned_to_child[0].lost); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); returned_to_child.clear(); } // The resource should be lost. - EXPECT_TRUE(child_resource_provider->IsLost(resource)); + EXPECT_TRUE(child_resource_provider_->IsLost(resource)); // Lost resources stay in use in the parent forever. - EXPECT_TRUE(child_resource_provider->InUseByConsumer(resource)); + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(resource)); } TEST_P(ResourceProviderTest, LostMailboxInParent) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - ResourceProviderContext* child_context = child_context_owned.get(); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - - unsigned texture = child_context->createTexture(); - gpu::Mailbox gpu_mailbox; - child_context->bindTexture(GL_TEXTURE_2D, texture); - child_context->genMailboxCHROMIUM(gpu_mailbox.name); - child_context->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name); - unsigned release_sync_point = 0; bool lost_resource = false; - ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); - ResourceProvider::ResourceId resource = - child_resource_provider->CreateResourceFromTextureMailbox( - TextureMailbox(gpu_mailbox), SingleReleaseCallback::Create(callback)); + bool release_called = false; + unsigned sync_point = 0; + ResourceProvider::ResourceId resource = CreateChildMailbox( + &release_sync_point, &lost_resource, &release_called, &sync_point); ReturnedResourceArray returned_to_child; int child_id = @@ -1473,8 +1843,8 @@ TEST_P(ResourceProviderTest, LostMailboxInParent) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(resource); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(1u, list.size()); resource_provider_->ReceiveFromChild(child_id, list); @@ -1493,51 +1863,27 @@ TEST_P(ResourceProviderTest, LostMailboxInParent) { ResourceProvider::ResourceIdArray no_resources; resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources); - // Expect the resource to be lost. ASSERT_EQ(1u, returned_to_child.size()); - EXPECT_TRUE(returned_to_child[0].lost); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + // Losing an output surface only loses hardware resources. + EXPECT_EQ(returned_to_child[0].lost, + GetParam() == ResourceProvider::GLTexture); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); returned_to_child.clear(); } - // Delete the resource in the child. Expect the resource to be lost. - child_resource_provider->DeleteResource(resource); - EXPECT_TRUE(lost_resource); - - child_context->waitSyncPoint(release_sync_point); - child_context->deleteTexture(texture); + // Delete the resource in the child. Expect the resource to be lost if it's + // a GL texture. + child_resource_provider_->DeleteResource(resource); + EXPECT_EQ(lost_resource, GetParam() == ResourceProvider::GLTexture); } TEST_P(ResourceProviderTest, LostMailboxInGrandParent) { - // Resource transfer is only supported with GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - - scoped_ptr<ResourceProviderContext> child_context_owned( - ResourceProviderContext::Create(shared_data_.get())); - ResourceProviderContext* child_context = child_context_owned.get(); - - FakeOutputSurfaceClient child_output_surface_client; - scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d( - child_context_owned.PassAs<TestWebGraphicsContext3D>())); - CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - - scoped_ptr<ResourceProvider> child_resource_provider( - ResourceProvider::Create(child_output_surface.get(), 0, false)); - - unsigned texture = child_context->createTexture(); - gpu::Mailbox gpu_mailbox; - child_context->bindTexture(GL_TEXTURE_2D, texture); - child_context->genMailboxCHROMIUM(gpu_mailbox.name); - child_context->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name); - unsigned release_sync_point = 0; bool lost_resource = false; - ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); - ResourceProvider::ResourceId resource = - child_resource_provider->CreateResourceFromTextureMailbox( - TextureMailbox(gpu_mailbox), SingleReleaseCallback::Create(callback)); + bool release_called = false; + unsigned sync_point = 0; + ResourceProvider::ResourceId resource = CreateChildMailbox( + &release_sync_point, &lost_resource, &release_called, &sync_point); ReturnedResourceArray returned_to_child; int child_id = @@ -1547,8 +1893,8 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) { ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(resource); TransferableResourceArray list; - child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, - &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(1u, list.size()); resource_provider_->ReceiveFromChild(child_id, list); @@ -1590,116 +1936,54 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) { // Expect the resource to be lost. ASSERT_EQ(1u, returned_to_child.size()); EXPECT_TRUE(returned_to_child[0].lost); - child_resource_provider->ReceiveReturnsFromParent(returned_to_child); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); returned_to_child.clear(); } // Delete the resource in the child. Expect the resource to be lost. - child_resource_provider->DeleteResource(resource); + child_resource_provider_->DeleteResource(resource); EXPECT_TRUE(lost_resource); - - child_context->waitSyncPoint(release_sync_point); - child_context->deleteTexture(texture); } TEST_P(ResourceProviderTest, Shutdown) { - // TextureMailbox callbacks only exist for GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - unsigned texture = context()->createTexture(); - context()->bindTexture(GL_TEXTURE_2D, texture); - gpu::Mailbox mailbox; - context()->genMailboxCHROMIUM(mailbox.name); - context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); - unsigned sync_point = context()->insertSyncPoint(); - - EXPECT_LT(0u, sync_point); - unsigned release_sync_point = 0; bool lost_resource = false; - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); - resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, sync_point), - callback.Pass()); + bool release_called = false; + unsigned sync_point = 0; + CreateChildMailbox( + &release_sync_point, &lost_resource, &release_called, &sync_point); EXPECT_EQ(0u, release_sync_point); EXPECT_FALSE(lost_resource); - resource_provider_.reset(); - - EXPECT_LE(sync_point, release_sync_point); - EXPECT_FALSE(lost_resource); -} - -static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory( - gfx::Size size, uint32_t value) { - scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory); - CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea())); - uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory()); - CHECK(pixels); - std::fill_n(pixels, size.GetArea(), value); - return shared_memory.Pass(); -} - -static void ReleaseSharedMemoryCallback( - bool* release_called, - unsigned sync_point, bool lost_resource) { - *release_called = true; -} - -TEST_P(ResourceProviderTest, ShutdownSharedMemory) { - if (GetParam() != ResourceProvider::Bitmap) - return; - - gfx::Size size(64, 64); - scoped_ptr<base::SharedMemory> shared_memory( - CreateAndFillSharedMemory(size, 0)); - - bool release_called = false; - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(ReleaseSharedMemoryCallback, &release_called)); - resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(shared_memory.get(), size), - callback.Pass()); - - resource_provider_.reset(); + child_resource_provider_.reset(); + if (GetParam() == ResourceProvider::GLTexture) { + EXPECT_LE(sync_point, release_sync_point); + } EXPECT_TRUE(release_called); + EXPECT_FALSE(lost_resource); } TEST_P(ResourceProviderTest, ShutdownWithExportedResource) { - // TextureMailbox callbacks only exist for GL textures for now. - if (GetParam() != ResourceProvider::GLTexture) - return; - unsigned texture = context()->createTexture(); - context()->bindTexture(GL_TEXTURE_2D, texture); - gpu::Mailbox mailbox; - context()->genMailboxCHROMIUM(mailbox.name); - context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); - unsigned sync_point = context()->insertSyncPoint(); - - EXPECT_LT(0u, sync_point); - unsigned release_sync_point = 0; bool lost_resource = false; - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); - ResourceProvider::ResourceId resource = - resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, sync_point), - callback.Pass()); + bool release_called = false; + unsigned sync_point = 0; + ResourceProvider::ResourceId resource = CreateChildMailbox( + &release_sync_point, &lost_resource, &release_called, &sync_point); // Transfer the resource, so we can't release it properly on shutdown. ResourceProvider::ResourceIdArray resource_ids_to_transfer; resource_ids_to_transfer.push_back(resource); TransferableResourceArray list; - resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list); + child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, + &list); EXPECT_EQ(0u, release_sync_point); EXPECT_FALSE(lost_resource); - resource_provider_.reset(); + child_resource_provider_.reset(); // Since the resource is in the parent, the child considers it lost. EXPECT_EQ(0u, release_sync_point); @@ -1752,7 +2036,7 @@ TEST_P(ResourceProviderTest, ScopedSampler) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1833,7 +2117,7 @@ TEST_P(ResourceProviderTest, ManagedResource) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1878,7 +2162,7 @@ TEST_P(ResourceProviderTest, TextureWrapMode) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1931,7 +2215,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( base::Bind(&EmptyReleaseCallback)); @@ -1966,7 +2250,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); unsigned texture_id = 1; unsigned sync_point = 30; @@ -2030,7 +2314,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); unsigned texture_id = 1; unsigned sync_point = 30; @@ -2150,7 +2434,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); gfx::Size size(2, 2); gfx::Vector2d offset(0, 0); @@ -2226,7 +2510,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { int texture_id = 123; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); @@ -2263,7 +2547,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_Bitmap) { const uint32_t kBadBeef = 0xbadbeef; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); @@ -2309,7 +2593,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { int texture_id = 123; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); @@ -2350,7 +2634,7 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) { int texture_id = 123; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); EXPECT_CALL(*context, createTexture()).WillRepeatedly(Return(texture_id)); @@ -2388,7 +2672,7 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { const unsigned kImageId = 234u; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); @@ -2480,7 +2764,7 @@ TEST_P(ResourceProviderTest, Image_Bitmap) { const uint32_t kBadBeef = 0xbadbeef; scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); @@ -2531,7 +2815,7 @@ TEST(ResourceProviderTest, BasicInitializeGLSoftware) { scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))); EXPECT_TRUE(output_surface->BindToClient(&client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL); diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc index 498d682..9f43f80 100644 --- a/cc/resources/resource_update_controller_unittest.cc +++ b/cc/resources/resource_update_controller_unittest.cc @@ -137,7 +137,7 @@ class ResourceUpdateControllerTest : public Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); } void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count, diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc index 8b59995..dc0df8b 100644 --- a/cc/resources/scoped_resource_unittest.cc +++ b/cc/resources/scoped_resource_unittest.cc @@ -19,7 +19,7 @@ TEST(ScopedResourceTest, NewScopedResource) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); @@ -37,7 +37,7 @@ TEST(ScopedResourceTest, CreateScopedResource) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); texture->Allocate(gfx::Size(30, 30), @@ -59,7 +59,7 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); { scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); @@ -93,7 +93,7 @@ TEST(ScopedResourceTest, LeakScopedResource) { CHECK(output_surface->BindToClient(&output_surface_client)); scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0, false)); + ResourceProvider::Create(output_surface.get(), NULL, 0, false)); { scoped_ptr<ScopedResource> texture = ScopedResource::create(resource_provider.get()); diff --git a/cc/resources/shared_bitmap.cc b/cc/resources/shared_bitmap.cc new file mode 100644 index 0000000..3a6fc35 --- /dev/null +++ b/cc/resources/shared_bitmap.cc @@ -0,0 +1,17 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/resources/shared_bitmap.h" + +namespace cc { + +SharedBitmap::SharedBitmap( + base::SharedMemory* memory, + const SharedBitmapId& id, + const base::Callback<void(SharedBitmap*)>& free_callback) + : memory_(memory), id_(id), free_callback_(free_callback) {} + +SharedBitmap::~SharedBitmap() { free_callback_.Run(this); } + +} // namespace cc diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h new file mode 100644 index 0000000..9575068 --- /dev/null +++ b/cc/resources/shared_bitmap.h @@ -0,0 +1,51 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_SHARED_BITMAP_H_ +#define CC_RESOURCES_SHARED_BITMAP_H_ + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/memory/shared_memory.h" +#include "cc/base/cc_export.h" +#include "gpu/command_buffer/common/mailbox.h" + +namespace base { class SharedMemory; } + +namespace cc { +typedef gpu::Mailbox SharedBitmapId; + +class CC_EXPORT SharedBitmap { + public: + SharedBitmap(base::SharedMemory* memory, + const SharedBitmapId& id, + const base::Callback<void(SharedBitmap*)>& free_callback); + + ~SharedBitmap(); + + bool operator<(const SharedBitmap& right) const { + if (memory_ < right.memory_) + return true; + if (memory_ > right.memory_) + return false; + return id_ < right.id_; + } + + uint8* pixels() { return static_cast<uint8*>(memory_->memory()); } + + base::SharedMemory* memory() { return memory_; } + + SharedBitmapId id() { return id_; } + + private: + base::SharedMemory* memory_; + SharedBitmapId id_; + base::Callback<void(SharedBitmap*)> free_callback_; + + DISALLOW_COPY_AND_ASSIGN(SharedBitmap); +}; + +} // namespace cc + +#endif // CC_RESOURCES_SHARED_BITMAP_H_ diff --git a/cc/resources/shared_bitmap_manager.h b/cc/resources/shared_bitmap_manager.h new file mode 100644 index 0000000..53dd156 --- /dev/null +++ b/cc/resources/shared_bitmap_manager.h @@ -0,0 +1,32 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_SHARED_BITMAP_MANAGER_H_ +#define CC_RESOURCES_SHARED_BITMAP_MANAGER_H_ + +#include "base/basictypes.h" +#include "cc/base/cc_export.h" +#include "cc/resources/shared_bitmap.h" +#include "ui/gfx/size.h" + +namespace cc { + +class CC_EXPORT SharedBitmapManager { + public: + SharedBitmapManager() {} + + virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(gfx::Size) = 0; + virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId( + gfx::Size, + const SharedBitmapId&) = 0; + virtual scoped_ptr<SharedBitmap> GetBitmapForSharedMemory( + base::SharedMemory*) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SharedBitmapManager); +}; + +} // namespace cc + +#endif // CC_RESOURCES_SHARED_BITMAP_MANAGER_H_ diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc index 7292f1d..f533e65 100644 --- a/cc/resources/tile_manager_perftest.cc +++ b/cc/resources/tile_manager_perftest.cc @@ -40,7 +40,7 @@ class TileManagerPerfTest : public testing::Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); tile_manager_ = make_scoped_ptr( new FakeTileManager(&tile_manager_client_, resource_provider_.get())); picture_pile_ = FakePicturePileImpl::CreatePile(); diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index 2f9db48..c5bc6da 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -26,7 +26,7 @@ class TileManagerTest : public testing::TestWithParam<bool> { CHECK(output_surface_->BindToClient(&output_surface_client_)); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); tile_manager_ = make_scoped_ptr( new FakeTileManager(&tile_manager_client_, resource_provider_.get())); diff --git a/cc/resources/transferable_resource.cc b/cc/resources/transferable_resource.cc index 88ad8fd..62f1bdb 100644 --- a/cc/resources/transferable_resource.cc +++ b/cc/resources/transferable_resource.cc @@ -9,7 +9,12 @@ namespace cc { TransferableResource::TransferableResource() - : id(0), sync_point(0), format(RGBA_8888), target(0), filter(0) {} + : id(0), + sync_point(0), + format(RGBA_8888), + target(0), + filter(0), + is_software(false) {} TransferableResource::~TransferableResource() { } diff --git a/cc/resources/transferable_resource.h b/cc/resources/transferable_resource.h index cb650a7..5c93d1c 100644 --- a/cc/resources/transferable_resource.h +++ b/cc/resources/transferable_resource.h @@ -35,6 +35,7 @@ struct CC_EXPORT TransferableResource { uint32 filter; gfx::Size size; gpu::Mailbox mailbox; + bool is_software; }; } // namespace cc diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 34c7ab6..b819b38 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc @@ -261,24 +261,30 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 0xff); } - // In software mode, the resource provider won't be lost. Soon this callback - // will be called directly from the resource provider, same as 3d - // compositing mode, so this raw unretained resource_provider will always - // be valid when the callback is fired. RecycleResourceData recycle_data = { plane_resources[0].resource_id, plane_resources[0].resource_size, plane_resources[0].resource_format, gpu::Mailbox() }; + base::SharedMemory* shared_memory = + resource_provider_->GetSharedMemory(plane_resources[0].resource_id); + if (shared_memory) { + external_resources.mailboxes.push_back( + TextureMailbox(shared_memory, plane_resources[0].resource_size)); + external_resources.release_callbacks + .push_back(base::Bind(&RecycleResource, AsWeakPtr(), recycle_data)); + external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; + } else { + // TODO(jbauman): Remove this path once shared memory is available + // everywhere. + external_resources.software_resources + .push_back(plane_resources[0].resource_id); + external_resources.software_release_callback = + base::Bind(&RecycleResource, AsWeakPtr(), recycle_data); + external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; + } - external_resources.software_resources.push_back( - plane_resources[0].resource_id); - external_resources.software_release_callback = - base::Bind(&RecycleResource, AsWeakPtr(), recycle_data); - - - external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; return external_resources; } diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc index c36689e..028e0a6 100644 --- a/cc/resources/video_resource_updater_unittest.cc +++ b/cc/resources/video_resource_updater_unittest.cc @@ -26,7 +26,7 @@ class VideoResourceUpdaterTest : public testing::Test { FakeOutputSurface::Create3d(context3d.Pass()); CHECK(output_surface3d_->BindToClient(&client_)); resource_provider3d_ = - ResourceProvider::Create(output_surface3d_.get(), 0, false); + ResourceProvider::Create(output_surface3d_.get(), NULL, 0, false); } scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() { diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h index 074355d..3acfdd2 100644 --- a/cc/test/fake_layer_tree_host.h +++ b/cc/test/fake_layer_tree_host.h @@ -46,7 +46,7 @@ class FakeLayerTreeHost : protected LayerTreeHost { private: FakeLayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) - : LayerTreeHost(client, settings), + : LayerTreeHost(client, NULL, settings), host_impl_(settings, &proxy_), needs_commit_(false) {} diff --git a/cc/test/fake_layer_tree_host_impl.cc b/cc/test/fake_layer_tree_host_impl.cc index c1a7326..258617b 100644 --- a/cc/test/fake_layer_tree_host_impl.cc +++ b/cc/test/fake_layer_tree_host_impl.cc @@ -11,18 +11,19 @@ FakeLayerTreeHostImpl::FakeLayerTreeHostImpl(Proxy* proxy) : LayerTreeHostImpl(LayerTreeSettings(), &client_, proxy, - &stats_instrumentation_) { + &stats_instrumentation_, + NULL) { // Explicitly clear all debug settings. SetDebugState(LayerTreeDebugState()); } -FakeLayerTreeHostImpl::FakeLayerTreeHostImpl( - const LayerTreeSettings& settings, - Proxy* proxy) +FakeLayerTreeHostImpl::FakeLayerTreeHostImpl(const LayerTreeSettings& settings, + Proxy* proxy) : LayerTreeHostImpl(settings, &client_, proxy, - &stats_instrumentation_) { + &stats_instrumentation_, + NULL) { // Explicitly clear all debug settings. SetDebugState(LayerTreeDebugState()); } diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index da0ed55..f5d7cf3a 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -68,7 +68,8 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl { : LayerTreeHostImpl(settings, host_impl_client, proxy, - stats_instrumentation), + stats_instrumentation, + NULL), test_hooks_(test_hooks), block_notify_ready_to_activate_for_testing_(false), notify_ready_to_activate_was_blocked_(false) {} @@ -233,7 +234,7 @@ class LayerTreeHostForTesting : public LayerTreeHost { LayerTreeHostForTesting(TestHooks* test_hooks, LayerTreeHostClient* client, const LayerTreeSettings& settings) - : LayerTreeHost(client, settings), + : LayerTreeHost(client, NULL, settings), test_hooks_(test_hooks), test_started_(false) {} diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index 05688b1..55ff562 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -165,7 +165,7 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) { output_surface_->BindToClient(fake_client_.get()); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); texture_mailbox_deleter_ = make_scoped_ptr(new TextureMailboxDeleter); @@ -208,12 +208,12 @@ void PixelTest::SetUpSoftwareRenderer() { output_surface_.reset(new PixelTestOutputSurface(device.Pass())); output_surface_->BindToClient(fake_client_.get()); resource_provider_ = - ResourceProvider::Create(output_surface_.get(), 0, false); + ResourceProvider::Create(output_surface_.get(), NULL, 0, false); renderer_ = SoftwareRenderer::Create(fake_client_.get(), &settings_, output_surface_.get(), resource_provider_.get()) - .PassAs<DirectRenderer>(); + .PassAs<DirectRenderer>(); } } // namespace cc diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 2d3c608..cc92fe3 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -95,10 +95,11 @@ bool LayerTreeHost::AnyLayerTreeHostInstanceExists() { scoped_ptr<LayerTreeHost> LayerTreeHost::Create( LayerTreeHostClient* client, + SharedBitmapManager* manager, const LayerTreeSettings& settings, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(client, - settings)); + scoped_ptr<LayerTreeHost> layer_tree_host( + new LayerTreeHost(client, manager, settings)); if (!layer_tree_host->Initialize(impl_task_runner)) return scoped_ptr<LayerTreeHost>(); return layer_tree_host.Pass(); @@ -107,6 +108,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::Create( static int s_next_tree_id = 1; LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, + SharedBitmapManager* manager, const LayerTreeSettings& settings) : next_ui_resource_id_(1), animating_(false), @@ -134,7 +136,8 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, in_paint_layer_contents_(false), total_frames_used_for_lcd_text_metrics_(0), tree_id_(s_next_tree_id++), - next_commit_forces_redraw_(false) { + next_commit_forces_redraw_(false), + shared_bitmap_manager_(manager) { if (settings_.accelerated_animation_enabled) animation_registrar_ = AnimationRegistrar::Create(); s_num_layer_tree_instances++; @@ -469,7 +472,9 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( LayerTreeHostImpl::Create(settings_, client, proxy_.get(), - rendering_stats_instrumentation_.get()); + rendering_stats_instrumentation_.get(), + shared_bitmap_manager_); + shared_bitmap_manager_ = NULL; if (settings_.calculate_top_controls_position && host_impl->top_controls_manager()) { top_controls_manager_weak_ptr_ = diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index fa025b6..1a035d0 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -67,6 +67,7 @@ class Region; class RenderingStatsInstrumentation; class ResourceProvider; class ResourceUpdateQueue; +class SharedBitmapManager; class TopControlsManager; struct RenderingStats; struct ScrollAndScaleSet; @@ -123,8 +124,10 @@ class CC_EXPORT UIResourceRequest { class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { public: + // The SharedBitmapManager will be used on the compositor thread. static scoped_ptr<LayerTreeHost> Create( LayerTreeHostClient* client, + SharedBitmapManager* manager, const LayerTreeSettings& settings, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); virtual ~LayerTreeHost(); @@ -324,7 +327,9 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { const MicroBenchmark::DoneCallback& callback); protected: - LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings); + LayerTreeHost(LayerTreeHostClient* client, + SharedBitmapManager* manager, + const LayerTreeSettings& settings); bool Initialize(scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); bool InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing); void SetOutputSurfaceLostForTesting(bool is_lost) { @@ -465,6 +470,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) { scoped_refptr<Layer> inner_viewport_scroll_layer_; scoped_refptr<Layer> outer_viewport_scroll_layer_; + SharedBitmapManager* shared_bitmap_manager_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index ebc1d83..3b3746f1 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -180,19 +180,18 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy, - RenderingStatsInstrumentation* rendering_stats_instrumentation) { - return make_scoped_ptr( - new LayerTreeHostImpl(settings, - client, - proxy, - rendering_stats_instrumentation)); + RenderingStatsInstrumentation* rendering_stats_instrumentation, + SharedBitmapManager* manager) { + return make_scoped_ptr(new LayerTreeHostImpl( + settings, client, proxy, rendering_stats_instrumentation, manager)); } LayerTreeHostImpl::LayerTreeHostImpl( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy, - RenderingStatsInstrumentation* rendering_stats_instrumentation) + RenderingStatsInstrumentation* rendering_stats_instrumentation, + SharedBitmapManager* manager) : client_(client), proxy_(proxy), input_handler_client_(NULL), @@ -230,7 +229,8 @@ LayerTreeHostImpl::LayerTreeHostImpl( external_stencil_test_enabled_(false), animation_registrar_(AnimationRegistrar::Create()), rendering_stats_instrumentation_(rendering_stats_instrumentation), - need_to_update_visible_tiles_before_draw_(false) { + need_to_update_visible_tiles_before_draw_(false), + shared_bitmap_manager_(manager) { DCHECK(proxy_->IsImplThread()); DidVisibilityChange(this, visible_); @@ -513,7 +513,8 @@ static DrawMode GetDrawMode(OutputSurface* output_surface) { } else if (output_surface->context_provider()) { return DRAW_MODE_HARDWARE; } else { - DCHECK(output_surface->software_device()); + DCHECK_EQ(!output_surface->software_device(), + output_surface->capabilities().delegated_rendering); return DRAW_MODE_SOFTWARE; } } @@ -1682,10 +1683,11 @@ bool LayerTreeHostImpl::InitializeRenderer( if (!output_surface->BindToClient(this)) return false; - scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( - output_surface.get(), - settings_.highp_threshold_min, - settings_.use_rgba_4444_textures); + scoped_ptr<ResourceProvider> resource_provider = + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_, + settings_.highp_threshold_min, + settings_.use_rgba_4444_textures); if (!resource_provider) return false; diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 555cb24..a2991f2 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -99,7 +99,8 @@ class CC_EXPORT LayerTreeHostImpl const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy, - RenderingStatsInstrumentation* rendering_stats_instrumentation); + RenderingStatsInstrumentation* rendering_stats_instrumentation, + SharedBitmapManager* manager); virtual ~LayerTreeHostImpl(); // InputHandler implementation @@ -411,7 +412,8 @@ class CC_EXPORT LayerTreeHostImpl const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy, - RenderingStatsInstrumentation* rendering_stats_instrumentation); + RenderingStatsInstrumentation* rendering_stats_instrumentation, + SharedBitmapManager* manager); // Virtual for testing. virtual void AnimateLayers(base::TimeTicks monotonic_time, @@ -620,6 +622,8 @@ class CC_EXPORT LayerTreeHostImpl // Optional callback to notify of new tree activations. base::Closure tree_activation_callback_; + SharedBitmapManager* shared_bitmap_manager_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index f635025..dd76c06 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -92,10 +92,8 @@ class LayerTreeHostImplTest : public testing::Test, settings.minimum_occlusion_tracking_size = gfx::Size(); settings.impl_side_painting = true; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); host_impl_->InitializeRenderer(CreateOutputSurface()); host_impl_->SetViewportSize(gfx::Size(10, 10)); } @@ -157,10 +155,8 @@ class LayerTreeHostImplTest : public testing::Test, settings.minimum_occlusion_tracking_size = gfx::Size(); settings.partial_swap_enabled = partial_swap; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); host_impl_->InitializeRenderer(output_surface.Pass()); host_impl_->SetViewportSize(gfx::Size(10, 10)); @@ -391,7 +387,7 @@ TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) { LayerTreeSettings settings; settings.impl_side_painting = true; host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_); + settings, this, &proxy_, &stats_instrumentation_, NULL); scoped_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::CreateAlwaysDrawAndSwap3d()); @@ -494,10 +490,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { LayerTreeSettings settings; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); scoped_ptr<TestWebGraphicsContext3D> context_owned = TestWebGraphicsContext3D::Create(); context_owned->set_times_make_current_succeeds(0); @@ -1152,8 +1146,8 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { : LayerTreeHostImpl(settings, client, proxy, - rendering_stats_instrumentation) {} - + rendering_stats_instrumentation, + NULL) {} virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE { return fake_current_physical_time_; @@ -1286,7 +1280,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( gfx::Size content_size(1000, 1000); host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_); + settings, this, &proxy_, &stats_instrumentation_, NULL); host_impl_->InitializeRenderer(CreateOutputSurface()); host_impl_->SetDeviceScaleFactor(device_scale_factor); host_impl_->SetViewportSize(device_viewport_size); @@ -1794,10 +1788,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) { settings.calculate_top_controls_position = true; settings.top_controls_height = 50; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); host_impl_->InitializeRenderer(CreateOutputSurface()); host_impl_->SetViewportSize(gfx::Size(10, 10)); @@ -2759,7 +2751,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { LayerTreeSettings settings; settings.always_overscroll = true; host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_); + settings, this, &proxy_, &stats_instrumentation_, NULL); SetupScrollAndContentsLayers(gfx::Size(50, 50)); host_impl_->SetViewportSize(gfx::Size(50, 50)); @@ -3112,7 +3104,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { settings.minimum_occlusion_tracking_size = gfx::Size(); settings.impl_side_painting = true; host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_); + settings, this, &proxy_, &stats_instrumentation_, NULL); scoped_ptr<FakeOutputSurface> output_surface; if (always_draw) @@ -3532,10 +3524,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { LayerTreeSettings settings; settings.partial_swap_enabled = true; scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); @@ -3847,8 +3837,8 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( LayerTreeSettings settings; settings.partial_swap_enabled = partial_swap; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, client, proxy, stats_instrumentation); + scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( + settings, client, proxy, stats_instrumentation, NULL); my_host_impl->InitializeRenderer(output_surface.Pass()); my_host_impl->SetViewportSize(gfx::Size(100, 100)); @@ -4228,10 +4218,8 @@ class FakeMaskLayerImpl : public LayerImpl { TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { LayerTreeSettings settings; settings.layer_transforms_should_scale_layer_contents = true; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); host_impl_->InitializeRenderer(CreateOutputSurface()); host_impl_->SetViewportSize(gfx::Size(10, 10)); @@ -5219,10 +5207,8 @@ TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) { // doesn't support memory management extensions. TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { LayerTreeSettings settings; - host_impl_ = LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); + host_impl_ = LayerTreeHostImpl::Create( + settings, this, &proxy_, &stats_instrumentation_, NULL); scoped_ptr<OutputSurface> output_surface( FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create())); @@ -5331,12 +5317,10 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); - host_impl_ = LayerTreeHostImpl::Create(LayerTreeSettings(), - this, - &proxy_, - &stats_instrumentation_); - host_impl_->InitializeRenderer( - FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>()); + host_impl_ = LayerTreeHostImpl::Create( + LayerTreeSettings(), this, &proxy_, &stats_instrumentation_, NULL); + host_impl_->InitializeRenderer(FakeOutputSurface::Create3d(context_provider) + .PassAs<OutputSurface>()); host_impl_->SetViewportSize(gfx::Size(10, 10)); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index c5127b1..1029b2e 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -2204,7 +2204,7 @@ class LayerTreeHostWithProxy : public LayerTreeHost { LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, const LayerTreeSettings& settings, scoped_ptr<FakeProxy> proxy) - : LayerTreeHost(client, settings) { + : LayerTreeHost(client, NULL, settings) { proxy->SetLayerTreeHost(this); EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>())); } @@ -2272,7 +2272,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { settings.max_partial_texture_updates = 4; scoped_ptr<LayerTreeHost> host = - LayerTreeHost::Create(&client, settings, NULL); + LayerTreeHost::Create(&client, NULL, settings, NULL); EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); } @@ -2284,7 +2284,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { settings.max_partial_texture_updates = 4; scoped_ptr<LayerTreeHost> host = - LayerTreeHost::Create(&client, settings, NULL); + LayerTreeHost::Create(&client, NULL, settings, NULL); EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); } @@ -2296,7 +2296,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { settings.max_partial_texture_updates = 4; scoped_ptr<LayerTreeHost> host = - LayerTreeHost::Create(&client, settings, NULL); + LayerTreeHost::Create(&client, NULL, settings, NULL); EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); } @@ -2309,7 +2309,7 @@ TEST(LayerTreeHostTest, settings.max_partial_texture_updates = 4; scoped_ptr<LayerTreeHost> host = - LayerTreeHost::Create(&client, settings, NULL); + LayerTreeHost::Create(&client, NULL, settings, NULL); EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded()); EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); } diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index e4a0ca7..ab6e93e 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -1089,7 +1089,7 @@ class LayerTreeHostContextTestDontUseLostResources child_output_surface_ = FakeOutputSurface::Create3d(); child_output_surface_->BindToClient(&output_surface_client_); child_resource_provider_ = - ResourceProvider::Create(child_output_surface_.get(), 0, false); + ResourceProvider::Create(child_output_surface_.get(), NULL, 0, false); } static void EmptyReleaseCallback(unsigned sync_point, bool lost) {} @@ -1781,6 +1781,7 @@ class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface settings.impl_side_painting = impl_side_painting; scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::Create( this, + NULL, settings, impl_thread ? impl_thread->message_loop_proxy() : NULL); EXPECT_FALSE(layer_tree_host); diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index ab87be1..88630be 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc @@ -1013,7 +1013,7 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { ASSERT_TRUE(impl_thread.message_loop_proxy().get()); scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::Create( - &client, settings, impl_thread.message_loop_proxy()); + &client, NULL, settings, impl_thread.message_loop_proxy()); impl_thread.message_loop_proxy() ->PostTask(FROM_HERE, diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc index 4e0c89f..3910bc0 100644 --- a/cc/trees/tree_synchronizer_unittest.cc +++ b/cc/trees/tree_synchronizer_unittest.cc @@ -552,11 +552,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeAnimations) { FakeProxy proxy; DebugScopedSetImplThread impl(&proxy); FakeRenderingStatsInstrumentation stats_instrumentation; - scoped_ptr<LayerTreeHostImpl> host_impl = - LayerTreeHostImpl::Create(settings, - NULL, - &proxy, - &stats_instrumentation); + scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( + settings, NULL, &proxy, &stats_instrumentation, NULL); scoped_refptr<Layer> layer_tree_root = Layer::Create(); host_->SetRootLayer(layer_tree_root); @@ -587,11 +584,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) { FakeProxy proxy; DebugScopedSetImplThread impl(&proxy); FakeRenderingStatsInstrumentation stats_instrumentation; - scoped_ptr<LayerTreeHostImpl> host_impl = - LayerTreeHostImpl::Create(settings, - NULL, - &proxy, - &stats_instrumentation); + scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( + settings, NULL, &proxy, &stats_instrumentation, NULL); scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> scroll_parent = Layer::Create(); @@ -665,11 +659,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) { FakeProxy proxy; DebugScopedSetImplThread impl(&proxy); FakeRenderingStatsInstrumentation stats_instrumentation; - scoped_ptr<LayerTreeHostImpl> host_impl = - LayerTreeHostImpl::Create(settings, - NULL, - &proxy, - &stats_instrumentation); + scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( + settings, NULL, &proxy, &stats_instrumentation, NULL); scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> clip_parent = Layer::Create(); |