diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index cb2f8081e4a0b..c1e2732e199bc 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -181,6 +181,7 @@ class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
     if (shared_image) {
       auto* sii = layer_tree_frame_sink->shared_image_interface();
       if (sii) {
+        scoped_mapping.reset();
         sii->DestroySharedImage(mailbox_sync_token, std::move(shared_image));
       }
     } else {
@@ -193,12 +194,20 @@ class HudSoftwareBacking : public ResourcePool::SoftwareBacking {
       const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
       uint64_t tracing_process_id,
       int importance) const override {
-    pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid,
-                                         shared_mapping.guid(), importance);
+    if (shared_image) {
+      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;
+  // Used for SharedImage.
   base::WritableSharedMemoryMapping shared_mapping;
+  // Used for SharedBitmap
+  std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
 };
 
 bool HeadsUpDisplayLayerImpl::WillDraw(
@@ -339,29 +348,14 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
       if (!pool_resource.software_backing()) {
         auto backing = std::make_unique<HudSoftwareBacking>();
         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(
             pool_resource.format(), pool_resource.size(),
             pool_resource.color_space(), kTopLeft_GrSurfaceOrigin,
             kPremul_SkAlphaType, gpu::SHARED_IMAGE_USAGE_CPU_WRITE,
-            "HeadsUpDisplayLayer", std::move(handle));
+            "HeadsUpDisplayLayer");
         CHECK(backing->shared_image);
-
+        backing->scoped_mapping = backing->shared_image->Map();
+        CHECK(backing->scoped_mapping);
         pool_resource.set_software_backing(std::move(backing));
       }
 
@@ -460,8 +454,10 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
     auto* backing =
         static_cast<HudSoftwareBacking*>(pool_resource.software_backing());
     SkSurfaceProps props = skia::LegacyDisplayGlobals::GetSkSurfaceProps();
-    sk_sp<SkSurface> surface = SkSurfaces::WrapPixels(
-        info, backing->shared_mapping.memory(), info.minRowBytes(), &props);
+    void* pixels = backing->scoped_mapping ? backing->scoped_mapping->Memory(0)
+                                           : backing->shared_mapping.memory();
+    sk_sp<SkSurface> surface =
+        SkSurfaces::WrapPixels(info, pixels, info.minRowBytes(), &props);
 
     SkiaPaintCanvas canvas(surface->getCanvas());
     DrawHudContents(&canvas);
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc
index 94626ccd00a27..8f7677d28432b 100644
--- a/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -37,6 +37,7 @@ class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking {
  public:
   ~BitmapSoftwareBacking() override {
     if (shared_image) {
+      scoped_mapping.reset();
       if (frame_sink->shared_image_interface()) {
         frame_sink->shared_image_interface()->DestroySharedImage(
             mailbox_sync_token, std::move(shared_image));
@@ -51,12 +52,20 @@ class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking {
       const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
       uint64_t tracing_process_id,
       int importance) const override {
-    pmd->CreateSharedMemoryOwnershipEdge(buffer_dump_guid, mapping.guid(),
-                                         importance);
+    if (shared_image) {
+      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;
+  // Used for SharedBitmap.
   base::WritableSharedMemoryMapping mapping;
+  // Used for SharedImage.
+  std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
 };
 
 class BitmapRasterBufferImpl : public RasterBuffer {
@@ -68,7 +77,8 @@ class BitmapRasterBufferImpl : public RasterBuffer {
                          uint64_t previous_content_id)
       : resource_size_(size),
         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_content_id && resource_content_id == previous_content_id),
         backing_(backing) {}
@@ -149,27 +159,14 @@ BitmapRasterBufferProvider::AcquireBufferForRaster(
     backing->frame_sink = frame_sink_;
 
     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 =
           frame_sink_->shared_image_interface()->CreateSharedImage(
               viz::SinglePlaneFormat::kBGRA_8888, size, color_space,
               kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
-              gpu::SHARED_IMAGE_USAGE_CPU_WRITE, "BitmapRasterBufferProvider",
-              std::move(handle));
+              gpu::SHARED_IMAGE_USAGE_CPU_WRITE, "BitmapRasterBufferProvider");
       CHECK(backing->shared_image);
+      backing->scoped_mapping = backing->shared_image->Map();
+      CHECK(backing->scoped_mapping);
     } else {
       backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
       base::MappedReadOnlyRegion shm =
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 753bf2b89addd..0b9b832f941ae 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -4662,7 +4662,8 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
   // For software compositing, shared memory will be allocated and the
   // UIResource will be copied into it.
   base::MappedReadOnlyRegion shm;
-  base::WritableSharedMemoryMapping mapping;
+  base::WritableSharedMemoryMapping shared_mapping;
+  std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> scoped_mapping;
   viz::SharedBitmapId shared_bitmap_id;
   bool overlay_candidate = false;
   bool use_shared_image =
@@ -4692,29 +4693,15 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
     auto* sii = layer_tree_frame_sink_->shared_image_interface();
     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(
         format, upload_size, color_space, kTopLeft_GrSurfaceOrigin,
-        kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource",
-        std::move(handle));
+        kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource");
     CHECK(client_shared_image);
-    shared_bitmap_id = client_shared_image->mailbox();
+    scoped_mapping = client_shared_image->Map();
+    CHECK(scoped_mapping);
   } else {
     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();
   }
 
@@ -4737,8 +4724,10 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
       SkImageInfo dst_info =
           SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
 
-      sk_sp<SkSurface> surface = SkSurfaces::WrapPixels(
-          dst_info, mapping.memory(), dst_info.minRowBytes());
+      void* pixels =
+          scoped_mapping ? scoped_mapping->Memory(0) : shared_mapping.memory();
+      sk_sp<SkSurface> surface =
+          SkSurfaces::WrapPixels(dst_info, pixels, dst_info.minRowBytes());
       surface->getCanvas()->writePixels(
           src_info, const_cast<uint8_t*>(bitmap.GetPixels()),
           bitmap.row_bytes(), 0, 0);
@@ -4774,8 +4763,10 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
     } else {
       SkImageInfo dst_info =
           SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
-      scaled_surface = SkSurfaces::WrapPixels(dst_info, mapping.memory(),
-                                              dst_info.minRowBytes());
+      void* pixels =
+          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.
     }
     SkCanvas* scaled_canvas = scaled_surface->getCanvas();
@@ -4823,7 +4814,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
     auto* sii = layer_tree_frame_sink_->shared_image_interface();
     gpu::SyncToken sync_token = sii->GenVerifiedSyncToken();
     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);
   } else {
     layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region),
@@ -4847,7 +4838,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
   data.format = format;
   if (!use_shared_image) {
     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.resource_id_for_export = id;
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc
index a3d7248cf1c06..71541bb0b744f 100644
--- a/components/viz/test/test_context_provider.cc
+++ b/components/viz/test/test_context_provider.cc
@@ -264,6 +264,21 @@ TestSharedImageInterface::CreateSharedImage(
   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>
 TestSharedImageInterface::CreateSharedImage(
     gfx::GpuMemoryBuffer* gpu_memory_buffer,
diff --git a/components/viz/test/test_context_provider.h b/components/viz/test/test_context_provider.h
index e22f14191ff9e..871067336dbd8 100644
--- a/components/viz/test/test_context_provider.h
+++ b/components/viz/test/test_context_provider.h
@@ -97,6 +97,15 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
       base::StringPiece debug_label,
       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(
       gfx::GpuMemoryBuffer* gpu_memory_buffer,
       gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
diff --git a/gpu/command_buffer/client/shared_image_interface.h b/gpu/command_buffer/client/shared_image_interface.h
index 000d7298b89a9..3a8f9d938349c 100644
--- a/gpu/command_buffer/client/shared_image_interface.h
+++ b/gpu/command_buffer/client/shared_image_interface.h
@@ -158,6 +158,19 @@ class GPU_EXPORT SharedImageInterface {
       base::StringPiece debug_label,
       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
   // single planar eg. RGB BufferFormats. Please use the equivalent method above
   // taking in single planar SharedImageFormat with GpuMemoryBufferHandle.
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process.cc b/gpu/command_buffer/service/shared_image_interface_in_process.cc
index e096b8aae38cc..7402f1bd711f6 100644
--- a/gpu/command_buffer/service/shared_image_interface_in_process.cc
+++ b/gpu/command_buffer/service/shared_image_interface_in_process.cc
@@ -5,10 +5,12 @@
 #include "gpu/command_buffer/service/shared_image_interface_in_process.h"
 
 #include <optional>
+
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.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/gpu_memory_buffer_manager.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_preferences.h"
 #include "gpu/ipc/common/gpu_client_ids.h"
+#include "ui/gfx/buffer_format_util.h"
 #include "ui/gl/gl_context.h"
 
 namespace gpu {
@@ -503,6 +506,60 @@ SharedImageInterfaceInProcess::CreateSharedImage(
 
   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(
     const Mailbox& mailbox,
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process.h b/gpu/command_buffer/service/shared_image_interface_in_process.h
index f9df8d637355c..748e0aa3c6d27 100644
--- a/gpu/command_buffer/service/shared_image_interface_in_process.h
+++ b/gpu/command_buffer/service/shared_image_interface_in_process.h
@@ -115,6 +115,14 @@ class GPU_GLES2_EXPORT SharedImageInterfaceInProcess
       uint32_t usage,
       base::StringPiece debug_label,
       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(
       gfx::GpuMemoryBuffer* gpu_memory_buffer,
       GpuMemoryBufferManager* gpu_memory_buffer_manager,
diff --git a/gpu/ipc/client/client_shared_image_interface.cc b/gpu/ipc/client/client_shared_image_interface.cc
index 02e5c217e687e..f7775acf0292f 100644
--- a/gpu/ipc/client/client_shared_image_interface.cc
+++ b/gpu/ipc/client/client_shared_image_interface.cc
@@ -12,6 +12,7 @@
 #include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/ipc/client/gpu_channel_host.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_memory_buffer.h"
 
@@ -198,6 +199,47 @@ scoped_refptr<ClientSharedImage> ClientSharedImageInterface::CreateSharedImage(
           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(
     gfx::GpuMemoryBuffer* gpu_memory_buffer,
     GpuMemoryBufferManager* gpu_memory_buffer_manager,
diff --git a/gpu/ipc/client/client_shared_image_interface.h b/gpu/ipc/client/client_shared_image_interface.h
index 0e7c5be2f3a87..67274b2afba99 100644
--- a/gpu/ipc/client/client_shared_image_interface.h
+++ b/gpu/ipc/client/client_shared_image_interface.h
@@ -96,6 +96,19 @@ class GPU_EXPORT ClientSharedImageInterface : public SharedImageInterface {
       uint32_t usage,
       base::StringPiece debug_label,
       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
   // single planar eg. RGB BufferFormats. Please use the equivalent method above
   // taking in single planar SharedImageFormat with GpuMemoryBufferHandle.
diff --git a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
index cdf04e308224d..6728ef054babe 100644
--- a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
+++ b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
@@ -159,6 +159,17 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
     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(
       gfx::GpuMemoryBuffer* gpu_memory_buffer,
       gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,