blob: 39e62a6c67d9431574c7ac8ce006a76785861895 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/common/buffer.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/gpu_export.h"
namespace gpu {
class CommandBufferHelper;
// Interface for managing the transfer buffer.
class GPU_EXPORT TransferBufferInterface {
TransferBufferInterface() { }
virtual ~TransferBufferInterface() { }
virtual bool Initialize(
unsigned int buffer_size,
unsigned int result_size,
unsigned int min_buffer_size,
unsigned int max_buffer_size,
unsigned int alignment,
unsigned int size_to_flush) = 0;
virtual int GetShmId() = 0;
virtual void* GetResultBuffer() = 0;
virtual int GetResultOffset() = 0;
virtual void Free() = 0;
virtual bool HaveBuffer() const = 0;
// Allocates up to size bytes.
virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0;
// Allocates size bytes.
// Note: Alloc will fail if it can not return size bytes.
virtual void* Alloc(unsigned int size) = 0;
virtual RingBuffer::Offset GetOffset(void* pointer) const = 0;
virtual void FreePendingToken(void* p, unsigned int token) = 0;
// Class that manages the transfer buffer.
class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
TransferBuffer(CommandBufferHelper* helper);
~TransferBuffer() override;
// Overridden from TransferBufferInterface.
bool Initialize(unsigned int default_buffer_size,
unsigned int result_size,
unsigned int min_buffer_size,
unsigned int max_buffer_size,
unsigned int alignment,
unsigned int size_to_flush) override;
int GetShmId() override;
void* GetResultBuffer() override;
int GetResultOffset() override;
void Free() override;
bool HaveBuffer() const override;
void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
void* Alloc(unsigned int size) override;
RingBuffer::Offset GetOffset(void* pointer) const override;
void FreePendingToken(void* p, unsigned int token) override;
// These are for testing.
unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
unsigned int GetMaxAllocation() const;
// Tries to reallocate the ring buffer if it's not large enough for size.
void ReallocateRingBuffer(unsigned int size);
void AllocateRingBuffer(unsigned int size);
CommandBufferHelper* helper_;
scoped_ptr<RingBuffer> ring_buffer_;
// size reserved for results
unsigned int result_size_;
// default size. Size we want when starting or re-allocating
unsigned int default_buffer_size_;
// min size we'll consider successful
unsigned int min_buffer_size_;
// max size we'll let the buffer grow
unsigned int max_buffer_size_;
// alignment for allocations
unsigned int alignment_;
// Size at which to do an async flush. 0 = never.
unsigned int size_to_flush_;
// Number of bytes since we last flushed.
unsigned int bytes_since_last_flush_;
// the current buffer.
scoped_refptr<gpu::Buffer> buffer_;
// id of buffer. -1 = no buffer
int32 buffer_id_;
// address of result area
void* result_buffer_;
// offset to result area
uint32 result_shm_offset_;
// false if we failed to allocate min_buffer_size
bool usable_;
// A class that will manage the lifetime of a transferbuffer allocation.
class GPU_EXPORT ScopedTransferBufferPtr {
unsigned int size,
CommandBufferHelper* helper,
TransferBufferInterface* transfer_buffer)
: buffer_(NULL),
transfer_buffer_(transfer_buffer) {
~ScopedTransferBufferPtr() {
bool valid() const {
return buffer_ != NULL;
unsigned int size() const {
return size_;
int shm_id() const {
return transfer_buffer_->GetShmId();
RingBuffer::Offset offset() const {
return transfer_buffer_->GetOffset(buffer_);
void* address() const {
return buffer_;
void Release();
void Reset(unsigned int new_size);
void* buffer_;
unsigned int size_;
CommandBufferHelper* helper_;
TransferBufferInterface* transfer_buffer_;
template <typename T>
class ScopedTransferBufferArray : public ScopedTransferBufferPtr {
unsigned int num_elements,
CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer)
: ScopedTransferBufferPtr(
num_elements * sizeof(T), helper, transfer_buffer) {
T* elements() {
return static_cast<T*>(address());
unsigned int num_elements() const {
return size() / sizeof(T);
} // namespace gpu