| // Copyright 2014 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/common/buffer.h" | |
| #include <stddef.h> | |
| #include <stdint.h> | |
| #include <ostream> | |
| #include "base/atomic_sequence_num.h" | |
| #include "base/bits.h" | |
| #include "base/check_op.h" | |
| #include "base/compiler_specific.h" | |
| #include "base/containers/span.h" | |
| #include "base/format_macros.h" | |
| #include "base/no_destructor.h" | |
| #include "base/numerics/safe_math.h" | |
| #include "base/strings/stringprintf.h" | |
| namespace gpu { | |
| namespace { | |
| // Global atomic to generate unique buffer IDs. | |
| base::AtomicSequenceNumber g_next_buffer_id; | |
| } // namespace | |
| const base::UnsafeSharedMemoryRegion& BufferBacking::shared_memory_region() | |
| const { | |
| static const base::NoDestructor<base::UnsafeSharedMemoryRegion> | |
| kInvalidRegion; | |
| return *kInvalidRegion; | |
| } | |
| base::UnguessableToken BufferBacking::GetGUID() const { | |
| return base::UnguessableToken(); | |
| } | |
| MemoryBufferBacking::MemoryBufferBacking(uint32_t size, uint32_t alignment) | |
| : memory_(base::AlignedUninit<uint8_t>(size, alignment)) {} | |
| MemoryBufferBacking::~MemoryBufferBacking() = default; | |
| const void* MemoryBufferBacking::GetMemory() const { | |
| return memory_.data(); | |
| } | |
| base::span<const uint8_t> MemoryBufferBacking::as_byte_span() const { | |
| return memory_.as_span(); | |
| } | |
| uint32_t MemoryBufferBacking::GetSize() const { | |
| return memory_.size(); | |
| } | |
| SharedMemoryBufferBacking::SharedMemoryBufferBacking( | |
| base::UnsafeSharedMemoryRegion shared_memory_region, | |
| base::WritableSharedMemoryMapping shared_memory_mapping) | |
| : shared_memory_region_(std::move(shared_memory_region)), | |
| shared_memory_mapping_(std::move(shared_memory_mapping)) { | |
| DCHECK_EQ(shared_memory_region_.GetGUID(), shared_memory_mapping_.guid()); | |
| DCHECK_LE(shared_memory_mapping_.size(), static_cast<size_t>(UINT32_MAX)); | |
| } | |
| SharedMemoryBufferBacking::~SharedMemoryBufferBacking() = default; | |
| const base::UnsafeSharedMemoryRegion& | |
| SharedMemoryBufferBacking::shared_memory_region() const { | |
| return shared_memory_region_; | |
| } | |
| base::UnguessableToken SharedMemoryBufferBacking::GetGUID() const { | |
| return shared_memory_region_.GetGUID(); | |
| } | |
| const void* SharedMemoryBufferBacking::GetMemory() const { | |
| return shared_memory_mapping_.memory(); | |
| } | |
| base::span<const uint8_t> SharedMemoryBufferBacking::as_byte_span() const { | |
| return base::span(shared_memory_mapping_); | |
| } | |
| uint32_t SharedMemoryBufferBacking::GetSize() const { | |
| return static_cast<uint32_t>(shared_memory_mapping_.size()); | |
| } | |
| Buffer::Buffer(std::unique_ptr<BufferBacking> backing) | |
| : backing_(std::move(backing)) { | |
| DCHECK(!backing_->as_byte_span().empty()) | |
| << "The memory must be mapped to create a Buffer"; | |
| } | |
| Buffer::~Buffer() = default; | |
| base::span<uint8_t> Buffer::GetSpanData(uint32_t data_offset, | |
| uint32_t data_size) const { | |
| base::CheckedNumeric<uint32_t> end = data_offset; | |
| end += data_size; | |
| if (!end.IsValid() || end.ValueOrDie() > size()) { | |
| return {}; | |
| } | |
| return backing_->as_byte_span().subspan(data_offset, data_size); | |
| } | |
| void* Buffer::GetDataAddress(uint32_t data_offset, uint32_t data_size) const { | |
| return GetSpanData(data_offset, data_size).data(); | |
| } | |
| void* Buffer::GetDataAddressAndSize(uint32_t data_offset, | |
| uint32_t* data_size) const { | |
| if (data_offset > size()) { | |
| return nullptr; | |
| } | |
| *data_size = GetRemainingSize(data_offset); | |
| return backing_->as_byte_span().subspan(data_offset, *data_size).data(); | |
| } | |
| uint32_t Buffer::GetRemainingSize(uint32_t data_offset) const { | |
| if (data_offset > size()) { | |
| return 0; | |
| } | |
| return size() - data_offset; | |
| } | |
| int32_t GetNextBufferId() { | |
| // 0 is a reserved value. | |
| return g_next_buffer_id.GetNext() + 1; | |
| } | |
| base::trace_event::MemoryAllocatorDumpGuid GetBufferGUIDForTracing( | |
| uint64_t tracing_process_id, | |
| int32_t buffer_id) { | |
| return base::trace_event::MemoryAllocatorDumpGuid(base::StringPrintf( | |
| "gpu-buffer-x-process/%" PRIx64 "/%d", tracing_process_id, buffer_id)); | |
| } | |
| } // namespace gpu |