Index: cc/resources/resource_provider.cc |
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
index 2f5b0a9d7917ea2fd00472cea2992a0c268b67a2..125bdf60732c9f1325444b71c7fa887d7cc1e67c 100644 |
--- a/cc/resources/resource_provider.cc |
+++ b/cc/resources/resource_provider.cc |
@@ -324,11 +324,13 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create( |
BlockingTaskRunner* blocking_main_thread_task_runner, |
int highp_threshold_min, |
size_t id_allocation_chunk_size, |
+ bool use_gpu_memory_buffer_resources, |
const std::vector<unsigned>& use_image_texture_targets) { |
scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider( |
output_surface, shared_bitmap_manager, gpu_memory_buffer_manager, |
blocking_main_thread_task_runner, highp_threshold_min, |
- id_allocation_chunk_size, use_image_texture_targets)); |
+ id_allocation_chunk_size, use_gpu_memory_buffer_resources, |
+ use_image_texture_targets)); |
resource_provider->Initialize(); |
return resource_provider; |
} |
@@ -386,10 +388,10 @@ ResourceId ResourceProvider::CreateResource(const gfx::Size& size, |
DCHECK(!size.IsEmpty()); |
switch (default_resource_type_) { |
case RESOURCE_TYPE_GL_TEXTURE: |
- return CreateGLTexture(size, |
- GL_TEXTURE_2D, |
- hint, |
- format); |
+ return CreateGLTexture(size, use_gpu_memory_buffer_resources_ |
+ ? GetImageTextureTarget(format) |
+ : GL_TEXTURE_2D, |
+ hint, format); |
case RESOURCE_TYPE_BITMAP: |
DCHECK_EQ(RGBA_8888, format); |
return CreateBitmap(size); |
@@ -816,6 +818,8 @@ ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL( |
resource_provider_->LazyAllocate(resource_); |
texture_id_ = resource_->gl_id; |
DCHECK(texture_id_); |
+ if (resource_->dirty_image) |
+ resource_provider_->BindImageForSampling(resource_); |
} |
ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() { |
@@ -860,13 +864,10 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider, |
ResourceId resource_id) |
: resource_provider_(resource_provider), |
- resource_(resource_provider->LockForWrite(resource_id)), |
- gpu_memory_buffer_manager_(resource_provider->gpu_memory_buffer_manager_), |
- gpu_memory_buffer_(nullptr), |
- size_(resource_->size), |
- format_(resource_->format) { |
+ resource_(resource_provider->LockForWrite(resource_id)) { |
DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource_->type); |
- std::swap(gpu_memory_buffer_, resource_->gpu_memory_buffer); |
+ gpu_memory_buffer_.reset(resource_->gpu_memory_buffer); |
+ resource_->gpu_memory_buffer = nullptr; |
} |
ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
@@ -876,27 +877,13 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
if (!gpu_memory_buffer_) |
return; |
+ DCHECK(!resource_->gpu_memory_buffer); |
resource_provider_->LazyCreate(resource_); |
- |
- if (!resource_->image_id) { |
- GLES2Interface* gl = resource_provider_->ContextGL(); |
- DCHECK(gl); |
- |
-#if defined(OS_CHROMEOS) |
- // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization |
- // on ChromeOS to avoid some performance issues. This only works with |
- // shared memory backed buffers. crbug.com/436314 |
- DCHECK_EQ(gpu_memory_buffer_->GetHandle().type, gfx::SHARED_MEMORY_BUFFER); |
-#endif |
- |
- resource_->image_id = gl->CreateImageCHROMIUM( |
- gpu_memory_buffer_->AsClientBuffer(), size_.width(), size_.height(), |
- GLInternalFormat(resource_->format)); |
- } |
- |
- std::swap(resource_->gpu_memory_buffer, gpu_memory_buffer_); |
+ resource_->gpu_memory_buffer = gpu_memory_buffer_.release(); |
resource_->allocated = true; |
+ resource_provider_->LazyCreateImage(resource_); |
resource_->dirty_image = true; |
+ resource_->is_overlay_candidate = true; |
// GpuMemoryBuffer provides direct access to the memory used by the GPU. |
// Read lock fences are required to ensure that we're not trying to map a |
@@ -906,14 +893,13 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
gfx::GpuMemoryBuffer* |
ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() { |
- if (gpu_memory_buffer_) |
- return gpu_memory_buffer_; |
- scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer = |
- gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
- size_, BufferFormat(format_), |
- gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); |
- gpu_memory_buffer_ = gpu_memory_buffer.release(); |
- return gpu_memory_buffer_; |
+ if (!gpu_memory_buffer_) { |
+ gpu_memory_buffer_ = |
+ resource_provider_->gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
+ resource_->size, BufferFormat(resource_->format), |
+ gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); |
+ } |
+ return gpu_memory_buffer_.get(); |
} |
ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( |
@@ -1002,6 +988,7 @@ ResourceProvider::ResourceProvider( |
BlockingTaskRunner* blocking_main_thread_task_runner, |
int highp_threshold_min, |
size_t id_allocation_chunk_size, |
+ bool use_gpu_memory_buffer_resources, |
const std::vector<unsigned>& use_image_texture_targets) |
: output_surface_(output_surface), |
shared_bitmap_manager_(shared_bitmap_manager), |
@@ -1012,6 +999,7 @@ ResourceProvider::ResourceProvider( |
next_id_(1), |
next_child_(1), |
default_resource_type_(RESOURCE_TYPE_BITMAP), |
+ use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources), |
use_texture_storage_ext_(false), |
use_texture_format_bgra_(false), |
use_texture_usage_hint_(false), |
@@ -1309,11 +1297,8 @@ void ResourceProvider::TransferResource(GLES2Interface* gl, |
LazyCreate(source); |
DCHECK(source->gl_id); |
DCHECK(source->origin == Resource::INTERNAL); |
- if (source->image_id) { |
- DCHECK(source->dirty_image); |
- gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id); |
+ if (source->image_id && source->dirty_image) |
BindImageForSampling(source); |
- } |
// This is a resource allocated by the compositor, we need to produce it. |
// Don't set a sync point, the caller will do it. |
gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name); |
@@ -1327,7 +1312,6 @@ void ResourceProvider::TransferResource(GLES2Interface* gl, |
if (source->image_id && source->dirty_image) { |
DCHECK(source->gl_id); |
DCHECK(source->origin == Resource::INTERNAL); |
- gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id); |
BindImageForSampling(source); |
} |
// This is either an external resource, or a compositor resource that we |
@@ -1515,9 +1499,18 @@ void ResourceProvider::LazyAllocate(Resource* resource) { |
gfx::Size& size = resource->size; |
ResourceFormat format = resource->format; |
gl->BindTexture(resource->target, resource->gl_id); |
- if (use_texture_storage_ext_ && |
- IsFormatSupportedForStorage(format, use_texture_format_bgra_) && |
- (resource->hint & TEXTURE_HINT_IMMUTABLE)) { |
+ if (use_gpu_memory_buffer_resources_) { |
+ resource->gpu_memory_buffer = |
+ gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
+ size, BufferFormat(format), |
+ gfx::BufferUsage::SCANOUT) |
+ .release(); |
+ LazyCreateImage(resource); |
+ resource->dirty_image = true; |
+ resource->is_overlay_candidate = true; |
+ } else if (use_texture_storage_ext_ && |
+ IsFormatSupportedForStorage(format, use_texture_format_bgra_) && |
+ (resource->hint & TEXTURE_HINT_IMMUTABLE)) { |
GLenum storage_format = TextureToStorageFormat(format); |
gl->TexStorage2DEXT(resource->target, 1, storage_format, size.width(), |
size.height()); |
@@ -1531,12 +1524,34 @@ void ResourceProvider::LazyAllocate(Resource* resource) { |
} |
} |
+void ResourceProvider::LazyCreateImage(Resource* resource) { |
+ DCHECK(resource->gpu_memory_buffer); |
+ DCHECK(resource->gl_id); |
+ DCHECK(resource->allocated); |
+ if (!resource->image_id) { |
+ GLES2Interface* gl = ContextGL(); |
+ DCHECK(gl); |
+ |
+#if defined(OS_CHROMEOS) |
+ // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization |
+ // on ChromeOS to avoid some performance issues. This only works with |
+ // shared memory backed buffers. crbug.com/436314 |
+ DCHECK_EQ(resource->gpu_memory_buffer->GetHandle().type, |
+ gfx::SHARED_MEMORY_BUFFER); |
+#endif |
+ resource->image_id = gl->CreateImageCHROMIUM( |
+ resource->gpu_memory_buffer->AsClientBuffer(), resource->size.width(), |
+ resource->size.height(), GLInternalFormat(resource->format)); |
+ } |
+} |
+ |
void ResourceProvider::BindImageForSampling(Resource* resource) { |
GLES2Interface* gl = ContextGL(); |
DCHECK(resource->gl_id); |
DCHECK(resource->image_id); |
// Release image currently bound to texture. |
+ gl->BindTexture(resource->target, resource->gl_id); |
if (resource->bound_image_id) |
gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id); |
gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id); |