| Index: cc/resources/resource_provider.cc
|
| diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
|
| index 8d5a3fce7fe37616bef719b2332ca41d18e7b74d..d4a33ab9347615973e055b1513addb59952b30ac 100644
|
| --- a/cc/resources/resource_provider.cc
|
| +++ b/cc/resources/resource_provider.cc
|
| @@ -928,8 +928,7 @@ void ResourceProvider::CopyToResource(ResourceId id,
|
| gl->OrderingBarrierCHROMIUM();
|
| gpu::SyncToken sync_token;
|
| gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
|
| - lock.set_sync_token(sync_token);
|
| - lock.set_synchronized(true);
|
| + lock.UpdateSyncToken(sync_token);
|
| }
|
| }
|
|
|
| @@ -1131,13 +1130,9 @@ void ResourceProvider::EnableReadLockFencesForTesting(ResourceId id) {
|
| ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
|
| ResourceProvider* resource_provider,
|
| ResourceId resource_id)
|
| - : resource_provider_(resource_provider), resource_id_(resource_id) {
|
| - const Resource* resource = resource_provider->LockForRead(resource_id);
|
| - texture_id_ = resource->gl_id;
|
| - target_ = resource->target;
|
| - size_ = resource->size;
|
| - color_space_ = resource->color_space;
|
| -}
|
| + : resource_provider_(resource_provider),
|
| + resource_id_(resource_id),
|
| + resource_(resource_provider->LockForRead(resource_id)) {}
|
|
|
| ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
|
| resource_provider_->UnlockForRead(resource_id_);
|
| @@ -1165,50 +1160,52 @@ ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {}
|
| ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
|
| ResourceProvider* resource_provider,
|
| ResourceId resource_id,
|
| - bool create_mailbox)
|
| + bool async_worker_context_enabled)
|
| : resource_provider_(resource_provider),
|
| - resource_id_(resource_id),
|
| - has_sync_token_(false),
|
| - synchronized_(false) {
|
| + resource_(resource_provider->LockForWrite(resource_id)) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - Resource* resource = resource_provider->LockForWrite(resource_id);
|
| - resource_provider_->LazyAllocate(resource);
|
| - if (resource->image_id && resource->dirty_image)
|
| - resource_provider_->BindImageForSampling(resource);
|
| - if (create_mailbox) {
|
| - resource_provider_->CreateMailboxAndBindResource(
|
| - resource_provider_->ContextGL(), resource);
|
| + resource_provider_->LazyCreate(resource_);
|
| + if (async_worker_context_enabled) {
|
| + resource_provider_->LazyCreateMailbox(resource_);
|
| + } else {
|
| + resource_provider_->LazyAllocate(resource_, resource_provider_->ContextGL(),
|
| + resource_->gl_id);
|
| + }
|
| + if (resource_->image_id && resource_->dirty_image) {
|
| + resource_provider_->BindImageForSampling(
|
| + resource_, resource_provider_->ContextGL(), resource_->gl_id);
|
| }
|
| - texture_id_ = resource->gl_id;
|
| - target_ = resource->target;
|
| - format_ = resource->format;
|
| - size_ = resource->size;
|
| - mailbox_ = resource->mailbox();
|
| - color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource);
|
| }
|
|
|
| ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - Resource* resource = resource_provider_->GetResource(resource_id_);
|
| - DCHECK(resource->locked_for_write);
|
| - // It's not sufficient to check sync_token_.HasData() here because the sync
|
| - // might be null because of context loss. Even in that case we want to set the
|
| - // sync token because it's checked in PrepareSendToParent while drawing.
|
| - if (has_sync_token_)
|
| - resource->UpdateSyncToken(sync_token_);
|
| - if (synchronized_)
|
| - resource->SetSynchronized();
|
| - resource_provider_->UnlockForWrite(resource);
|
| + DCHECK(resource_->locked_for_write);
|
| + if (resource_->synchronization_state() == Resource::LOCALLY_USED)
|
| + resource_->SetSynchronized();
|
| + resource_provider_->UnlockForWrite(resource_);
|
| +}
|
| +
|
| +void ResourceProvider::ScopedWriteLockGL::LazyAllocate(
|
| + gpu::gles2::GLES2Interface* gl,
|
| + unsigned gl_id) {
|
| + resource_provider_->LazyAllocate(resource_, gl, gl_id);
|
| +}
|
| +
|
| +void ResourceProvider::ScopedWriteLockGL::UpdateSyncToken(
|
| + const gpu::SyncToken& sync_token) {
|
| + resource_->UpdateSyncToken(sync_token);
|
| }
|
|
|
| ResourceProvider::ScopedTextureProvider::ScopedTextureProvider(
|
| gpu::gles2::GLES2Interface* gl,
|
| ScopedWriteLockGL* resource_lock,
|
| - bool use_mailbox)
|
| - : gl_(gl), use_mailbox_(use_mailbox) {
|
| - if (use_mailbox_) {
|
| + bool async_worker_context_enabled)
|
| + : gl_(gl), async_worker_context_enabled_(async_worker_context_enabled) {
|
| + if (async_worker_context_enabled) {
|
| + DCHECK(resource_lock->mailbox().IsValid());
|
| texture_id_ = gl_->CreateAndConsumeTextureCHROMIUM(
|
| resource_lock->target(), resource_lock->mailbox().name());
|
| + resource_lock->LazyAllocate(gl, texture_id_);
|
| } else {
|
| texture_id_ = resource_lock->texture_id();
|
| }
|
| @@ -1216,20 +1213,20 @@ ResourceProvider::ScopedTextureProvider::ScopedTextureProvider(
|
| }
|
|
|
| ResourceProvider::ScopedTextureProvider::~ScopedTextureProvider() {
|
| - if (use_mailbox_)
|
| + if (async_worker_context_enabled_)
|
| gl_->DeleteTextures(1, &texture_id_);
|
| }
|
|
|
| ResourceProvider::ScopedSkSurfaceProvider::ScopedSkSurfaceProvider(
|
| ContextProvider* context_provider,
|
| ScopedWriteLockGL* resource_lock,
|
| - bool use_mailbox,
|
| + bool async_worker_context_enabled,
|
| bool use_distance_field_text,
|
| bool can_use_lcd_text,
|
| int msaa_sample_count)
|
| : texture_provider_(context_provider->ContextGL(),
|
| resource_lock,
|
| - use_mailbox) {
|
| + async_worker_context_enabled) {
|
| GrGLTextureInfo texture_info;
|
| texture_info.fID = texture_provider_.texture_id();
|
| texture_info.fTarget = resource_lock->target();
|
| @@ -1323,68 +1320,48 @@ ResourceProvider::ScopedReadLockSkImage::~ScopedReadLockSkImage() {
|
| ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
|
| ResourceProvider* resource_provider,
|
| ResourceId resource_id)
|
| - : resource_provider_(resource_provider), resource_id_(resource_id) {
|
| - Resource* resource = resource_provider->LockForWrite(resource_id);
|
| - resource_provider->PopulateSkBitmapWithResource(&sk_bitmap_, resource);
|
| - color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource);
|
| + : resource_provider_(resource_provider),
|
| + resource_(resource_provider->LockForWrite(resource_id)),
|
| + color_space_(
|
| + resource_provider->GetResourceColorSpaceForRaster(resource_)) {
|
| + resource_provider->PopulateSkBitmapWithResource(&sk_bitmap_, resource_);
|
| DCHECK(valid());
|
| }
|
|
|
| ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - Resource* resource = resource_provider_->GetResource(resource_id_);
|
| - DCHECK(resource);
|
| - resource->SetSynchronized();
|
| - resource_provider_->UnlockForWrite(resource);
|
| + resource_->SetSynchronized();
|
| + resource_provider_->UnlockForWrite(resource_);
|
| }
|
|
|
| ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
|
| ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
|
| ResourceId resource_id)
|
| - : resource_provider_(resource_provider), resource_id_(resource_id) {
|
| - Resource* resource = resource_provider->LockForWrite(resource_id);
|
| - DCHECK(IsGpuResourceType(resource->type));
|
| - format_ = resource->format;
|
| - size_ = resource->size;
|
| - usage_ = resource->usage;
|
| - gpu_memory_buffer_ = std::move(resource->gpu_memory_buffer);
|
| - resource->gpu_memory_buffer = nullptr;
|
| - color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource);
|
| + : resource_provider_(resource_provider),
|
| + resource_(resource_provider->LockForWrite(resource_id)),
|
| + color_space_(
|
| + resource_provider->GetResourceColorSpaceForRaster(resource_)) {
|
| + DCHECK(IsGpuResourceType(resource_->type));
|
| }
|
|
|
| ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
|
| ~ScopedWriteLockGpuMemoryBuffer() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - Resource* resource = resource_provider_->GetResource(resource_id_);
|
| - DCHECK(resource);
|
| - if (gpu_memory_buffer_) {
|
| - // Note that this impacts overlay compositing, not rasterization.
|
| - if (resource_provider_->settings_.enable_color_correct_rasterization)
|
| - gpu_memory_buffer_->SetColorSpaceForScanout(resource->color_space);
|
| - DCHECK(!resource->gpu_memory_buffer);
|
| - resource_provider_->LazyCreate(resource);
|
| - resource->gpu_memory_buffer = std::move(gpu_memory_buffer_);
|
| - 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
|
| - // buffer that is currently in-use by the GPU.
|
| - resource->read_lock_fences_enabled = true;
|
| + if (resource_->gpu_memory_buffer) {
|
| + resource_provider_->LazyCreate(resource_);
|
| + resource_provider_->LazyCreateImage(resource_,
|
| + resource_provider_->ContextGL());
|
| + resource_provider_->BindImageForSampling(
|
| + resource_, resource_provider_->ContextGL(), resource_->gl_id);
|
| }
|
| - resource->SetSynchronized();
|
| - resource_provider_->UnlockForWrite(resource);
|
| + resource_->SetSynchronized();
|
| + resource_provider_->UnlockForWrite(resource_);
|
| }
|
|
|
| gfx::GpuMemoryBuffer*
|
| ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
|
| - if (!gpu_memory_buffer_) {
|
| - gpu_memory_buffer_ =
|
| - resource_provider_->gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
|
| - size_, BufferFormat(format_), usage_, gpu::kNullSurfaceHandle);
|
| - }
|
| - return gpu_memory_buffer_.get();
|
| + resource_provider_->LazyAllocateGpuMemoryBuffer(resource_);
|
| + return resource_->gpu_memory_buffer.get();
|
| }
|
|
|
| ResourceProvider::ScopedBatchReturnResources::ScopedBatchReturnResources(
|
| @@ -1509,7 +1486,10 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resource_ids,
|
| if (!IsGpuResourceType(resource->type))
|
| continue;
|
|
|
| - CreateMailboxAndBindResource(gl, resource);
|
| + // Texture must already be bound to image.
|
| + DCHECK(!resource->image_id || !resource->dirty_image);
|
| +
|
| + LazyCreateMailbox(resource);
|
|
|
| if (settings_.delegated_sync_points_required) {
|
| if (resource->needs_sync_token()) {
|
| @@ -1750,31 +1730,6 @@ void ResourceProvider::SendPromotionHints(
|
| }
|
| #endif
|
|
|
| -void ResourceProvider::CreateMailboxAndBindResource(
|
| - gpu::gles2::GLES2Interface* gl,
|
| - Resource* resource) {
|
| - DCHECK(IsGpuResourceType(resource->type));
|
| - DCHECK(gl);
|
| -
|
| - if (!resource->mailbox().IsValid()) {
|
| - LazyCreate(resource);
|
| -
|
| - gpu::MailboxHolder mailbox_holder;
|
| - mailbox_holder.texture_target = resource->target;
|
| - gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name);
|
| - gl->ProduceTextureDirectCHROMIUM(resource->gl_id,
|
| - mailbox_holder.texture_target,
|
| - mailbox_holder.mailbox.name);
|
| - resource->set_mailbox(TextureMailbox(mailbox_holder));
|
| - }
|
| -
|
| - if (resource->image_id && resource->dirty_image) {
|
| - DCHECK(resource->gl_id);
|
| - DCHECK(resource->origin == Resource::INTERNAL);
|
| - BindImageForSampling(resource);
|
| - }
|
| -}
|
| -
|
| void ResourceProvider::TransferResource(Resource* source,
|
| ResourceId id,
|
| TransferableResource* resource) {
|
| @@ -1948,7 +1903,7 @@ GLenum ResourceProvider::BindForSampling(ResourceId resource_id,
|
| }
|
|
|
| if (resource->image_id && resource->dirty_image)
|
| - BindImageForSampling(resource);
|
| + BindImageForSampling(resource, gl, resource->gl_id);
|
|
|
| return target;
|
| }
|
| @@ -1987,68 +1942,98 @@ void ResourceProvider::LazyCreate(Resource* resource) {
|
| }
|
| }
|
|
|
| +void ResourceProvider::LazyCreateMailbox(Resource* resource) {
|
| + DCHECK(resource);
|
| + DCHECK(resource->gl_id);
|
| +
|
| + if (!resource->mailbox().IsValid()) {
|
| + gpu::gles2::GLES2Interface* gl = ContextGL();
|
| + DCHECK(gl);
|
| +
|
| + gpu::MailboxHolder mailbox_holder;
|
| + mailbox_holder.texture_target = resource->target;
|
| + gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name);
|
| + gl->ProduceTextureDirectCHROMIUM(resource->gl_id,
|
| + mailbox_holder.texture_target,
|
| + mailbox_holder.mailbox.name);
|
| + resource->set_mailbox(TextureMailbox(mailbox_holder));
|
| + }
|
| +}
|
| +
|
| void ResourceProvider::AllocateForTesting(ResourceId id) {
|
| - LazyAllocate(GetResource(id));
|
| + Resource* resource = GetResource(id);
|
| + LazyCreate(resource);
|
| + LazyAllocate(resource, ContextGL(), resource->gl_id);
|
| }
|
|
|
| -void ResourceProvider::LazyAllocate(Resource* resource) {
|
| - DCHECK(resource);
|
| +void ResourceProvider::LazyAllocate(ResourceProvider::Resource* resource,
|
| + gpu::gles2::GLES2Interface* gl,
|
| + unsigned gl_id) {
|
| + DCHECK(resource->locked_for_write);
|
| +
|
| if (resource->allocated)
|
| return;
|
| - LazyCreate(resource);
|
| - if (!resource->gl_id)
|
| - return;
|
| resource->allocated = true;
|
| - GLES2Interface* gl = ContextGL();
|
| +
|
| + GLenum target = resource->target;
|
| gfx::Size& size = resource->size;
|
| ResourceFormat format = resource->format;
|
| - gl->BindTexture(resource->target, resource->gl_id);
|
| - if (resource->type == RESOURCE_TYPE_GPU_MEMORY_BUFFER) {
|
| - resource->gpu_memory_buffer =
|
| - gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
|
| - size, BufferFormat(format), resource->usage,
|
| - gpu::kNullSurfaceHandle);
|
| - // Note that this impacts overlay compositing, not rasterization.
|
| - if (resource->gpu_memory_buffer &&
|
| - settings_.enable_color_correct_rasterization) {
|
| - resource->gpu_memory_buffer->SetColorSpaceForScanout(
|
| - resource->color_space);
|
| - }
|
|
|
| - 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
|
| - // buffer that is currently in-use by the GPU.
|
| - resource->read_lock_fences_enabled = true;
|
| + gl->BindTexture(target, gl_id);
|
| +
|
| + if (resource->type == RESOURCE_TYPE_GPU_MEMORY_BUFFER) {
|
| + LazyAllocateGpuMemoryBuffer(resource);
|
| + LazyCreateImage(resource, gl);
|
| + BindImageForSampling(resource, gl, gl_id);
|
| } else if (settings_.use_texture_storage_ext &&
|
| IsFormatSupportedForStorage(format,
|
| settings_.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());
|
| - } else {
|
| + gl->TexStorage2DEXT(target, 1, storage_format, size.width(), size.height());
|
| + } else if (format != ETC1) {
|
| // ETC1 does not support preallocation.
|
| - if (format != ETC1) {
|
| - gl->TexImage2D(resource->target, 0, GLInternalFormat(format),
|
| - size.width(), size.height(), 0, GLDataFormat(format),
|
| - GLDataType(format), nullptr);
|
| - }
|
| + gl->TexImage2D(target, 0, GLInternalFormat(format), size.width(),
|
| + size.height(), 0, GLDataFormat(format), GLDataType(format),
|
| + nullptr);
|
| }
|
| }
|
|
|
| -void ResourceProvider::LazyCreateImage(Resource* resource) {
|
| +void ResourceProvider::LazyAllocateGpuMemoryBuffer(Resource* resource) {
|
| + DCHECK(resource->locked_for_write);
|
| +
|
| + if (resource->allocated)
|
| + return;
|
| + resource->allocated = true;
|
| +
|
| + DCHECK(!resource->gpu_memory_buffer);
|
| + resource->gpu_memory_buffer =
|
| + gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
|
| + resource->size, BufferFormat(resource->format), resource->usage,
|
| + gpu::kNullSurfaceHandle);
|
| + // Note that this impacts overlay compositing, not rasterization.
|
| + if (settings_.enable_color_correct_rasterization)
|
| + resource->gpu_memory_buffer->SetColorSpaceForScanout(resource->color_space);
|
| +
|
| + 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
|
| + // buffer that is currently in-use by the GPU.
|
| + resource->read_lock_fences_enabled = true;
|
| +}
|
| +
|
| +void ResourceProvider::LazyCreateImage(Resource* resource,
|
| + gpu::gles2::GLES2Interface* gl) {
|
| DCHECK(resource->gpu_memory_buffer);
|
| DCHECK(resource->gl_id);
|
| + DCHECK(resource->locked_for_write);
|
| DCHECK(resource->allocated);
|
| // Avoid crashing in release builds if GpuMemoryBuffer allocation fails.
|
| // http://crbug.com/554541
|
| if (!resource->gpu_memory_buffer)
|
| return;
|
| if (!resource->image_id) {
|
| - GLES2Interface* gl = ContextGL();
|
| DCHECK(gl);
|
|
|
| #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
|
| @@ -2064,16 +2049,18 @@ void ResourceProvider::LazyCreateImage(Resource* resource) {
|
| DCHECK(resource->image_id || IsGLContextLost());
|
|
|
| resource->SetLocallyUsed();
|
| + resource->dirty_image = true;
|
| }
|
| }
|
|
|
| -void ResourceProvider::BindImageForSampling(Resource* resource) {
|
| - GLES2Interface* gl = ContextGL();
|
| - DCHECK(resource->gl_id);
|
| +void ResourceProvider::BindImageForSampling(Resource* resource,
|
| + gpu::gles2::GLES2Interface* gl,
|
| + unsigned gl_id) {
|
| + DCHECK(gl_id);
|
| DCHECK(resource->image_id);
|
|
|
| // Release image currently bound to texture.
|
| - gl->BindTexture(resource->target, resource->gl_id);
|
| + gl->BindTexture(resource->target, gl_id);
|
| if (resource->bound_image_id)
|
| gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
|
| gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
|
|
|