blob: a9d740ac8bc83eff447cae0cc636815ac0f0e3e8 [file] [log] [blame]
// 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.
#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_SHARED_IMAGE_H_
#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_SHARED_IMAGE_H_
#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/gpu_export.h"
#include "gpu/ipc/common/gpu_memory_buffer_handle_info.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/gpu_memory_buffer.h"
namespace viz {
class TestSharedImageInterface;
}
namespace gpu {
// Controls whether all ClientSharedImage::GetTextureTarget*(...) variants call
// through to ClientSharedImage::GetTextureTarget() under the hood.
GPU_EXPORT BASE_DECLARE_FEATURE(kUseUniversalGetTextureTargetFunction);
struct ExportedSharedImage;
class GPU_EXPORT ClientSharedImage
: public base::RefCountedThreadSafe<ClientSharedImage> {
public:
// Provides access to the CPU visible memory for the SharedImage if it is
// being used for CPU READ/WRITE and underlying resource(native buffers/shared
// memory) is CPU mappable. Memory and strides can be requested for each
// plane.
class GPU_EXPORT ScopedMapping {
public:
~ScopedMapping();
// Returns a pointer to the beginning of the plane.
void* Memory(const uint32_t plane_index);
// Returns plane stride.
size_t Stride(const uint32_t plane_index);
// Returns the size of the buffer.
gfx::Size Size();
// Returns BufferFormat.
gfx::BufferFormat Format();
// Returns whether the underlying resource is shared memory.
bool IsSharedMemory();
// Dumps information about the memory backing this instance to |pmd|.
// The memory usage is attributed to |buffer_dump_guid|.
// |tracing_process_id| uniquely identifies the process owning the memory.
// |importance| is relevant only for the cases of co-ownership, the memory
// gets attributed to the owner with the highest importance.
void OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd,
const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
uint64_t tracing_process_id,
int importance);
private:
friend class ClientSharedImage;
ScopedMapping();
static std::unique_ptr<ScopedMapping> Create(
gfx::GpuMemoryBuffer* gpu_memory_buffer);
bool Init(gfx::GpuMemoryBuffer* gpu_memory_buffer);
// ScopedMapping is essentially a wrapper around GpuMemoryBuffer for now for
// simplicity and will be removed later.
// TODO(crbug.com/1474697): Refactor/Rename GpuMemoryBuffer and its
// implementations as the end goal after all clients using GMB are
// converted to use the ScopedMapping and notion of GpuMemoryBuffer is being
// removed.
raw_ptr<gfx::GpuMemoryBuffer> buffer_;
};
explicit ClientSharedImage(
const Mailbox& mailbox,
const SharedImageMetadata& metadata,
const SyncToken& sync_token,
scoped_refptr<SharedImageInterfaceHolder> sii_holder,
gfx::GpuMemoryBufferType gmb_type = gfx::EMPTY_BUFFER);
ClientSharedImage(const Mailbox& mailbox,
const SharedImageMetadata& metadata,
const SyncToken& sync_token,
GpuMemoryBufferHandleInfo handle_info,
scoped_refptr<SharedImageInterfaceHolder> sii_holder);
const Mailbox& mailbox() { return mailbox_; }
viz::SharedImageFormat format() const { return metadata_.format; }
gfx::Size size() const { return metadata_.size; }
uint32_t usage() { return metadata_.usage; }
bool HasHolder() { return sii_holder_ != nullptr; }
// Returns a clone of the GpuMemoryBufferHandle associated with this ClientSI.
// Valid to call only if this instance was created with a non-null
// GpuMemoryBuffer.
gfx::GpuMemoryBufferHandle CloneGpuMemoryBufferHandle() const {
CHECK(gpu_memory_buffer_);
return gpu_memory_buffer_->CloneHandle();
}
#if BUILDFLAG(IS_APPLE)
// Sets the color space in which the native buffer backing this SharedImage
// should be interpreted when used as an overlay. Note that this will not
// impact texturing from the buffer. Used only for SharedImages backed by a
// client-accessible IOSurface.
void SetColorSpaceOnNativeBuffer(const gfx::ColorSpace& color_space);
#endif
// Returns the GL texture target to use for this SharedImage.
// TODO(crbug.com/41494843): Eliminate all the below variants in favor of all
// clients using this function.
uint32_t GetTextureTarget();
// Returns the texture target to use for overlays:
// * GL_TEXTURE_2D on platforms other than MacOS
// * The platform-specific texture target for MacOS
uint32_t GetTextureTargetForOverlays();
// Returns the texture target to be used for the given |format|. For usage
// when this SharedImage was created from a native buffer and the client knows
// that the usages of this SI would result in needing the platform-specific
// texture target for `format` if one exists on this platform. Returns
// GL_TEXTURE_2D if |format| does not require a platform-specific target and
// the relevant platform-specific target otherwise.
uint32_t GetTextureTarget(gfx::BufferFormat format);
// Returns the texture target to be used for the given |usage| and |format|
// based on the underlying SharedImageCapabilities. Requires that
// `HasHolder()` is true. For usage when this SharedImage was created from a
// native buffer. Returns GL_TEXTURE_2D if the `usage`/`format` pair does not
// require a platform-specific target and the relevant platform-specific
// target otherwise.
uint32_t GetTextureTarget(gfx::BufferUsage usage, gfx::BufferFormat format);
// Similar to the above, but for usage if the client did not explicitly create
// this SharedImage from a native buffer. Returns GL_TEXTURE_2D if the set of
// usages that the client specified do not result in this SharedImage being
// backed by a native buffer. Otherwise, uses this instance's
// SharedImageFormat (which must be a single-planar format) to compute the
// BufferFormat and returns the result of the above GetTextureTarget() call.
uint32_t GetTextureTarget(gfx::BufferUsage usage);
base::trace_event::MemoryAllocatorDumpGuid GetGUIDForTracing() {
return gpu::GetSharedImageGUIDForTracing(mailbox_);
}
// Maps |mailbox| into CPU visible memory and returns a ScopedMapping object
// which can be used to read/write to the CPU mapped memory. The SharedImage
// backing this ClientSI must have been created with CPU_READ/CPU_WRITE usage.
std::unique_ptr<ScopedMapping> Map();
ExportedSharedImage Export();
// Returns an unowned reference. The caller should ensure that the original
// shared image outlives this reference. Note that it is preferable to use
// SharedImageInterface::ImportSharedImage() instead, which returns an owning
// reference.
static scoped_refptr<ClientSharedImage> ImportUnowned(
const ExportedSharedImage& exported_shared_image);
static scoped_refptr<ClientSharedImage> CreateForTesting() {
return base::MakeRefCounted<ClientSharedImage>(
Mailbox::GenerateForSharedImage(), SharedImageMetadata(),
gpu::SyncToken(), nullptr);
}
static scoped_refptr<ClientSharedImage> CreateForTesting(
const Mailbox& mailbox,
const SharedImageMetadata& metadata,
const SyncToken& sync_token,
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
scoped_refptr<SharedImageInterfaceHolder> sii_holder) {
auto client_si = base::MakeRefCounted<ClientSharedImage>(
mailbox, metadata, sync_token, sii_holder);
client_si->gpu_memory_buffer_ = std::move(gpu_memory_buffer);
return client_si;
}
private:
friend class base::RefCountedThreadSafe<ClientSharedImage>;
~ClientSharedImage();
const Mailbox mailbox_;
const SharedImageMetadata metadata_;
SyncToken creation_sync_token_;
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
scoped_refptr<SharedImageInterfaceHolder> sii_holder_;
// Whether a client-side native buffer was used in the creation of this
// SharedImage.
bool client_side_native_buffer_used_ = false;
};
struct GPU_EXPORT ExportedSharedImage {
private:
friend class ClientSharedImage;
friend class SharedImageInterface;
friend class ClientSharedImageInterface;
friend class viz::TestSharedImageInterface;
ExportedSharedImage(const Mailbox& mailbox,
const SharedImageMetadata& metadata,
const SyncToken& sync_token);
const Mailbox mailbox_;
const SharedImageMetadata metadata_;
SyncToken sync_token_;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_SHARED_IMAGE_H_