Chromium Code Reviews| Index: cc/resources/resource_provider.cc |
| diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
| index 8d5a3fce7fe37616bef719b2332ca41d18e7b74d..526914070ee456f6638395678d4cc537ebac069a 100644 |
| --- a/cc/resources/resource_provider.cc |
| +++ b/cc/resources/resource_provider.cc |
| @@ -135,23 +135,6 @@ bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) { |
| return false; |
| } |
| -GrPixelConfig ToGrPixelConfig(ResourceFormat format) { |
| - switch (format) { |
| - case RGBA_8888: |
| - return kRGBA_8888_GrPixelConfig; |
| - case BGRA_8888: |
| - return kBGRA_8888_GrPixelConfig; |
| - case RGBA_4444: |
| - return kRGBA_4444_GrPixelConfig; |
| - case RGBA_F16: |
| - return kRGBA_half_GrPixelConfig; |
| - default: |
| - break; |
| - } |
| - DCHECK(false) << "Unsupported resource format."; |
| - return kSkia8888_GrPixelConfig; |
| -} |
| - |
| class ScopedSetActiveTexture { |
| public: |
| ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit) |
| @@ -929,7 +912,6 @@ void ResourceProvider::CopyToResource(ResourceId id, |
| gpu::SyncToken sync_token; |
| gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); |
| lock.set_sync_token(sync_token); |
| - lock.set_synchronized(true); |
| } |
| } |
| @@ -1003,8 +985,8 @@ ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) { |
| const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) { |
| Resource* resource = GetResource(id); |
| - DCHECK(!resource->locked_for_write) << "locked for write: " |
| - << resource->locked_for_write; |
| + DCHECK(!resource->locked_for_write) |
| + << "locked for write: " << resource->locked_for_write; |
| DCHECK_EQ(resource->exported_count, 0); |
| // Uninitialized! Call SetPixels or LockForWrite first. |
| DCHECK(resource->allocated); |
| @@ -1165,101 +1147,99 @@ ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {} |
| ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL( |
| ResourceProvider* resource_provider, |
| ResourceId resource_id, |
| - bool create_mailbox) |
| + bool async_worker_context_enabled) |
|
piman
2017/06/09 22:14:20
nit: I'm not sure the parameter name is just right
|
| : resource_provider_(resource_provider), |
| resource_id_(resource_id), |
| - has_sync_token_(false), |
| - synchronized_(false) { |
| + async_worker_context_enabled_(async_worker_context_enabled) { |
| 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); |
| + DCHECK(IsGpuResourceType(resource->type)); |
| + |
| + if (async_worker_context_enabled) { |
| + resource_provider->LazyCreateMailbox(resource); |
| + } else { |
| + resource_provider->LazyAllocate(resource); |
| + if (resource->image_id && resource->dirty_image) |
| + resource_provider_->BindImageForSampling(resource); |
| } |
| + |
| + type_ = resource->type; |
| texture_id_ = resource->gl_id; |
| + gpu_memory_buffer_ = std::move(resource->gpu_memory_buffer); |
| + usage_ = resource->usage; |
| + image_id_ = resource->image_id; |
| + bound_image_id_ = resource->bound_image_id; |
| + dirty_image_ = resource->dirty_image; |
| target_ = resource->target; |
| format_ = resource->format; |
| size_ = resource->size; |
| - mailbox_ = resource->mailbox(); |
| - color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource); |
| + color_space_ = resource->color_space; |
| + color_space_for_raster_ = |
| + resource_provider->GetResourceColorSpaceForRaster(resource); |
| + hint_ = resource->hint; |
| + allocated_ = resource->allocated; |
| + mailbox_ = resource->mailbox().mailbox(); |
| + set_sync_token_ = false; |
| } |
| 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->allocated = allocated_; |
| + |
| + if (gpu_memory_buffer_) { |
| + resource_provider_->SetGpuMemoryBuffer(resource, |
| + std::move(gpu_memory_buffer_)); |
| + } |
| + resource->image_id = image_id_; |
| + resource->bound_image_id = bound_image_id_; |
| + resource->dirty_image = dirty_image_; |
| + |
| + if (set_sync_token_) |
| resource->UpdateSyncToken(sync_token_); |
| - if (synchronized_) |
| + if (!async_worker_context_enabled_) |
| resource->SetSynchronized(); |
| + |
| resource_provider_->UnlockForWrite(resource); |
| } |
| -ResourceProvider::ScopedTextureProvider::ScopedTextureProvider( |
| - gpu::gles2::GLES2Interface* gl, |
| - ScopedWriteLockGL* resource_lock, |
| - bool use_mailbox) |
| - : gl_(gl), use_mailbox_(use_mailbox) { |
| - if (use_mailbox_) { |
| - texture_id_ = gl_->CreateAndConsumeTextureCHROMIUM( |
| - resource_lock->target(), resource_lock->mailbox().name()); |
| - } else { |
| - texture_id_ = resource_lock->texture_id(); |
| - } |
| - DCHECK(texture_id_); |
| -} |
| - |
| -ResourceProvider::ScopedTextureProvider::~ScopedTextureProvider() { |
| - if (use_mailbox_) |
| - gl_->DeleteTextures(1, &texture_id_); |
| -} |
| - |
| -ResourceProvider::ScopedSkSurfaceProvider::ScopedSkSurfaceProvider( |
| - ContextProvider* context_provider, |
| - ScopedWriteLockGL* resource_lock, |
| - bool use_mailbox, |
| - bool use_distance_field_text, |
| - bool can_use_lcd_text, |
| - int msaa_sample_count) |
| - : texture_provider_(context_provider->ContextGL(), |
| - resource_lock, |
| - use_mailbox) { |
| - GrGLTextureInfo texture_info; |
| - texture_info.fID = texture_provider_.texture_id(); |
| - texture_info.fTarget = resource_lock->target(); |
| - GrBackendTextureDesc desc; |
| - desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| - desc.fWidth = resource_lock->size().width(); |
| - desc.fHeight = resource_lock->size().height(); |
| - desc.fConfig = ToGrPixelConfig(resource_lock->format()); |
| - desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| - desc.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(texture_info); |
| - desc.fSampleCnt = msaa_sample_count; |
| - |
| - uint32_t flags = |
| - use_distance_field_text ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; |
| - // Use unknown pixel geometry to disable LCD text. |
| - SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry); |
| - if (can_use_lcd_text) { |
| - // LegacyFontHost will get LCD text and skia figures out what type to use. |
| - surface_props = |
| - SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); |
| - } |
| - sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( |
| - context_provider->GrContext(), desc, nullptr, &surface_props); |
| -} |
| - |
| -ResourceProvider::ScopedSkSurfaceProvider::~ScopedSkSurfaceProvider() { |
| - if (sk_surface_.get()) { |
| - sk_surface_->prepareForExternalIO(); |
| - sk_surface_.reset(); |
| +unsigned ResourceProvider::ScopedWriteLockGL::ConsumeTexture( |
| + gpu::gles2::GLES2Interface* gl) { |
| + DCHECK(async_worker_context_enabled_); |
| + DCHECK(!mailbox_.IsZero()); |
| + |
| + unsigned gl_id = gl->CreateAndConsumeTextureCHROMIUM(target_, mailbox_.name); |
| + DCHECK(gl_id); |
| + |
| + if (!allocated_) { |
| + allocated_ = true; |
| + if (type_ == RESOURCE_TYPE_GPU_MEMORY_BUFFER) { |
| + DCHECK(!gpu_memory_buffer_); |
| + DCHECK(!image_id_); |
| + gpu_memory_buffer_ = resource_provider_->AllocateGpuMemoryBuffer( |
| + size_, format_, usage_, color_space_); |
| + image_id_ = resource_provider_->CreateImage(gl, gpu_memory_buffer_.get(), |
| + size_, format_); |
| + dirty_image_ = true; |
| + } else { |
| + resource_provider_->AllocateGLTexture(gl, gl_id, target_, size_, format_, |
| + hint_); |
| + } |
| } |
| + |
| + if (image_id_ && dirty_image_) { |
| + gl->BindTexture(target_, gl_id); |
| + if (bound_image_id_) |
| + gl->ReleaseTexImage2DCHROMIUM(target_, bound_image_id_); |
| + gl->BindTexImage2DCHROMIUM(target_, image_id_); |
| + bound_image_id_ = image_id_; |
| + dirty_image_ = false; |
| + } |
| + |
| + return gl_id; |
| } |
| void ResourceProvider::PopulateSkBitmapWithResource(SkBitmap* sk_bitmap, |
| @@ -1325,15 +1305,14 @@ ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware( |
| 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->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); |
| } |
| @@ -1343,35 +1322,23 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
| 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; |
| + DCHECK_EQ(resource->type, ResourceProvider::RESOURCE_TYPE_GPU_MEMORY_BUFFER); |
| size_ = resource->size; |
| + format_ = resource->format; |
| usage_ = resource->usage; |
| - gpu_memory_buffer_ = std::move(resource->gpu_memory_buffer); |
| - resource->gpu_memory_buffer = nullptr; |
| color_space_ = resource_provider->GetResourceColorSpaceForRaster(resource); |
| + gpu_memory_buffer_ = std::move(resource->gpu_memory_buffer); |
| } |
| 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_->SetGpuMemoryBuffer(resource, |
| + std::move(gpu_memory_buffer_)); |
| 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; |
| } |
| resource->SetSynchronized(); |
| resource_provider_->UnlockForWrite(resource); |
| @@ -1380,9 +1347,8 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer:: |
| 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); |
| + gpu_memory_buffer_ = resource_provider_->AllocateGpuMemoryBuffer( |
| + size_, format_, usage_, color_space_); |
| } |
| return gpu_memory_buffer_.get(); |
| } |
| @@ -1502,14 +1468,18 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resource_ids, |
| resources.push_back(resource); |
| } |
| - // Lazily create any mailboxes and verify all unverified sync tokens. |
| + // Lazily create any mailboxes and verify all unverified sync tokens. Also |
| + // upload GMB resources to GPU if necessary. |
| std::vector<GLbyte*> unverified_sync_tokens; |
| std::vector<Resource*> need_synchronization_resources; |
| for (Resource* resource : resources) { |
| if (!IsGpuResourceType(resource->type)) |
| continue; |
| - CreateMailboxAndBindResource(gl, resource); |
| + LazyCreateMailbox(resource); |
| + |
| + if (resource->image_id && resource->dirty_image) |
| + BindImageForSampling(resource); |
| if (settings_.delegated_sync_points_required) { |
| if (resource->needs_sync_token()) { |
| @@ -1676,9 +1646,7 @@ void ResourceProvider::ReceiveReturnsFromParent( |
| DCHECK(!resource->has_shared_bitmap_id); |
| if (resource->origin == Resource::INTERNAL) { |
| DCHECK(resource->gl_id); |
| - DCHECK(returned.sync_token.HasData()); |
| gl->WaitSyncTokenCHROMIUM(returned.sync_token.GetConstData()); |
| - resource->SetSynchronized(); |
|
piman
2017/06/09 22:14:20
Why are we removing this one? Won't this cause ext
|
| } else { |
| DCHECK(!resource->gl_id); |
| resource->UpdateSyncToken(returned.sync_token); |
| @@ -1750,31 +1718,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) { |
| @@ -1968,6 +1911,7 @@ void ResourceProvider::LazyCreate(Resource* resource) { |
| DCHECK(resource->origin == Resource::INTERNAL); |
| DCHECK(!resource->mailbox().IsValid()); |
| resource->gl_id = texture_id_allocator_->NextId(); |
| + DCHECK(resource->gl_id); |
| GLES2Interface* gl = ContextGL(); |
| DCHECK(gl); |
| @@ -1987,6 +1931,26 @@ void ResourceProvider::LazyCreate(Resource* resource) { |
| } |
| } |
| +void ResourceProvider::LazyCreateMailbox(Resource* resource) { |
| + DCHECK(resource); |
| + if (resource->mailbox().IsValid()) |
| + return; |
| + |
| + LazyCreate(resource); |
| + DCHECK(resource->gl_id); |
| + |
| + 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)); |
| } |
| @@ -1995,83 +1959,116 @@ void ResourceProvider::LazyAllocate(Resource* resource) { |
| DCHECK(resource); |
| if (resource->allocated) |
| return; |
| - LazyCreate(resource); |
| - if (!resource->gl_id) |
| - return; |
| + // Bitmap resources are always allocated on initialization. |
| + DCHECK(IsGpuResourceType(resource->type)); |
| resource->allocated = true; |
| - GLES2Interface* gl = ContextGL(); |
| - 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); |
| - } |
| + if (resource->type == RESOURCE_TYPE_GPU_MEMORY_BUFFER) { |
| + SetGpuMemoryBuffer(resource, AllocateGpuMemoryBuffer( |
| + resource->size, resource->format, |
| + resource->usage, 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; |
| - } 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 { |
| + LazyCreate(resource); |
| + AllocateGLTexture(ContextGL(), resource->gl_id, resource->target, |
| + resource->size, resource->format, resource->hint); |
| + } |
| +} |
| + |
| +void ResourceProvider::AllocateGLTexture(gpu::gles2::GLES2Interface* gl, |
| + unsigned gl_id, |
| + GLenum target, |
| + const gfx::Size& size, |
| + ResourceFormat format, |
| + TextureHint hint) { |
| + if (settings_.use_texture_storage_ext && |
| + IsFormatSupportedForStorage(format, settings_.use_texture_format_bgra) && |
| + (hint & TEXTURE_HINT_IMMUTABLE)) { |
| + GLenum storage_format = TextureToStorageFormat(format); |
| + gl->BindTexture(target, gl_id); |
| + 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->BindTexture(target, gl_id); |
| + gl->TexImage2D(target, 0, GLInternalFormat(format), size.width(), |
| + size.height(), 0, GLDataFormat(format), GLDataType(format), |
| + nullptr); |
| } |
| } |
| -void ResourceProvider::LazyCreateImage(Resource* resource) { |
| - DCHECK(resource->gpu_memory_buffer); |
| - DCHECK(resource->gl_id); |
| - DCHECK(resource->allocated); |
| +std::unique_ptr<gfx::GpuMemoryBuffer> ResourceProvider::AllocateGpuMemoryBuffer( |
| + const gfx::Size& size, |
| + ResourceFormat format, |
| + gfx::BufferUsage usage, |
| + gfx::ColorSpace color_space) { |
| + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer = |
| + gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( |
| + size, BufferFormat(format), usage, gpu::kNullSurfaceHandle); |
| + // Note that this impacts overlay compositing, not rasterization. |
| + if (settings_.enable_color_correct_rasterization) |
| + gpu_memory_buffer->SetColorSpaceForScanout(color_space); |
| + return gpu_memory_buffer; |
| +} |
| + |
| +void ResourceProvider::SetGpuMemoryBuffer( |
| + Resource* resource, |
| + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer) { |
| + DCHECK(gpu_memory_buffer); |
| + DCHECK(resource->locked_for_write); |
| + DCHECK(!resource->gpu_memory_buffer); |
| + resource->gpu_memory_buffer = std::move(gpu_memory_buffer); |
| + resource->allocated = 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; |
| +} |
| + |
| +unsigned ResourceProvider::CreateImage(gpu::gles2::GLES2Interface* gl, |
| + gfx::GpuMemoryBuffer* gpu_memory_buffer, |
| + const gfx::Size& size, |
| + ResourceFormat format) { |
| + DCHECK(gl); |
| + DCHECK(gpu_memory_buffer); |
| // 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 (!gpu_memory_buffer) |
| + return 0; |
| #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) |
| - // TODO(reveman): This avoids a performance problem on ARM ChromeOS |
| - // devices. This only works with shared memory backed buffers. |
| - // crbug.com/580166 |
| - DCHECK_EQ(resource->gpu_memory_buffer->GetHandle().type, |
| - gfx::SHARED_MEMORY_BUFFER); |
| + // TODO(reveman): This avoids a performance problem on ARM ChromeOS |
| + // devices. This only works with shared memory backed buffers. |
| + // crbug.com/580166 |
| + DCHECK_EQ(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)); |
| - DCHECK(resource->image_id || IsGLContextLost()); |
| + unsigned image_id = |
| + gl->CreateImageCHROMIUM(gpu_memory_buffer->AsClientBuffer(), size.width(), |
| + size.height(), GLInternalFormat(format)); |
| + DCHECK(image_id || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR); |
| + return image_id; |
| +} |
| - resource->SetLocallyUsed(); |
| - } |
| +void ResourceProvider::LazyCreateImage(Resource* resource) { |
| + DCHECK(resource); |
| + if (resource->image_id) |
| + return; |
| + |
| + LazyCreate(resource); |
| + DCHECK(resource->gl_id); |
| + |
| + resource->image_id = |
| + CreateImage(ContextGL(), resource->gpu_memory_buffer.get(), |
| + resource->size, resource->format); |
| + resource->dirty_image = true; |
| } |
| void ResourceProvider::BindImageForSampling(Resource* resource) { |
| - GLES2Interface* gl = ContextGL(); |
| DCHECK(resource->gl_id); |
| DCHECK(resource->image_id); |
| + gpu::gles2::GLES2Interface* gl = ContextGL(); |
| + DCHECK(gl); |
| + |
| // Release image currently bound to texture. |
| gl->BindTexture(resource->target, resource->gl_id); |
| if (resource->bound_image_id) |