forked from sanyaade-mobiledev/chromium.src
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changes the GLES2Implementation to use a RingBuffer
to manage the transfer buffer. This is significantly faster than the FencedAllocator for our purposes. TEST=some unit tests BUG=none Review URL: http://codereview.chromium.org/1796002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45844 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
gman@chromium.org
committed
Apr 28, 2010
1 parent
ec11be6
commit f6a5698
Showing
6 changed files
with
576 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright (c) 2010 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 implementation of the RingBuffer class. | ||
|
||
#include "../client/ring_buffer.h" | ||
#include <algorithm> | ||
#include "../client/cmd_buffer_helper.h" | ||
|
||
namespace gpu { | ||
|
||
RingBuffer::RingBuffer( | ||
Offset base_offset, unsigned int size, CommandBufferHelper* helper) | ||
: helper_(helper), | ||
base_offset_(base_offset), | ||
size_(size), | ||
free_offset_(0), | ||
in_use_offset_(0) { | ||
} | ||
|
||
RingBuffer::~RingBuffer() { | ||
// Free blocks pending tokens. | ||
while (!blocks_.empty()) { | ||
FreeOldestBlock(); | ||
} | ||
} | ||
|
||
void RingBuffer::FreeOldestBlock() { | ||
DCHECK(!blocks_.empty()) << "no free blocks"; | ||
Block& block = blocks_.front(); | ||
DCHECK(block.valid) << "attempt to allocate more than maximum memory"; | ||
helper_->WaitForToken(block.token); | ||
in_use_offset_ += block.size; | ||
if (in_use_offset_ == size_) { | ||
in_use_offset_ = 0; | ||
} | ||
// If they match then the entire buffer is free. | ||
if (in_use_offset_ == free_offset_) { | ||
in_use_offset_ = 0; | ||
free_offset_ = 0; | ||
} | ||
blocks_.pop_back(); | ||
} | ||
|
||
RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { | ||
DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; | ||
// Similarly to malloc, an allocation of 0 allocates at least 1 byte, to | ||
// return different pointers every time. | ||
if (size == 0) size = 1; | ||
|
||
// Wait until there is enough room. | ||
while (size > GetLargestFreeSizeNoWaiting()) { | ||
FreeOldestBlock(); | ||
} | ||
|
||
Offset offset = free_offset_; | ||
blocks_.push_back(Block(offset, size)); | ||
free_offset_ += size; | ||
if (free_offset_ == size_) { | ||
free_offset_ = 0; | ||
} | ||
return offset + base_offset_; | ||
} | ||
|
||
void RingBuffer::FreePendingToken(RingBuffer::Offset offset, | ||
unsigned int token) { | ||
offset -= base_offset_; | ||
DCHECK(!blocks_.empty()) << "no allocations to free"; | ||
for (Container::reverse_iterator it = blocks_.rbegin(); | ||
it != blocks_.rend(); | ||
++it) { | ||
Block& block = *it; | ||
if (block.offset == offset) { | ||
DCHECK(!block.valid) << "block that corresponds to offset already freed"; | ||
block.token = token; | ||
block.valid = true; | ||
return; | ||
} | ||
} | ||
NOTREACHED() << "attempt to free non-existant block"; | ||
} | ||
|
||
unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { | ||
if (free_offset_ == in_use_offset_) { | ||
if (blocks_.empty()) { | ||
// The entire buffer is free. | ||
DCHECK_EQ(free_offset_, 0u); | ||
return size_; | ||
} else { | ||
// The entire buffer is in use. | ||
return 0; | ||
} | ||
} else if (free_offset_ > in_use_offset_) { | ||
// It's free from free_offset_ to size_ | ||
return size_ - free_offset_; | ||
} else { | ||
// It's free from free_offset_ -> in_use_offset_; | ||
return in_use_offset_ - free_offset_; | ||
} | ||
} | ||
|
||
} // namespace gpu |
Oops, something went wrong.