0

Add a new CreateSharedImage() to SharedImageInterface

This new interface is for supporting bitmap in software composition.

Bug: 1434885
Change-Id: I23ba7d205a90581139a20dd27ea1dc52712949b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5191211
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1246791}
This commit is contained in:
Maggie Chen
2024-01-13 01:29:51 +00:00
committed by Chromium LUCI CQ
parent 3600f1e2bb
commit c5d2dbd8df
11 changed files with 218 additions and 66 deletions

@@ -181,6 +181,7 @@ class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
if (shared_image) { if (shared_image) {
auto* sii = layer_tree_frame_sink->shared_image_interface(); auto* sii = layer_tree_frame_sink->shared_image_interface();
if (sii) { if (sii) {
scoped_mapping.reset();
sii->DestroySharedImage(mailbox_sync_token, std::move(shared_image)); sii->DestroySharedImage(mailbox_sync_token, std::move(shared_image));
} }
} else { } else {
@@ -193,12 +194,20 @@ class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid, const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id, uint64_t tracing_process_id,
int importance) const override { int importance) const override {
pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid, if (shared_image) {
shared_mapping.guid(), importance); scoped_mapping->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
importance);
} else {
pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid,
shared_mapping.guid(), importance);
}
} }
raw_ptr<LayerTreeFrameSink> layer_tree_frame_sink; raw_ptr<LayerTreeFrameSink> layer_tree_frame_sink;
// Used for SharedImage.
base::WritableSharedMemoryMapping shared_mapping; base::WritableSharedMemoryMapping shared_mapping;
// Used for SharedBitmap
std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
}; };
bool HeadsUpDisplayLayerImpl::WillDraw( bool HeadsUpDisplayLayerImpl::WillDraw(
@@ -339,29 +348,14 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
if (!pool_resource.software_backing()) { if (!pool_resource.software_backing()) {
auto backing = std::make_unique<HudSoftwareBacking>(); auto backing = std::make_unique<HudSoftwareBacking>();
backing->layer_tree_frame_sink = layer_tree_frame_sink; backing->layer_tree_frame_sink = layer_tree_frame_sink;
const size_t buffer_size = gfx::BufferSizeForBufferFormat(
pool_resource.size(), gfx::BufferFormat::BGRA_8888);
auto shared_memory_region =
base::UnsafeSharedMemoryRegion::Create(buffer_size);
backing->shared_mapping = shared_memory_region.Map();
CHECK(shared_memory_region.IsValid() &&
backing->shared_mapping.IsValid());
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.offset = 0;
handle.stride = static_cast<int32_t>(gfx::RowSizeForBufferFormat(
pool_resource.size().width(), gfx::BufferFormat::BGRA_8888, 0));
handle.region = std::move(shared_memory_region);
backing->shared_image = sii->CreateSharedImage( backing->shared_image = sii->CreateSharedImage(
pool_resource.format(), pool_resource.size(), pool_resource.format(), pool_resource.size(),
pool_resource.color_space(), kTopLeft_GrSurfaceOrigin, pool_resource.color_space(), kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, gpu::SHARED_IMAGE_USAGE_CPU_WRITE, kPremul_SkAlphaType, gpu::SHARED_IMAGE_USAGE_CPU_WRITE,
"HeadsUpDisplayLayer", std::move(handle)); "HeadsUpDisplayLayer");
CHECK(backing->shared_image); CHECK(backing->shared_image);
backing->scoped_mapping = backing->shared_image->Map();
CHECK(backing->scoped_mapping);
pool_resource.set_software_backing(std::move(backing)); pool_resource.set_software_backing(std::move(backing));
} }
@@ -460,8 +454,10 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
auto* backing = auto* backing =
static_cast<HudSoftwareBacking*>(pool_resource.software_backing()); static_cast<HudSoftwareBacking*>(pool_resource.software_backing());
SkSurfaceProps props = skia::LegacyDisplayGlobals::GetSkSurfaceProps(); SkSurfaceProps props = skia::LegacyDisplayGlobals::GetSkSurfaceProps();
sk_sp<SkSurface> surface = SkSurfaces::WrapPixels( void* pixels = backing->scoped_mapping ? backing->scoped_mapping->Memory(0)
info, backing->shared_mapping.memory(), info.minRowBytes(), &props); : backing->shared_mapping.memory();
sk_sp<SkSurface> surface =
SkSurfaces::WrapPixels(info, pixels, info.minRowBytes(), &props);
SkiaPaintCanvas canvas(surface->getCanvas()); SkiaPaintCanvas canvas(surface->getCanvas());
DrawHudContents(&canvas); DrawHudContents(&canvas);

@@ -37,6 +37,7 @@ class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking {
public: public:
~BitmapSoftwareBacking() override { ~BitmapSoftwareBacking() override {
if (shared_image) { if (shared_image) {
scoped_mapping.reset();
if (frame_sink->shared_image_interface()) { if (frame_sink->shared_image_interface()) {
frame_sink->shared_image_interface()->DestroySharedImage( frame_sink->shared_image_interface()->DestroySharedImage(
mailbox_sync_token, std::move(shared_image)); mailbox_sync_token, std::move(shared_image));
@@ -51,12 +52,20 @@ class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking {
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid, const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id, uint64_t tracing_process_id,
int importance) const override { int importance) const override {
pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid, mapping.guid(), if (shared_image) {
importance); scoped_mapping->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id,
importance);
} else {
pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid, mapping.guid(),
importance);
}
} }
raw_ptr<LayerTreeFrameSink> frame_sink; raw_ptr<LayerTreeFrameSink> frame_sink;
// Used for SharedBitmap.
base::WritableSharedMemoryMapping mapping; base::WritableSharedMemoryMapping mapping;
// Used for SharedImage.
std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
}; };
class BitmapRasterBufferImpl : public RasterBuffer { class BitmapRasterBufferImpl : public RasterBuffer {
@@ -68,7 +77,8 @@ class BitmapRasterBufferImpl : public RasterBuffer {
uint64_t previous_content_id) uint64_t previous_content_id)
: resource_size_(size), : resource_size_(size),
color_space_(color_space), color_space_(color_space),
pixels_(backing->mapping.memory()), pixels_(backing->shared_image ? backing->scoped_mapping->Memory(0)
: backing->mapping.memory()),
resource_has_previous_content_( resource_has_previous_content_(
resource_content_id && resource_content_id == previous_content_id), resource_content_id && resource_content_id == previous_content_id),
backing_(backing) {} backing_(backing) {}
@@ -149,27 +159,14 @@ BitmapRasterBufferProvider::AcquireBufferForRaster(
backing->frame_sink = frame_sink_; backing->frame_sink = frame_sink_;
if (frame_sink_->shared_image_interface()) { if (frame_sink_->shared_image_interface()) {
const size_t buffer_size =
gfx::BufferSizeForBufferFormat(size, gfx::BufferFormat::BGRA_8888);
auto shared_memory_region =
base::UnsafeSharedMemoryRegion::Create(buffer_size);
backing->mapping = shared_memory_region.Map();
CHECK(shared_memory_region.IsValid() && backing->mapping.IsValid());
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.offset = 0;
handle.stride = static_cast<int32_t>(gfx::RowSizeForBufferFormat(
size.width(), gfx::BufferFormat::BGRA_8888, 0));
handle.region = std::move(shared_memory_region);
backing->shared_image = backing->shared_image =
frame_sink_->shared_image_interface()->CreateSharedImage( frame_sink_->shared_image_interface()->CreateSharedImage(
viz::SinglePlaneFormat::kBGRA_8888, size, color_space, viz::SinglePlaneFormat::kBGRA_8888, size, color_space,
kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
gpu::SHARED_IMAGE_USAGE_CPU_WRITE, "BitmapRasterBufferProvider", gpu::SHARED_IMAGE_USAGE_CPU_WRITE, "BitmapRasterBufferProvider");
std::move(handle));
CHECK(backing->shared_image); CHECK(backing->shared_image);
backing->scoped_mapping = backing->shared_image->Map();
CHECK(backing->scoped_mapping);
} else { } else {
backing->shared_bitmap_id = viz::SharedBitmap::GenerateId(); backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
base::MappedReadOnlyRegion shm = base::MappedReadOnlyRegion shm =

@@ -4662,7 +4662,8 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// For software compositing, shared memory will be allocated and the // For software compositing, shared memory will be allocated and the
// UIResource will be copied into it. // UIResource will be copied into it.
base::MappedReadOnlyRegion shm; base::MappedReadOnlyRegion shm;
base::WritableSharedMemoryMapping mapping; base::WritableSharedMemoryMapping shared_mapping;
std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
viz::SharedBitmapId shared_bitmap_id; viz::SharedBitmapId shared_bitmap_id;
bool overlay_candidate = false; bool overlay_candidate = false;
bool use_shared_image = bool use_shared_image =
@@ -4692,29 +4693,15 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
auto* sii = layer_tree_frame_sink_->shared_image_interface(); auto* sii = layer_tree_frame_sink_->shared_image_interface();
CHECK(sii); CHECK(sii);
const size_t buffer_size = gfx::BufferSizeForBufferFormat(
upload_size, gfx::BufferFormat::RGBA_8888);
auto shared_memory_region =
base::UnsafeSharedMemoryRegion::Create(buffer_size);
mapping = shared_memory_region.Map();
CHECK(shared_memory_region.IsValid() && mapping.IsValid());
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.offset = 0;
handle.stride = static_cast<int32_t>(gfx::RowSizeForBufferFormat(
upload_size.width(), gfx::BufferFormat::RGBA_8888, 0));
handle.region = std::move(shared_memory_region);
client_shared_image = sii->CreateSharedImage( client_shared_image = sii->CreateSharedImage(
format, upload_size, color_space, kTopLeft_GrSurfaceOrigin, format, upload_size, color_space, kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource", kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource");
std::move(handle));
CHECK(client_shared_image); CHECK(client_shared_image);
shared_bitmap_id = client_shared_image->mailbox(); scoped_mapping = client_shared_image->Map();
CHECK(scoped_mapping);
} else { } else {
shm = viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format); shm = viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format);
mapping = std::move(shm.mapping); shared_mapping = std::move(shm.mapping);
shared_bitmap_id = viz::SharedBitmap::GenerateId(); shared_bitmap_id = viz::SharedBitmap::GenerateId();
} }
@@ -4737,8 +4724,10 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
SkImageInfo dst_info = SkImageInfo dst_info =
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size)); SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
sk_sp<SkSurface> surface = SkSurfaces::WrapPixels( void* pixels =
dst_info, mapping.memory(), dst_info.minRowBytes()); scoped_mapping ? scoped_mapping->Memory(0) : shared_mapping.memory();
sk_sp<SkSurface> surface =
SkSurfaces::WrapPixels(dst_info, pixels, dst_info.minRowBytes());
surface->getCanvas()->writePixels( surface->getCanvas()->writePixels(
src_info, const_cast<uint8_t*>(bitmap.GetPixels()), src_info, const_cast<uint8_t*>(bitmap.GetPixels()),
bitmap.row_bytes(), 0, 0); bitmap.row_bytes(), 0, 0);
@@ -4774,8 +4763,10 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
} else { } else {
SkImageInfo dst_info = SkImageInfo dst_info =
SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size)); SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
scaled_surface = SkSurfaces::WrapPixels(dst_info, mapping.memory(), void* pixels =
dst_info.minRowBytes()); scoped_mapping ? scoped_mapping->Memory(0) : shared_mapping.memory();
scaled_surface =
SkSurfaces::WrapPixels(dst_info, pixels, dst_info.minRowBytes());
CHECK(scaled_surface); // This could fail on invalid parameters. CHECK(scaled_surface); // This could fail on invalid parameters.
} }
SkCanvas* scaled_canvas = scaled_surface->getCanvas(); SkCanvas* scaled_canvas = scaled_surface->getCanvas();
@@ -4823,7 +4814,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
auto* sii = layer_tree_frame_sink_->shared_image_interface(); auto* sii = layer_tree_frame_sink_->shared_image_interface();
gpu::SyncToken sync_token = sii->GenVerifiedSyncToken(); gpu::SyncToken sync_token = sii->GenVerifiedSyncToken();
transferable = viz::TransferableResource::MakeSoftware( transferable = viz::TransferableResource::MakeSoftware(
shared_bitmap_id, sync_token, upload_size, format, client_shared_image->mailbox(), sync_token, upload_size, format,
viz::TransferableResource::ResourceSource::kUI); viz::TransferableResource::ResourceSource::kUI);
} else { } else {
layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region), layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region),
@@ -4847,7 +4838,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
data.format = format; data.format = format;
if (!use_shared_image) { if (!use_shared_image) {
data.shared_bitmap_id = shared_bitmap_id; data.shared_bitmap_id = shared_bitmap_id;
data.shared_mapping = std::move(mapping); data.shared_mapping = std::move(shared_mapping);
} }
data.shared_image = std::move(client_shared_image); data.shared_image = std::move(client_shared_image);
data.resource_id_for_export = id; data.resource_id_for_export = id;

@@ -264,6 +264,21 @@ TestSharedImageInterface::CreateSharedImage(
return base::MakeRefCounted<gpu::ClientSharedImage>(mailbox); return base::MakeRefCounted<gpu::ClientSharedImage>(mailbox);
} }
scoped_refptr<gpu::ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) {
base::AutoLock locked(lock_);
auto mailbox = gpu::Mailbox::GenerateForSharedImage();
shared_images_.insert(mailbox);
most_recent_size_ = size;
return base::MakeRefCounted<gpu::ClientSharedImage>(mailbox);
}
scoped_refptr<gpu::ClientSharedImage> scoped_refptr<gpu::ClientSharedImage>
TestSharedImageInterface::CreateSharedImage( TestSharedImageInterface::CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer, gfx::GpuMemoryBuffer* gpu_memory_buffer,

@@ -97,6 +97,15 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
base::StringPiece debug_label, base::StringPiece debug_label,
gfx::GpuMemoryBufferHandle buffer_handle) override; gfx::GpuMemoryBufferHandle buffer_handle) override;
scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) override;
scoped_refptr<gpu::ClientSharedImage> CreateSharedImage( scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer, gfx::GpuMemoryBuffer* gpu_memory_buffer,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,

@@ -158,6 +158,19 @@ class GPU_EXPORT SharedImageInterface {
base::StringPiece debug_label, base::StringPiece debug_label,
gfx::GpuMemoryBufferHandle buffer_handle) = 0; gfx::GpuMemoryBufferHandle buffer_handle) = 0;
// Creates a shared image with the usage of gpu::SHARED_IMAGE_USAGE_CPU_WRITE
// only. A shared memory buffer is created internally and a shared image is
// created out this buffer. This method is used by the software compositor
// only.
virtual scoped_refptr<ClientSharedImage> CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) = 0;
// NOTE: The below method is DEPRECATED for `gpu_memory_buffer` only with // NOTE: The below method is DEPRECATED for `gpu_memory_buffer` only with
// single planar eg. RGB BufferFormats. Please use the equivalent method above // single planar eg. RGB BufferFormats. Please use the equivalent method above
// taking in single planar SharedImageFormat with GpuMemoryBufferHandle. // taking in single planar SharedImageFormat with GpuMemoryBufferHandle.

@@ -5,10 +5,12 @@
#include "gpu/command_buffer/service/shared_image_interface_in_process.h" #include "gpu/command_buffer/service/shared_image_interface_in_process.h"
#include <optional> #include <optional>
#include "base/functional/bind.h" #include "base/functional/bind.h"
#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/command_buffer/client/client_shared_image.h" #include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/shared_image_usage.h"
@@ -24,6 +26,7 @@
#include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_preferences.h" #include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/common/gpu_client_ids.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gl/gl_context.h" #include "ui/gl/gl_context.h"
namespace gpu { namespace gpu {
@@ -503,6 +506,60 @@ SharedImageInterfaceInProcess::CreateSharedImage(
return base::MakeRefCounted<ClientSharedImage>(mailbox); return base::MakeRefCounted<ClientSharedImage>(mailbox);
} }
scoped_refptr<ClientSharedImage>
SharedImageInterfaceInProcess::CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) {
DCHECK(gpu::IsValidClientUsage(usage));
DCHECK_EQ(usage, gpu::SHARED_IMAGE_USAGE_CPU_WRITE);
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
CHECK(!format.PrefersExternalSampler());
#endif
gfx::BufferFormat buffer_format =
viz::SinglePlaneSharedImageFormatToBufferFormat(format);
const size_t buffer_size =
gfx::BufferSizeForBufferFormat(size, buffer_format);
auto shared_memory_region =
base::UnsafeSharedMemoryRegion::Create(buffer_size);
CHECK(shared_memory_region.IsValid());
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.offset = 0;
handle.stride = static_cast<int32_t>(
gfx::RowSizeForBufferFormat(size.width(), buffer_format, 0));
handle.region = std::move(shared_memory_region);
GpuMemoryBufferHandleInfo handle_info = GpuMemoryBufferHandleInfo(
handle.Clone(), format, size, gfx::BufferUsage::SCANOUT_CPU_READ_WRITE);
auto mailbox = Mailbox::GenerateForSharedImage();
{
base::AutoLock lock(lock_);
SyncToken sync_token = MakeSyncToken(next_fence_sync_release_++);
// Note: we enqueue the task under the lock to guarantee monotonicity of
// the release ids as seen by the service. Unretained is safe because
// InProcessCommandBuffer synchronizes with the GPU thread at destruction
// time, cancelling tasks, before |this| is destroyed.
ScheduleGpuTask(
base::BindOnce(&SharedImageInterfaceInProcess::
CreateSharedImageWithBufferOnGpuThread,
base::Unretained(this), mailbox, format, size,
color_space, surface_origin, alpha_type, usage,
std::move(handle), std::string(debug_label), sync_token),
{});
}
return base::MakeRefCounted<ClientSharedImage>(mailbox,
std::move(handle_info));
}
void SharedImageInterfaceInProcess::CreateSharedImageWithBufferOnGpuThread( void SharedImageInterfaceInProcess::CreateSharedImageWithBufferOnGpuThread(
const Mailbox& mailbox, const Mailbox& mailbox,

@@ -115,6 +115,14 @@ class GPU_GLES2_EXPORT SharedImageInterfaceInProcess
uint32_t usage, uint32_t usage,
base::StringPiece debug_label, base::StringPiece debug_label,
gfx::GpuMemoryBufferHandle buffer_handle) override; gfx::GpuMemoryBufferHandle buffer_handle) override;
scoped_refptr<ClientSharedImage> CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) override;
scoped_refptr<ClientSharedImage> CreateSharedImage( scoped_refptr<ClientSharedImage> CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer, gfx::GpuMemoryBuffer* gpu_memory_buffer,
GpuMemoryBufferManager* gpu_memory_buffer_manager, GpuMemoryBufferManager* gpu_memory_buffer_manager,

@@ -12,6 +12,7 @@
#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/ipc/client/gpu_channel_host.h" #include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/client/shared_image_interface_proxy.h" #include "gpu/ipc/client/shared_image_interface_proxy.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/gpu_memory_buffer.h"
@@ -198,6 +199,47 @@ scoped_refptr<ClientSharedImage> ClientSharedImageInterface::CreateSharedImage(
debug_label, std::move(buffer_handle)))); debug_label, std::move(buffer_handle))));
} }
scoped_refptr<ClientSharedImage> ClientSharedImageInterface::CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) {
DCHECK(gpu::IsValidClientUsage(usage)) << usage;
DCHECK_EQ(usage, gpu::SHARED_IMAGE_USAGE_CPU_WRITE);
DCHECK(viz::HasEquivalentBufferFormat(format)) << format.ToString();
CHECK(!format.IsLegacyMultiplanar()) << format.ToString();
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
CHECK(!format.PrefersExternalSampler()) << format.ToString();
#endif
gfx::BufferFormat buffer_format =
viz::SinglePlaneSharedImageFormatToBufferFormat(format);
const size_t buffer_size =
gfx::BufferSizeForBufferFormat(size, buffer_format);
auto shared_memory_region =
base::UnsafeSharedMemoryRegion::Create(buffer_size);
CHECK(shared_memory_region.IsValid());
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.offset = 0;
handle.stride = static_cast<int32_t>(
gfx::RowSizeForBufferFormat(size.width(), buffer_format, 0));
handle.region = std::move(shared_memory_region);
GpuMemoryBufferHandleInfo handle_info = GpuMemoryBufferHandleInfo(
handle.Clone(), format, size, gfx::BufferUsage::SCANOUT_CPU_READ_WRITE);
return base::MakeRefCounted<ClientSharedImage>(
AddMailbox(proxy_->CreateSharedImage(format, size, color_space,
surface_origin, alpha_type, usage,
debug_label, std::move(handle))),
std::move(handle_info));
}
scoped_refptr<ClientSharedImage> ClientSharedImageInterface::CreateSharedImage( scoped_refptr<ClientSharedImage> ClientSharedImageInterface::CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer, gfx::GpuMemoryBuffer* gpu_memory_buffer,
GpuMemoryBufferManager* gpu_memory_buffer_manager, GpuMemoryBufferManager* gpu_memory_buffer_manager,

@@ -96,6 +96,19 @@ class GPU_EXPORT ClientSharedImageInterface : public SharedImageInterface {
uint32_t usage, uint32_t usage,
base::StringPiece debug_label, base::StringPiece debug_label,
gfx::GpuMemoryBufferHandle buffer_handle) override; gfx::GpuMemoryBufferHandle buffer_handle) override;
// Used by the software compositor only. |useage| must be
// gpu::SHARED_IMAGE_USAGE_CPU_WRITE. Call client_shared_image->Map() later to
// get the shared memory mapping.
scoped_refptr<ClientSharedImage> CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) override;
// NOTE: The below method is DEPRECATED for `gpu_memory_buffer` only with // NOTE: The below method is DEPRECATED for `gpu_memory_buffer` only with
// single planar eg. RGB BufferFormats. Please use the equivalent method above // single planar eg. RGB BufferFormats. Please use the equivalent method above
// taking in single planar SharedImageFormat with GpuMemoryBufferHandle. // taking in single planar SharedImageFormat with GpuMemoryBufferHandle.

@@ -159,6 +159,17 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
return base::MakeRefCounted<gpu::ClientSharedImage>(result); return base::MakeRefCounted<gpu::ClientSharedImage>(result);
} }
scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
base::StringPiece debug_label) override {
return base::MakeRefCounted<gpu::ClientSharedImage>(gpu::Mailbox());
}
scoped_refptr<gpu::ClientSharedImage> CreateSharedImage( scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
gfx::GpuMemoryBuffer* gpu_memory_buffer, gfx::GpuMemoryBuffer* gpu_memory_buffer,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,