diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-27 11:46:45 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-27 11:46:45 +0000 |
commit | 2f38c45427c68fe731c1f5c05256b6c141a6a590 (patch) | |
tree | 3a7aeefef2e2d4f7dd936907b7966fad85639dfe /gpu | |
parent | f6813d1566dec10663c1492d517f45b5c0b9d546 (diff) | |
download | chromium_src-2f38c45427c68fe731c1f5c05256b6c141a6a590.zip chromium_src-2f38c45427c68fe731c1f5c05256b6c141a6a590.tar.gz chromium_src-2f38c45427c68fe731c1f5c05256b6c141a6a590.tar.bz2 |
Revert 119430 - Make transferbuffer increase in size dynamically
TEST=unit tests
BUG=101431
Review URL: http://codereview.chromium.org/9113069
TBR=gman@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9298005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119436 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 15 | ||||
-rw-r--r-- | gpu/command_buffer/client/client_test_helper.cc | 138 | ||||
-rw-r--r-- | gpu/command_buffer/client/client_test_helper.h | 76 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 748 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.h | 109 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_unittest.cc | 1247 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_unittest_autogen.h | 148 | ||||
-rw-r--r-- | gpu/command_buffer/client/ring_buffer.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer.cc | 211 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer.h | 221 | ||||
-rw-r--r-- | gpu/command_buffer/client/transfer_buffer_unittest.cc | 434 | ||||
-rw-r--r-- | gpu/command_buffer/common/compiler_specific.h | 23 | ||||
-rw-r--r-- | gpu/demos/framework/window.cc | 31 | ||||
-rw-r--r-- | gpu/demos/framework/window.h | 6 | ||||
-rw-r--r-- | gpu/gles2_conform_support/egl/display.cc | 31 | ||||
-rw-r--r-- | gpu/gles2_conform_support/egl/display.h | 5 | ||||
-rw-r--r-- | gpu/gpu.gyp | 6 |
17 files changed, 1300 insertions, 2155 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index ad5ab44..57ca482 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -3220,10 +3220,9 @@ TEST_F(GLES2ImplementationTest, %(name)s) { typedef %(name)s::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(%(cmd_args)s, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(%(cmd_args)s, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->%(name)s(%(args)s, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -4146,12 +4145,10 @@ TEST_F(GLES2ImplementationTest, %(name)s) { typedef %(name)s::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(%(name)s::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->%(name)s(1); diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc deleted file mode 100644 index e6ddfad..0000000 --- a/gpu/command_buffer/client/client_test_helper.cc +++ /dev/null @@ -1,138 +0,0 @@ -// 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. - -// Tests for GLES2Implementation. - -#include "gpu/command_buffer/client/client_test_helper.h" - -#include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "testing/gmock/include/gmock/gmock.h" - -using ::testing::_; -using ::testing::Invoke; - -namespace gpu { - -MockCommandBufferBase::~MockCommandBufferBase() { -} - -bool MockCommandBufferBase::Initialize() { - return true; -} - -CommandBuffer::State MockCommandBufferBase::GetState() { - return state_; -} - -CommandBuffer::State MockCommandBufferBase::GetLastState() { - return state_; -} - -void MockCommandBufferBase::Flush(int32 put_offset) { - state_.put_offset = put_offset; -} - -void MockCommandBufferBase::SetGetOffset(int32 get_offset) { - state_.get_offset = get_offset; -} - -CommandBuffer::State MockCommandBufferBase::FlushSync( - int32 put_offset, int32 last_known_get) { - state_.put_offset = put_offset; - state_.get_offset = put_offset; - OnFlush(); - return state_; -} - -void MockCommandBufferBase::SetGetBuffer(int transfer_buffer_id) { - ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id); - ring_buffer_ = static_cast<CommandBufferEntry*>(ring_buffer_buffer_.ptr); - state_.num_entries = ring_buffer_buffer_.size / sizeof(ring_buffer_[0]); - state_.token = 10000; // All token checks in the tests should pass. -} - -// Get's the Id of the next transfer buffer that will be returned -// by CreateTransferBuffer. This is useful for testing expected ids. -int32 MockCommandBufferBase::GetNextFreeTransferBufferId() { - for (size_t ii = 0; ii < arraysize(transfer_buffers_); ++ii) { - if (!transfer_buffers_[ii].get()) { - return kTransferBufferBaseId + ii; - } - } - return -1; -} - -int32 MockCommandBufferBase::CreateTransferBuffer( - size_t size, int32 id_request) { - int32 id = GetNextFreeTransferBufferId(); - if (id >= 0) { - int32 ndx = id - kTransferBufferBaseId; - transfer_buffers_[ndx].reset(new int8[size]); - transfer_buffer_buffers_[ndx].ptr = transfer_buffers_[ndx].get(); - transfer_buffer_buffers_[ndx].size = size; - } - return id; -} - -void MockCommandBufferBase::DestroyTransferBufferHelper(int32 id) { - GPU_DCHECK_GE(id, kTransferBufferBaseId); - GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); - id -= kTransferBufferBaseId; - transfer_buffers_[id].reset(); - transfer_buffer_buffers_[id] = Buffer(); -} - -Buffer MockCommandBufferBase::GetTransferBuffer(int32 id) { - GPU_DCHECK_GE(id, kTransferBufferBaseId); - GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); - return transfer_buffer_buffers_[id - kTransferBufferBaseId]; -} - -int32 MockCommandBufferBase::RegisterTransferBuffer( - base::SharedMemory* shared_memory, - size_t size, - int32 id_request) { - GPU_NOTREACHED(); - return -1; -} - -void MockCommandBufferBase::SetToken(int32 token) { - GPU_NOTREACHED(); - state_.token = token; -} - -void MockCommandBufferBase::SetParseError(error::Error error) { - GPU_NOTREACHED(); - state_.error = error; -} - -void MockCommandBufferBase::SetContextLostReason( - error::ContextLostReason reason) { - GPU_NOTREACHED(); - state_.context_lost_reason = reason; -} - -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER -const int32 MockCommandBufferBase::kTransferBufferBaseId; -const int32 MockCommandBufferBase::kMaxTransferBuffers; -#endif - -MockClientCommandBuffer::MockClientCommandBuffer() { - DelegateToFake(); -} - -MockClientCommandBuffer::~MockClientCommandBuffer() { -} - -void MockClientCommandBuffer::DelegateToFake() { - ON_CALL(*this, DestroyTransferBuffer(_)) - .WillByDefault(Invoke( - this, &MockCommandBufferBase::DestroyTransferBufferHelper)); -} - -} // namespace gpu - - diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h deleted file mode 100644 index 1b32c24..0000000 --- a/gpu/command_buffer/client/client_test_helper.h +++ /dev/null @@ -1,76 +0,0 @@ -// 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. - -// Helper classes for implementing gpu client side unit tests. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_ - -#include "gpu/command_buffer/common/cmd_buffer_common.h" -#include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" -#include "gpu/command_buffer/common/scoped_ptr.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu { - -class CommandBufferHelper; - -class MockCommandBufferBase : public CommandBuffer { - public: - static const int32 kTransferBufferBaseId = 0x123; - static const int32 kMaxTransferBuffers = 6; - - MockCommandBufferBase() { } - virtual ~MockCommandBufferBase(); - - virtual bool Initialize() OVERRIDE; - virtual State GetState() OVERRIDE; - virtual State GetLastState() OVERRIDE; - virtual void Flush(int32 put_offset) OVERRIDE; - virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE; - virtual void SetGetBuffer(int transfer_buffer_id) OVERRIDE; - virtual void SetGetOffset(int32 get_offset) OVERRIDE; - virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE; - virtual Buffer GetTransferBuffer(int32 id) OVERRIDE; - virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, - size_t size, - int32 id_request) OVERRIDE; - virtual void SetToken(int32 token) OVERRIDE; - virtual void SetParseError(error::Error error) OVERRIDE; - virtual void SetContextLostReason(error::ContextLostReason reason) OVERRIDE; - - // Get's the Id of the next transfer buffer that will be returned - // by CreateTransferBuffer. This is useful for testing expected ids. - int32 GetNextFreeTransferBufferId(); - - void DestroyTransferBufferHelper(int32 id); - - virtual void OnFlush() = 0; - - private: - scoped_array<int8> transfer_buffers_[kMaxTransferBuffers]; - Buffer transfer_buffer_buffers_[kMaxTransferBuffers]; - CommandBufferEntry* ring_buffer_; - Buffer ring_buffer_buffer_; - State state_; -}; - -class MockClientCommandBuffer : public MockCommandBufferBase { - public: - MockClientCommandBuffer(); - virtual ~MockClientCommandBuffer(); - - // This is so we can use all the gmock functions when Flush is called. - MOCK_METHOD0(OnFlush, void()); - MOCK_METHOD1(DestroyTransferBuffer, void(int32 id)); - - void DelegateToFake(); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_ - diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 8f1e415..2428c1e 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -11,7 +11,6 @@ #include <GLES2/gl2ext.h> #include "../client/mapped_memory.h" #include "../client/program_info_manager.h" -#include "../client/transfer_buffer.h" #include "../common/gles2_cmd_utils.h" #include "../common/id_allocator.h" #include "../common/trace_event.h" @@ -433,7 +432,7 @@ class ClientSideBufferHelper { } // Returns true if buffers were setup. - void SetupSimulatedClientSideBuffers( + void SetupSimualtedClientSideBuffers( GLES2Implementation* gl, GLES2CmdHelper* gl_helper, GLsizei num_elements) { @@ -536,9 +535,87 @@ class ClientSideBufferHelper { DISALLOW_COPY_AND_ASSIGN(ClientSideBufferHelper); }; +AlignedRingBuffer::~AlignedRingBuffer() { +} + +TransferBuffer::TransferBuffer( + CommandBufferHelper* helper, + int32 buffer_id, + void* buffer, + size_t buffer_size, + size_t result_size, + unsigned int alignment) + : helper_(helper), + buffer_size_(buffer_size), + result_size_(result_size), + alignment_(alignment), + usable_(true) { + Setup(buffer_id, buffer); +} + +TransferBuffer::~TransferBuffer() { +} + +void TransferBuffer::Setup(int32 buffer_id, void* buffer) { + GPU_CHECK(!ring_buffer_.get()); + ring_buffer_.reset(new AlignedRingBuffer( + alignment_, + buffer_id, + result_size_, + buffer_size_ - result_size_, + helper_, + static_cast<char*>(buffer) + result_size_)); + buffer_id_ = buffer_id; + result_buffer_ = buffer; + result_shm_offset_ = 0; +} + +void TransferBuffer::Free() { + if (buffer_id_) { + // TODO(gman): should we check the memory is unused? + helper_->command_buffer()->DestroyTransferBuffer(buffer_id_); + buffer_id_ = 0; + result_buffer_ = NULL; + result_shm_offset_ = 0; + ring_buffer_.reset(); + } +} + +void TransferBuffer::AllocateRingBuffer() { + if (!buffer_id_ && usable_) { + int32 id = helper_->command_buffer()->CreateTransferBuffer( + buffer_size_, -1); + if (id == -1) { + usable_ = false; + return; + } + gpu::Buffer shm = helper_->command_buffer()->GetTransferBuffer(id); + Setup(id, shm.ptr); + } +} + +AlignedRingBuffer* TransferBuffer::GetBuffer() { + AllocateRingBuffer(); + return ring_buffer_.get(); +} + +void* TransferBuffer::GetResultBuffer() { + AllocateRingBuffer(); + return result_buffer_; +} + +int TransferBuffer::GetResultOffset() { + AllocateRingBuffer(); + return result_shm_offset_; +} + +int TransferBuffer::GetShmId() { + AllocateRingBuffer(); + return buffer_id_; +} + #if !defined(_MSC_VER) const size_t GLES2Implementation::kMaxSizeOfSimpleResult; -const unsigned int GLES2Implementation::kStartingOffset; #endif COMPILE_ASSERT(gpu::kInvalidResource == 0, @@ -558,11 +635,19 @@ GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() { GLES2Implementation::GLES2Implementation( GLES2CmdHelper* helper, - TransferBufferInterface* transfer_buffer, + size_t transfer_buffer_size, + void* transfer_buffer, + int32 transfer_buffer_id, bool share_resources, bool bind_generates_resource) : helper_(helper), - transfer_buffer_(transfer_buffer), + transfer_buffer_( + helper, + transfer_buffer_id, + transfer_buffer, + transfer_buffer_size, + GLES2Implementation::kStartingOffset, + GLES2Implementation::kAlignment), angle_pack_reverse_row_order_status(kUnknownExtensionStatus), pack_alignment_(4), unpack_alignment_(4), @@ -580,38 +665,18 @@ GLES2Implementation::GLES2Implementation( sharing_resources_(share_resources), bind_generates_resource_(bind_generates_resource), use_count_(0) { - GPU_DCHECK(helper); - GPU_DCHECK(transfer_buffer); GPU_CLIENT_LOG_CODE_BLOCK({ debug_ = CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableGPUClientLogging); }); memset(&reserved_ids_, 0, sizeof(reserved_ids_)); -} - -bool GLES2Implementation::Initialize( - unsigned int starting_transfer_buffer_size, - unsigned int min_transfer_buffer_size, - unsigned int max_transfer_buffer_size) { - GPU_DCHECK_GE(starting_transfer_buffer_size, min_transfer_buffer_size); - GPU_DCHECK_LE(starting_transfer_buffer_size, max_transfer_buffer_size); - GPU_DCHECK_GE(min_transfer_buffer_size, kStartingOffset); - - if (!transfer_buffer_->Initialize( - starting_transfer_buffer_size, - kStartingOffset, - min_transfer_buffer_size, - max_transfer_buffer_size, - kAlignment)) { - return false; - } mapped_memory_.reset(new MappedMemoryManager(helper_)); SetSharedMemoryChunkSizeMultiple(1024 * 1024 * 2); - if (sharing_resources_) { - if (!bind_generates_resource_) { + if (share_resources) { + if (!bind_generates_resource) { for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { id_handlers_[i].reset(new StrictSharedIdHandler( this, static_cast<id_namespaces::IdNamespaces>(i))); @@ -669,8 +734,6 @@ bool GLES2Implementation::Initialize( reserved_ids_[0], reserved_ids_[1])); #endif - - return true; } GLES2Implementation::~GLES2Implementation() { @@ -684,18 +747,6 @@ GLES2Implementation::~GLES2Implementation() { Finish(); } -void* GLES2Implementation::GetResultBuffer() { - return transfer_buffer_->GetResultBuffer(); -} - -int32 GLES2Implementation::GetResultShmId() { - return transfer_buffer_->GetShmId(); -} - -uint32 GLES2Implementation::GetResultShmOffset() { - return transfer_buffer_->GetResultOffset(); -} - void GLES2Implementation::SetSharedMemoryChunkSizeMultiple( unsigned int multiple) { mapped_memory_->set_chunk_size_multiple(multiple); @@ -708,7 +759,7 @@ void GLES2Implementation::FreeUnusedSharedMemory() { void GLES2Implementation::FreeEverything() { Finish(); FreeUnusedSharedMemory(); - transfer_buffer_->Free(); + transfer_buffer_.Free(); helper_->FreeRingBuffer(); } @@ -810,18 +861,27 @@ bool GLES2Implementation::GetBucketContents(uint32 bucket_id, uint32 size = *result; data->resize(size); if (size > 0u) { + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return false; + } + uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize(); uint32 offset = 0; while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { + uint32 part_size = std::min(max_size, size); + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { return false; } helper_->GetBucketData( - bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset()); + bucket_id, offset, part_size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer)); WaitForCmd(); - memcpy(&(*data)[offset], buffer.address(), buffer.size()); - offset += buffer.size(); - size -= buffer.size(); + memcpy(&(*data)[offset], buffer, part_size); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + size -= part_size; } // Free the bucket. This is not required but it does free up the memory. // and we don't have to wait for the result so from the client's perspective @@ -836,18 +896,26 @@ void GLES2Implementation::SetBucketContents( GPU_DCHECK(data); helper_->SetBucketSize(bucket_id, size); if (size > 0u) { + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize(); uint32 offset = 0; while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { + uint32 part_size = std::min(static_cast<size_t>(max_size), size); + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { return; } - memcpy(buffer.address(), static_cast<const int8*>(data) + offset, - buffer.size()); + memcpy(buffer, static_cast<const int8*>(data) + offset, part_size); helper_->SetBucketData( - bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - size -= buffer.size(); + bucket_id, offset, part_size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer)); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + size -= part_size; } } } @@ -1056,7 +1124,7 @@ void GLES2Implementation::DrawElements( } } if (have_client_side) { - client_side_buffer_helper_->SetupSimulatedClientSideBuffers( + client_side_buffer_helper_->SetupSimualtedClientSideBuffers( this, helper_, num_elements); } helper_->DrawElements(mode, count, type, offset); @@ -1122,18 +1190,27 @@ void GLES2Implementation::GenSharedIdsCHROMIUM( << namespace_id << ", " << id_offset << ", " << n << ", " << static_cast<void*>(ids) << ")"); TRACE_EVENT0("gpu", "GLES2::GenSharedIdsCHROMIUM"); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize(); + GLsizei max_num_per = max_size / sizeof(ids[0]); while (n) { - ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_); - if (!id_buffer.valid()) { + GLsizei num = std::min(n, max_num_per); + GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(num); + if (!id_buffer) { return; } helper_->GenSharedIdsCHROMIUM( - namespace_id, id_offset, id_buffer.num_elements(), - id_buffer.shm_id(), id_buffer.offset()); + namespace_id, id_offset, num, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(id_buffer)); WaitForCmd(); - memcpy(ids, id_buffer.address(), sizeof(*ids) * id_buffer.num_elements()); - n -= id_buffer.num_elements(); - ids += id_buffer.num_elements(); + memcpy(ids, id_buffer, sizeof(*ids) * num); + transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken()); + n -= num; + ids += num; } GPU_CLIENT_LOG_CODE_BLOCK({ for (GLsizei i = 0; i < n; ++i) { @@ -1153,18 +1230,27 @@ void GLES2Implementation::DeleteSharedIdsCHROMIUM( } }); TRACE_EVENT0("gpu", "GLES2::DeleteSharedIdsCHROMIUM"); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize(); + GLsizei max_num_per = max_size / sizeof(ids[0]); while (n) { - ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_); - if (!id_buffer.valid()) { + GLsizei num = std::min(n, max_num_per); + GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(num); + if (!id_buffer) { return; } - memcpy(id_buffer.address(), ids, sizeof(*ids) * id_buffer.num_elements()); + memcpy(id_buffer, ids, sizeof(*ids) * num); helper_->DeleteSharedIdsCHROMIUM( - namespace_id, id_buffer.num_elements(), - id_buffer.shm_id(), id_buffer.offset()); + namespace_id, num, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(id_buffer)); WaitForCmd(); - n -= id_buffer.num_elements(); - ids += id_buffer.num_elements(); + transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken()); + n -= num; + ids += num; } } @@ -1179,18 +1265,27 @@ void GLES2Implementation::RegisterSharedIdsCHROMIUM( } }); TRACE_EVENT0("gpu", "GLES2::RegisterSharedIdsCHROMIUM"); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + GLsizei max_size = transfer_buffer->GetLargestFreeOrPendingSize(); + GLsizei max_num_per = max_size / sizeof(ids[0]); while (n) { - ScopedTransferBufferArray<GLint> id_buffer(n, helper_, transfer_buffer_); - if (!id_buffer.valid()) { + GLsizei num = std::min(n, max_num_per); + GLint* id_buffer = transfer_buffer->AllocTyped<GLint>(n); + if (!id_buffer) { return; } - memcpy(id_buffer.address(), ids, sizeof(*ids) * id_buffer.num_elements()); + memcpy(id_buffer, ids, sizeof(*ids) * n); helper_->RegisterSharedIdsCHROMIUM( - namespace_id, id_buffer.num_elements(), - id_buffer.shm_id(), id_buffer.offset()); + namespace_id, n, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(id_buffer)); WaitForCmd(); - n -= id_buffer.num_elements(); - ids += id_buffer.num_elements(); + transfer_buffer->FreePendingToken(id_buffer, helper_->InsertToken()); + n -= num; + ids += num; } } @@ -1343,26 +1438,28 @@ void GLES2Implementation::ShaderBinary( SetGLError(GL_INVALID_VALUE, "glShaderBinary length < 0."); return; } - // TODO(gman): ShaderBinary should use buckets. - unsigned int shader_id_size = n * sizeof(*shaders); - ScopedTransferBufferArray<GLint> buffer( - shader_id_size + length, helper_, transfer_buffer_); - if (!buffer.valid() || buffer.num_elements() != shader_id_size + length) { - SetGLError(GL_OUT_OF_MEMORY, "glShaderBinary: out of memory."); + GLsizei shader_id_size = n * sizeof(*shaders); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { return; } - void* shader_ids = buffer.elements(); - void* shader_data = buffer.elements() + shader_id_size; + int8* buffer = transfer_buffer->AllocTyped<int8>(shader_id_size + length); + if (!buffer) { + return; + } + 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( n, - buffer.shm_id(), - buffer.offset(), + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(shader_ids), binaryformat, - buffer.shm_id(), - buffer.offset() + shader_id_size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(shader_data), length); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); } void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { @@ -1458,6 +1555,11 @@ void GLES2Implementation::ShaderSource( // Concatenate all the strings in to a bucket on the service. helper_->SetBucketSize(kResultBucketId, total_size); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + uint32 max_size = transfer_buffer->GetLargestFreeOrPendingSize(); uint32 offset = 0; for (GLsizei ii = 0; ii <= count; ++ii) { const char* src = ii < count ? source[ii] : ""; @@ -1465,16 +1567,19 @@ void GLES2Implementation::ShaderSource( uint32 size = ii < count ? (length ? static_cast<size_t>(length[ii]) : strlen(src)) : 1; while (size) { - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { + uint32 part_size = std::min(size, max_size); + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { return; } - memcpy(buffer.address(), src, buffer.size()); - helper_->SetBucketData(kResultBucketId, offset, buffer.size(), - buffer.shm_id(), buffer.offset()); - offset += buffer.size(); - src += buffer.size(); - size -= buffer.size(); + memcpy(buffer, src, part_size); + helper_->SetBucketData(kResultBucketId, offset, part_size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer)); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + src += part_size; + size -= part_size; } } } @@ -1487,41 +1592,25 @@ void GLES2Implementation::ShaderSource( void GLES2Implementation::BufferDataHelper( GLenum target, GLsizeiptr size, const void* data, GLenum usage) { - if (size == 0) { - return; - } - - if (size < 0) { - SetGLError(GL_INVALID_VALUE, "glBufferData: size < 0"); - return; - } - - // If there is no data just send BufferData - if (!data) { + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize(); + if (size > max_size || !data) { helper_->BufferData(target, size, 0, 0, usage); + if (data != NULL) { + BufferSubDataHelper(target, 0, size, data); + } return; } - // See if we can send all at once. - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { - return; - } - - if (buffer.size() >= static_cast<unsigned int>(size)) { - memcpy(buffer.address(), data, size); - helper_->BufferData( - target, - size, - buffer.shm_id(), - buffer.offset(), - usage); - return; - } - - // Make the buffer with BufferData then send via BufferSubData - helper_->BufferData(target, size, 0, 0, usage); - BufferSubDataHelperImpl(target, 0, size, data, &buffer); + void* buffer = transfer_buffer->Alloc(size); + memcpy(buffer, data, size); + helper_->BufferData( + target, + size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer), + usage); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); } void GLES2Implementation::BufferData( @@ -1546,31 +1635,26 @@ void GLES2Implementation::BufferSubDataHelper( return; } - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - BufferSubDataHelperImpl(target, offset, size, data, &buffer); -} - -void GLES2Implementation::BufferSubDataHelperImpl( - GLenum target, GLintptr offset, GLsizeiptr size, const void* data, - ScopedTransferBufferPtr* buffer) { - GPU_DCHECK(buffer); - GPU_DCHECK_GT(size, 0); - const int8* source = static_cast<const int8*>(data); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize(); while (size) { - if (!buffer->valid() || buffer->size() == 0) { - buffer->Reset(size); - if (!buffer->valid()) { - return; - } + GLsizeiptr part_size = std::min(size, max_size); + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { + return; } - memcpy(buffer->address(), source, buffer->size()); - helper_->BufferSubData( - target, offset, buffer->size(), buffer->shm_id(), buffer->offset()); - offset += buffer->size(); - source += buffer->size(); - size -= buffer->size(); - buffer->Release(); + memcpy(buffer, source, part_size); + helper_->BufferSubData(target, offset, part_size, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer)); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + offset += part_size; + source += part_size; + size -= part_size; } } @@ -1699,44 +1783,42 @@ void GLES2Implementation::TexImage2D( return; } - // If there's no data just issue TexImage2D - if (!pixels) { + // Check if we can send it all at once. + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + unsigned int max_size = transfer_buffer->GetLargestFreeOrPendingSize(); + if (size > max_size || !pixels) { + // No, so send it using TexSubImage2D. helper_->TexImage2D( target, level, internalformat, width, height, border, format, type, 0, 0); + if (pixels) { + TexSubImage2DImpl( + target, level, 0, 0, width, height, format, type, pixels, GL_TRUE); + } return; } - // Check if we can send it all at once. - ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); - if (!buffer.valid()) { + void* buffer = transfer_buffer->Alloc(size); + if (!buffer) { return; } - - if (buffer.size() >= size) { - bool copy_success = true; - if (unpack_flip_y_) { - copy_success = CopyRectToBufferFlipped( - pixels, width, height, format, type, buffer.address()); - } else { - memcpy(buffer.address(), pixels, size); - } - - if (copy_success) { - helper_->TexImage2D( - target, level, internalformat, width, height, border, format, type, - buffer.shm_id(), buffer.offset()); - } - return; + bool copy_success = true; + if (unpack_flip_y_) { + copy_success = CopyRectToBufferFlipped( + pixels, width, height, format, type, buffer); + } else { + memcpy(buffer, pixels, size); } - // No, so send it using TexSubImage2D. - helper_->TexImage2D( - target, level, internalformat, width, height, border, format, type, - 0, 0); - TexSubImage2DImpl( - target, level, 0, 0, width, height, format, type, pixels, GL_TRUE, - &buffer); + if (copy_success) { + helper_->TexImage2D( + target, level, internalformat, width, height, border, format, type, + transfer_buffer->GetShmId(), transfer_buffer->GetOffset(buffer)); + } + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); } void GLES2Implementation::TexSubImage2D( @@ -1751,7 +1833,15 @@ void GLES2Implementation::TexSubImage2D( << GLES2Util::GetStringTextureFormat(format) << ", " << GLES2Util::GetStringPixelType(type) << ", " << static_cast<const void*>(pixels) << ")"); + TexSubImage2DImpl( + target, level, xoffset, yoffset, width, height, format, type, pixels, + GL_FALSE); +} +void GLES2Implementation::TexSubImage2DImpl( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* pixels, + GLboolean internal) { if (level < 0 || height < 0 || width < 0) { SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0"); return; @@ -1759,41 +1849,12 @@ void GLES2Implementation::TexSubImage2D( if (height == 0 || width == 0) { return; } - - uint32 temp_size; - if (!GLES2Util::ComputeImageDataSize( - width, height, format, type, unpack_alignment_, &temp_size)) { - SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); + const int8* source = static_cast<const int8*>(pixels); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { return; } - - ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); - TexSubImage2DImpl( - target, level, xoffset, yoffset, width, height, format, type, pixels, - GL_FALSE, &buffer); -} - -static GLint ComputeNumRowsThatFitInBuffer( - GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size, - unsigned int size) { - GPU_DCHECK_GE(unpadded_row_size, 0); - if (padded_row_size == 0) { - return 1; - } - GLint num_rows = size / padded_row_size; - return num_rows + (size - num_rows * padded_row_size) / unpadded_row_size; -} - -void GLES2Implementation::TexSubImage2DImpl( - GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void* pixels, - GLboolean internal, ScopedTransferBufferPtr* buffer) { - GPU_DCHECK(buffer); - GPU_DCHECK_GE(level, 0); - GPU_DCHECK_GT(height, 0); - GPU_DCHECK_GT(width, 0); - - const int8* source = static_cast<const int8*>(pixels); + GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize(); uint32 temp_size; if (!GLES2Util::ComputeImageDataSize( width, 1, format, type, unpack_alignment_, &temp_size)) { @@ -1813,37 +1874,70 @@ void GLES2Implementation::TexSubImage2DImpl( } GLint original_yoffset = yoffset; - // Transfer by rows. - while (height) { - unsigned int desired_size = - padded_row_size * (height - 1) + unpadded_row_size; - if (!buffer->valid() || buffer->size() == 0) { - buffer->Reset(desired_size); - if (!buffer->valid()) { + if (padded_row_size <= max_size) { + // Transfer by rows. + GLint max_rows = max_size / std::max(padded_row_size, + static_cast<GLsizeiptr>(1)); + while (height) { + GLint num_rows = std::min(height, max_rows); + GLsizeiptr part_size = + (num_rows - 1) * padded_row_size + unpadded_row_size; + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { return; } + GLint y; + if (unpack_flip_y_) { + CopyRectToBufferFlipped( + source, width, num_rows, format, type, buffer); + // GPU_DCHECK(copy_success); // can't check this because bot fails! + y = original_yoffset + height - num_rows; + } else { + memcpy(buffer, source, part_size); + y = yoffset; + } + helper_->TexSubImage2D( + target, level, xoffset, y, width, num_rows, format, type, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer), internal); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + yoffset += num_rows; + source += num_rows * padded_row_size; + height -= num_rows; } - - GLint num_rows = ComputeNumRowsThatFitInBuffer( - padded_row_size, unpadded_row_size, buffer->size()); - num_rows = std::min(num_rows, height); - GLint y; - if (unpack_flip_y_) { - CopyRectToBufferFlipped( - source, width, num_rows, format, type, buffer->address()); - y = original_yoffset + height - num_rows; - } else { - temp_size = padded_row_size * (num_rows - 1) + unpadded_row_size; - memcpy(buffer->address(), source, temp_size); - y = yoffset; + } else { + // Transfer by sub rows. Because GL has no maximum texture dimensions. + uint32 temp; + GLES2Util::ComputeImageDataSize( + 1, 1, format, type, unpack_alignment_, &temp); + GLsizeiptr element_size = temp; + max_size -= max_size % element_size; + GLint max_sub_row_pixels = max_size / element_size; + for (; height; --height) { + GLint temp_width = width; + GLint temp_xoffset = xoffset; + const int8* row_source = source; + while (temp_width) { + GLint num_pixels = std::min(width, max_sub_row_pixels); + GLsizeiptr part_size = num_pixels * element_size; + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { + return; + } + memcpy(buffer, row_source, part_size); + GLint y = unpack_flip_y_ ? (original_yoffset + height - 1) : yoffset; + helper_->TexSubImage2D( + target, level, temp_xoffset, y, num_pixels, 1, format, type, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer), internal); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + row_source += part_size; + temp_xoffset += num_pixels; + temp_width -= num_pixels; + } + ++yoffset; + source += padded_row_size; } - helper_->TexSubImage2D( - target, level, xoffset, y, width, num_rows, format, type, - buffer->shm_id(), buffer->offset(), internal); - buffer->Release(); - yoffset += num_rows; - source += num_rows * padded_row_size; - height -= num_rows; } } @@ -2001,15 +2095,19 @@ void GLES2Implementation::GetAttachedShaders( TRACE_EVENT0("gpu", "GLES2::GetAttachedShaders"); typedef gles2::GetAttachedShaders::Result Result; uint32 size = Result::ComputeSize(maxcount); - Result* result = static_cast<Result*>(transfer_buffer_->Alloc(size)); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + Result* result = transfer_buffer->AllocTyped<Result>(size); if (!result) { return; } result->SetNumResults(0); helper_->GetAttachedShaders( program, - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(result), + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(result), size); int32 token = helper_->InsertToken(); WaitForCmd(); @@ -2022,7 +2120,7 @@ void GLES2Implementation::GetAttachedShaders( GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); } }); - transfer_buffer_->FreePendingToken(result, token); + transfer_buffer->FreePendingToken(result, token); } void GLES2Implementation::GetShaderPrecisionFormat( @@ -2183,8 +2281,16 @@ void GLES2Implementation::ReadPixels( TRACE_EVENT0("gpu", "GLES2::ReadPixels"); typedef gles2::ReadPixels::Result Result; - + Result* result = GetResultAs<Result*>(); + if (!result) { + return; + } int8* dest = reinterpret_cast<int8*>(pixels); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + GLsizeiptr max_size = transfer_buffer->GetLargestFreeOrPendingSize(); uint32 temp_size; if (!GLES2Util::ComputeImageDataSize( width, 1, format, type, pack_alignment_, &temp_size)) { @@ -2197,61 +2303,107 @@ void GLES2Implementation::ReadPixels( SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); return; } - GLsizei padded_row_size = temp_size - unpadded_row_size; + GLsizeiptr padded_row_size = temp_size - unpadded_row_size; if (padded_row_size < 0 || unpadded_row_size < 0) { SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); return; } - // Transfer by rows. - // The max rows we can transfer. - while (height) { - GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; - ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); - if (!buffer.valid()) { - return; - } - GLint num_rows = ComputeNumRowsThatFitInBuffer( - padded_row_size, unpadded_row_size, buffer.size()); - num_rows = std::min(num_rows, height); - // NOTE: We must look up the address of the result area AFTER allocation - // of the transfer buffer since the transfer buffer may be reallocated. - Result* result = GetResultAs<Result*>(); - if (!result) { - return; - } - *result = 0; // mark as failed. - helper_->ReadPixels( - xoffset, yoffset, width, num_rows, format, type, - buffer.shm_id(), buffer.offset(), - GetResultShmId(), GetResultShmOffset()); - WaitForCmd(); - if (*result != 0) { - // when doing a y-flip we have to iterate through top-to-bottom chunks - // of the dst. The service side handles reversing the rows within a - // chunk. - int8* rows_dst; - if (pack_reverse_row_order_) { - rows_dst = dest + (height - num_rows) * padded_row_size; - } else { - rows_dst = dest; + // Check if we have enough space to transfer at least an entire row. + if (padded_row_size <= max_size) { + // Transfer by rows. + // The max rows we can transfer. + GLint max_rows = max_size / std::max(padded_row_size, + static_cast<GLsizeiptr>(1)); + while (height) { + // Compute how many rows to transfer. + GLint num_rows = std::min(height, max_rows); + // Compute how much space those rows will take. The last row will not + // include padding. + GLsizeiptr part_size = + unpadded_row_size + padded_row_size * (num_rows - 1); + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { + return; } - // We have to copy 1 row at a time to avoid writing pad bytes. - const int8* src = static_cast<const int8*>(buffer.address()); - for (GLint yy = 0; yy < num_rows; ++yy) { - memcpy(rows_dst, src, unpadded_row_size); - rows_dst += padded_row_size; - src += padded_row_size; + *result = 0; // mark as failed. + helper_->ReadPixels( + xoffset, yoffset, width, num_rows, format, type, + transfer_buffer->GetShmId(), transfer_buffer->GetOffset(buffer), + GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + if (*result != 0) { + // when doing a y-flip we have to iterate through top-to-bottom chunks + // of the dst. The service side handles reversing the rows within a + // chunk. + int8* rows_dst; + if (pack_reverse_row_order_) { + rows_dst = dest + (height - num_rows) * padded_row_size; + } else { + rows_dst = dest; + } + // 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(rows_dst, src, unpadded_row_size); + rows_dst += padded_row_size; + src += padded_row_size; + } + if (!pack_reverse_row_order_) { + dest = rows_dst; + } } - if (!pack_reverse_row_order_) { - dest = rows_dst; + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); + // If it was not marked as successful exit. + if (*result == 0) { + return; } + yoffset += num_rows; + height -= num_rows; } - // If it was not marked as successful exit. - if (*result == 0) { - return; + } else { + // Transfer by sub rows. Because GL has no maximum texture dimensions. + GLES2Util::ComputeImageDataSize( + 1, 1, format, type, pack_alignment_, &temp_size); + GLsizeiptr element_size = temp_size; + max_size -= max_size % element_size; + GLint max_sub_row_pixels = max_size / element_size; + if (pack_reverse_row_order_) { + // start at the last row when flipping y. + dest = dest + (height - 1) * padded_row_size; + } + for (; height; --height) { + GLint temp_width = width; + GLint temp_xoffset = xoffset; + int8* row_dest = dest; + while (temp_width) { + GLint num_pixels = std::min(width, max_sub_row_pixels); + GLsizeiptr part_size = num_pixels * element_size; + void* buffer = transfer_buffer->Alloc(part_size); + if (!buffer) { + return; + } + *result = 0; // mark as failed. + helper_->ReadPixels( + temp_xoffset, yoffset, temp_width, 1, format, type, + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(buffer), + GetResultShmId(), GetResultShmOffset()); + 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; + } + row_dest += part_size; + temp_xoffset += num_pixels; + temp_width -= num_pixels; + } + ++yoffset; + dest += pack_reverse_row_order_ ? -padded_row_size : padded_row_size; } - yoffset += num_rows; - height -= num_rows; } } @@ -2463,7 +2615,7 @@ void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { bool have_client_side = client_side_buffer_helper_->HaveEnabledClientSideBuffers(); if (have_client_side) { - client_side_buffer_helper_->SetupSimulatedClientSideBuffers( + client_side_buffer_helper_->SetupSimualtedClientSideBuffers( this, helper_, first + count); } #endif @@ -2819,7 +2971,11 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM( } uint32 size_needed = count * sizeof(pnames[0]) + num_results * sizeof(results[0]); - void* buffer = transfer_buffer_->Alloc(size_needed); + AlignedRingBuffer* transfer_buffer = transfer_buffer_.GetBuffer(); + if (!transfer_buffer) { + return; + } + void* buffer = transfer_buffer->Alloc(size_needed); if (!buffer) { return; } @@ -2828,16 +2984,16 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM( memcpy(pnames_buffer, pnames, count * sizeof(GLenum)); memset(results_buffer, 0, num_results * sizeof(GLint)); helper_->GetMultipleIntegervCHROMIUM( - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(pnames_buffer), + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(pnames_buffer), count, - transfer_buffer_->GetShmId(), - transfer_buffer_->GetOffset(results_buffer), + transfer_buffer->GetShmId(), + transfer_buffer->GetOffset(results_buffer), size); WaitForCmd(); memcpy(results, results_buffer, size); // TODO(gman): We should be able to free without a token. - transfer_buffer_->FreePendingToken(buffer, helper_->InsertToken()); + transfer_buffer->FreePendingToken(buffer, helper_->InsertToken()); GPU_CLIENT_LOG(" returned"); GPU_CLIENT_LOG_CODE_BLOCK({ for (int i = 0; i < num_results; ++i) { diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index d8adc44..0d1a633 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -74,13 +74,12 @@ namespace gpu { class MappedMemoryManager; -class ScopedTransferBufferPtr; -class TransferBufferInterface; namespace gles2 { class ClientSideBufferHelper; class ProgramInfoManager; +class AlignedRingBuffer; // Base class for IdHandlers class IdHandlerInterface { @@ -98,6 +97,84 @@ class IdHandlerInterface { virtual bool MarkAsUsedForBind(GLuint id) = 0; }; +// Wraps RingBufferWrapper to provide aligned allocations. +class AlignedRingBuffer : public RingBufferWrapper { + public: + AlignedRingBuffer( + unsigned int alignment, + int32 shm_id, + RingBuffer::Offset base_offset, + unsigned int size, + CommandBufferHelper* helper, + void* base) + : RingBufferWrapper(base_offset, size, helper, base), + alignment_(alignment), + shm_id_(shm_id) { + } + ~AlignedRingBuffer(); + + // Overrriden from RingBufferWrapper + void* Alloc(unsigned int size) { + return RingBufferWrapper::Alloc(RoundToAlignment(size)); + } + + template <typename T>T* AllocTyped(unsigned int count) { + return static_cast<T*>(Alloc(count * sizeof(T))); + } + + int32 GetShmId() const { + return shm_id_; + } + + private: + unsigned int RoundToAlignment(unsigned int size) { + return (size + alignment_ - 1) & ~(alignment_ - 1); + } + + unsigned int alignment_; + int32 shm_id_; +}; + +// Manages the transfer buffer. +class TransferBuffer { + public: + TransferBuffer( + CommandBufferHelper* helper, + int32 buffer_id, + void* buffer, + size_t buffer_size, + size_t result_size, + unsigned int alignment); + ~TransferBuffer(); + + AlignedRingBuffer* GetBuffer(); + int GetShmId(); + void* GetResultBuffer(); + int GetResultOffset(); + + void Free(); + + // This is for unit testing only. + bool HaveBuffer() const { + return buffer_id_ != 0; + } + + private: + void AllocateRingBuffer(); + + void Setup(int32 buffer_id, void* buffer); + + CommandBufferHelper* helper_; + scoped_ptr<AlignedRingBuffer> ring_buffer_; + unsigned int buffer_size_; + unsigned int result_size_; + unsigned int alignment_; + int32 buffer_id_; + void* result_buffer_; + uint32 result_shm_offset_; + bool usable_; +}; + // This class emulates GLES2 over command buffers. It can be used by a client // program so that the program does not need deal with shared memory and command // buffer management. See gl2_lib.h. Note that there is a performance gain to @@ -158,17 +235,14 @@ class GLES2Implementation { GLES2Implementation( GLES2CmdHelper* helper, - TransferBufferInterface* transfer_buffer, + size_t transfer_buffer_size, + void* transfer_buffer, + int32 transfer_buffer_id, bool share_resources, bool bind_generates_resource); ~GLES2Implementation(); - bool Initialize( - unsigned int starting_transfer_buffer_size, - unsigned int min_transfer_buffer_size, - unsigned int max_transfer_buffer_size); - // The GLES2CmdHelper being used by this GLES2Implementation. You can use // this to issue cmds at a lower level for certain kinds of optimization. GLES2CmdHelper* helper() const { @@ -328,12 +402,16 @@ class GLES2Implementation { // Gets the value of the result. template <typename T> T GetResultAs() { - return static_cast<T>(GetResultBuffer()); + return static_cast<T>(transfer_buffer_.GetResultBuffer()); } - void* GetResultBuffer(); - int32 GetResultShmId(); - uint32 GetResultShmOffset(); + int32 GetResultShmId() { + return transfer_buffer_.GetShmId(); + } + + uint32 GetResultShmOffset() { + return transfer_buffer_.GetResultOffset(); + } // Lazily determines if GL_ANGLE_pack_reverse_row_order is available bool IsAnglePackReverseRowOrderAvailable(); @@ -394,9 +472,6 @@ class GLES2Implementation { GLenum target, GLsizeiptr size, const void* data, GLenum usage); void BufferSubDataHelper( GLenum target, GLintptr offset, GLsizeiptr size, const void* data); - void BufferSubDataHelperImpl( - GLenum target, GLintptr offset, GLsizeiptr size, const void* data, - ScopedTransferBufferPtr* buffer); // Helper for GetVertexAttrib bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32* param); @@ -410,7 +485,7 @@ class GLES2Implementation { void TexSubImage2DImpl( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, - GLboolean internal, ScopedTransferBufferPtr* buffer); + GLboolean internal); // Helpers for query functions. bool GetHelper(GLenum pname, GLint* params); @@ -432,8 +507,8 @@ class GLES2Implementation { GLES2Util util_; GLES2CmdHelper* helper_; - TransferBufferInterface* transfer_buffer_; scoped_ptr<IdHandlerInterface> id_handlers_[id_namespaces::kNumIdNamespaces]; + TransferBuffer transfer_buffer_; std::string last_error_; std::queue<int32> swap_buffers_tokens_; diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index c354e9e..46f60ae 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -2,15 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Tests for GLES2Implementation. +// Tests for the Command Buffer Helper. #include "gpu/command_buffer/client/gles2_implementation.h" #include <GLES2/gl2ext.h> -#include "gpu/command_buffer/client/client_test_helper.h" -#include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gmock/include/gmock/gmock.h" @@ -25,19 +22,162 @@ using testing::InSequence; using testing::Invoke; using testing::Mock; using testing::Sequence; -using testing::StrictMock; using testing::Truly; using testing::Return; namespace gpu { + +class GLES2MockCommandBufferHelper : public CommandBuffer { + public: + static const int32 kTransferBufferBaseId = 0x123; + static const int32 kMaxTransferBuffers = 6; + + GLES2MockCommandBufferHelper() { } + virtual ~GLES2MockCommandBufferHelper() { } + + // CommandBuffer implementation: + virtual bool Initialize() { + return true; + } + + virtual State GetState() { + return state_; + } + + virtual State GetLastState() { + return state_; + } + + virtual void Flush(int32 put_offset) { + state_.put_offset = put_offset; + } + + virtual State FlushSync(int32 put_offset, int32 last_known_get) { + state_.put_offset = put_offset; + state_.get_offset = put_offset; + // Warning: This is a hack. We just happen to know that the default + // transfer buffer will be the first transfer buffer. + OnFlush(transfer_buffer_buffers_[0].ptr); + return state_; + } + + virtual void SetGetBuffer(int transfer_buffer_id) { + ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id); + ring_buffer_ = static_cast<CommandBufferEntry*>(ring_buffer_buffer_.ptr); + state_.num_entries = ring_buffer_buffer_.size / sizeof(ring_buffer_[0]); + state_.token = 10000; // All token checks in the tests should pass. + } + + virtual void SetGetOffset(int32 get_offset) { + state_.get_offset = get_offset; + } + + // Get's the Id of the next transfer buffer that will be returned + // by CreateTransferBuffer. This is useful for testing expected ids. + int32 GetNextFreeTransferBufferId() { + for (size_t ii = 0; ii < arraysize(transfer_buffers_); ++ii) { + if (!transfer_buffers_[ii].get()) { + return kTransferBufferBaseId + ii; + } + } + return -1; + } + + virtual int32 CreateTransferBuffer(size_t size, int32 id_request) { + int32 id = GetNextFreeTransferBufferId(); + if (id >= 0) { + int32 ndx = id - kTransferBufferBaseId; + transfer_buffers_[ndx].reset(new int8[size]); + transfer_buffer_buffers_[ndx].ptr = transfer_buffers_[ndx].get(); + transfer_buffer_buffers_[ndx].size = size; + } + return id; + } + + void DestroyTransferBufferHelper(int32 id) { + GPU_DCHECK_GE(id, kTransferBufferBaseId); + GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); + id -= kTransferBufferBaseId; + transfer_buffers_[id].reset(); + transfer_buffer_buffers_[id] = Buffer(); + } + + virtual Buffer GetTransferBuffer(int32 id) { + GPU_DCHECK_GE(id, kTransferBufferBaseId); + GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); + return transfer_buffer_buffers_[id - kTransferBufferBaseId]; + } + + virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, + size_t size, + int32 id_request) { + GPU_NOTREACHED(); + return -1; + } + + virtual void SetToken(int32 token) { + GPU_NOTREACHED(); + state_.token = token; + } + + virtual void SetParseError(error::Error error) { + GPU_NOTREACHED(); + state_.error = error; + } + + virtual void SetContextLostReason(error::ContextLostReason reason) { + GPU_NOTREACHED(); + state_.context_lost_reason = reason; + } + + virtual void OnFlush(void* transfer_buffer) = 0; + + private: + scoped_array<int8> transfer_buffers_[kMaxTransferBuffers]; + Buffer transfer_buffer_buffers_[kMaxTransferBuffers]; + CommandBufferEntry* ring_buffer_; + Buffer ring_buffer_buffer_; + State state_; +}; + +class MockGLES2CommandBuffer : public GLES2MockCommandBufferHelper { + public: + MockGLES2CommandBuffer() { + DelegateToFake(); + } + + virtual ~MockGLES2CommandBuffer() { + } + + // This is so we can use all the gmock functions when Flush is called. + MOCK_METHOD1(OnFlush, void(void* result)); + MOCK_METHOD1(DestroyTransferBuffer, void(int32 id)); + + void DelegateToFake() { + ON_CALL(*this, DestroyTransferBuffer(_)) + .WillByDefault(Invoke( + this, &GLES2MockCommandBufferHelper::DestroyTransferBufferHelper)); + } +}; + +// GCC requires these declarations, but MSVC requires they not be present +#ifndef _MSC_VER +const int32 GLES2MockCommandBufferHelper::kTransferBufferBaseId; +const int32 GLES2MockCommandBufferHelper::kMaxTransferBuffers; +#endif + namespace gles2 { -ACTION_P2(SetMemory, dst, obj) { - memcpy(dst, &obj, sizeof(obj)); +ACTION_P(SetMemory, obj) { + memcpy(arg0, &obj, sizeof(obj)); } -ACTION_P3(SetMemoryFromArray, dst, array, size) { - memcpy(dst, array, size); +ACTION_P2(SetMemoryAtOffset, offset, obj) { + memcpy(static_cast<char*>(arg0) + offset, &obj, sizeof(obj)); +} + +ACTION_P3(SetMemoryAtOffsetFromArray, offset, array, size) { + memcpy(static_cast<char*>(arg0) + offset, array, size); } // Used to help set the transfer buffer result to SizedResult of a single value. @@ -76,229 +216,211 @@ struct Str7 { }; #pragma pack(pop) -class MockTransferBuffer : public TransferBufferInterface { - public: - struct ExpectedMemoryInfo { - uint32 offset; - int32 id; - uint8* ptr; - }; +class GLES2CommandBufferTestBase : public testing::Test { + protected: + static const int32 kNumCommandEntries = 400; + static const int32 kCommandBufferSizeBytes = + kNumCommandEntries * sizeof(CommandBufferEntry); + static const size_t kTransferBufferSize = 256; + static const uint8 kInitialValue = 0xBD; - MockTransferBuffer( - CommandBuffer* command_buffer, - unsigned int size, - unsigned int result_size, - unsigned int alignment) - : command_buffer_(command_buffer), - size_(size), - result_size_(result_size), - alignment_(alignment), - actual_buffer_index_(0), - expected_buffer_index_(0), - last_alloc_(NULL), - expected_offset_(result_size), - actual_offset_(result_size) { - // We have to allocate the buffers here because - // we need to know their address before GLES2Implementation::Initialize - // is called. - for (int ii = 0; ii < kNumBuffers; ++ii) { - buffer_ids_[ii] = command_buffer_->CreateTransferBuffer( - size_ + ii * alignment_, -1); - EXPECT_NE(-1, buffer_ids_[ii]); - buffers_[ii] = command_buffer_->GetTransferBuffer(buffer_ids_[ii]); - } + GLES2CommandBufferTestBase() + : commands_(NULL), + token_(0), + offset_(0), + initial_offset_(0), + alignment_(0), + transfer_buffer_id_(-1) { } - virtual ~MockTransferBuffer() { } - - bool Initialize( - unsigned int starting_buffer_size, - unsigned int result_size, - unsigned int /* min_buffer_size */, - unsigned int /* max_buffer_size */, - unsigned int alignment) OVERRIDE; - virtual int GetShmId() OVERRIDE; - virtual void* GetResultBuffer() OVERRIDE; - virtual int GetResultOffset() OVERRIDE; - virtual void Free() OVERRIDE; - virtual bool HaveBuffer() const OVERRIDE; - virtual void* AllocUpTo( - unsigned int size, unsigned int* size_allocated) OVERRIDE; - virtual void* Alloc(unsigned int size) OVERRIDE; - virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE; - virtual void FreePendingToken(void* p, unsigned int /* token */) OVERRIDE; + void SetupCommandBuffer(unsigned int offset, unsigned alignment) { + initial_offset_ = offset; + offset_ = offset; + alignment_ = alignment; - size_t MaxTransferBufferSize() { - return size_ - result_size_; - } + command_buffer_.reset(new MockGLES2CommandBuffer()); + command_buffer_->Initialize(); - unsigned int RoundToAlignment(unsigned int size) { - return (size + alignment_ - 1) & ~(alignment_ - 1); - } + transfer_buffer_id_ = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); + transfer_buffer_ = command_buffer_->GetTransferBuffer(transfer_buffer_id_); + ClearTransferBuffer(); - bool InSync() { - return expected_buffer_index_ == actual_buffer_index_; + helper_.reset(new GLES2CmdHelper(command_buffer_.get())); + helper_->Initialize(kCommandBufferSizeBytes); } - ExpectedMemoryInfo GetExpectedMemory(size_t size) { - ExpectedMemoryInfo mem; - mem.offset = AllocateExpectedTransferBuffer(size); - mem.id = GetExpectedTransferBufferId(); - mem.ptr = static_cast<uint8*>( - GetExpectedTransferAddressFromOffset(mem.offset, size)); - return mem; + const void* GetPut() { + return helper_->GetSpace(0); } - ExpectedMemoryInfo GetExpectedResultMemory(size_t size) { - ExpectedMemoryInfo mem; - mem.offset = GetExpectedResultBufferOffset(); - mem.id = GetExpectedResultBufferId(); - mem.ptr = static_cast<uint8*>( - GetExpectedTransferAddressFromOffset(mem.offset, size)); - return mem; + size_t MaxTransferBufferSize() { + return kTransferBufferSize - initial_offset_; } - private: - static const int kNumBuffers = 2; - - uint8* actual_buffer() const { - return static_cast<uint8*>(buffers_[actual_buffer_index_].ptr); + void ClearCommands() { + Buffer ring_buffer = helper_->get_ring_buffer(); + memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); } - uint8* expected_buffer() const { - return static_cast<uint8*>(buffers_[expected_buffer_index_].ptr); + bool NoCommandsWritten() { + return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] == + kInitialValue; } - uint32 AllocateExpectedTransferBuffer(size_t size) { - EXPECT_LE(size, MaxTransferBufferSize()); - - // Toggle which buffer we get each time to simulate the buffer being - // reallocated. - expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers; + void ClearTransferBuffer() { + memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize); + } - if (expected_offset_ + size > size_) { - expected_offset_ = result_size_; - } - uint32 offset = expected_offset_; - expected_offset_ += RoundToAlignment(size); + unsigned int RoundToAlignment(unsigned int size) { + return (size + alignment_ - 1) & ~(alignment_ - 1); + } - // Make sure each buffer has a different offset. - return offset + expected_buffer_index_ * alignment_; + int GetNextToken() { + return ++token_; } - void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) { - EXPECT_GE(offset, expected_buffer_index_ * alignment_); - EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_); - return expected_buffer() + offset; + int32 GetNextFreeTransferBufferId() { + return command_buffer_->GetNextFreeTransferBufferId(); } - int GetExpectedResultBufferId() { - return buffer_ids_[expected_buffer_index_]; + uint32 AllocateTransferBuffer(size_t size) { + if (offset_ + size > kTransferBufferSize) { + offset_ = initial_offset_; + } + uint32 offset = offset_; + offset_ += RoundToAlignment(size); + return offset; } - uint32 GetExpectedResultBufferOffset() { - return expected_buffer_index_ * alignment_; + void* GetTransferAddressFromOffset(uint32 offset, size_t size) { + EXPECT_LE(offset + size, transfer_buffer_.size); + return static_cast<int8*>(transfer_buffer_.ptr) + offset; } - int GetExpectedTransferBufferId() { - return buffer_ids_[expected_buffer_index_]; + template <typename T> + T* GetTransferAddressFromOffsetAs(uint32 offset, size_t size) { + return static_cast<T*>(GetTransferAddressFromOffset(offset, size)); } - CommandBuffer* command_buffer_; - size_t size_; - size_t result_size_; + Buffer transfer_buffer_; + CommandBufferEntry* commands_; + scoped_ptr<MockGLES2CommandBuffer> command_buffer_; + scoped_ptr<GLES2CmdHelper> helper_; + int token_; + uint32 offset_; + uint32 initial_offset_; uint32 alignment_; - int buffer_ids_[kNumBuffers]; - gpu::Buffer buffers_[kNumBuffers]; - int actual_buffer_index_; - int expected_buffer_index_; - void* last_alloc_; - uint32 expected_offset_; - uint32 actual_offset_; - - DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer); + int32 transfer_buffer_id_; }; -bool MockTransferBuffer::Initialize( - unsigned int starting_buffer_size, - unsigned int result_size, - unsigned int /* min_buffer_size */, - unsigned int /* max_buffer_size */, - unsigned int alignment) { - // Just check they match. - return size_ == starting_buffer_size && - result_size_ == result_size && - alignment_ == alignment; -}; - -int MockTransferBuffer::GetShmId() { - return buffer_ids_[actual_buffer_index_]; -} - -void* MockTransferBuffer::GetResultBuffer() { - return actual_buffer() + actual_buffer_index_ * alignment_; -} +// GCC requires these declarations, but MSVC requires they not be present +#ifndef _MSC_VER +const int32 GLES2CommandBufferTestBase::kNumCommandEntries; +const int32 GLES2CommandBufferTestBase::kCommandBufferSizeBytes; +const size_t GLES2CommandBufferTestBase::kTransferBufferSize; +const uint8 GLES2CommandBufferTestBase::kInitialValue; +#endif -int MockTransferBuffer::GetResultOffset() { - return actual_buffer_index_ * alignment_; -} +class TransferBufferTest : public GLES2CommandBufferTestBase { + protected: + static const unsigned int kStartingOffset = 64; + static const unsigned int kAlignment = 4; -void MockTransferBuffer::Free() { - GPU_NOTREACHED(); -} + TransferBufferTest() { } -bool MockTransferBuffer::HaveBuffer() const { - return true; -} + virtual void SetUp() { + SetupCommandBuffer( + GLES2Implementation::kStartingOffset, + GLES2Implementation::kAlignment); -void* MockTransferBuffer::AllocUpTo( - unsigned int size, unsigned int* size_allocated) { - EXPECT_TRUE(size_allocated != NULL); - EXPECT_TRUE(last_alloc_ == NULL); + transfer_buffer_id_ = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); - // Toggle which buffer we get each time to simulate the buffer being - // reallocated. - actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers; + transfer_buffer_.reset(new TransferBuffer( + helper_.get(), + transfer_buffer_id_, + GetTransferAddressFromOffset(0, 0), + kTransferBufferSize, + kStartingOffset, + kAlignment)); + } - size = std::min(static_cast<size_t>(size), MaxTransferBufferSize()); - if (actual_offset_ + size > size_) { - actual_offset_ = result_size_; + virtual void TearDown() { + transfer_buffer_.reset(); } - uint32 offset = actual_offset_; - actual_offset_ += RoundToAlignment(size); - *size_allocated = size; - // Make sure each buffer has a different offset. - last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_; - return last_alloc_; -} + scoped_ptr<TransferBuffer> transfer_buffer_; +}; -void* MockTransferBuffer::Alloc(unsigned int size) { - EXPECT_LE(size, MaxTransferBufferSize()); - unsigned int temp = 0; - void* p = AllocUpTo(size, &temp); - EXPECT_EQ(temp, size); - return p; -} +// GCC requires these declarations, but MSVC requires they not be present +#ifndef _MSC_VER +const unsigned int TransferBufferTest::kStartingOffset; +const unsigned int TransferBufferTest::kAlignment; +#endif -RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const { - // Make sure each buffer has a different offset. - return static_cast<uint8*>(pointer) - actual_buffer(); +TEST_F(TransferBufferTest, Basic) { + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); } -void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) { - EXPECT_EQ(last_alloc_, p); - last_alloc_ = NULL; +TEST_F(TransferBufferTest, Free) { + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + + // Free buffer. + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) + .Times(1) + .RetiresOnSaturation(); + transfer_buffer_->Free(); + // See it's freed. + EXPECT_FALSE(transfer_buffer_->HaveBuffer()); + // See that it gets reallocated. + EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + + // Free buffer. + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) + .Times(1) + .RetiresOnSaturation(); + transfer_buffer_->Free(); + // See it's freed. + EXPECT_FALSE(transfer_buffer_->HaveBuffer()); + // See that it gets reallocated. + EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL); + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + + // Free buffer. + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) + .Times(1) + .RetiresOnSaturation(); + transfer_buffer_->Free(); + // See it's freed. + EXPECT_FALSE(transfer_buffer_->HaveBuffer()); + // See that it gets reallocated. + EXPECT_TRUE(transfer_buffer_->GetBuffer() != NULL); + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + + // Free buffer. + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) + .Times(1) + .RetiresOnSaturation(); + transfer_buffer_->Free(); + // See it's freed. + EXPECT_FALSE(transfer_buffer_->HaveBuffer()); + // See that it gets reallocated. + transfer_buffer_->GetResultOffset(); + EXPECT_TRUE(transfer_buffer_->HaveBuffer()); + + // Test freeing twice. + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) + .Times(1) + .RetiresOnSaturation(); + transfer_buffer_->Free(); + transfer_buffer_->Free(); } -class GLES2ImplementationTest : public testing::Test { +class GLES2ImplementationTest : public GLES2CommandBufferTestBase { protected: - static const uint8 kInitialValue = 0xBD; - static const int32 kNumCommandEntries = 400; - static const int32 kCommandBufferSizeBytes = - kNumCommandEntries * sizeof(CommandBufferEntry); - static const size_t kTransferBufferSize = 256; - static const GLint kMaxCombinedTextureImageUnits = 8; static const GLint kMaxCubeMapTextureSize = 64; static const GLint kMaxFragmentUniformVectors = 16; @@ -319,33 +441,22 @@ class GLES2ImplementationTest : public testing::Test { static const GLuint kRenderbuffersStartId = 1; static const GLuint kTexturesStartId = 1; - typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; + GLES2ImplementationTest() { } - GLES2ImplementationTest() - : commands_(NULL), - token_(0) { + virtual void SetUp() { + Initialize(false, true); } - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; - - bool NoCommandsWritten() { - return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] == - kInitialValue; + virtual void TearDown() { + Mock::VerifyAndClear(gl_.get()); + EXPECT_CALL(*command_buffer_, OnFlush(_)).Times(AnyNumber()); + gl_.reset(); } void Initialize(bool shared_resources, bool bind_generates_resource) { - command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); - ASSERT_TRUE(command_buffer_->Initialize()); - - transfer_buffer_.reset(new MockTransferBuffer( - command_buffer(), - kTransferBufferSize, + SetupCommandBuffer( GLES2Implementation::kStartingOffset, - GLES2Implementation::kAlignment)); - - helper_.reset(new GLES2CmdHelper(command_buffer())); - helper_->Initialize(kCommandBufferSizeBytes); + GLES2Implementation::kAlignment); GLES2Implementation::GLState state; state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; @@ -364,13 +475,14 @@ class GLES2ImplementationTest : public testing::Test { // This just happens to work for now because GLState has 1 GLint per // state. If GLState gets more complicated this code will need to get // more complicated. - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(state) * 2); + AllocateTransferBuffer(sizeof(state)); // in + uint32 offset = AllocateTransferBuffer(sizeof(state)); // out { InSequence sequence; - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(mem1.ptr + sizeof(state), state)) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffset(offset, state)) .RetiresOnSaturation(); GetNextToken(); // eat the token that starting up will use. @@ -388,9 +500,9 @@ class GLES2ImplementationTest : public testing::Test { while (num_ids) { GLuint num = std::min(num_ids, max_num_per); size_t size = num * sizeof(ids[0]); - ExpectedMemoryInfo mem = GetExpectedMemory(size); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemoryFromArray(mem.ptr, ids, size)) + uint32 offset = AllocateTransferBuffer(size); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffsetFromArray(offset, ids, size)) .RetiresOnSaturation(); GetNextToken(); start += num; @@ -402,93 +514,36 @@ class GLES2ImplementationTest : public testing::Test { gl_.reset(new GLES2Implementation( helper_.get(), - transfer_buffer_.get(), + kTransferBufferSize, + transfer_buffer_.ptr, + transfer_buffer_id_, shared_resources, bind_generates_resource)); - ASSERT_TRUE(gl_->Initialize( - kTransferBufferSize, - kTransferBufferSize, - kTransferBufferSize)); } - EXPECT_CALL(*command_buffer(), OnFlush()) + EXPECT_CALL(*command_buffer_, OnFlush(_)) .Times(1) .RetiresOnSaturation(); helper_->CommandBufferHelper::Finish(); - ::testing::Mock::VerifyAndClearExpectations(gl_.get()); - Buffer ring_buffer = helper_->get_ring_buffer(); commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + - command_buffer()->GetState().put_offset; + command_buffer_->GetState().put_offset; ClearCommands(); - EXPECT_TRUE(transfer_buffer_->InSync()); - - ::testing::Mock::VerifyAndClearExpectations(command_buffer()); - } - - MockClientCommandBuffer* command_buffer() const { - return command_buffer_.get(); - } - - int GetNextToken() { - return ++token_; - } - - const void* GetPut() { - return helper_->GetSpace(0); - } - - void ClearCommands() { - Buffer ring_buffer = helper_->get_ring_buffer(); - memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); - } - - size_t MaxTransferBufferSize() { - return transfer_buffer_->MaxTransferBufferSize(); - } - - ExpectedMemoryInfo GetExpectedMemory(size_t size) { - return transfer_buffer_->GetExpectedMemory(size); - } - - ExpectedMemoryInfo GetExpectedResultMemory(size_t size) { - return transfer_buffer_->GetExpectedResultMemory(size); } Sequence sequence_; - scoped_ptr<MockClientCommandBuffer> command_buffer_; - scoped_ptr<GLES2CmdHelper> helper_; - scoped_ptr<MockTransferBuffer> transfer_buffer_; scoped_ptr<GLES2Implementation> gl_; - CommandBufferEntry* commands_; - int token_; }; -void GLES2ImplementationTest::SetUp() { - Initialize(false, true); -} - -void GLES2ImplementationTest::TearDown() { - Mock::VerifyAndClear(gl_.get()); - EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); - gl_.reset(); -} - class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { protected: - virtual void SetUp() OVERRIDE; + virtual void SetUp() { + Initialize(true, false); + } }; -void GLES2ImplementationStrictSharedTest::SetUp() { - Initialize(true, false); -} - // GCC requires these declarations, but MSVC requires they not be present #ifndef _MSC_VER -const uint8 GLES2ImplementationTest::kInitialValue; -const int32 GLES2ImplementationTest::kNumCommandEntries; -const int32 GLES2ImplementationTest::kCommandBufferSizeBytes; -const size_t GLES2ImplementationTest::kTransferBufferSize; const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits; const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize; const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors; @@ -510,7 +565,7 @@ const GLuint GLES2ImplementationTest::kTexturesStartId; #endif TEST_F(GLES2ImplementationTest, ShaderSource) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const GLuint kShaderId = 456; const char* kString1 = "foobar"; const char* kString2 = "barfoo"; @@ -518,12 +573,9 @@ TEST_F(GLES2ImplementationTest, ShaderSource) { const size_t kString2Size = strlen(kString2); const size_t kString3Size = 1; // Want the NULL; const size_t kSourceSize = kString1Size + kString2Size + kString3Size; - const size_t kPaddedString1Size = - transfer_buffer_->RoundToAlignment(kString1Size); - const size_t kPaddedString2Size = - transfer_buffer_->RoundToAlignment(kString2Size); - const size_t kPaddedString3Size = - transfer_buffer_->RoundToAlignment(kString3Size); + const size_t kPaddedString1Size = RoundToAlignment(kString1Size); + const size_t kPaddedString2Size = RoundToAlignment(kString2Size); + const size_t kPaddedString3Size = RoundToAlignment(kString3Size); struct Cmds { cmd::SetBucketSize set_bucket_size; cmd::SetBucketData set_bucket_data1; @@ -535,22 +587,20 @@ TEST_F(GLES2ImplementationTest, ShaderSource) { ShaderSourceBucket shader_source_bucket; cmd::SetBucketSize clear_bucket_size; }; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); - ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size); - Cmds expected; expected.set_bucket_size.Init(kBucketId, kSourceSize); expected.set_bucket_data1.Init( - kBucketId, 0, kString1Size, mem1.id, mem1.offset); + kBucketId, 0, kString1Size, transfer_buffer_id_, + AllocateTransferBuffer(kPaddedString1Size)); expected.set_token1.Init(GetNextToken()); expected.set_bucket_data2.Init( - kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset); + kBucketId, kString1Size, kString2Size, transfer_buffer_id_, + AllocateTransferBuffer(kPaddedString2Size)); expected.set_token2.Init(GetNextToken()); expected.set_bucket_data3.Init( kBucketId, kString1Size + kString2Size, - kString3Size, mem3.id, mem3.offset); + kString3Size, transfer_buffer_id_, + AllocateTransferBuffer(kPaddedString3Size)); expected.set_token3.Init(GetNextToken()); expected.shader_source_bucket.Init(kShaderId, kBucketId); expected.clear_bucket_size.Init(kBucketId, 0); @@ -563,7 +613,7 @@ TEST_F(GLES2ImplementationTest, ShaderSource) { } TEST_F(GLES2ImplementationTest, GetShaderSource) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const GLuint kShaderId = 456; const Str7 kString = {"foobar"}; const char kBad = 0x12; @@ -575,29 +625,25 @@ TEST_F(GLES2ImplementationTest, GetShaderSource) { cmd::SetToken set_token1; cmd::SetBucketSize set_bucket_size2; }; - - ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32)); - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString)); - + uint32 offset = AllocateTransferBuffer(sizeof(kString)); Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_shader_source.Init(kShaderId, kBucketId); - expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), mem1.id, mem1.offset); + kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); char buf[sizeof(kString) + 1]; memset(buf, kBad, sizeof(buf)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString)))) - .WillOnce(SetMemory(mem1.ptr, kString)) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(sizeof(kString)))) + .WillOnce(SetMemoryAtOffset(offset, kString)) .RetiresOnSaturation(); GLsizei length = 0; gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length)); EXPECT_STREQ(kString.str, buf); EXPECT_EQ(buf[sizeof(kString)], kBad); @@ -639,34 +685,33 @@ TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) { arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); const GLsizei kEmuOffset1 = 0; const GLsizei kEmuOffset2 = kSize1; - const GLsizei kTotalSize = kSize1 + kSize2; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2); + const GLsizei kTotalSize = kSize1 + kSize2; Cmds expected; expected.enable1.Init(kAttribIndex1); expected.enable2.Init(kAttribIndex2); expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); expected.copy_data1.Init( - GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset); + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_, + AllocateTransferBuffer(kSize1)); expected.set_token1.Init(GetNextToken()); - expected.set_pointer1.Init( - kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); + expected.set_pointer1.Init(kAttribIndex1, kNumComponents1, + GL_FLOAT, GL_FALSE, 0, kEmuOffset1); expected.copy_data2.Init( - GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset); + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, + AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); - expected.set_pointer2.Init( - kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2); + expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, + GL_FLOAT, GL_FALSE, 0, kEmuOffset2); expected.draw.Init(GL_POINTS, kFirst, kCount); expected.restore.Init(GL_ARRAY_BUFFER, 0); gl_->EnableVertexAttribArray(kAttribIndex1); gl_->EnableVertexAttribArray(kAttribIndex2); - gl_->VertexAttribPointer( - kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts); - gl_->VertexAttribPointer( - kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts); + gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, + GL_FLOAT, GL_FALSE, kClientStride, verts); + gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, + GL_FLOAT, GL_FALSE, kClientStride, verts); gl_->DrawArrays(GL_POINTS, kFirst, kCount); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } @@ -715,12 +760,8 @@ TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) { arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); const GLsizei kEmuOffset1 = 0; const GLsizei kEmuOffset2 = kSize1; - const GLsizei kTotalSize = kSize1 + kSize2; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); - ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); + const GLsizei kTotalSize = kSize1 + kSize2; Cmds expected; expected.enable1.Init(kAttribIndex1); expected.enable2.Init(kAttribIndex2); @@ -728,17 +769,20 @@ TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) { expected.set_index_size.Init( GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW); expected.copy_data0.Init( - GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset); + GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, transfer_buffer_id_, + AllocateTransferBuffer(kIndexSize)); expected.set_token0.Init(GetNextToken()); expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); expected.copy_data1.Init( - GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_, + AllocateTransferBuffer(kSize1)); expected.set_token1.Init(GetNextToken()); - expected.set_pointer1.Init( - kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); + expected.set_pointer1.Init(kAttribIndex1, kNumComponents1, + GL_FLOAT, GL_FALSE, 0, kEmuOffset1); expected.copy_data2.Init( - GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, + AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2); @@ -794,36 +838,33 @@ TEST_F(GLES2ImplementationTest, arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); const GLsizei kEmuOffset1 = 0; const GLsizei kEmuOffset2 = kSize1; - const GLsizei kTotalSize = kSize1 + kSize2; - - ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32)); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); - ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); - + const GLsizei kTotalSize = kSize1 + kSize2; Cmds expected; expected.enable1.Init(kAttribIndex1); expected.enable2.Init(kAttribIndex2); expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId); expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT, - kIndexOffset, mem1.id, mem1.offset); + kIndexOffset, transfer_buffer_id_, 0); expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); expected.copy_data1.Init( - GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_, + AllocateTransferBuffer(kSize1)); expected.set_token1.Init(GetNextToken()); expected.set_pointer1.Init(kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); expected.copy_data2.Init( - GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, + AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2); expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset); expected.restore.Init(GL_ARRAY_BUFFER, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(mem1.ptr,kMaxIndex)) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(kMaxIndex)) .RetiresOnSaturation(); gl_->EnableVertexAttribArray(kAttribIndex1); @@ -856,19 +897,16 @@ TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) { VertexAttribPointer set_pointer; GetVertexAttribPointerv get_pointer; }; - - ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16); - Cmds expected; expected.bind.Init(GL_ARRAY_BUFFER, kBufferId); expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kStride2, kOffset2); expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, - mem1.id, mem1.offset); + transfer_buffer_id_, 0); // One call to flush to way for GetVertexAttribPointerv - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(mem1.ptr, SizedResultHelper<uint32>(kOffset2))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<uint32>(kOffset2))) .RetiresOnSaturation(); // Set one client side buffer. @@ -914,10 +952,6 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) { GetVertexAttribiv get1; // for getting the buffer from attrib2 GetVertexAttribfv get2; // for getting the value from attrib1 }; - - ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16); - ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16); - Cmds expected; expected.enable.Init(kAttribIndex1); expected.bind.Init(GL_ARRAY_BUFFER, kBufferId); @@ -925,19 +959,17 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) { kStride2, kOffset2); expected.get1.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, - mem1.id, mem1.offset); + transfer_buffer_id_, 0); expected.get2.Init(kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, - mem2.id, mem2.offset); + transfer_buffer_id_, 0); FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f); // One call to flush to way for GetVertexAttribiv - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory( - mem1.ptr, SizedResultHelper<GLuint>(kBufferId))) - .WillOnce(SetMemory( - mem2.ptr, SizedResultHelper<FourFloats>(current_attrib))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<GLuint>(kBufferId))) + .WillOnce(SetMemory(SizedResultHelper<FourFloats>(current_attrib))) .RetiresOnSaturation(); gl_->EnableVertexAttribArray(kAttribIndex1); @@ -993,14 +1025,11 @@ TEST_F(GLES2ImplementationTest, ReservedIds) { GetError get; }; Cmds expected; - - ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(GetError::Result)); - - expected.get.Init(mem1.id, mem1.offset); + expected.get.Init(transfer_buffer_id_, 0); // One call to flush to wait for GetError - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); gl_->BindBuffer( @@ -1031,29 +1060,24 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { const GLenum kFormat = GL_RGBA; const GLenum kType = GL_UNSIGNED_BYTE; - ExpectedMemoryInfo mem1 = - GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel); - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(ReadPixels::Result)); - ExpectedMemoryInfo mem2 = - GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(ReadPixels::Result)); - Cmds expected; expected.read1.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - mem1.id, mem1.offset, result1.id, result1.offset); + transfer_buffer_id_, + AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), + transfer_buffer_id_, 0); expected.set_token1.Init(GetNextToken()); expected.read2.Init( 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - mem2.id, mem2.offset, result2.id, result2.offset); + transfer_buffer_id_, + AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), + transfer_buffer_id_, 0); expected.set_token2.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1))) - .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(static_cast<uint32>(1))) + .WillOnce(SetMemory(static_cast<uint32>(1))) .RetiresOnSaturation(); gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get()); @@ -1071,19 +1095,16 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) { const GLenum kFormat = 0; const GLenum kType = 0; - ExpectedMemoryInfo mem1 = - GetExpectedMemory(kWidth * kHeight * kBytesPerPixel); - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(ReadPixels::Result)); - Cmds expected; expected.read.Init( - 0, 0, kWidth, kHeight, kFormat, kType, - mem1.id, mem1.offset, result1.id, result1.offset); + 0, 0, kWidth, kHeight / 2, kFormat, kType, + transfer_buffer_id_, + AllocateTransferBuffer(kWidth * kHeight * kBytesPerPixel), + transfer_buffer_id_, 0); expected.set_token.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); - EXPECT_CALL(*command_buffer(), OnFlush()) + EXPECT_CALL(*command_buffer_, OnFlush(_)) .Times(1) .RetiresOnSaturation(); @@ -1099,18 +1120,17 @@ TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) { const GLintptr kOffset = 15; const GLsizeiptr kSize = 16; - ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize); - + uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, mem1.id, mem1.offset); + kTarget, kOffset, kSize, transfer_buffer_id_, offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( kTarget, kOffset, kSize, GL_WRITE_ONLY); ASSERT_TRUE(mem != NULL); gl_->UnmapBufferSubDataCHROMIUM(mem); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) + EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) .Times(1) .RetiresOnSaturation(); gl_->FreeUnusedSharedMemory(); @@ -1128,8 +1148,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, - command_buffer()->GetNextFreeTransferBufferId(), offset); + kTarget, kOffset, kSize, GetNextFreeTransferBufferId(), offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( @@ -1144,21 +1163,12 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) { const GLintptr kOffset = 15; const GLsizeiptr kSize = 16; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result3 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result4 = - GetExpectedResultMemory(sizeof(GetError::Result)); - // Calls to flush to wait for GetError - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); void* mem; @@ -1193,8 +1203,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) { Cmds expected; expected.tex.Init( GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat, - kType, - command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE); + kType, GetNextFreeTransferBufferId(), offset, GL_FALSE); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapTexSubImage2DCHROMIUM( @@ -1221,30 +1230,15 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) { const GLenum kFormat = GL_RGBA; const GLenum kType = GL_UNSIGNED_BYTE; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result3 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result4 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result5 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result6 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result7 = - GetExpectedResultMemory(sizeof(GetError::Result)); - // Calls to flush to wait for GetError - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); void* mem; @@ -1339,18 +1333,13 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { }; const GLsizei kNumPnames = arraysize(pnames); const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); - const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]); - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize); - ExpectedMemoryInfo result1 = GetExpectedResultMemory( - sizeof(GetError::Result)); - - const uint32 kPnamesOffset = mem1.offset; - const uint32 kResultsOffset = mem1.offset + kPNamesSize; + const uint32 kPnamesOffset = + AllocateTransferBuffer(kNumPnames * sizeof(pnames[0])); + const uint32 kResultsOffset = AllocateTransferBuffer(kResultsSize); Cmds expected; expected.get_multiple.Init( - mem1.id, kPnamesOffset, kNumPnames, - mem1.id, kResultsOffset, kResultsSize); + transfer_buffer_id_, kPnamesOffset, kNumPnames, + transfer_buffer_id_, kResultsOffset, kResultsSize); expected.set_token.Init(GetNextToken()); const GLint kSentinel = 0x12345678; @@ -1360,10 +1349,10 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { 1, 0, 1, 0, 1, -1, }; // One call to flush to wait for results - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize, - returned_results, sizeof(returned_results))) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffsetFromArray( + kResultsOffset, returned_results, sizeof(returned_results))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); gl_->GetMultipleIntegervCHROMIUM( @@ -1385,21 +1374,12 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { const GLsizei kNumPnames = arraysize(pnames); const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result3 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result4 = - GetExpectedResultMemory(sizeof(GetError::Result)); - // Calls to flush to wait for GetError - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); const GLint kSentinel = 0x12345678; @@ -1442,25 +1422,19 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { } TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const GLuint kProgramId = 123; const char kBad = 0x12; GLsizei size = 0; const Str7 kString = {"foobar"}; char buf[20]; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result)); - ExpectedMemoryInfo mem1 = - GetExpectedMemory(sizeof(kString)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - memset(buf, kBad, sizeof(buf)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString)))) - .WillOnce(SetMemory(mem1.ptr, kString)) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) + uint32 offset = AllocateTransferBuffer(sizeof(kString)); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(sizeof(kString)))) + .WillOnce(SetMemoryAtOffset(offset, kString)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); struct Cmds { @@ -1474,9 +1448,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_program_info.Init(kProgramId, kBucketId); - expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), mem1.id, mem1.offset); + kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf); @@ -1488,28 +1462,19 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { } TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const GLuint kProgramId = 123; GLsizei size = 0; const Str7 kString = {"foobar"}; char buf[20]; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result)); - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result3 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result4 = - GetExpectedResultMemory(sizeof(GetError::Result)); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString)))) - .WillOnce(SetMemory(mem1.ptr, kString)) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) + uint32 offset = AllocateTransferBuffer(sizeof(kString)); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(sizeof(kString)))) + .WillOnce(SetMemoryAtOffset(offset, kString)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); // try bufsize not big enough. @@ -1524,9 +1489,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_program_info.Init(kProgramId, kBucketId); - expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), mem1.id, mem1.offset); + kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf); @@ -1581,11 +1546,8 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) { EXPECT_EQ(pv.expected, v); } - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); } @@ -1620,11 +1582,8 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) { EXPECT_EQ(pv.expected, v); } - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); } @@ -1704,13 +1663,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125, 41, 42, 43, 43, 44, 45, 45, 46, 47, }; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels)); - + uint32 offset = AllocateTransferBuffer(sizeof(pixels)); Cmds expected; expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - mem1.id, mem1.offset); + transfer_buffer_id_, offset); expected.set_token.Init(GetNextToken()); gl_->TexImage2D( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, @@ -1718,14 +1675,14 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(CheckRect( kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false, - pixels, mem1.ptr)); + pixels, GetTransferAddressFromOffsetAs<uint8>(offset, sizeof(pixels)))); ClearCommands(); - ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels)); + uint32 offset2 = AllocateTransferBuffer(sizeof(pixels)); Cmds2 expected2; expected2.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - mem2.id, mem2.offset); + transfer_buffer_id_, offset2); expected2.set_token.Init(GetNextToken()); const void* commands2 = GetPut(); gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); @@ -1735,7 +1692,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2))); EXPECT_TRUE(CheckRect( kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true, - pixels, mem2.ptr)); + pixels, GetTransferAddressFromOffsetAs<uint8>(offset2, sizeof(pixels)))); } // Test TexImage2D with 2 writes @@ -1774,29 +1731,27 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { for (uint32 ii = 0; ii < size; ++ii) { pixels[ii] = static_cast<uint8>(ii); } - - ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size); - ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size); - + uint32 offset1 = AllocateTransferBuffer(half_size); + uint32 offset2 = AllocateTransferBuffer(half_size); Cmds expected; expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, - mem1.id, mem1.offset, true); + transfer_buffer_id_, offset1, true); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init( kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - mem2.id, mem2.offset, true); + transfer_buffer_id_, offset2, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test - // EXPECT_CALL(*command_buffer(), OnFlush()) + // EXPECT_CALL(*command_buffer_, OnFlush(_)) // .WillOnce(CheckRectAction( // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, // false, pixels.get(), - // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size))) + // GetTransferAddressFromOffsetAs<uint8>(offset1, half_size))) // .RetiresOnSaturation(); gl_->TexImage2D( @@ -1805,30 +1760,31 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_TRUE(CheckRect( kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false, - pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr)); + pixels.get() + kHeight / 2 * padded_row_size, + GetTransferAddressFromOffsetAs<uint8>(offset2, half_size))); ClearCommands(); const void* commands2 = GetPut(); - ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size); - ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size); + uint32 offset3 = AllocateTransferBuffer(half_size); + uint32 offset4 = AllocateTransferBuffer(half_size); expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - mem3.id, mem3.offset, true); + transfer_buffer_id_, offset3, true); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init( kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, - mem4.id, mem4.offset, true); + transfer_buffer_id_, offset4, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test - // EXPECT_CALL(*command_buffer(), OnFlush()) + // EXPECT_CALL(*command_buffer_, OnFlush(_)) // .WillOnce(CheckRectAction( // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, // true, pixels.get(), - // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size))) + // GetTransferAddressFromOffsetAs<uint8>(offset3, half_size))) // .RetiresOnSaturation(); gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); @@ -1838,7 +1794,145 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected))); EXPECT_TRUE(CheckRect( kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true, - pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr)); + pixels.get() + kHeight / 2 * padded_row_size, + GetTransferAddressFromOffsetAs<uint8>(offset4, half_size))); +} + +// Test TexImage2D with sub rows +TEST_F(GLES2ImplementationTest, TexImage2DSubRows) { + struct Cmds { + TexImage2D tex_image_2d; + TexSubImage2D tex_sub_image_2d1; + cmd::SetToken set_token1; + TexSubImage2D tex_sub_image_2d2; + cmd::SetToken set_token2; + TexSubImage2D tex_sub_image_2d3; + cmd::SetToken set_token3; + TexSubImage2D tex_sub_image_2d4; + cmd::SetToken set_token4; + }; + const GLenum kTarget = GL_TEXTURE_2D; + const GLint kLevel = 0; + const GLenum kFormat = GL_RGB; + const GLint kBorder = 0; + const GLenum kType = GL_UNSIGNED_BYTE; + const GLint kPixelStoreUnpackAlignment = 4; + const GLsizei kHeight = 2; + const GLsizei kWidth = (MaxTransferBufferSize() / 3) * 2; + + uint32 size = 0; + uint32 unpadded_row_size = 0; + uint32 padded_row_size = 0; + ASSERT_TRUE(ComputeImageDataSizes( + kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, + &size, &unpadded_row_size, &padded_row_size)); + uint32 part_size = kWidth * 3 / 2; + + scoped_array<uint8> pixels(new uint8[size]); + for (uint32 ii = 0; ii < size; ++ii) { + pixels[ii] = static_cast<uint8>(ii); + } + uint32 offset1 = AllocateTransferBuffer(part_size); + uint32 offset2 = AllocateTransferBuffer(part_size); + uint32 offset3 = AllocateTransferBuffer(part_size); + uint32 offset4 = AllocateTransferBuffer(part_size); + Cmds expected; + expected.tex_image_2d.Init( + kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, + 0, 0); + expected.tex_sub_image_2d1.Init( + kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset1, true); + expected.set_token1.Init(GetNextToken()); + expected.tex_sub_image_2d2.Init( + kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset2, true); + expected.set_token2.Init(GetNextToken()); + expected.tex_sub_image_2d3.Init( + kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset3, true); + expected.set_token3.Init(GetNextToken()); + expected.tex_sub_image_2d4.Init( + kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset4, true); + expected.set_token4.Init(GetNextToken()); + + // TODO(gman): Make it possible to run this test + // EXPECT_CALL(*command_buffer_, OnFlush(_)) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get(), + // GetTransferAddressFromOffsetAs<uint8>(offset1, part_size))) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get() + part_size, + // GetTransferAddressFromOffsetAs<uint8>(offset2, part_size))) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get() + padded_row_size, + // GetTransferAddressFromOffsetAs<uint8>(offset3, part_size))) + // .RetiresOnSaturation(); + + gl_->TexImage2D( + kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, + pixels.get()); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(CheckRect( + kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + pixels.get() + padded_row_size + part_size, + GetTransferAddressFromOffsetAs<uint8>(offset4, part_size))); + + ClearCommands(); + const void* commands2 = GetPut(); + offset1 = AllocateTransferBuffer(part_size); + offset2 = AllocateTransferBuffer(part_size); + offset3 = AllocateTransferBuffer(part_size); + offset4 = AllocateTransferBuffer(part_size); + expected.tex_image_2d.Init( + kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, + 0, 0); + expected.tex_sub_image_2d1.Init( + kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset1, true); + expected.set_token1.Init(GetNextToken()); + expected.tex_sub_image_2d2.Init( + kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset2, true); + expected.set_token2.Init(GetNextToken()); + expected.tex_sub_image_2d3.Init( + kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset3, true); + expected.set_token3.Init(GetNextToken()); + expected.tex_sub_image_2d4.Init( + kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType, + transfer_buffer_id_, offset4, true); + expected.set_token4.Init(GetNextToken()); + + // TODO(gman): Make it possible to run this test + // EXPECT_CALL(*command_buffer_, OnFlush(_)) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get(), + // GetTransferAddressFromOffsetAs<uint8>(offset1, part_size))) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get() + part_size, + // GetTransferAddressFromOffsetAs<uint8>(offset2, part_size))) + // .WillOnce(CheckRectAction( + // kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + // pixels.get() + padded_row_size, + // GetTransferAddressFromOffsetAs<uint8>(offset3, part_size))) + // .RetiresOnSaturation(); + + gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); + gl_->TexImage2D( + kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, + pixels.get()); + EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected))); + EXPECT_TRUE(CheckRect( + kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, + pixels.get() + padded_row_size + part_size, + GetTransferAddressFromOffsetAs<uint8>(offset4, part_size))); } // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers @@ -1869,9 +1963,8 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { ASSERT_TRUE(GLES2Util::ComputeImageDataSize( kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, &sub_2_high_size)); - - ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size); - ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size); + uint32 offset1 = AllocateTransferBuffer(sub_2_high_size); + uint32 offset2 = AllocateTransferBuffer(sub_2_high_size); Cmds expected; expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment); @@ -1880,11 +1973,11 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { kType, 0, NULL); expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset, kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType, - mem1.id, mem1.offset, false); + transfer_buffer_id_, offset1, false); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset, - kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, - mem2.id, mem2.offset, false); + kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, transfer_buffer_id_, + offset2, false); expected.set_token2.Init(GetNextToken()); gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment); @@ -1907,7 +2000,7 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { EXPECT_TRUE(CheckRect( kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true, reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth), - mem2.ptr)); + GetTransferAddressFromOffsetAs<uint8>(offset2, sub_2_high_size))); } // Test that GenBuffer does not call GenSharedIds. @@ -1948,11 +2041,8 @@ TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { for (size_t ii = 0; ii < num_pairs; ++ii) { const PNameValue& pv = pairs[ii]; GLint v = -1; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetIntegerv::Result)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, - SizedResultHelper<GLuint>(pv.expected))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<GLuint>(pv.expected))) .RetiresOnSaturation(); gl_->GetIntegerv(pv.pname, &v); EXPECT_EQ(pv.expected, v); @@ -1962,26 +2052,13 @@ TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) { GLuint id = 0x12345678; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result3 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result4 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result5 = - GetExpectedResultMemory(sizeof(GetError::Result)); - ExpectedMemoryInfo result6 = - GetExpectedResultMemory(sizeof(GetError::Result)); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR))) - .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); gl_->DeleteBuffers(1, &id); @@ -2001,32 +2078,28 @@ TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) { TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) { const GLuint kTextureId = 123; const GLuint kResult = 456; + const uint32 kResultOffset = 0; struct Cmds { CreateStreamTextureCHROMIUM create_stream; }; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(CreateStreamTextureCHROMIUM::Result)); - ExpectedMemoryInfo result2 = - GetExpectedResultMemory(sizeof(GetError::Result)); - Cmds expected; - expected.create_stream.Init(kTextureId, result1.id, result1.offset); + expected.create_stream.Init(kTextureId, transfer_buffer_id_, kResultOffset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, kResult)) - .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffset(kResultOffset, kResult)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) .RetiresOnSaturation(); GLuint handle = gl_->CreateStreamTextureCHROMIUM(kTextureId); - EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); EXPECT_EQ(handle, kResult); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } TEST_F(GLES2ImplementationTest, GetString) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const Str7 kString = {"foobar"}; // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into // GLES2Implementation. @@ -2040,23 +2113,21 @@ TEST_F(GLES2ImplementationTest, GetString) { cmd::SetToken set_token1; cmd::SetBucketSize set_bucket_size2; }; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result)); - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString)); + uint32 offset = AllocateTransferBuffer(sizeof(kString)); Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_string.Init(GL_EXTENSIONS, kBucketId); - expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), mem1.id, mem1.offset); + kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); char buf[sizeof(kString) + 1]; memset(buf, kBad, sizeof(buf)); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString)))) - .WillOnce(SetMemory(mem1.ptr, kString)) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(sizeof(kString)))) + .WillOnce(SetMemoryAtOffset(offset, kString)) .RetiresOnSaturation(); const GLubyte* result = gl_->GetString(GL_EXTENSIONS); @@ -2065,7 +2136,7 @@ TEST_F(GLES2ImplementationTest, GetString) { } TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) { - const uint32 kBucketId = GLES2Implementation::kResultBucketId; + const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation const Str7 kString = {"foobar"}; struct Cmds { cmd::SetBucketSize set_bucket_size1; @@ -2076,24 +2147,20 @@ TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) { cmd::SetBucketSize set_bucket_size2; PixelStorei pixel_store; }; - - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(cmd::GetBucketSize::Result)); - ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(kString)); - + uint32 offset = AllocateTransferBuffer(sizeof(kString)); Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_string.Init(GL_EXTENSIONS, kBucketId); - expected.get_bucket_size.Init(kBucketId, result1.id, result1.offset); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), mem1.id, mem1.offset); + kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(sizeof(kString)))) - .WillOnce(SetMemory(mem1.ptr, kString)) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(sizeof(kString)))) + .WillOnce(SetMemoryAtOffset(offset, kString)) .RetiresOnSaturation(); gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1); @@ -2123,18 +2190,16 @@ TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) { const unsigned kUsableSize = kTransferBufferSize - GLES2Implementation::kStartingOffset; uint8 buf[kUsableSize * 2] = { 0, }; - - ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize); - ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize); - Cmds expected; expected.set_size.Init( GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW); expected.copy_data1.Init( - GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset); + GL_ARRAY_BUFFER, 0, kUsableSize, transfer_buffer_id_, + AllocateTransferBuffer(kUsableSize)); expected.set_token1.Init(GetNextToken()); expected.copy_data2.Init( - GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset); + GL_ARRAY_BUFFER, kUsableSize, kUsableSize, transfer_buffer_id_, + AllocateTransferBuffer(kUsableSize)); expected.set_token2.Init(GetNextToken()); gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index fae58d97..e8cf5f9 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -130,12 +130,10 @@ TEST_F(GLES2ImplementationTest, CheckFramebufferStatus) { typedef CheckFramebufferStatus::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(CheckFramebufferStatus::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->CheckFramebufferStatus(1); @@ -553,10 +551,9 @@ TEST_F(GLES2ImplementationTest, GetBooleanv) { typedef GetBooleanv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetBooleanv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -570,10 +567,9 @@ TEST_F(GLES2ImplementationTest, GetBufferParameteriv) { typedef GetBufferParameteriv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_BUFFER_SIZE, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_BUFFER_SIZE, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetBufferParameteriv(123, GL_BUFFER_SIZE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -587,10 +583,9 @@ TEST_F(GLES2ImplementationTest, GetFloatv) { typedef GetFloatv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetFloatv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -604,12 +599,11 @@ TEST_F(GLES2ImplementationTest, GetFramebufferAttachmentParameteriv) { typedef GetFramebufferAttachmentParameteriv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); expected.cmd.Init( 123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, - result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetFramebufferAttachmentParameteriv( 123, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, @@ -625,10 +619,9 @@ TEST_F(GLES2ImplementationTest, GetIntegerv) { typedef GetIntegerv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetIntegerv(123, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -642,10 +635,9 @@ TEST_F(GLES2ImplementationTest, GetProgramiv) { typedef GetProgramiv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_DELETE_STATUS, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_DELETE_STATUS, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetProgramiv(123, GL_DELETE_STATUS, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -660,10 +652,9 @@ TEST_F(GLES2ImplementationTest, GetRenderbufferParameteriv) { typedef GetRenderbufferParameteriv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_RENDERBUFFER_RED_SIZE, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_RENDERBUFFER_RED_SIZE, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetRenderbufferParameteriv(123, GL_RENDERBUFFER_RED_SIZE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -677,10 +668,9 @@ TEST_F(GLES2ImplementationTest, GetShaderiv) { typedef GetShaderiv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_SHADER_TYPE, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_SHADER_TYPE, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetShaderiv(123, GL_SHADER_TYPE, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -696,10 +686,9 @@ TEST_F(GLES2ImplementationTest, GetTexParameterfv) { typedef GetTexParameterfv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetTexParameterfv(123, GL_TEXTURE_MAG_FILTER, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -713,10 +702,9 @@ TEST_F(GLES2ImplementationTest, GetTexParameteriv) { typedef GetTexParameteriv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); - expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + expected.cmd.Init(123, GL_TEXTURE_MAG_FILTER, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetTexParameteriv(123, GL_TEXTURE_MAG_FILTER, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -733,11 +721,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttribfv) { typedef GetVertexAttribfv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); expected.cmd.Init( - 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetVertexAttribfv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -751,11 +738,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttribiv) { typedef GetVertexAttribiv::Result Result; Result::Type result = 0; Cmds expected; - ExpectedMemoryInfo result1 = GetExpectedResultMemory(4); expected.cmd.Init( - 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, result1.id, result1.offset); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, SizedResultHelper<Result::Type>(1))) + 123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, transfer_buffer_id_, 0); + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(SizedResultHelper<Result::Type>(1))) .RetiresOnSaturation(); gl_->GetVertexAttribiv(123, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &result); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); @@ -780,12 +766,10 @@ TEST_F(GLES2ImplementationTest, IsBuffer) { typedef IsBuffer::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsBuffer::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsBuffer(1); @@ -800,12 +784,10 @@ TEST_F(GLES2ImplementationTest, IsEnabled) { typedef IsEnabled::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsEnabled::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsEnabled(1); @@ -820,12 +802,10 @@ TEST_F(GLES2ImplementationTest, IsFramebuffer) { typedef IsFramebuffer::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsFramebuffer::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsFramebuffer(1); @@ -840,12 +820,10 @@ TEST_F(GLES2ImplementationTest, IsProgram) { typedef IsProgram::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsProgram::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsProgram(1); @@ -860,12 +838,10 @@ TEST_F(GLES2ImplementationTest, IsRenderbuffer) { typedef IsRenderbuffer::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsRenderbuffer::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsRenderbuffer(1); @@ -880,12 +856,10 @@ TEST_F(GLES2ImplementationTest, IsShader) { typedef IsShader::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsShader::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsShader(1); @@ -900,12 +874,10 @@ TEST_F(GLES2ImplementationTest, IsTexture) { typedef IsTexture::Result Result; Cmds expected; - ExpectedMemoryInfo result1 = - GetExpectedResultMemory(sizeof(IsTexture::Result)); - expected.cmd.Init(1, result1.id, result1.offset); + expected.cmd.Init(1, transfer_buffer_id_, 0); - EXPECT_CALL(*command_buffer(), OnFlush()) - .WillOnce(SetMemory(result1.ptr, uint32(1))) + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemory(uint32(1))) .RetiresOnSaturation(); GLboolean result = gl_->IsTexture(1); diff --git a/gpu/command_buffer/client/ring_buffer.h b/gpu/command_buffer/client/ring_buffer.h index 582d4ee..e3a3980 100644 --- a/gpu/command_buffer/client/ring_buffer.h +++ b/gpu/command_buffer/client/ring_buffer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -165,12 +165,12 @@ class RingBufferWrapper { } // 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) { 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 { + RingBuffer::Offset GetOffset(void* pointer) { return static_cast<int8*>(pointer) - static_cast<int8*>(base_); } diff --git a/gpu/command_buffer/client/transfer_buffer.cc b/gpu/command_buffer/client/transfer_buffer.cc deleted file mode 100644 index 28bb0e6..0000000 --- a/gpu/command_buffer/client/transfer_buffer.cc +++ /dev/null @@ -1,211 +0,0 @@ -// 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. - -// A class to Manage a growing transfer buffer. - -#include "../client/transfer_buffer.h" -#include "../client/cmd_buffer_helper.h" - -namespace gpu { - -AlignedRingBuffer::~AlignedRingBuffer() { -} - -TransferBuffer::TransferBuffer( - CommandBufferHelper* helper) - : helper_(helper), - result_size_(0), - min_buffer_size_(0), - max_buffer_size_(0), - alignment_(), - buffer_id_(-1), - result_buffer_(NULL), - result_shm_offset_(0), - usable_(true) { -} - -TransferBuffer::~TransferBuffer() { - Free(); -} - -bool TransferBuffer::Initialize( - unsigned int starting_buffer_size, - unsigned int result_size, - unsigned int min_buffer_size, - unsigned int max_buffer_size, - unsigned int alignment) { - result_size_ = result_size; - min_buffer_size_ = min_buffer_size; - max_buffer_size_ = max_buffer_size; - alignment_ = alignment; - ReallocateRingBuffer(starting_buffer_size - result_size); - return HaveBuffer(); -} - -void TransferBuffer::Free() { - if (HaveBuffer()) { - helper_->Finish(); - helper_->command_buffer()->DestroyTransferBuffer(buffer_id_); - buffer_id_ = -1; - buffer_.ptr = NULL; - buffer_.size = 0; - result_buffer_ = NULL; - result_shm_offset_ = 0; - ring_buffer_.reset(); - } -} - -bool TransferBuffer::HaveBuffer() const { - return buffer_id_ != -1; -} - -RingBuffer::Offset TransferBuffer::GetOffset(void* pointer) const { - return ring_buffer_->GetOffset(pointer); -} - -void TransferBuffer::FreePendingToken(void* p, unsigned int token) { - ring_buffer_->FreePendingToken(p, token); -} - -void TransferBuffer::AllocateRingBuffer(unsigned int size) { - for (;size >= min_buffer_size_; size /= 2) { - int32 id = helper_->command_buffer()->CreateTransferBuffer(size, -1); - if (id != -1) { - buffer_ = helper_->command_buffer()->GetTransferBuffer(id); - ring_buffer_.reset(new AlignedRingBuffer( - alignment_, - id, - result_size_, - buffer_.size - result_size_, - helper_, - static_cast<char*>(buffer_.ptr) + result_size_)); - buffer_id_ = id; - result_buffer_ = buffer_.ptr; - result_shm_offset_ = 0; - return; - } - // we failed so don't try larger than this. - max_buffer_size_ = size / 2; - } - usable_ = false; -} - -// Returns the integer i such as 2^i <= n < 2^(i+1) -static int Log2Floor(uint32 n) { - if (n == 0) - return -1; - int log = 0; - uint32 value = n; - for (int i = 4; i >= 0; --i) { - int shift = (1 << i); - uint32 x = value >> shift; - if (x != 0) { - value = x; - log += shift; - } - } - GPU_DCHECK_EQ(value, 1u); - return log; -} - -// Returns the integer i such as 2^(i-1) < n <= 2^i -static int Log2Ceiling(uint32 n) { - if (n == 0) { - return -1; - } else { - // Log2Floor returns -1 for 0, so the following works correctly for n=1. - return 1 + Log2Floor(n - 1); - } -} - -static unsigned int ComputePOTSize(unsigned int dimension) { - return (dimension == 0) ? 0 : 1 << Log2Ceiling(dimension); -} - -void TransferBuffer::ReallocateRingBuffer(unsigned int size) { - // What size buffer would we ask for if we needed a new one? - unsigned int needed_buffer_size = ComputePOTSize(size + result_size_); - needed_buffer_size = std::max(needed_buffer_size, min_buffer_size_); - needed_buffer_size = std::min(needed_buffer_size, max_buffer_size_); - - if (usable_ && (!HaveBuffer() || needed_buffer_size > buffer_.size)) { - if (HaveBuffer()) { - Free(); - } - AllocateRingBuffer(needed_buffer_size); - } -} - -void* TransferBuffer::AllocUpTo( - unsigned int size, unsigned int* size_allocated) { - GPU_DCHECK(size_allocated); - - ReallocateRingBuffer(size); - - if (!HaveBuffer()) { - return NULL; - } - - unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize(); - *size_allocated = std::min(max_size, size); - return ring_buffer_->Alloc(*size_allocated); -} - -void* TransferBuffer::Alloc(unsigned int size) { - ReallocateRingBuffer(size); - - if (!HaveBuffer()) { - return NULL; - } - - unsigned int max_size = ring_buffer_->GetLargestFreeOrPendingSize(); - if (size > max_size) { - return NULL; - } - - return ring_buffer_->Alloc(size); -} - -void* TransferBuffer::GetResultBuffer() { - ReallocateRingBuffer(result_size_); - return result_buffer_; -} - -int TransferBuffer::GetResultOffset() { - ReallocateRingBuffer(result_size_); - return result_shm_offset_; -} - -int TransferBuffer::GetShmId() { - ReallocateRingBuffer(result_size_); - return buffer_id_; -} - -unsigned int TransferBuffer::GetCurrentMaxAllocationWithoutRealloc() const { - return HaveBuffer() ? ring_buffer_->GetLargestFreeOrPendingSize() : 0; -} - -unsigned int TransferBuffer::GetMaxAllocation() const { - return HaveBuffer() ? max_buffer_size_ - result_size_ : 0; -} - -void ScopedTransferBufferPtr::Release() { - if (buffer_) { - transfer_buffer_->FreePendingToken(buffer_, helper_->InsertToken()); - buffer_ = NULL; - size_ = 0; - } -} - -void ScopedTransferBufferPtr::Reset(unsigned int new_size) { - Release(); - // NOTE: we allocate buffers of size 0 so that HaveBuffer will be true, so - // that address will return a pointer just like malloc, and so that GetShmId - // will be valid. That has the side effect that we'll insert a token on free. - // We could add code skip the token for a zero size buffer but it doesn't seem - // worth the complication. - buffer_ = transfer_buffer_->AllocUpTo(new_size, &size_); -} - -} // namespace gpu diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h deleted file mode 100644 index 654465c..0000000 --- a/gpu/command_buffer/client/transfer_buffer.h +++ /dev/null @@ -1,221 +0,0 @@ -// 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. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_ - -#include "../common/buffer.h" -#include "../common/compiler_specific.h" -#include "../common/gles2_cmd_utils.h" -#include "../common/scoped_ptr.h" -#include "../client/ring_buffer.h" - -namespace gpu { - -class CommandBufferHelper; - -// Wraps RingBufferWrapper to provide aligned allocations. -class AlignedRingBuffer : public RingBufferWrapper { - public: - AlignedRingBuffer( - unsigned int alignment, - int32 shm_id, - RingBuffer::Offset base_offset, - unsigned int size, - CommandBufferHelper* helper, - void* base) - : RingBufferWrapper(base_offset, size, helper, base), - alignment_(alignment), - shm_id_(shm_id) { - } - ~AlignedRingBuffer(); - - // Hiding Alloc from RingBufferWrapper - void* Alloc(unsigned int size) { - return RingBufferWrapper::Alloc(RoundToAlignment(size)); - } - - int32 GetShmId() const { - return shm_id_; - } - - private: - unsigned int RoundToAlignment(unsigned int size) { - return (size + alignment_ - 1) & ~(alignment_ - 1); - } - - unsigned int alignment_; - int32 shm_id_; -}; - -// Interface for managing the transfer buffer. -class TransferBufferInterface { - public: - TransferBufferInterface() { } - virtual ~TransferBufferInterface() { } - - virtual bool Initialize( - unsigned int buffer_size, - unsigned int result_size, - unsigned int min_buffer_size, - unsigned int max_buffer_size, - unsigned int alignment) = 0; - - virtual int GetShmId() = 0; - virtual void* GetResultBuffer() = 0; - virtual int GetResultOffset() = 0; - - virtual void Free() = 0; - - virtual bool HaveBuffer() const = 0; - - // Allocates up to size bytes. - virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0; - - // Allocates size bytes. - // Note: Alloc will fail if it can not return size bytes. - virtual void* Alloc(unsigned int size) = 0; - - virtual RingBuffer::Offset GetOffset(void* pointer) const = 0; - - virtual void FreePendingToken(void* p, unsigned int token) = 0; -}; - -// Class that manages the transfer buffer. -class TransferBuffer : public TransferBufferInterface { - public: - TransferBuffer(CommandBufferHelper* helper); - virtual ~TransferBuffer(); - - // Overridden from TransferBufferInterface. - virtual bool Initialize( - unsigned int buffer_size, - unsigned int result_size, - unsigned int min_buffer_size, - unsigned int max_buffer_size, - unsigned int alignment) OVERRIDE; - virtual int GetShmId() OVERRIDE; - virtual void* GetResultBuffer() OVERRIDE; - virtual int GetResultOffset() OVERRIDE; - virtual void Free() OVERRIDE; - virtual bool HaveBuffer() const OVERRIDE; - virtual void* AllocUpTo( - unsigned int size, unsigned int* size_allocated) OVERRIDE; - virtual void* Alloc(unsigned int size) OVERRIDE; - virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE; - virtual void FreePendingToken(void* p, unsigned int token) OVERRIDE; - - // These are for testing. - unsigned int GetCurrentMaxAllocationWithoutRealloc() const; - unsigned int GetMaxAllocation() const; - - private: - // Tries to reallocate the ring buffer if it's not large enough for size. - void ReallocateRingBuffer(unsigned int size); - - void AllocateRingBuffer(unsigned int size); - - CommandBufferHelper* helper_; - scoped_ptr<AlignedRingBuffer> ring_buffer_; - - // size reserved for results - unsigned int result_size_; - - // min size we'll consider successful - unsigned int min_buffer_size_; - - // max size we'll let the buffer grow - unsigned int max_buffer_size_; - - // alignment for allocations - unsigned int alignment_; - - // the current buffer. - gpu::Buffer buffer_; - - // id of buffer. -1 = no buffer - int32 buffer_id_; - - // address of result area - void* result_buffer_; - - // offset to result area - uint32 result_shm_offset_; - - // false if we failed to allocate min_buffer_size - bool usable_; -}; - -// A class that will manage the lifetime of a transferbuffer allocation. -class ScopedTransferBufferPtr { - public: - ScopedTransferBufferPtr( - unsigned int size, - CommandBufferHelper* helper, - TransferBufferInterface* transfer_buffer) - : buffer_(NULL), - size_(0), - helper_(helper), - transfer_buffer_(transfer_buffer) { - Reset(size); - } - - ~ScopedTransferBufferPtr() { - Release(); - } - - bool valid() const { - return buffer_ != NULL; - } - - unsigned int size() const { - return size_; - } - - int shm_id() const { - return transfer_buffer_->GetShmId(); - } - - RingBuffer::Offset offset() const { - return transfer_buffer_->GetOffset(buffer_); - } - - void* address() const { - return buffer_; - } - - void Release(); - - void Reset(unsigned int new_size); - - private: - void* buffer_; - unsigned int size_; - CommandBufferHelper* helper_; - TransferBufferInterface* transfer_buffer_; - DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr); -}; - -template <typename T> -class ScopedTransferBufferArray : public ScopedTransferBufferPtr { - public: - ScopedTransferBufferArray( - unsigned int num_elements, - CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer) - : ScopedTransferBufferPtr( - num_elements * sizeof(T), helper, transfer_buffer) { - } - - T* elements() { - return static_cast<T*>(address()); - } - - unsigned int num_elements() const { - return size() / sizeof(T); - } -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_ diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc deleted file mode 100644 index 26b2057..0000000 --- a/gpu/command_buffer/client/transfer_buffer_unittest.cc +++ /dev/null @@ -1,434 +0,0 @@ -// 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. - -// Tests for the Command Buffer Helper. - -#include "gpu/command_buffer/client/transfer_buffer.h" - -#include "gpu/command_buffer/client/client_test_helper.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/command_buffer/common/compiler_specific.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" - -using ::testing::_; -using ::testing::Invoke; -using ::testing::Return; -using ::testing::StrictMock; - -namespace gpu { - -class TransferBufferTest : public testing::Test { - protected: - static const int32 kNumCommandEntries = 400; - static const int32 kCommandBufferSizeBytes = - kNumCommandEntries * sizeof(CommandBufferEntry); - static const unsigned int kStartingOffset = 64; - static const unsigned int kAlignment = 4; - static const size_t kTransferBufferSize = 256; - - TransferBufferTest() - : transfer_buffer_id_(0) { - } - - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; - - MockClientCommandBuffer* command_buffer() const { - return command_buffer_.get(); - } - - scoped_ptr<MockClientCommandBuffer> command_buffer_; - scoped_ptr<CommandBufferHelper> helper_; - scoped_ptr<TransferBuffer> transfer_buffer_; - int32 transfer_buffer_id_; -}; - -void TransferBufferTest::SetUp() { - command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); - ASSERT_TRUE(command_buffer_->Initialize()); - - helper_.reset(new CommandBufferHelper(command_buffer())); - ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes)); - - transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId(); - - transfer_buffer_.reset(new TransferBuffer(helper_.get())); - ASSERT_TRUE(transfer_buffer_->Initialize( - kTransferBufferSize, - kStartingOffset, - kTransferBufferSize, - kTransferBufferSize, - kAlignment)); -} - -void TransferBufferTest::TearDown() { - if (transfer_buffer_->HaveBuffer()) { - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - } - transfer_buffer_.reset(); -} - -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER -const int32 TransferBufferTest::kNumCommandEntries; -const int32 TransferBufferTest::kCommandBufferSizeBytes; -const unsigned int TransferBufferTest::kStartingOffset; -const unsigned int TransferBufferTest::kAlignment; -const size_t TransferBufferTest::kTransferBufferSize; -#endif - -TEST_F(TransferBufferTest, Basic) { - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); - EXPECT_EQ( - kTransferBufferSize - kStartingOffset, - transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); -} - -TEST_F(TransferBufferTest, Free) { - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - // See that it gets reallocated. - EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - // See that it gets reallocated. - EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL); - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - // See that it gets reallocated. - unsigned int size = 0; - void* data = transfer_buffer_->AllocUpTo(1, &size); - EXPECT_TRUE(data != NULL); - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - transfer_buffer_->FreePendingToken(data, 1); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - // See that it gets reallocated. - transfer_buffer_->GetResultOffset(); - EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - - EXPECT_EQ( - kTransferBufferSize - kStartingOffset, - transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - - // Test freeing twice. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - transfer_buffer_->Free(); -} - -TEST_F(TransferBufferTest, TooLargeAllocation) { - // Check that we can't allocate large than max size. - void* ptr = transfer_buffer_->Alloc(kTransferBufferSize + 1); - EXPECT_TRUE(ptr == NULL); - // Check we if we try to allocate larger than max we get max. - unsigned int size_allocated = 0; - ptr = transfer_buffer_->AllocUpTo( - kTransferBufferSize + 1, &size_allocated); - ASSERT_TRUE(ptr != NULL); - EXPECT_EQ(kTransferBufferSize - kStartingOffset, size_allocated); - transfer_buffer_->FreePendingToken(ptr, 1); -} - -class MockClientCommandBufferCanFail : public MockClientCommandBuffer { - public: - MockClientCommandBufferCanFail() { - } - virtual ~MockClientCommandBufferCanFail() { - } - - MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request)); - - int32 RealCreateTransferBuffer(size_t size, int32 id_request) { - return MockCommandBufferBase::CreateTransferBuffer(size, id_request); - } -}; - -class TransferBufferExpandContractTest : public testing::Test { - protected: - static const int32 kNumCommandEntries = 400; - static const int32 kCommandBufferSizeBytes = - kNumCommandEntries * sizeof(CommandBufferEntry); - static const unsigned int kStartingOffset = 64; - static const unsigned int kAlignment = 4; - static const size_t kStartTransferBufferSize = 256; - static const size_t kMaxTransferBufferSize = 1024; - static const size_t kMinTransferBufferSize = 128; - - TransferBufferExpandContractTest() - : transfer_buffer_id_(0) { - } - - virtual void SetUp() OVERRIDE; - virtual void TearDown() OVERRIDE; - - MockClientCommandBufferCanFail* command_buffer() const { - return command_buffer_.get(); - } - - scoped_ptr<MockClientCommandBufferCanFail> command_buffer_; - scoped_ptr<CommandBufferHelper> helper_; - scoped_ptr<TransferBuffer> transfer_buffer_; - int32 transfer_buffer_id_; -}; - -void TransferBufferExpandContractTest::SetUp() { - command_buffer_.reset(new StrictMock<MockClientCommandBufferCanFail>()); - ASSERT_TRUE(command_buffer_->Initialize()); - - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kCommandBufferSizeBytes, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - helper_.reset(new CommandBufferHelper(command_buffer())); - ASSERT_TRUE(helper_->Initialize(kCommandBufferSizeBytes)); - - transfer_buffer_id_ = command_buffer()->GetNextFreeTransferBufferId(); - - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kStartTransferBufferSize, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - transfer_buffer_.reset(new TransferBuffer(helper_.get())); - ASSERT_TRUE(transfer_buffer_->Initialize( - kStartTransferBufferSize, - kStartingOffset, - kMinTransferBufferSize, - kMaxTransferBufferSize, - kAlignment)); -} - -void TransferBufferExpandContractTest::TearDown() { - if (transfer_buffer_->HaveBuffer()) { - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - } - transfer_buffer_.reset(); -} - -// GCC requires these declarations, but MSVC requires they not be present -#ifndef _MSC_VER -const int32 TransferBufferExpandContractTest::kNumCommandEntries; -const int32 TransferBufferExpandContractTest::kCommandBufferSizeBytes; -const unsigned int TransferBufferExpandContractTest::kStartingOffset; -const unsigned int TransferBufferExpandContractTest::kAlignment; -const size_t TransferBufferExpandContractTest::kStartTransferBufferSize; -const size_t TransferBufferExpandContractTest::kMaxTransferBufferSize; -const size_t TransferBufferExpandContractTest::kMinTransferBufferSize; -#endif - -TEST_F(TransferBufferExpandContractTest, Expand) { - // Check it starts at starting size. - EXPECT_EQ( - kStartTransferBufferSize - kStartingOffset, - transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kStartTransferBufferSize * 2, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - // Try next power of 2. - const size_t kSize1 = 512 - kStartingOffset; - unsigned int size_allocated = 0; - void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated); - ASSERT_TRUE(ptr != NULL); - EXPECT_EQ(kSize1, size_allocated); - EXPECT_EQ(kSize1, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - transfer_buffer_->FreePendingToken(ptr, 1); - - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kMaxTransferBufferSize, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - // Try next power of 2. - const size_t kSize2 = 1024 - kStartingOffset; - ptr = transfer_buffer_->AllocUpTo(kSize2, &size_allocated); - ASSERT_TRUE(ptr != NULL); - EXPECT_EQ(kSize2, size_allocated); - EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - transfer_buffer_->FreePendingToken(ptr, 1); - - // Try next one more. Should not go past max. - size_allocated = 0; - const size_t kSize3 = kSize2 + 1; - ptr = transfer_buffer_->AllocUpTo(kSize3, &size_allocated); - EXPECT_EQ(kSize2, size_allocated); - EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - transfer_buffer_->FreePendingToken(ptr, 1); -} - -TEST_F(TransferBufferExpandContractTest, Contract) { - // Check it starts at starting size. - EXPECT_EQ( - kStartTransferBufferSize - kStartingOffset, - transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - - // Try to allocate again, fail first request - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kStartTransferBufferSize, _)) - .WillOnce(Return(-1)) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kMinTransferBufferSize, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - const size_t kSize1 = 256 - kStartingOffset; - const size_t kSize2 = 128 - kStartingOffset; - unsigned int size_allocated = 0; - void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated); - ASSERT_TRUE(ptr != NULL); - EXPECT_EQ(kSize2, size_allocated); - EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - transfer_buffer_->FreePendingToken(ptr, 1); - - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - - // Try to allocate again, - EXPECT_CALL(*command_buffer(), - CreateTransferBuffer(kMinTransferBufferSize, _)) - .WillOnce(Invoke( - command_buffer(), - &MockClientCommandBufferCanFail::RealCreateTransferBuffer)) - .RetiresOnSaturation(); - - ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated); - ASSERT_TRUE(ptr != NULL); - EXPECT_EQ(kSize2, size_allocated); - EXPECT_EQ(kSize2, transfer_buffer_->GetCurrentMaxAllocationWithoutRealloc()); - transfer_buffer_->FreePendingToken(ptr, 1); -} - -TEST_F(TransferBufferExpandContractTest, OutOfMemory) { - // Free buffer. - EXPECT_CALL(*command_buffer(), OnFlush()) - .Times(1) - .RetiresOnSaturation(); - EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) - .Times(1) - .RetiresOnSaturation(); - transfer_buffer_->Free(); - // See it's freed. - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); - - // Try to allocate again, fail both requests. - EXPECT_CALL(*command_buffer(), CreateTransferBuffer(_, _)) - .WillOnce(Return(-1)) - .WillOnce(Return(-1)) - .WillOnce(Return(-1)) - .RetiresOnSaturation(); - - const size_t kSize1 = 512 - kStartingOffset; - unsigned int size_allocated = 0; - void* ptr = transfer_buffer_->AllocUpTo(kSize1, &size_allocated); - ASSERT_TRUE(ptr == NULL); - EXPECT_FALSE(transfer_buffer_->HaveBuffer()); -} - -} // namespace gpu - - diff --git a/gpu/command_buffer/common/compiler_specific.h b/gpu/command_buffer/common/compiler_specific.h deleted file mode 100644 index 8cbc713..0000000 --- a/gpu/command_buffer/common/compiler_specific.h +++ /dev/null @@ -1,23 +0,0 @@ -// 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. - -#ifndef GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ -#define GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ -#pragma once - -// Annotate a virtual method indicating it must be overriding a virtual -// method in the parent class. -// Use like: -// virtual void foo() OVERRIDE; -#ifndef OVERRIDE -#ifdef _MSC_VER -#define OVERRIDE override -#elif defined(__clang__) -#define OVERRIDE override -#else -#define OVERRIDE -#endif -#endif - -#endif // GPU_COMMAND_BUFFER_COMMON_COMPILER_SPECIFIC_H_ diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 722eaf0..ca07a25 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,7 +10,6 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/demos/framework/demo.h" #include "gpu/demos/framework/demo_factory.h" @@ -20,7 +19,6 @@ using gpu::CommandBufferService; using gpu::GpuScheduler; using gpu::gles2::GLES2CmdHelper; using gpu::gles2::GLES2Implementation; -using gpu::TransferBuffer; namespace { const int32 kCommandBufferSize = 1024 * 1024; @@ -105,24 +103,19 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { if (!gles2_cmd_helper_->Initialize(kCommandBufferSize)) return false; - transfer_buffer_.reset(new gpu::TransferBuffer(gles2_cmd_helper_.get())); + int32 transfer_buffer_id = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); + Buffer transfer_buffer = + command_buffer_->GetTransferBuffer(transfer_buffer_id); + if (transfer_buffer.ptr == NULL) return false; ::gles2::Initialize(); - GLES2Implementation* gles2_implementation = new GLES2Implementation( - gles2_cmd_helper_.get(), - transfer_buffer_.get(), - false, - true); - - ::gles2::SetGLContext(gles2_implementation); - - if (!gles2_implementation->Initialize( - kTransferBufferSize, - kTransferBufferSize, - kTransferBufferSize)) { - return false; - } - + ::gles2::SetGLContext(new GLES2Implementation(gles2_cmd_helper_.get(), + transfer_buffer.size, + transfer_buffer.ptr, + transfer_buffer_id, + false, + true)); return true; } diff --git a/gpu/demos/framework/window.h b/gpu/demos/framework/window.h index 80b8b67..4c6cd46 100644 --- a/gpu/demos/framework/window.h +++ b/gpu/demos/framework/window.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -15,9 +15,6 @@ #include "ui/gfx/native_widget_types.h" namespace gpu { - -class TransferBuffer; - namespace demos { class Demo; @@ -55,7 +52,6 @@ class Window { scoped_refptr<gfx::GLContext> context_; scoped_refptr<gfx::GLSurface> surface_; scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_; - scoped_ptr<gpu::TransferBuffer> transfer_buffer_; DISALLOW_COPY_AND_ASSIGN(Window); }; diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 1b540f4..47fcd51 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/gles2_conform_support/egl/config.h" #include "gpu/gles2_conform_support/egl/surface.h" @@ -22,7 +21,8 @@ namespace egl { Display::Display(EGLNativeDisplayType display_id) : display_id_(display_id), - is_initialized_(false) { + is_initialized_(false), + transfer_buffer_id_(-1) { } Display::~Display() { @@ -131,11 +131,15 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config, if (!cmd_helper->Initialize(kCommandBufferSize)) return false; - scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer( - cmd_helper.get())); + int32 transfer_buffer_id = + command_buffer->CreateTransferBuffer(kTransferBufferSize, -1); + gpu::Buffer transfer_buffer = + command_buffer->GetTransferBuffer(transfer_buffer_id); + if (transfer_buffer.ptr == NULL) + return false; command_buffer_.reset(command_buffer.release()); - transfer_buffer_.reset(transfer_buffer.release()); + transfer_buffer_id_ = transfer_buffer_id; gles2_cmd_helper_.reset(cmd_helper.release()); surface_.reset(new Surface(win)); @@ -167,26 +171,23 @@ EGLContext Display::CreateContext(EGLConfig config, EGLContext share_ctx, const EGLint* attrib_list) { DCHECK(IsValidConfig(config)); - // TODO(alokp): Add support for shared contexts. + // TODO(alokp): Command buffer does not support shared contexts. if (share_ctx != NULL) return EGL_NO_CONTEXT; DCHECK(command_buffer_ != NULL); - DCHECK(transfer_buffer_.get()); + DCHECK(transfer_buffer_id_ != -1); + gpu::Buffer buffer = command_buffer_->GetTransferBuffer(transfer_buffer_id_); + DCHECK(buffer.ptr != NULL); bool share_resources = share_ctx != NULL; context_.reset(new gpu::gles2::GLES2Implementation( gles2_cmd_helper_.get(), - transfer_buffer_.get(), + buffer.size, + buffer.ptr, + transfer_buffer_id_, share_resources, true)); - if (!context_->Initialize( - kTransferBufferSize / 2, - kTransferBufferSize, - kTransferBufferSize * 2)) { - return EGL_NO_CONTEXT; - } - context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets"); context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs"); diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h index f7e20e8..19571b3 100644 --- a/gpu/gles2_conform_support/egl/display.h +++ b/gpu/gles2_conform_support/egl/display.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -19,7 +19,6 @@ namespace gpu { class CommandBufferService; class GpuScheduler; -class TransferBuffer; namespace gles2 { class GLES2CmdHelper; @@ -72,7 +71,7 @@ class Display { scoped_refptr<gfx::GLContext> gl_context_; scoped_refptr<gfx::GLSurface> gl_surface_; scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_; - scoped_ptr<gpu::TransferBuffer> transfer_buffer_; + int32 transfer_buffer_id_; // TODO(alokp): Support more than one config, surface, and context. scoped_ptr<Config> config_; diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index c24c4d1..f9f945b 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -51,7 +51,6 @@ 'command_buffer/common/cmd_buffer_common.h', 'command_buffer/common/cmd_buffer_common.cc', 'command_buffer/common/command_buffer.h', - 'command_buffer/common/compiler_specific.h', 'command_buffer/common/constants.h', 'command_buffer/common/gles2_cmd_ids_autogen.h', 'command_buffer/common/gles2_cmd_ids.h', @@ -199,8 +198,6 @@ 'command_buffer/client/mapped_memory.h', 'command_buffer/client/ring_buffer.cc', 'command_buffer/client/ring_buffer.h', - 'command_buffer/client/transfer_buffer.cc', - 'command_buffer/client/transfer_buffer.h', ], }, { @@ -305,15 +302,12 @@ ], 'sources': [ '<@(gles2_c_lib_source_files)', - 'command_buffer/client/client_test_helper.cc', - 'command_buffer/client/client_test_helper.h', 'command_buffer/client/cmd_buffer_helper_test.cc', 'command_buffer/client/fenced_allocator_test.cc', 'command_buffer/client/gles2_implementation_unittest.cc', 'command_buffer/client/mapped_memory_unittest.cc', 'command_buffer/client/program_info_manager_unittest.cc', 'command_buffer/client/ring_buffer_test.cc', - 'command_buffer/client/transfer_buffer_unittest.cc', 'command_buffer/common/bitfield_helpers_test.cc', 'command_buffer/common/command_buffer_mock.cc', 'command_buffer/common/command_buffer_mock.h', |