| Index: cc/resources/resource_provider.cc
|
| diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
|
| index 09ed3ee0b42df09a21c830303d424de8ba786ffc..fb1dd19f0510f877e858a3ffbc15331b854f498e 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)
|
| @@ -928,7 +911,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);
|
| }
|
| }
|
|
|
| @@ -1002,8 +984,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);
|
| @@ -1164,101 +1146,99 @@ 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) {
|
| + 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,
|
| @@ -1324,15 +1304,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);
|
| }
|
| @@ -1342,35 +1321,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);
|
| @@ -1379,9 +1346,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();
|
| }
|
| @@ -1501,14 +1467,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()) {
|
| @@ -1675,9 +1645,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();
|
| } else {
|
| DCHECK(!resource->gl_id);
|
| resource->UpdateSyncToken(returned.sync_token);
|
| @@ -1749,31 +1717,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) {
|
| @@ -1967,6 +1910,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);
|
| @@ -1986,6 +1930,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));
|
| }
|
| @@ -1994,83 +1958,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)
|
|
|