#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
#include <inttypes.h>
#include <memory>
#include "base/containers/contains.h"
#include "base/metrics/histogram_functions.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "build/chromeos_buildflags.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image/compound_image_backing.h"
#include "gpu/command_buffer/service/shared_image/egl_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
#include "gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.h"
#include "ui/base/ozone_buildflags.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gl_display.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/gl_version_info.h"
#include "ui/gl/trace_util.h"
#if BUILDFLAG(ENABLE_VULKAN)
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_WIN)
#include "gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include <vulkan/vulkan_android.h>
#endif
#endif
#if BUILDFLAG(IS_OZONE)
#include "gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h"
#include "ui/ozone/public/gl_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"
#endif
#if BUILDFLAG(IS_APPLE)
#include "gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "gpu/command_buffer/service/dxgi_shared_handle_manager.h"
#include "gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.h"
#include "ui/gl/direct_composition_support.h"
#include "ui/gl/gl_angle_util_win.h"
#endif
#if BUILDFLAG(IS_FUCHSIA)
#include <lib/zx/channel.h>
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_implementation.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/android_hardware_buffer_compat.h"
#include "gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.h"
#endif
namespace gpu {
namespace {
const char* GmbTypeToString(gfx::GpuMemoryBufferType type) { … }
gfx::GpuMemoryBufferType GetNativeBufferType() { … }
bool WillGetGmbConfigFromGpu() { … }
}
std::size_t
SharedImageFactory::SharedImageRepresentationFactoryRefHash::operator()(
const std::unique_ptr<SharedImageRepresentationFactoryRef>& o) const { … }
std::size_t
SharedImageFactory::SharedImageRepresentationFactoryRefHash::operator()(
const gpu::Mailbox& m) const { … }
bool SharedImageFactory::SharedImageRepresentationFactoryRefKeyEqual::
operator()(
const std::unique_ptr<SharedImageRepresentationFactoryRef>& lhs,
const std::unique_ptr<SharedImageRepresentationFactoryRef>& rhs) const { … }
bool SharedImageFactory::SharedImageRepresentationFactoryRefKeyEqual::
operator()(const std::unique_ptr<SharedImageRepresentationFactoryRef>& lhs,
const gpu::Mailbox& rhs) const { … }
bool SharedImageFactory::SharedImageRepresentationFactoryRefKeyEqual::
operator()(
const gpu::Mailbox& lhs,
const std::unique_ptr<SharedImageRepresentationFactoryRef>& rhs) const { … }
SharedImageFactory::SharedImageFactory(
const GpuPreferences& gpu_preferences,
const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info,
SharedContextState* context_state,
SharedImageManager* shared_image_manager,
MemoryTracker* memory_tracker,
bool is_for_display_compositor)
: … { … }
SharedImageFactory::~SharedImageFactory() { … }
bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
gpu::SurfaceHandle surface_handle,
SharedImageUsageSet usage,
std::string debug_label) { … }
bool SharedImageFactory::IsNativeBufferSupported(gfx::BufferFormat format,
gfx::BufferUsage usage) { … }
bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
SurfaceHandle surface_handle,
SharedImageUsageSet usage,
std::string debug_label,
gfx::BufferUsage buffer_usage) { … }
bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
SharedImageUsageSet usage,
std::string debug_label,
base::span<const uint8_t> data) { … }
bool SharedImageFactory::CreateSharedImage(
const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
SharedImageUsageSet usage,
std::string debug_label,
gfx::GpuMemoryBufferHandle buffer_handle) { … }
bool SharedImageFactory::UpdateSharedImage(const Mailbox& mailbox) { … }
bool SharedImageFactory::UpdateSharedImage(
const Mailbox& mailbox,
std::unique_ptr<gfx::GpuFence> in_fence) { … }
bool SharedImageFactory::DestroySharedImage(const Mailbox& mailbox) { … }
bool SharedImageFactory::SetSharedImagePurgeable(const Mailbox& mailbox,
bool purgeable) { … }
void SharedImageFactory::DestroyAllSharedImages(bool have_context) { … }
#if BUILDFLAG(IS_WIN)
bool SharedImageFactory::CreateSwapChain(const Mailbox& front_buffer_mailbox,
const Mailbox& back_buffer_mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
gpu::SharedImageUsageSet usage) {
if (!D3DImageBackingFactory::IsSwapChainSupported(gpu_preferences_)) {
return false;
}
auto backings = d3d_backing_factory_->CreateSwapChain(
front_buffer_mailbox, back_buffer_mailbox, format, size, color_space,
surface_origin, alpha_type, usage);
return RegisterBacking(std::move(backings.front_buffer)) &&
RegisterBacking(std::move(backings.back_buffer));
}
bool SharedImageFactory::PresentSwapChain(const Mailbox& mailbox) {
if (!D3DImageBackingFactory::IsSwapChainSupported(gpu_preferences_)) {
return false;
}
auto it = shared_images_.find(mailbox);
if (it == shared_images_.end()) {
DLOG(ERROR) << "PresentSwapChain: Could not find shared image mailbox";
return false;
}
(*it)->PresentSwapChain();
return true;
}
#endif
#if BUILDFLAG(IS_FUCHSIA)
void SharedImageFactory::RegisterSysmemBufferCollection(
zx::eventpair service_handle,
zx::channel sysmem_token,
const viz::SharedImageFormat& format,
gfx::BufferUsage usage,
bool register_with_image_pipe) {
auto* vulkan_context_provider = context_state_->vk_context_provider();
VkDevice device =
vulkan_context_provider->GetDeviceQueue()->GetVulkanDevice();
DCHECK(device != VK_NULL_HANDLE);
auto buffer_format = ToBufferFormat(format);
vulkan_context_provider->GetVulkanImplementation()
->RegisterSysmemBufferCollection(
device, std::move(service_handle), std::move(sysmem_token),
buffer_format, usage, gfx::Size(), 0, register_with_image_pipe);
}
#endif
bool SharedImageFactory::CopyToGpuMemoryBuffer(const Mailbox& mailbox) { … }
#if BUILDFLAG(IS_WIN)
bool SharedImageFactory::CopyToGpuMemoryBufferAsync(
const Mailbox& mailbox,
base::OnceCallback<void(bool)> callback) {
auto it = shared_images_.find(mailbox);
if (it == shared_images_.end()) {
DLOG(ERROR)
<< "CopyToGpuMemoryBufferAsync: Could not find shared image mailbox";
return false;
}
(*it)->CopyToGpuMemoryBufferAsync(std::move(callback));
return true;
}
#endif
bool SharedImageFactory::GetGpuMemoryBufferHandleInfo(
const Mailbox& mailbox,
gfx::GpuMemoryBufferHandle& handle,
viz::SharedImageFormat& format,
gfx::Size& size,
gfx::BufferUsage& buffer_usage) { … }
void SharedImageFactory::RegisterSharedImageBackingFactoryForTesting(
SharedImageBackingFactory* factory) { … }
gpu::SharedImageCapabilities SharedImageFactory::MakeCapabilities() { … }
bool SharedImageFactory::HasSharedImage(const Mailbox& mailbox) const { … }
void SharedImageFactory::SetGpuExtraInfo(
const gfx::GpuExtraInfo& gpu_extra_info) { … }
bool SharedImageFactory::IsSharedBetweenThreads(
gpu::SharedImageUsageSet usage) { … }
SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
gpu::SharedImageUsageSet usage,
viz::SharedImageFormat format,
const gfx::Size& size,
base::span<const uint8_t> pixel_data,
gfx::GpuMemoryBufferType gmb_type) { … }
void SharedImageFactory::LogGetFactoryFailed(gpu::SharedImageUsageSet usage,
viz::SharedImageFormat format,
gfx::GpuMemoryBufferType gmb_type,
const std::string& debug_label) { … }
bool SharedImageFactory::RegisterBacking(
std::unique_ptr<SharedImageBacking> backing) { … }
bool SharedImageFactory::AddSecondaryReference(const gpu::Mailbox& mailbox) { … }
SharedImageUsageSet SharedImageFactory::GetUsageForMailbox(
const Mailbox& mailbox) { … }
SharedImageRepresentationFactory::SharedImageRepresentationFactory(
SharedImageManager* manager,
MemoryTracker* tracker)
: … { … }
SharedImageRepresentationFactory::~SharedImageRepresentationFactory() { … }
std::unique_ptr<GLTextureImageRepresentation>
SharedImageRepresentationFactory::ProduceGLTexture(const Mailbox& mailbox) { … }
std::unique_ptr<GLTexturePassthroughImageRepresentation>
SharedImageRepresentationFactory::ProduceGLTexturePassthrough(
const Mailbox& mailbox) { … }
std::unique_ptr<SkiaImageRepresentation>
SharedImageRepresentationFactory::ProduceSkia(
const Mailbox& mailbox,
scoped_refptr<SharedContextState> context_state) { … }
std::unique_ptr<DawnImageRepresentation>
SharedImageRepresentationFactory::ProduceDawn(
const Mailbox& mailbox,
const wgpu::Device& device,
wgpu::BackendType backend_type,
std::vector<wgpu::TextureFormat> view_formats,
scoped_refptr<SharedContextState> context_state) { … }
std::unique_ptr<OverlayImageRepresentation>
SharedImageRepresentationFactory::ProduceOverlay(const gpu::Mailbox& mailbox) { … }
std::unique_ptr<MemoryImageRepresentation>
SharedImageRepresentationFactory::ProduceMemory(const gpu::Mailbox& mailbox) { … }
std::unique_ptr<RasterImageRepresentation>
SharedImageRepresentationFactory::ProduceRaster(const Mailbox& mailbox) { … }
#if BUILDFLAG(IS_ANDROID)
std::unique_ptr<LegacyOverlayImageRepresentation>
SharedImageRepresentationFactory::ProduceLegacyOverlay(
const gpu::Mailbox& mailbox) {
return manager_->ProduceLegacyOverlay(mailbox, tracker_.get());
}
#endif
#if BUILDFLAG(ENABLE_VULKAN) && BUILDFLAG(IS_OZONE)
std::unique_ptr<VulkanImageRepresentation>
SharedImageRepresentationFactory::ProduceVulkan(
const gpu::Mailbox& mailbox,
gpu::VulkanDeviceQueue* vulkan_device_queue,
gpu::VulkanImplementation& vulkan_impl,
bool needs_detiling) { … }
#endif
}