mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
138 lines
4.0 KiB
C++
138 lines
4.0 KiB
C++
// 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_
|