Skip to content

Commit

Permalink
gpu: Pass plane format to compound image gpu backing factory
Browse files Browse the repository at this point in the history
For YUV formats, CompoundImageBacking uses the resource format instead
of the plane format when trying to find a compatible GPU backing. This
just happens to work because D3DImageBackingFactory special cases NV12
for CPU upload usage set by the compound backing. This CL fixes this by
passing the plane format instead and updating the D3D backing factory.
This is necessary if we want more platforms to use compound backings for
software video frames e.g. using GL texture backing on Linux.

Bug: 1371982
Change-Id: I49301e40b137f1b9d1b49664790bb59178e496b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4043646
Reviewed-by: Saifuddin Hitawala <hitawala@chromium.org>
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1076994}
  • Loading branch information
sunnyps authored and Chromium LUCI CQ committed Nov 29, 2022
1 parent 4ad5780 commit dda2dce
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 52 deletions.
65 changes: 40 additions & 25 deletions gpu/command_buffer/service/shared_image/compound_image_backing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/trace_event/memory_allocator_dump_guid.h"
#include "base/trace_event/process_memory_dump.h"
Expand Down Expand Up @@ -37,26 +38,6 @@ BASE_FEATURE(kSkipReadbackToSharedMemory,
"SkipReadbackToSharedMemory",
base::FEATURE_ENABLED_BY_DEFAULT);

bool IsValidSharedMemoryBufferFormat(const gfx::Size& size,
gfx::BufferFormat buffer_format,
gfx::BufferPlane plane) {
if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, buffer_format)) {
DLOG(ERROR) << "Invalid image size for format.";
return false;
}
switch (plane) {
case gfx::BufferPlane::DEFAULT:
case gfx::BufferPlane::Y:
case gfx::BufferPlane::UV:
break;
default:
DLOG(ERROR) << "Invalid plane " << gfx::BufferPlaneToString(plane);
return false;
}

return true;
}

// Unique GUIDs for child backings.
base::trace_event::MemoryAllocatorDumpGuid GetSubBackingGUIDForTracing(
const Mailbox& mailbox,
Expand All @@ -66,6 +47,23 @@ base::trace_event::MemoryAllocatorDumpGuid GetSubBackingGUIDForTracing(
mailbox.ToDebugString().c_str(), backing_index));
}

bool IsBufferPlaneAndFormatSupported(gfx::BufferPlane plane,
gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::YVU_420:
return plane == gfx::BufferPlane::Y || plane == gfx::BufferPlane::U ||
plane == gfx::BufferPlane::V;
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::P010:
return plane == gfx::BufferPlane::Y || plane == gfx::BufferPlane::UV;
case gfx::BufferFormat::YUVA_420_TRIPLANAR:
return plane == gfx::BufferPlane::Y || plane == gfx::BufferPlane::UV ||
plane == gfx::BufferPlane::A;
default:
return plane == gfx::BufferPlane::DEFAULT;
}
}

} // namespace

// Wrapped representation types are not in the anonymous namespace because they
Expand Down Expand Up @@ -286,6 +284,24 @@ class WrappedOverlayCompoundImageRepresentation
std::unique_ptr<OverlayImageRepresentation> wrapped_;
};

// static
bool CompoundImageBacking::IsValidSharedMemoryBufferFormat(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferPlane plane) {
if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) {
DVLOG(1) << "Invalid image size: " << size.ToString()
<< " for format: " << gfx::BufferFormatToString(format);
return false;
}
if (!IsBufferPlaneAndFormatSupported(plane, format)) {
DVLOG(1) << "Unsupported buffer plane: " << gfx::BufferPlaneToString(plane)
<< " for format: " << gfx::BufferFormatToString(format);
return false;
}
return true;
}

// static
std::unique_ptr<SharedImageBacking> CompoundImageBacking::CreateSharedMemory(
SharedImageBackingFactory* gpu_backing_factory,
Expand All @@ -300,14 +316,13 @@ std::unique_ptr<SharedImageBacking> CompoundImageBacking::CreateSharedMemory(
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage) {
if (!IsValidSharedMemoryBufferFormat(size, buffer_format, plane))
return nullptr;
DCHECK(IsValidSharedMemoryBufferFormat(size, buffer_format, plane));

const gfx::Size plane_size = GetPlaneSize(plane, size);
const viz::ResourceFormat plane_format =
viz::GetResourceFormat(GetPlaneBufferFormat(plane, buffer_format));

const size_t plane_index = plane == gfx::BufferPlane::UV ? 1 : 0;
const size_t plane_index = GetPlaneIndex(plane, buffer_format);
handle.offset +=
gfx::BufferOffsetForBufferFormat(size, buffer_format, plane_index);

Expand All @@ -324,10 +339,10 @@ std::unique_ptr<SharedImageBacking> CompoundImageBacking::CreateSharedMemory(
SHARED_IMAGE_USAGE_CPU_WRITE, std::move(shm_wrapper));
shm_backing->SetNotRefCounted();

return std::make_unique<CompoundImageBacking>(
return base::WrapUnique(new CompoundImageBacking(
mailbox, si_format, plane_size, color_space, surface_origin, alpha_type,
usage, surface_handle, allow_shm_overlays, std::move(shm_backing),
gpu_backing_factory->GetWeakPtr());
gpu_backing_factory->GetWeakPtr()));
}

CompoundImageBacking::CompoundImageBacking(
Expand Down
30 changes: 17 additions & 13 deletions gpu/command_buffer/service/shared_image/compound_image_backing.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ enum class SharedImageAccessStream {
// TODO(crbug.com/1293509): Support multiple GPU backings.
class GPU_GLES2_EXPORT CompoundImageBacking : public SharedImageBacking {
public:
static bool IsValidSharedMemoryBufferFormat(const gfx::Size& size,
gfx::BufferFormat buffer_format,
gfx::BufferPlane plane);

// Creates a backing that contains a shared memory backing and GPU backing
// provided by `gpu_backing_factory`.
static std::unique_ptr<SharedImageBacking> CreateSharedMemory(
Expand All @@ -55,19 +59,6 @@ class GPU_GLES2_EXPORT CompoundImageBacking : public SharedImageBacking {
SkAlphaType alpha_type,
uint32_t usage);

CompoundImageBacking(
const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
SurfaceHandle surface_handle,
bool allow_shm_overlays,
std::unique_ptr<SharedMemoryImageBacking> shm_backing,
base::WeakPtr<SharedImageBackingFactory> gpu_backing_factory);

~CompoundImageBacking() override;

// Called by wrapped representations before access. This will update
Expand Down Expand Up @@ -107,6 +98,19 @@ class GPU_GLES2_EXPORT CompoundImageBacking : public SharedImageBacking {
private:
friend class CompoundImageBackingTest;

CompoundImageBacking(
const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
SurfaceHandle surface_handle,
bool allow_shm_overlays,
std::unique_ptr<SharedMemoryImageBacking> shm_backing,
base::WeakPtr<SharedImageBackingFactory> gpu_backing_factory);

void OnMemoryDump(const std::string& dump_name,
base::trace_event::MemoryAllocatorDumpGuid client_guid,
base::trace_event::ProcessMemoryDump* pmd,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ absl::optional<DXGI_FORMAT> GetSupportedRGBAFormat(
return DXGI_FORMAT_R8_UNORM;
case viz::RG_88:
return DXGI_FORMAT_R8G8_UNORM;
case viz::R16_EXT:
return DXGI_FORMAT_R16_UNORM;
case viz::RG16_EXT:
return DXGI_FORMAT_R16G16_UNORM;
default:
NOTREACHED();
return {};
Expand All @@ -89,7 +93,7 @@ DXGI_FORMAT GetDXGIFormat(gfx::BufferFormat buffer_format) {
}
}

// Formats supported by CreateSharedImage(GMB).
// Typeless formats supported by CreateSharedImage(GMB) for XR.
DXGI_FORMAT GetDXGITypelessFormat(gfx::BufferFormat buffer_format) {
switch (buffer_format) {
case gfx::BufferFormat::RGBA_8888:
Expand Down Expand Up @@ -509,15 +513,9 @@ bool D3DImageBackingFactory::IsSupported(uint32_t usage,
}

if (gmb_type == gfx::EMPTY_BUFFER) {
if (usage & SHARED_IMAGE_USAGE_CPU_UPLOAD) {
// Only allow single NV12 shared memory GMBs for now. This excludes
// dual shared memory GMBs used by software video decoder.
if (format.resource_format() != viz::YUV_420_BIPLANAR)
return false;
} else {
if (!GetSupportedRGBAFormat(format))
return false;
}
// We only support rendering or uploading to RGBA formats.
if (!GetSupportedRGBAFormat(format))
return false;
} else if (gmb_type == gfx::DXGI_SHARED_HANDLE) {
if (GetDXGIFormat(ToBufferFormat(format)) == DXGI_FORMAT_UNKNOWN)
return false;
Expand Down
17 changes: 13 additions & 4 deletions gpu/command_buffer/service/shared_image/shared_image_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,19 @@ bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
!IsSharedBetweenThreads(usage)) {
// Check if CompoundImageBacking can hold shared memory buffer plus
// another GPU backing type to satisfy requirements.
use_compound = true;
factory = GetFactoryByUsage(usage | SHARED_IMAGE_USAGE_CPU_UPLOAD,
si_format, size,
/*pixel_data=*/{}, gfx::EMPTY_BUFFER);
if (CompoundImageBacking::IsValidSharedMemoryBufferFormat(size, format,
plane)) {
// For shared memory backed compound backings, we need to check if the
// corresponding GPU backing can support the format and size for the given
// plane rather than the original GMB format and size.
const auto plane_format = viz::SharedImageFormat::SinglePlane(
viz::GetResourceFormat(GetPlaneBufferFormat(plane, format)));
const gfx::Size plane_size = GetPlaneSize(plane, size);
factory =
GetFactoryByUsage(usage | SHARED_IMAGE_USAGE_CPU_UPLOAD, plane_format,
plane_size, /*pixel_data=*/{}, gfx::EMPTY_BUFFER);
use_compound = factory != nullptr;
}
}

if (!factory) {
Expand Down

0 comments on commit dda2dce

Please sign in to comment.