910e62b5创建于 1月15日历史提交
// 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.

#ifndef GPU_COMMAND_BUFFER_COMMON_BUFFER_H_
#define GPU_COMMAND_BUFFER_COMMON_BUFFER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <utility>

#include "base/containers/span.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/ref_counted.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "gpu/command_buffer/common/gpu_command_buffer_common_export.h"
namespace gpu {

class GPU_COMMAND_BUFFER_COMMON_EXPORT BufferBacking {
 public:
  virtual ~BufferBacking() = default;
  virtual const base::UnsafeSharedMemoryRegion& shared_memory_region() const;
  virtual base::UnguessableToken GetGUID() const;
  void* GetMemory() {
    return const_cast<void*>(std::as_const(*this).GetMemory());
  }
  virtual const void* GetMemory() const = 0;
  base::span<uint8_t> as_byte_span() {
    // SAFETY, this is the same as_byte_span() just without const.
    base::span<const uint8_t> tmp = std::as_const(*this).as_byte_span();
    return UNSAFE_BUFFERS(
        base::span<uint8_t>(const_cast<uint8_t*>(tmp.data()), tmp.size()));
  }
  virtual base::span<const uint8_t> as_byte_span() const = 0;
  virtual uint32_t GetSize() const = 0;
};

class GPU_COMMAND_BUFFER_COMMON_EXPORT MemoryBufferBacking
    : public BufferBacking {
 public:
  explicit MemoryBufferBacking(uint32_t size, uint32_t alignment = 0);

  MemoryBufferBacking(const MemoryBufferBacking&) = delete;
  MemoryBufferBacking& operator=(const MemoryBufferBacking&) = delete;

  ~MemoryBufferBacking() override;
  const void* GetMemory() const override;
  base::span<const uint8_t> as_byte_span() const override;
  uint32_t GetSize() const override;

 private:
  base::AlignedHeapArray<uint8_t> memory_;
};

class GPU_COMMAND_BUFFER_COMMON_EXPORT SharedMemoryBufferBacking
    : public BufferBacking {
 public:
  SharedMemoryBufferBacking(
      base::UnsafeSharedMemoryRegion shared_memory_region,
      base::WritableSharedMemoryMapping shared_memory_mapping);

  SharedMemoryBufferBacking(const SharedMemoryBufferBacking&) = delete;
  SharedMemoryBufferBacking& operator=(const SharedMemoryBufferBacking&) =
      delete;

  ~SharedMemoryBufferBacking() override;
  const base::UnsafeSharedMemoryRegion& shared_memory_region() const override;
  base::UnguessableToken GetGUID() const override;
  const void* GetMemory() const override;
  base::span<const uint8_t> as_byte_span() const override;
  uint32_t GetSize() const override;

 private:
  base::UnsafeSharedMemoryRegion shared_memory_region_;
  base::WritableSharedMemoryMapping shared_memory_mapping_;
};

// Buffer owns a piece of shared-memory of a certain size.
class GPU_COMMAND_BUFFER_COMMON_EXPORT Buffer
    : public base::RefCountedThreadSafe<Buffer> {
 public:
  explicit Buffer(std::unique_ptr<BufferBacking> backing);

  Buffer(const Buffer&) = delete;
  Buffer& operator=(const Buffer&) = delete;

  BufferBacking* backing() const { return backing_.get(); }
  void* memory() { return as_byte_span().data(); }
  const void* memory() const { return as_byte_span().data(); }
  base::span<uint8_t> as_byte_span() { return backing_->as_byte_span(); }
  base::span<const uint8_t> as_byte_span() const {
    return backing_->as_byte_span();
  }
  uint32_t size() const { return backing_->GetSize(); }

  // Returns nullptr if the address overflows the memory.
  void* GetDataAddress(uint32_t data_offset, uint32_t data_size) const;

  // Returns nullptr if the address overflows the memory.
  void* GetDataAddressAndSize(uint32_t data_offset, uint32_t* data_size) const;

  // Returns the remaining size of the buffer after an offset
  uint32_t GetRemainingSize(uint32_t data_offset) const;

 private:
  friend class base::RefCountedThreadSafe<Buffer>;
  ~Buffer();

  std::unique_ptr<BufferBacking> backing_;
};

inline std::unique_ptr<BufferBacking> MakeBackingFromSharedMemory(
    base::UnsafeSharedMemoryRegion shared_memory_region,
    base::WritableSharedMemoryMapping shared_memory_mapping) {
  return std::make_unique<SharedMemoryBufferBacking>(
      std::move(shared_memory_region), std::move(shared_memory_mapping));
}
inline scoped_refptr<Buffer> MakeBufferFromSharedMemory(
    base::UnsafeSharedMemoryRegion shared_memory_region,
    base::WritableSharedMemoryMapping shared_memory_mapping) {
  return base::MakeRefCounted<Buffer>(MakeBackingFromSharedMemory(
      std::move(shared_memory_region), std::move(shared_memory_mapping)));
}

inline scoped_refptr<Buffer> MakeMemoryBuffer(uint32_t size,
                                              uint32_t alignment = 0) {
  return base::MakeRefCounted<Buffer>(
      std::make_unique<MemoryBufferBacking>(size, alignment));
}

// Generates a process unique buffer ID which can be safely used with
// GetBufferGUIDForTracing.
GPU_COMMAND_BUFFER_COMMON_EXPORT int32_t GetNextBufferId();

// Generates GUID which can be used to trace buffer using an Id.
GPU_COMMAND_BUFFER_COMMON_EXPORT base::trace_event::MemoryAllocatorDumpGuid
GetBufferGUIDForTracing(uint64_t tracing_process_id, int32_t buffer_id);

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_COMMON_BUFFER_H_