Commit 6df2efa5 authored by Brian Sheedy's avatar Brian Sheedy Committed by Commit Bot

Revert "GPU: Grow and shrink transfer buffer"

This reverts commit 65c38f54.

Reason for revert: Causing DCHECK failures in VR instrumentation tests

Original change's description:
> GPU: Grow and shrink transfer buffer
> 
> Automatically grow the transfer buffer when it is full and shrink it
> when the full capacity is not being used. Allow choosing larger and
> smaller sizes than before.
> 
> Before we would only grow it when a single transfer request was larger
> than the whole buffer; requests smaller than the whole buffer would just
> block if the buffer was full. Also we would not ever shrink the buffer
> until someone called Free() manually.
> 
> Bug: 850271, 835353, 828363, 856347
> Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
> Change-Id: If2f2235a1d5297c63663398b37e1e30791347a3e
> Reviewed-on: https://chromium-review.googlesource.com/1105505
> Commit-Queue: James Darpinian <jdarpinian@chromium.org>
> Reviewed-by: Antoine Labour <piman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#572135}

TBR=jdarpinian@chromium.org,sunnyps@chromium.org,piman@chromium.org

Change-Id: I031b30234cdcfbd8a4e48c7ebb6fd23312ec10ed
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 850271, 835353, 828363, 856347, 859952
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Reviewed-on: https://chromium-review.googlesource.com/1124822Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Commit-Queue: Brian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572277}
parent 38af6b5f
...@@ -43,11 +43,10 @@ int32_t FakeCommandBufferServiceBase::GetNextFreeTransferBufferId() { ...@@ -43,11 +43,10 @@ int32_t FakeCommandBufferServiceBase::GetNextFreeTransferBufferId() {
return -1; return -1;
} }
void FakeCommandBufferServiceBase::SetGetBufferHelper(int transfer_buffer_id, void FakeCommandBufferServiceBase::SetGetBufferHelper(int transfer_buffer_id) {
int32_t token) {
++state_.set_get_buffer_count; ++state_.set_get_buffer_count;
state_.get_offset = 0; state_.get_offset = 0;
state_.token = token; state_.token = 10000; // All token checks in the tests should pass.
} }
scoped_refptr<gpu::Buffer> scoped_refptr<gpu::Buffer>
...@@ -132,7 +131,7 @@ CommandBuffer::State MockClientCommandBuffer::WaitForGetOffsetInRange( ...@@ -132,7 +131,7 @@ CommandBuffer::State MockClientCommandBuffer::WaitForGetOffsetInRange(
} }
void MockClientCommandBuffer::SetGetBuffer(int transfer_buffer_id) { void MockClientCommandBuffer::SetGetBuffer(int transfer_buffer_id) {
SetGetBufferHelper(transfer_buffer_id, token_); SetGetBufferHelper(transfer_buffer_id);
} }
scoped_refptr<gpu::Buffer> MockClientCommandBuffer::CreateTransferBuffer( scoped_refptr<gpu::Buffer> MockClientCommandBuffer::CreateTransferBuffer(
......
...@@ -44,7 +44,7 @@ class FakeCommandBufferServiceBase : public CommandBufferServiceBase { ...@@ -44,7 +44,7 @@ class FakeCommandBufferServiceBase : public CommandBufferServiceBase {
int32_t GetNextFreeTransferBufferId(); int32_t GetNextFreeTransferBufferId();
void FlushHelper(int32_t put_offset); void FlushHelper(int32_t put_offset);
void SetGetBufferHelper(int transfer_buffer_id, int32_t token); void SetGetBufferHelper(int transfer_buffer_id);
scoped_refptr<gpu::Buffer> CreateTransferBufferHelper(size_t size, scoped_refptr<gpu::Buffer> CreateTransferBufferHelper(size_t size,
int32_t* id); int32_t* id);
void DestroyTransferBufferHelper(int32_t id); void DestroyTransferBufferHelper(int32_t id);
...@@ -80,11 +80,8 @@ class MockClientCommandBuffer : public CommandBuffer, ...@@ -80,11 +80,8 @@ class MockClientCommandBuffer : public CommandBuffer,
int32_t GetServicePutOffset() { return put_offset_; } int32_t GetServicePutOffset() { return put_offset_; }
void SetTokenForSetGetBuffer(int32_t token) { token_ = token; }
private: private:
int32_t put_offset_ = 0; int32_t put_offset_ = 0;
int32_t token_ = 10000; // All token checks in the tests should pass.
}; };
class MockClientCommandBufferMockFlush : public MockClientCommandBuffer { class MockClientCommandBufferMockFlush : public MockClientCommandBuffer {
......
...@@ -1546,12 +1546,12 @@ void GLES2Implementation::DeleteSyncStub(GLsizei n, const GLuint* syncs) { ...@@ -1546,12 +1546,12 @@ void GLES2Implementation::DeleteSyncStub(GLsizei n, const GLuint* syncs) {
GLint GLES2Implementation::GetAttribLocationHelper( GLint GLES2Implementation::GetAttribLocationHelper(
GLuint program, const char* name) { GLuint program, const char* name) {
typedef cmds::GetAttribLocation::Result Result; typedef cmds::GetAttribLocation::Result Result;
SetBucketAsCString(kResultBucketId, name);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return -1; return -1;
} }
*result = -1; *result = -1;
SetBucketAsCString(kResultBucketId, name);
helper_->GetAttribLocation( helper_->GetAttribLocation(
program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); program, kResultBucketId, GetResultShmId(), GetResultShmOffset());
WaitForCmd(); WaitForCmd();
...@@ -1575,12 +1575,12 @@ GLint GLES2Implementation::GetAttribLocation( ...@@ -1575,12 +1575,12 @@ GLint GLES2Implementation::GetAttribLocation(
GLint GLES2Implementation::GetUniformLocationHelper( GLint GLES2Implementation::GetUniformLocationHelper(
GLuint program, const char* name) { GLuint program, const char* name) {
typedef cmds::GetUniformLocation::Result Result; typedef cmds::GetUniformLocation::Result Result;
SetBucketAsCString(kResultBucketId, name);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return -1; return -1;
} }
*result = -1; *result = -1;
SetBucketAsCString(kResultBucketId, name);
helper_->GetUniformLocation(program, kResultBucketId, helper_->GetUniformLocation(program, kResultBucketId,
GetResultShmId(), GetResultShmOffset()); GetResultShmId(), GetResultShmOffset());
WaitForCmd(); WaitForCmd();
...@@ -1662,12 +1662,12 @@ bool GLES2Implementation::GetProgramivHelper( ...@@ -1662,12 +1662,12 @@ bool GLES2Implementation::GetProgramivHelper(
GLint GLES2Implementation::GetFragDataIndexEXTHelper(GLuint program, GLint GLES2Implementation::GetFragDataIndexEXTHelper(GLuint program,
const char* name) { const char* name) {
typedef cmds::GetFragDataIndexEXT::Result Result; typedef cmds::GetFragDataIndexEXT::Result Result;
SetBucketAsCString(kResultBucketId, name);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return -1; return -1;
} }
*result = -1; *result = -1;
SetBucketAsCString(kResultBucketId, name);
helper_->GetFragDataIndexEXT(program, kResultBucketId, GetResultShmId(), helper_->GetFragDataIndexEXT(program, kResultBucketId, GetResultShmId(),
GetResultShmOffset()); GetResultShmOffset());
WaitForCmd(); WaitForCmd();
...@@ -1691,12 +1691,12 @@ GLint GLES2Implementation::GetFragDataIndexEXT(GLuint program, ...@@ -1691,12 +1691,12 @@ GLint GLES2Implementation::GetFragDataIndexEXT(GLuint program,
GLint GLES2Implementation::GetFragDataLocationHelper( GLint GLES2Implementation::GetFragDataLocationHelper(
GLuint program, const char* name) { GLuint program, const char* name) {
typedef cmds::GetFragDataLocation::Result Result; typedef cmds::GetFragDataLocation::Result Result;
SetBucketAsCString(kResultBucketId, name);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return -1; return -1;
} }
*result = -1; *result = -1;
SetBucketAsCString(kResultBucketId, name);
helper_->GetFragDataLocation( helper_->GetFragDataLocation(
program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); program, kResultBucketId, GetResultShmId(), GetResultShmOffset());
WaitForCmd(); WaitForCmd();
...@@ -1720,12 +1720,12 @@ GLint GLES2Implementation::GetFragDataLocation( ...@@ -1720,12 +1720,12 @@ GLint GLES2Implementation::GetFragDataLocation(
GLuint GLES2Implementation::GetUniformBlockIndexHelper( GLuint GLES2Implementation::GetUniformBlockIndexHelper(
GLuint program, const char* name) { GLuint program, const char* name) {
typedef cmds::GetUniformBlockIndex::Result Result; typedef cmds::GetUniformBlockIndex::Result Result;
SetBucketAsCString(kResultBucketId, name);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return GL_INVALID_INDEX; return GL_INVALID_INDEX;
} }
*result = GL_INVALID_INDEX; *result = GL_INVALID_INDEX;
SetBucketAsCString(kResultBucketId, name);
helper_->GetUniformBlockIndex( helper_->GetUniformBlockIndex(
program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); program, kResultBucketId, GetResultShmId(), GetResultShmOffset());
WaitForCmd(); WaitForCmd();
...@@ -4956,12 +4956,12 @@ GLboolean GLES2Implementation::EnableFeatureCHROMIUM( ...@@ -4956,12 +4956,12 @@ GLboolean GLES2Implementation::EnableFeatureCHROMIUM(
<< feature << ")"); << feature << ")");
TRACE_EVENT0("gpu", "GLES2::EnableFeatureCHROMIUM"); TRACE_EVENT0("gpu", "GLES2::EnableFeatureCHROMIUM");
typedef cmds::EnableFeatureCHROMIUM::Result Result; typedef cmds::EnableFeatureCHROMIUM::Result Result;
SetBucketAsCString(kResultBucketId, feature);
Result* result = GetResultAs<Result*>(); Result* result = GetResultAs<Result*>();
if (!result) { if (!result) {
return false; return false;
} }
*result = 0; *result = 0;
SetBucketAsCString(kResultBucketId, feature);
helper_->EnableFeatureCHROMIUM( helper_->EnableFeatureCHROMIUM(
kResultBucketId, GetResultShmId(), GetResultShmOffset()); kResultBucketId, GetResultShmId(), GetResultShmOffset());
WaitForCmd(); WaitForCmd();
......
...@@ -156,7 +156,7 @@ gpu::ContextResult ImplementationBase::Initialize( ...@@ -156,7 +156,7 @@ gpu::ContextResult ImplementationBase::Initialize(
if (!transfer_buffer_->Initialize( if (!transfer_buffer_->Initialize(
limits.start_transfer_buffer_size, kStartingOffset, limits.start_transfer_buffer_size, kStartingOffset,
limits.min_transfer_buffer_size, limits.max_transfer_buffer_size, limits.min_transfer_buffer_size, limits.max_transfer_buffer_size,
kAlignment)) { kAlignment, kSizeToFlush)) {
// TransferBuffer::Initialize doesn't fail for transient reasons such as if // TransferBuffer::Initialize doesn't fail for transient reasons such as if
// the context was lost. See http://crrev.com/c/720269 // the context was lost. See http://crrev.com/c/720269
LOG(ERROR) << "ContextResult::kFatalFailure: " LOG(ERROR) << "ContextResult::kFatalFailure: "
......
...@@ -51,6 +51,9 @@ class GLES2_IMPL_EXPORT ImplementationBase ...@@ -51,6 +51,9 @@ class GLES2_IMPL_EXPORT ImplementationBase
// used for testing only. If more things are reseved add them here. // used for testing only. If more things are reseved add them here.
static const unsigned int kStartingOffset = kMaxSizeOfSimpleResult; static const unsigned int kStartingOffset = kMaxSizeOfSimpleResult;
// Size in bytes to issue async flush for transfer buffer.
static const unsigned int kSizeToFlush = 256 * 1024;
// Alignment of allocations. // Alignment of allocations.
static const unsigned int kAlignment = 16; static const unsigned int kAlignment = 16;
......
...@@ -44,7 +44,8 @@ bool MockTransferBuffer::Initialize(unsigned int starting_buffer_size, ...@@ -44,7 +44,8 @@ bool MockTransferBuffer::Initialize(unsigned int starting_buffer_size,
unsigned int result_size, unsigned int result_size,
unsigned int /* min_buffer_size */, unsigned int /* min_buffer_size */,
unsigned int /* max_buffer_size */, unsigned int /* max_buffer_size */,
unsigned int alignment) { unsigned int alignment,
unsigned int /* size_to_flush */) {
// Just check they match. // Just check they match.
return size_ == starting_buffer_size && result_size_ == result_size && return size_ == starting_buffer_size && result_size_ == result_size &&
alignment_ == alignment && !initialize_fail_; alignment_ == alignment && !initialize_fail_;
......
...@@ -35,7 +35,8 @@ class MockTransferBuffer : public TransferBufferInterface { ...@@ -35,7 +35,8 @@ class MockTransferBuffer : public TransferBufferInterface {
unsigned int result_size, unsigned int result_size,
unsigned int /* min_buffer_size */, unsigned int /* min_buffer_size */,
unsigned int /* max_buffer_size */, unsigned int /* max_buffer_size */,
unsigned int alignment) override; unsigned int alignment,
unsigned int size_to_flush) override;
int GetShmId() override; int GetShmId() override;
void* GetResultBuffer() override; void* GetResultBuffer() override;
int GetResultOffset() override; int GetResultOffset() override;
......
...@@ -80,9 +80,6 @@ class GPU_EXPORT RingBuffer { ...@@ -80,9 +80,6 @@ class GPU_EXPORT RingBuffer {
return size_ - size_ % alignment_; return size_ - size_ % alignment_;
} }
// Total size minus usable size.
unsigned int GetUsedSize() { return size_ - GetLargestFreeSizeNoWaiting(); }
// Gets a pointer to a memory block given the base memory and the offset. // Gets a pointer to a memory block given the base memory and the offset.
void* GetPointer(RingBuffer::Offset offset) const { void* GetPointer(RingBuffer::Offset offset) const {
return static_cast<int8_t*>(base_) + offset; return static_cast<int8_t*>(base_) + offset;
......
...@@ -28,17 +28,17 @@ struct SharedMemoryLimits { ...@@ -28,17 +28,17 @@ struct SharedMemoryLimits {
// On memory constrained devices, switch to lower limits. // On memory constrained devices, switch to lower limits.
if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) { if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) {
command_buffer_size = 512 * 1024; command_buffer_size = 512 * 1024;
start_transfer_buffer_size = 32 * 1024; start_transfer_buffer_size = 256 * 1024;
min_transfer_buffer_size = 32 * 1024; min_transfer_buffer_size = 128 * 1024;
mapped_memory_chunk_size = 256 * 1024; mapped_memory_chunk_size = 256 * 1024;
} }
#endif #endif
} }
int32_t command_buffer_size = 1024 * 1024; int32_t command_buffer_size = 1024 * 1024;
uint32_t start_transfer_buffer_size = 64 * 1024; uint32_t start_transfer_buffer_size = 1024 * 1024;
uint32_t min_transfer_buffer_size = 64 * 1024; uint32_t min_transfer_buffer_size = 256 * 1024;
uint32_t max_transfer_buffer_size = 64 * 1024 * 1024; uint32_t max_transfer_buffer_size = 16 * 1024 * 1024;
static constexpr uint32_t kNoLimit = 0; static constexpr uint32_t kNoLimit = 0;
uint32_t mapped_memory_reclaim_limit = kNoLimit; uint32_t mapped_memory_reclaim_limit = kNoLimit;
......
...@@ -17,17 +17,21 @@ ...@@ -17,17 +17,21 @@
namespace gpu { namespace gpu {
TransferBuffer::TransferBuffer(CommandBufferHelper* helper) TransferBuffer::TransferBuffer(
CommandBufferHelper* helper)
: helper_(helper), : helper_(helper),
result_size_(0), result_size_(0),
default_buffer_size_(0), default_buffer_size_(0),
min_buffer_size_(0), min_buffer_size_(0),
max_buffer_size_(0), max_buffer_size_(0),
alignment_(0), alignment_(0),
size_to_flush_(0),
bytes_since_last_flush_(0),
buffer_id_(-1), buffer_id_(-1),
result_buffer_(NULL), result_buffer_(NULL),
result_shm_offset_(0), result_shm_offset_(0),
usable_(true) {} usable_(true) {
}
TransferBuffer::~TransferBuffer() { TransferBuffer::~TransferBuffer() {
Free(); Free();
...@@ -41,16 +45,19 @@ base::SharedMemoryHandle TransferBuffer::shared_memory_handle() const { ...@@ -41,16 +45,19 @@ base::SharedMemoryHandle TransferBuffer::shared_memory_handle() const {
return buffer_->backing()->shared_memory_handle(); return buffer_->backing()->shared_memory_handle();
} }
bool TransferBuffer::Initialize(unsigned int default_buffer_size, bool TransferBuffer::Initialize(
unsigned int default_buffer_size,
unsigned int result_size, unsigned int result_size,
unsigned int min_buffer_size, unsigned int min_buffer_size,
unsigned int max_buffer_size, unsigned int max_buffer_size,
unsigned int alignment) { unsigned int alignment,
unsigned int size_to_flush) {
result_size_ = result_size; result_size_ = result_size;
default_buffer_size_ = default_buffer_size; default_buffer_size_ = default_buffer_size;
min_buffer_size_ = min_buffer_size; min_buffer_size_ = min_buffer_size;
max_buffer_size_ = max_buffer_size; max_buffer_size_ = max_buffer_size;
alignment_ = alignment; alignment_ = alignment;
size_to_flush_ = size_to_flush;
ReallocateRingBuffer(default_buffer_size_ - result_size); ReallocateRingBuffer(default_buffer_size_ - result_size);
return HaveBuffer(); return HaveBuffer();
} }
...@@ -64,10 +71,8 @@ void TransferBuffer::Free() { ...@@ -64,10 +71,8 @@ void TransferBuffer::Free() {
buffer_ = NULL; buffer_ = NULL;
result_buffer_ = NULL; result_buffer_ = NULL;
result_shm_offset_ = 0; result_shm_offset_ = 0;
previous_ring_buffers_.push_back(std::move(ring_buffer_)); ring_buffer_.reset();
last_allocated_size_ = 0; bytes_since_last_flush_ = 0;
high_water_mark_ = GetPreviousRingBufferUsedBytes();
bytes_since_last_shrink_ = 0;
} }
} }
...@@ -86,6 +91,10 @@ void TransferBuffer::DiscardBlock(void* p) { ...@@ -86,6 +91,10 @@ void TransferBuffer::DiscardBlock(void* p) {
void TransferBuffer::FreePendingToken(void* p, unsigned int token) { void TransferBuffer::FreePendingToken(void* p, unsigned int token) {
ring_buffer_->FreePendingToken(p, token); ring_buffer_->FreePendingToken(p, token);
if (bytes_since_last_flush_ >= size_to_flush_ && size_to_flush_ > 0) {
helper_->Flush();
bytes_since_last_flush_ = 0;
}
} }
unsigned int TransferBuffer::GetSize() const { unsigned int TransferBuffer::GetSize() const {
...@@ -110,7 +119,6 @@ void TransferBuffer::AllocateRingBuffer(unsigned int size) { ...@@ -110,7 +119,6 @@ void TransferBuffer::AllocateRingBuffer(unsigned int size) {
scoped_refptr<gpu::Buffer> buffer = scoped_refptr<gpu::Buffer> buffer =
helper_->command_buffer()->CreateTransferBuffer(size, &id); helper_->command_buffer()->CreateTransferBuffer(size, &id);
if (id != -1) { if (id != -1) {
last_allocated_size_ = size;
DCHECK(buffer.get()); DCHECK(buffer.get());
buffer_ = buffer; buffer_ = buffer;
ring_buffer_ = std::make_unique<RingBuffer>( ring_buffer_ = std::make_unique<RingBuffer>(
...@@ -119,7 +127,6 @@ void TransferBuffer::AllocateRingBuffer(unsigned int size) { ...@@ -119,7 +127,6 @@ void TransferBuffer::AllocateRingBuffer(unsigned int size) {
buffer_id_ = id; buffer_id_ = id;
result_buffer_ = buffer_->memory(); result_buffer_ = buffer_->memory();
result_shm_offset_ = 0; result_shm_offset_ = 0;
bytes_since_last_shrink_ = 0;
return; return;
} }
// we failed so don't try larger than this. // we failed so don't try larger than this.
...@@ -132,7 +139,7 @@ static unsigned int ComputePOTSize(unsigned int dimension) { ...@@ -132,7 +139,7 @@ static unsigned int ComputePOTSize(unsigned int dimension) {
return (dimension == 0) ? 0 : 1 << base::bits::Log2Ceiling(dimension); return (dimension == 0) ? 0 : 1 << base::bits::Log2Ceiling(dimension);
} }
void TransferBuffer::ReallocateRingBuffer(unsigned int size, bool shrink) { void TransferBuffer::ReallocateRingBuffer(unsigned int size) {
// What size buffer would we ask for if we needed a new one? // What size buffer would we ask for if we needed a new one?
unsigned int needed_buffer_size = ComputePOTSize(size + result_size_); unsigned int needed_buffer_size = ComputePOTSize(size + result_size_);
DCHECK_EQ(needed_buffer_size % alignment_, 0u) DCHECK_EQ(needed_buffer_size % alignment_, 0u)
...@@ -141,11 +148,7 @@ void TransferBuffer::ReallocateRingBuffer(unsigned int size, bool shrink) { ...@@ -141,11 +148,7 @@ void TransferBuffer::ReallocateRingBuffer(unsigned int size, bool shrink) {
needed_buffer_size = std::max(needed_buffer_size, default_buffer_size_); needed_buffer_size = std::max(needed_buffer_size, default_buffer_size_);
needed_buffer_size = std::min(needed_buffer_size, max_buffer_size_); needed_buffer_size = std::min(needed_buffer_size, max_buffer_size_);
unsigned int current_size = HaveBuffer() ? buffer_->size() : 0; if (usable_ && (!HaveBuffer() || needed_buffer_size > buffer_->size())) {
if (current_size == needed_buffer_size)
return;
if (usable_ && (shrink || needed_buffer_size > current_size)) {
if (HaveBuffer()) { if (HaveBuffer()) {
Free(); Free();
} }
...@@ -153,49 +156,11 @@ void TransferBuffer::ReallocateRingBuffer(unsigned int size, bool shrink) { ...@@ -153,49 +156,11 @@ void TransferBuffer::ReallocateRingBuffer(unsigned int size, bool shrink) {
} }
} }
unsigned int TransferBuffer::GetPreviousRingBufferUsedBytes() {
while (!previous_ring_buffers_.empty() &&
previous_ring_buffers_.front()->GetUsedSize() == 0) {
previous_ring_buffers_.pop_front();
}
unsigned int total = 0;
for (auto& buffer : previous_ring_buffers_) {
total += buffer->GetUsedSize();
}
return total;
}
void TransferBuffer::ShrinkOrExpandRingBufferIfNecessary(
unsigned int size_to_allocate) {
unsigned int available_size = GetFreeSize();
high_water_mark_ =
std::max(high_water_mark_, last_allocated_size_ - available_size +
size_to_allocate +
GetPreviousRingBufferUsedBytes());
if (size_to_allocate > available_size) {
// Try to expand the ring buffer.
ReallocateRingBuffer(high_water_mark_);
} else if (bytes_since_last_shrink_ > high_water_mark_ * kShrinkThreshold) {
// The intent of the above check is to limit the frequency of buffer shrink
// attempts. Unfortunately if an application uploads a large amount of data
// once and from then on uploads only a small amount per frame, it will be a
// very long time before we attempt to shrink (or forever, if no data is
// uploaded).
// TODO(jdarpinian): Change this heuristic to be based on frame number
// instead, and consider shrinking at the end of each frame (for clients
// that have a notion of frames).
bytes_since_last_shrink_ = 0;
ReallocateRingBuffer(high_water_mark_ + high_water_mark_ / 4,
true /* shrink */);
high_water_mark_ = size_to_allocate + GetPreviousRingBufferUsedBytes();
}
}
void* TransferBuffer::AllocUpTo( void* TransferBuffer::AllocUpTo(
unsigned int size, unsigned int* size_allocated) { unsigned int size, unsigned int* size_allocated) {
DCHECK(size_allocated); DCHECK(size_allocated);
ShrinkOrExpandRingBufferIfNecessary(size); ReallocateRingBuffer(size);
if (!HaveBuffer()) { if (!HaveBuffer()) {
return NULL; return NULL;
...@@ -203,12 +168,12 @@ void* TransferBuffer::AllocUpTo( ...@@ -203,12 +168,12 @@ void* TransferBuffer::AllocUpTo(
unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize(); unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize();
*size_allocated = std::min(max_size, size); *size_allocated = std::min(max_size, size);
bytes_since_last_shrink_ += *size_allocated; bytes_since_last_flush_ += *size_allocated;
return ring_buffer_->Alloc(*size_allocated); return ring_buffer_->Alloc(*size_allocated);
} }
void* TransferBuffer::Alloc(unsigned int size) { void* TransferBuffer::Alloc(unsigned int size) {
ShrinkOrExpandRingBufferIfNecessary(size); ReallocateRingBuffer(size);
if (!HaveBuffer()) { if (!HaveBuffer()) {
return NULL; return NULL;
...@@ -218,7 +183,8 @@ void* TransferBuffer::Alloc(unsigned int size) { ...@@ -218,7 +183,8 @@ void* TransferBuffer::Alloc(unsigned int size) {
if (size > max_size) { if (size > max_size) {
return NULL; return NULL;
} }
bytes_since_last_shrink_ += size;
bytes_since_last_flush_ += size;
return ring_buffer_->Alloc(size); return ring_buffer_->Alloc(size);
} }
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <memory> #include <memory>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h" #include "base/macros.h"
#include "gpu/command_buffer/client/ring_buffer.h" #include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/common/buffer.h" #include "gpu/command_buffer/common/buffer.h"
...@@ -37,11 +36,13 @@ class GPU_EXPORT TransferBufferInterface { ...@@ -37,11 +36,13 @@ class GPU_EXPORT TransferBufferInterface {
// Otherwise, this returns an invalid handle. // Otherwise, this returns an invalid handle.
virtual base::SharedMemoryHandle shared_memory_handle() const = 0; virtual base::SharedMemoryHandle shared_memory_handle() const = 0;
virtual bool Initialize(unsigned int buffer_size, virtual bool Initialize(
unsigned int buffer_size,
unsigned int result_size, unsigned int result_size,
unsigned int min_buffer_size, unsigned int min_buffer_size,
unsigned int max_buffer_size, unsigned int max_buffer_size,
unsigned int alignment) = 0; unsigned int alignment,
unsigned int size_to_flush) = 0;
virtual int GetShmId() = 0; virtual int GetShmId() = 0;
virtual void* GetResultBuffer() = 0; virtual void* GetResultBuffer() = 0;
...@@ -85,7 +86,8 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface { ...@@ -85,7 +86,8 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
unsigned int result_size, unsigned int result_size,
unsigned int min_buffer_size, unsigned int min_buffer_size,
unsigned int max_buffer_size, unsigned int max_buffer_size,
unsigned int alignment) override; unsigned int alignment,
unsigned int size_to_flush) override;
int GetShmId() override; int GetShmId() override;
void* GetResultBuffer() override; void* GetResultBuffer() override;
int GetResultOffset() override; int GetResultOffset() override;
...@@ -105,25 +107,14 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface { ...@@ -105,25 +107,14 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
unsigned int GetCurrentMaxAllocationWithoutRealloc() const; unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
unsigned int GetMaxAllocation() const; unsigned int GetMaxAllocation() const;
// We will attempt to shrink the ring buffer once the number of bytes
// allocated reaches this threshold times the high water mark.
static const int kShrinkThreshold = 120;
private: private:
// Tries to reallocate the ring buffer if it's not large enough for size. // Tries to reallocate the ring buffer if it's not large enough for size.
void ReallocateRingBuffer(unsigned int size, bool shrink = false); void ReallocateRingBuffer(unsigned int size);
void AllocateRingBuffer(unsigned int size); void AllocateRingBuffer(unsigned int size);
void ShrinkOrExpandRingBufferIfNecessary(unsigned int size);
// Returns the number of bytes that are still in use in ring buffers that we
// previously freed.
unsigned int GetPreviousRingBufferUsedBytes();
CommandBufferHelper* helper_; CommandBufferHelper* helper_;
std::unique_ptr<RingBuffer> ring_buffer_; std::unique_ptr<RingBuffer> ring_buffer_;
base::circular_deque<std::unique_ptr<RingBuffer>> previous_ring_buffers_;
// size reserved for results // size reserved for results
unsigned int result_size_; unsigned int result_size_;
...@@ -137,17 +128,14 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface { ...@@ -137,17 +128,14 @@ class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
// max size we'll let the buffer grow // max size we'll let the buffer grow
unsigned int max_buffer_size_; unsigned int max_buffer_size_;
// Size of the currently allocated ring buffer.
unsigned int last_allocated_size_ = 0;
// The size to shrink the ring buffer to next time shrinking happens.
unsigned int high_water_mark_ = 0;
// alignment for allocations // alignment for allocations
unsigned int alignment_; unsigned int alignment_;
// Number of bytes since we last attempted to shrink the ring buffer. // Size at which to do an async flush. 0 = never.
unsigned int bytes_since_last_shrink_ = 0; unsigned int size_to_flush_;
// Number of bytes since we last flushed.
unsigned int bytes_since_last_flush_;
// the current buffer. // the current buffer.
scoped_refptr<gpu::Buffer> buffer_; scoped_refptr<gpu::Buffer> buffer_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment