1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// 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.
// This file contains the definition of the RingBuffer class.
#ifndef GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
#define GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
#include <deque>
#include "base/logging.h"
#include "base/macros.h"
#include "gpu/gpu_export.h"
namespace gpu {
class CommandBufferHelper;
// RingBuffer manages a piece of memory as a ring buffer. Memory is allocated
// with Alloc and then a is freed pending a token with FreePendingToken. Old
// allocations must not be kept past new allocations.
class GPU_EXPORT RingBuffer {
public:
typedef unsigned int Offset;
// Creates a RingBuffer.
// Parameters:
// alignment: Alignment for allocations.
// base_offset: The offset of the start of the buffer.
// size: The size of the buffer in bytes.
// helper: A CommandBufferHelper for dealing with tokens.
// base: The physical address that corresponds to base_offset.
RingBuffer(unsigned int alignment, Offset base_offset,
unsigned int size, CommandBufferHelper* helper, void* base);
~RingBuffer();
// Allocates a block of memory. If the buffer is out of directly available
// memory, this function may wait until memory that was freed "pending a
// token" can be re-used.
//
// Parameters:
// size: the size of the memory block to allocate.
//
// Returns:
// the pointer to the allocated memory block.
void* Alloc(unsigned int size);
// Frees a block of memory, pending the passage of a token. That memory won't
// be re-allocated until the token has passed through the command stream.
//
// Parameters:
// pointer: the pointer to the memory block to free.
// token: the token value to wait for before re-using the memory.
void FreePendingToken(void* pointer, unsigned int token);
// Gets the size of the largest free block that is available without waiting.
unsigned int GetLargestFreeSizeNoWaiting();
// Gets the size of the largest free block that can be allocated if the
// caller can wait. Allocating a block of this size will succeed, but may
// block.
unsigned int GetLargestFreeOrPendingSize() {
return size_;
}
// Gets a pointer to a memory block given the base memory and the offset.
void* GetPointer(RingBuffer::Offset offset) const {
return static_cast<int8*>(base_) + offset;
}
// Gets the offset to a memory block given the base memory and the address.
RingBuffer::Offset GetOffset(void* pointer) const {
return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
}
// Rounds the given size to the alignment in use.
unsigned int RoundToAlignment(unsigned int size) {
return (size + alignment_ - 1) & ~(alignment_ - 1);
}
private:
enum State {
IN_USE,
PADDING,
FREE_PENDING_TOKEN
};
// Book-keeping sturcture that describes a block of memory.
struct Block {
Block(Offset _offset, unsigned int _size, State _state)
: offset(_offset),
size(_size),
token(0),
state(_state) {
}
Offset offset;
unsigned int size;
unsigned int token; // token to wait for.
State state;
};
typedef std::deque<Block> Container;
typedef unsigned int BlockIndex;
void FreeOldestBlock();
CommandBufferHelper* helper_;
// Used blocks are added to the end, blocks are freed from the beginning.
Container blocks_;
// The base offset of the ring buffer.
Offset base_offset_;
// The size of the ring buffer.
Offset size_;
// Offset of first free byte.
Offset free_offset_;
// Offset of first used byte.
// Range between in_use_mark and free_mark is in use.
Offset in_use_offset_;
// Alignment for allocations.
unsigned int alignment_;
// The physical address that corresponds to base_offset.
void* base_;
DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
|