blob: 33f189c2d6763adf2704a46ab7116658b5ba7b6c [file]
// Copyright 2023 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/command_buffer/client/client_shared_image.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
namespace gpu {
ClientSharedImage::ScopedMapping::ScopedMapping() = default;
ClientSharedImage::ScopedMapping::~ScopedMapping() {
if (buffer_) {
buffer_->Unmap();
}
}
// static
std::unique_ptr<ClientSharedImage::ScopedMapping>
ClientSharedImage::ScopedMapping::Create(
gfx::GpuMemoryBuffer* gpu_memory_buffer) {
auto scoped_mapping = base::WrapUnique(new ScopedMapping());
if (!scoped_mapping->Init(gpu_memory_buffer)) {
LOG(ERROR) << "ScopedMapping init failed.";
return nullptr;
}
return scoped_mapping;
}
bool ClientSharedImage::ScopedMapping::Init(
gfx::GpuMemoryBuffer* gpu_memory_buffer) {
if (!gpu_memory_buffer) {
LOG(ERROR) << "No GpuMemoryBuffer.";
return false;
}
if (!gpu_memory_buffer->Map()) {
LOG(ERROR) << "Failed to map the buffer.";
return false;
}
buffer_ = gpu_memory_buffer;
return true;
}
void* ClientSharedImage::ScopedMapping::Memory(const uint32_t plane_index) {
CHECK(buffer_);
return buffer_->memory(plane_index);
}
size_t ClientSharedImage::ScopedMapping::Stride(const uint32_t plane_index) {
CHECK(buffer_);
return buffer_->stride(plane_index);
}
gfx::Size ClientSharedImage::ScopedMapping::Size() {
CHECK(buffer_);
return buffer_->GetSize();
}
gfx::BufferFormat ClientSharedImage::ScopedMapping::Format() {
CHECK(buffer_);
return buffer_->GetFormat();
}
bool ClientSharedImage::ScopedMapping::IsSharedMemory() {
CHECK(buffer_);
return buffer_->GetType() == gfx::GpuMemoryBufferType::SHARED_MEMORY_BUFFER;
}
void ClientSharedImage::ScopedMapping::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd,
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id,
int importance) {
buffer_->OnMemoryDump(pmd, buffer_dump_guid, tracing_process_id, importance);
}
ClientSharedImage::ClientSharedImage(const Mailbox& mailbox)
: mailbox_(mailbox) {
CHECK(!mailbox.IsZero());
}
ClientSharedImage::ClientSharedImage(const Mailbox& mailbox,
GpuMemoryBufferHandleInfo handle_info)
: mailbox_(mailbox),
gpu_memory_buffer_(
GpuMemoryBufferSupport().CreateGpuMemoryBufferImplFromHandle(
std::move(handle_info.handle),
handle_info.size,
// Only single planar buffer formats are supported currently.
// Multiplanar will be supported when Multiplanar SharedImages are
// fully implemented.
viz::SinglePlaneSharedImageFormatToBufferFormat(
handle_info.format),
handle_info.buffer_usage,
base::DoNothing())) {
CHECK(!mailbox.IsZero());
}
ClientSharedImage::~ClientSharedImage() = default;
std::unique_ptr<ClientSharedImage::ScopedMapping> ClientSharedImage::Map() {
auto scoped_mapping = ScopedMapping::Create(gpu_memory_buffer_.get());
if (!scoped_mapping) {
LOG(ERROR) << "Unable to create ScopedMapping";
}
return scoped_mapping;
}
#if BUILDFLAG(IS_APPLE)
void ClientSharedImage::SetColorSpaceOnNativeBuffer(
const gfx::ColorSpace& color_space) {
CHECK(gpu_memory_buffer_);
gpu_memory_buffer_->SetColorSpace(color_space);
}
#endif
} // namespace gpu