summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/client
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-30 00:17:36 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-30 00:17:36 +0000
commitf5b5f8584c0951c3d26e9cb088792d132b48c203 (patch)
tree92e37fc94ca9251d21ef707ad32147b70956f962 /gpu/command_buffer/client
parent3dc141fb1830a112f50b96411ab6841fc8c0c16c (diff)
downloadchromium_src-f5b5f8584c0951c3d26e9cb088792d132b48c203.zip
chromium_src-f5b5f8584c0951c3d26e9cb088792d132b48c203.tar.gz
chromium_src-f5b5f8584c0951c3d26e9cb088792d132b48c203.tar.bz2
Fix Bug in RingBuffer
TEST=unit test BUG=42859 Review URL: http://codereview.chromium.org/1806003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46017 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/client')
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc33
-rw-r--r--gpu/command_buffer/client/ring_buffer.cc6
-rw-r--r--gpu/command_buffer/client/ring_buffer_test.cc16
3 files changed, 39 insertions, 16 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 0df4121..3886b95 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -644,8 +644,9 @@ void GLES2Implementation::ShaderBinary(
return;
}
GLsizei shader_id_size = n * sizeof(*shaders);
- void* shader_ids = transfer_buffer_.Alloc(shader_id_size);
- void* shader_data = transfer_buffer_.Alloc(length);
+ int8* buffer = transfer_buffer_.AllocTyped<int8>(shader_id_size + length);
+ void* shader_ids = buffer;
+ void* shader_data = buffer + shader_id_size;
memcpy(shader_ids, shaders, shader_id_size);
memcpy(shader_data, binary, length);
helper_->ShaderBinary(
@@ -654,9 +655,7 @@ void GLES2Implementation::ShaderBinary(
binaryformat,
transfer_buffer_id_, transfer_buffer_.GetOffset(shader_data),
length);
- int32 token = helper_->InsertToken();
- transfer_buffer_.FreePendingToken(shader_ids, token);
- transfer_buffer_.FreePendingToken(shader_data, token);
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
}
void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
@@ -1145,18 +1144,20 @@ void GLES2Implementation::ReadPixels(
transfer_buffer_id_, transfer_buffer_.GetOffset(buffer),
result_shm_id(), result_shm_offset());
WaitForCmd();
+ if (*result != 0) {
+ // We have to copy 1 row at a time to avoid writing pad bytes.
+ const int8* src = static_cast<const int8*>(buffer);
+ for (GLint yy = 0; yy < num_rows; ++yy) {
+ memcpy(dest, src, unpadded_row_size);
+ dest += padded_row_size;
+ src += padded_row_size;
+ }
+ }
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
// If it was not marked as successful exit.
if (*result == 0) {
return;
}
- // We have to copy 1 row at a time to avoid writing pad bytes.
- const int8* src = static_cast<const int8*>(buffer);
- for (GLint yy = 0; yy < num_rows; ++yy) {
- memcpy(dest, src, unpadded_row_size);
- dest += padded_row_size;
- src += padded_row_size;
- }
- transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
yoffset += num_rows;
height -= num_rows;
}
@@ -1181,12 +1182,14 @@ void GLES2Implementation::ReadPixels(
transfer_buffer_id_, transfer_buffer_.GetOffset(buffer),
result_shm_id(), result_shm_offset());
WaitForCmd();
+ if (*result != 0) {
+ memcpy(row_dest, buffer, part_size);
+ }
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
// If it was not marked as successful exit.
if (*result == 0) {
return;
}
- memcpy(row_dest, buffer, part_size);
- transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
row_dest += part_size;
temp_xoffset += num_pixels;
temp_width -= num_pixels;
diff --git a/gpu/command_buffer/client/ring_buffer.cc b/gpu/command_buffer/client/ring_buffer.cc
index 678110a..89da7fe 100644
--- a/gpu/command_buffer/client/ring_buffer.cc
+++ b/gpu/command_buffer/client/ring_buffer.cc
@@ -40,11 +40,13 @@ void RingBuffer::FreeOldestBlock() {
in_use_offset_ = 0;
free_offset_ = 0;
}
- blocks_.pop_back();
+ blocks_.pop_front();
}
RingBuffer::Offset RingBuffer::Alloc(unsigned int size) {
DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory";
+ DCHECK(blocks_.empty() || blocks_.back().valid)
+ << "Attempt to alloc another block before freeing the previous.";
// Similarly to malloc, an allocation of 0 allocates at least 1 byte, to
// return different pointers every time.
if (size == 0) size = 1;
@@ -82,6 +84,8 @@ void RingBuffer::FreePendingToken(RingBuffer::Offset offset,
}
unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() {
+ // TODO(gman): Should check what the current token is and free up to that
+ // point.
if (free_offset_ == in_use_offset_) {
if (blocks_.empty()) {
// The entire buffer is free.
diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc
index a6ec71a..4ba74ac 100644
--- a/gpu/command_buffer/client/ring_buffer_test.cc
+++ b/gpu/command_buffer/client/ring_buffer_test.cc
@@ -161,6 +161,22 @@ TEST_F(RingBufferTest, TestGetLargestFreeSizeNoWaiting) {
allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
}
+TEST_F(RingBufferTest, TestFreeBug) {
+ // The first and second allocations must not match.
+ const unsigned int kAlloc1 = 10;
+ const unsigned int kAlloc2 = 20;
+ RingBuffer::Offset offset = allocator_->Alloc(kAlloc1);
+ EXPECT_EQ(kBufferSize - kAlloc1, allocator_->GetLargestFreeSizeNoWaiting());
+ allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
+ offset = allocator_->Alloc(kAlloc2);
+ EXPECT_EQ(kBufferSize - kAlloc1 - kAlloc2,
+ allocator_->GetLargestFreeSizeNoWaiting());
+ allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
+ offset = allocator_->Alloc(kBufferSize);
+ EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
+ allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
+}
+
// Test fixture for RingBufferWrapper test - Creates a
// RingBufferWrapper, using a CommandBufferHelper with a mock
// AsyncAPIInterface for its interface (calling it directly, not through the