blob: 5ab9703c397ca31a0fe135a153342d11d700f612 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include <inttypes.h>
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/numerics/checked_math.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_usage_util.h"
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/android_hardware_buffer_compat.h"
#endif
namespace gpu {
namespace {
gfx::GpuMemoryBufferType GetNativeGpuMemoryBufferType() {
#if BUILDFLAG(IS_APPLE)
return gfx::IO_SURFACE_BUFFER;
#elif BUILDFLAG(IS_ANDROID)
return gfx::ANDROID_HARDWARE_BUFFER;
#elif BUILDFLAG(IS_OZONE)
return gfx::NATIVE_PIXMAP;
#elif BUILDFLAG(IS_WIN)
return gfx::DXGI_SHARED_HANDLE;
#else
return gfx::EMPTY_BUFFER;
#endif
}
} // namespace
GpuMemoryBufferSupport::GpuMemoryBufferSupport() = default;
GpuMemoryBufferSupport::~GpuMemoryBufferSupport() = default;
// static
bool GpuMemoryBufferSupport::IsNativeGpuMemoryBufferConfigurationSupported(
gfx::BufferFormat format,
gfx::BufferUsage usage) {
DCHECK_NE(gfx::SHARED_MEMORY_BUFFER, GetNativeGpuMemoryBufferType());
#if BUILDFLAG(IS_APPLE)
switch (usage) {
case gfx::BufferUsage::GPU_READ:
case gfx::BufferUsage::SCANOUT:
case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_FRONT_RENDERING:
case gfx::BufferUsage::SCANOUT_VEA_CPU_READ:
return format == gfx::BufferFormat::BGRA_8888 ||
format == gfx::BufferFormat::RGBA_8888 ||
format == gfx::BufferFormat::BGRX_8888 ||
format == gfx::BufferFormat::RGBX_8888 ||
format == gfx::BufferFormat::R_8 ||
format == gfx::BufferFormat::RG_88 ||
format == gfx::BufferFormat::R_16 ||
format == gfx::BufferFormat::RG_1616 ||
format == gfx::BufferFormat::RGBA_F16 ||
format == gfx::BufferFormat::BGRA_1010102 ||
format == gfx::BufferFormat::YUV_420_BIPLANAR ||
format == gfx::BufferFormat::YUVA_420_TRIPLANAR ||
format == gfx::BufferFormat::P010;
case gfx::BufferUsage::SCANOUT_VDA_WRITE:
case gfx::BufferUsage::PROTECTED_SCANOUT:
case gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE:
case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE:
case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE:
return false;
}
NOTREACHED();
#elif BUILDFLAG(IS_ANDROID)
if (!base::AndroidHardwareBufferCompat::IsSupportAvailable()) {
return false;
}
switch (usage) {
case gfx::BufferUsage::GPU_READ:
case gfx::BufferUsage::SCANOUT:
return format == gfx::BufferFormat::RGBA_8888 ||
format == gfx::BufferFormat::RGBX_8888 ||
format == gfx::BufferFormat::BGR_565;
case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_VDA_WRITE:
case gfx::BufferUsage::PROTECTED_SCANOUT:
case gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE:
case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_VEA_CPU_READ:
case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_FRONT_RENDERING:
return false;
}
NOTREACHED();
#elif BUILDFLAG(IS_OZONE)
return ui::OzonePlatform::GetInstance()->IsNativePixmapConfigSupported(format,
usage);
#elif BUILDFLAG(IS_WIN)
switch (usage) {
case gfx::BufferUsage::GPU_READ:
case gfx::BufferUsage::SCANOUT:
return format == gfx::BufferFormat::RGBA_8888 ||
format == gfx::BufferFormat::RGBX_8888 ||
format == gfx::BufferFormat::BGRA_8888 ||
format == gfx::BufferFormat::BGRX_8888;
case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_VDA_WRITE:
case gfx::BufferUsage::PROTECTED_SCANOUT:
case gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE:
case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_VEA_CPU_READ:
case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE:
case gfx::BufferUsage::SCANOUT_FRONT_RENDERING:
return false;
}
NOTREACHED();
#else
DCHECK_EQ(GetNativeGpuMemoryBufferType(), gfx::EMPTY_BUFFER);
return false;
#endif
}
// static
GpuMemoryBufferConfigurationSet
GpuMemoryBufferSupport::GetNativeGpuMemoryBufferConfigurations() {
GpuMemoryBufferConfigurationSet configurations;
#if BUILDFLAG(IS_OZONE) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) || \
BUILDFLAG(IS_ANDROID)
const gfx::BufferFormat kBufferFormats[] = {
gfx::BufferFormat::R_8,
gfx::BufferFormat::R_16,
gfx::BufferFormat::RG_88,
gfx::BufferFormat::RG_1616,
gfx::BufferFormat::BGR_565,
gfx::BufferFormat::RGBA_4444,
gfx::BufferFormat::RGBX_8888,
gfx::BufferFormat::RGBA_8888,
gfx::BufferFormat::BGRX_8888,
gfx::BufferFormat::BGRA_1010102,
gfx::BufferFormat::RGBA_1010102,
gfx::BufferFormat::BGRA_8888,
gfx::BufferFormat::RGBA_F16,
gfx::BufferFormat::YVU_420,
gfx::BufferFormat::YUV_420_BIPLANAR,
gfx::BufferFormat::YUVA_420_TRIPLANAR,
gfx::BufferFormat::P010};
const gfx::BufferUsage kUsages[] = {
gfx::BufferUsage::GPU_READ,
gfx::BufferUsage::SCANOUT,
gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE,
gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE,
gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
gfx::BufferUsage::SCANOUT_VDA_WRITE,
gfx::BufferUsage::PROTECTED_SCANOUT,
gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE,
gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
gfx::BufferUsage::SCANOUT_VEA_CPU_READ,
gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE,
gfx::BufferUsage::SCANOUT_FRONT_RENDERING,
};
for (auto format : kBufferFormats) {
for (auto usage : kUsages) {
if (IsNativeGpuMemoryBufferConfigurationSupported(format, usage)) {
configurations.insert(gfx::BufferUsageAndFormat(usage, format));
}
}
}
#endif // BUILDFLAG(IS_OZONE) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) ||
// BUILDFLAG(IS_ANDROID)
return configurations;
}
} // namespace gpu