diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-07 22:06:18 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-07 22:06:18 +0000 |
commit | bb62ce3d7922d0bd07b066f6460c7cd00f946011 (patch) | |
tree | 22657f3db7f64c7b8ace37bb2a3d4d1e2426cba0 /gpu | |
parent | 481a6d899f7c9a4d3e029fa6553f6bec589b5564 (diff) | |
download | chromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.zip chromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.tar.gz chromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.tar.bz2 |
Revert "Revert 113250 - Add CommandBuffer::SetGetBuffer"
This reverts commit bd45bd252aeb8babac62547a5c605fbf64287cd3.
TEST=ran webkit tests in DRT and webgl tests in chrome
BUG=103989
Review URL: http://codereview.chromium.org/8758026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
23 files changed, 368 insertions, 269 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index 6328923..d43efc3 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -17,6 +17,8 @@ const double kFlushDelay = 1.0 / (5.0 * 60.0); CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) : command_buffer_(command_buffer), + ring_buffer_id_(-1), + ring_buffer_size_(0), entries_(NULL), total_entry_count_(0), usable_entry_count_(0), @@ -27,14 +29,25 @@ CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) last_flush_time_(0) { } -bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { - ring_buffer_ = command_buffer_->GetRingBuffer(); +bool CommandBufferHelper::AllocateRingBuffer() { + int32 id = command_buffer_->CreateTransferBuffer(ring_buffer_size_, -1); + if (id < 0) { + return false; + } + + ring_buffer_ = command_buffer_->GetTransferBuffer(id); if (!ring_buffer_.ptr) return false; + ring_buffer_id_ = id; + command_buffer_->SetGetBuffer(id); + + // TODO(gman): Do we really need to call GetState here? We know get & put = 0 + // Also do we need to check state.num_entries? CommandBuffer::State state = command_buffer_->GetState(); entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr); - int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry); + int32 num_ring_buffer_entries = + ring_buffer_size_ / sizeof(CommandBufferEntry); if (num_ring_buffer_entries > state.num_entries) { return false; } @@ -48,6 +61,11 @@ bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { return true; } +bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { + ring_buffer_size_ = ring_buffer_size; + return AllocateRingBuffer(); +} + CommandBufferHelper::~CommandBufferHelper() { } diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h index b6f45e2..5fbf462 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/gpu/command_buffer/client/cmd_buffer_helper.h @@ -214,6 +214,10 @@ class CommandBufferHelper { return command_buffer_; } + Buffer get_ring_buffer() const { + return ring_buffer_; + } + private: // Waits until get changes, updating the value of get_. void WaitForGetChange(); @@ -224,9 +228,13 @@ class CommandBufferHelper { usable_entry_count_; } + bool AllocateRingBuffer(); + CommandBuffer* command_buffer_; + int32 ring_buffer_id_; + int32 ring_buffer_size_; Buffer ring_buffer_; - CommandBufferEntry *entries_; + CommandBufferEntry* entries_; int32 total_entry_count_; // the total number of entries int32 usable_entry_count_; // the usable number (ie, minus space for jump) int32 token_; diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc index 3b314c4..216bb60 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -66,15 +66,9 @@ class CommandBufferHelperTest : public testing::Test { .WillRepeatedly(Return(error::kNoError)); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(kCommandBufferSizeBytes); - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + command_buffer_->Initialize(); - parser_ = new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - api_mock_.get()); + parser_ = new CommandParser(api_mock_.get()); do_jump_command_.reset(new DoJumpCommand(parser_)); EXPECT_CALL(*api_mock_, DoCommand(cmd::kJump, _, _)) @@ -90,6 +84,12 @@ class CommandBufferHelperTest : public testing::Test { helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kCommandBufferSizeBytes); + + // Note: parser->SetBuffer would normally be called through + // helper_->Initialize but currently it needs a GpuCommandBufferStub as the + // CommandBuffer instead of the CommandBufferService for that to happen. + Buffer ring_buffer = helper_->get_ring_buffer(); + parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size); } virtual void TearDown() { diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc index 417b26a..ebd8ff6 100644 --- a/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/gpu/command_buffer/client/fenced_allocator_test.cc @@ -45,15 +45,9 @@ class BaseFencedAllocatorTest : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(kBufferSize); - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + command_buffer_->Initialize(); - parser_ = new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - api_mock_.get()); + parser_ = new CommandParser(api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -64,6 +58,12 @@ class BaseFencedAllocatorTest : public testing::Test { helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); + + // Note: parser->SetBuffer would normally be called through + // helper_->Initialize but currently it needs a GpuCommandBufferStub as the + // CommandBuffer instead of the CommandBufferService for that to happen. + Buffer ring_buffer = helper_->get_ring_buffer(); + parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size); } int32 GetToken() { diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 5ce2a8b..4c6013d 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -15,34 +15,30 @@ #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS #endif +using testing::_; +using testing::DoAll; +using testing::InSequence; +using testing::Invoke; +using testing::Mock; +using testing::Sequence; +using testing::Truly; +using testing::Return; + namespace gpu { class GLES2MockCommandBufferHelper : public CommandBuffer { public: - static const int32 kTransferBufferId = 0x123; + static const int32 kTransferBufferBaseId = 0x123; + static const int32 kMaxTransferBuffers = 6; GLES2MockCommandBufferHelper() { } virtual ~GLES2MockCommandBufferHelper() { } // CommandBuffer implementation: - virtual bool Initialize(int32 size) { - ring_buffer_.reset(new CommandBufferEntry[size]); - ring_buffer_buffer_.ptr = ring_buffer_.get(); - ring_buffer_buffer_.size = size; - state_.num_entries = size / sizeof(ring_buffer_[0]); - state_.token = 10000; // All token checks in the tests should pass. + virtual bool Initialize() { return true; } - virtual bool Initialize(base::SharedMemory* buffer, int32 size) { - GPU_NOTREACHED(); - return false; - } - - virtual Buffer GetRingBuffer() { - return ring_buffer_buffer_; - } - virtual State GetState() { return state_; } @@ -58,28 +54,57 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { virtual State FlushSync(int32 put_offset, int32 last_known_get) { state_.put_offset = put_offset; state_.get_offset = put_offset; - OnFlush(transfer_buffer_buffer_.ptr); + // 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) { - transfer_buffer_.reset(new int8[size]); - transfer_buffer_buffer_.ptr = transfer_buffer_.get(); - transfer_buffer_buffer_.size = size; - return kTransferBufferId; + 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; } - virtual void DestroyTransferBuffer(int32 /* id */) { - GPU_NOTREACHED(); + 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_EQ(id, kTransferBufferId); - return transfer_buffer_buffer_; + GPU_DCHECK_GE(id, kTransferBufferBaseId); + GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); + return transfer_buffer_buffers_[id - kTransferBufferBaseId]; } virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -107,39 +132,41 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { virtual void OnFlush(void* transfer_buffer) = 0; private: - scoped_array<int8> transfer_buffer_; - Buffer transfer_buffer_buffer_; - scoped_array<CommandBufferEntry> ring_buffer_; + 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::kTransferBufferId; +const int32 GLES2MockCommandBufferHelper::kTransferBufferBaseId; +const int32 GLES2MockCommandBufferHelper::kMaxTransferBuffers; #endif namespace gles2 { -using testing::_; -using testing::DoAll; -using testing::InSequence; -using testing::Invoke; -using testing::Mock; -using testing::Sequence; -using testing::Truly; -using testing::Return; - ACTION_P(SetMemory, obj) { memcpy(arg0, &obj, sizeof(obj)); } @@ -194,8 +221,6 @@ class GLES2CommandBufferTestBase : public testing::Test { static const int32 kCommandBufferSizeBytes = kNumCommandEntries * sizeof(CommandBufferEntry); static const size_t kTransferBufferSize = 256; - static const int32 kTransferBufferId = - GLES2MockCommandBufferHelper::kTransferBufferId; static const uint8 kInitialValue = 0xBD; GLES2CommandBufferTestBase() @@ -203,7 +228,8 @@ class GLES2CommandBufferTestBase : public testing::Test { token_(0), offset_(0), initial_offset_(0), - alignment_(0) { + alignment_(0), + transfer_buffer_id_(-1) { } void SetupCommandBuffer(unsigned int offset, unsigned alignment) { @@ -212,11 +238,11 @@ class GLES2CommandBufferTestBase : public testing::Test { alignment_ = alignment; command_buffer_.reset(new MockGLES2CommandBuffer()); - command_buffer_->Initialize(kCommandBufferSizeBytes); + command_buffer_->Initialize(); - EXPECT_EQ(kTransferBufferId, - command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); - transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); + transfer_buffer_id_ = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); + transfer_buffer_ = command_buffer_->GetTransferBuffer(transfer_buffer_id_); ClearTransferBuffer(); helper_.reset(new GLES2CmdHelper(command_buffer_.get())); @@ -232,7 +258,7 @@ class GLES2CommandBufferTestBase : public testing::Test { } void ClearCommands() { - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + Buffer ring_buffer = helper_->get_ring_buffer(); memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); } @@ -253,6 +279,10 @@ class GLES2CommandBufferTestBase : public testing::Test { return ++token_; } + int32 GetNextFreeTransferBufferId() { + return command_buffer_->GetNextFreeTransferBufferId(); + } + uint32 AllocateTransferBuffer(size_t size) { if (offset_ + size > kTransferBufferSize) { offset_ = initial_offset_; @@ -280,6 +310,7 @@ class GLES2CommandBufferTestBase : public testing::Test { uint32 offset_; uint32 initial_offset_; uint32 alignment_; + int32 transfer_buffer_id_; }; // GCC requires these declarations, but MSVC requires they not be present @@ -287,7 +318,6 @@ class GLES2CommandBufferTestBase : public testing::Test { const int32 GLES2CommandBufferTestBase::kNumCommandEntries; const int32 GLES2CommandBufferTestBase::kCommandBufferSizeBytes; const size_t GLES2CommandBufferTestBase::kTransferBufferSize; -const int32 GLES2CommandBufferTestBase::kTransferBufferId; const uint8 GLES2CommandBufferTestBase::kInitialValue; #endif @@ -303,9 +333,12 @@ class TransferBufferTest : public GLES2CommandBufferTestBase { GLES2Implementation::kStartingOffset, GLES2Implementation::kAlignment); + transfer_buffer_id_ = + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); + transfer_buffer_.reset(new TransferBuffer( helper_.get(), - kTransferBufferId, + transfer_buffer_id_, GetTransferAddressFromOffset(0, 0), kTransferBufferSize, kStartingOffset, @@ -327,7 +360,7 @@ const unsigned int TransferBufferTest::kAlignment; TEST_F(TransferBufferTest, Basic) { EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); + EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); } TEST_F(TransferBufferTest, Free) { @@ -341,7 +374,7 @@ TEST_F(TransferBufferTest, Free) { // See it's freed. EXPECT_FALSE(transfer_buffer_->HaveBuffer()); // See that it gets reallocated. - EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); + EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); EXPECT_TRUE(transfer_buffer_->HaveBuffer()); // Free buffer. @@ -473,7 +506,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase { helper_.get(), kTransferBufferSize, transfer_buffer_.ptr, - kTransferBufferId, + transfer_buffer_id_, shared_resources, bind_generates_resource)); } @@ -482,7 +515,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase { .Times(1) .RetiresOnSaturation(); helper_->CommandBufferHelper::Finish(); - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + Buffer ring_buffer = helper_->get_ring_buffer(); commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + command_buffer_->GetState().put_offset; ClearCommands(); @@ -525,16 +558,16 @@ TEST_F(GLES2ImplementationTest, ShaderSource) { Cmds expected; expected.set_bucket_size.Init(kBucketId, kSourceSize); expected.set_bucket_data1.Init( - kBucketId, 0, kString1Size, kTransferBufferId, + kBucketId, 0, kString1Size, transfer_buffer_id_, AllocateTransferBuffer(kPaddedString1Size)); expected.set_token1.Init(GetNextToken()); expected.set_bucket_data2.Init( - kBucketId, kString1Size, kString2Size, kTransferBufferId, + kBucketId, kString1Size, kString2Size, transfer_buffer_id_, AllocateTransferBuffer(kPaddedString2Size)); expected.set_token2.Init(GetNextToken()); expected.set_bucket_data3.Init( kBucketId, kString1Size + kString2Size, - kString3Size, kTransferBufferId, + kString3Size, transfer_buffer_id_, AllocateTransferBuffer(kPaddedString3Size)); expected.set_token3.Init(GetNextToken()); expected.shader_source_bucket.Init(kShaderId, kBucketId); @@ -564,9 +597,9 @@ TEST_F(GLES2ImplementationTest, GetShaderSource) { Cmds expected; expected.set_bucket_size1.Init(kBucketId, 0); expected.get_shader_source.Init(kShaderId, kBucketId); - expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), kTransferBufferId, 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]; @@ -628,13 +661,13 @@ TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) { 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, kTransferBufferId, + 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, kTransferBufferId, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -704,19 +737,19 @@ 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, kTransferBufferId, + 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, kTransferBufferId, + 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, kTransferBufferId, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -780,17 +813,17 @@ TEST_F(GLES2ImplementationTest, expected.enable2.Init(kAttribIndex2); expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId); expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT, - kIndexOffset, kTransferBufferId, 0); + 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, kTransferBufferId, + 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, kTransferBufferId, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -837,7 +870,7 @@ TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) { expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kStride2, kOffset2); expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, - kTransferBufferId, 0); + transfer_buffer_id_, 0); // One call to flush to way for GetVertexAttribPointerv EXPECT_CALL(*command_buffer_, OnFlush(_)) @@ -894,10 +927,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) { kStride2, kOffset2); expected.get1.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, - kTransferBufferId, 0); + transfer_buffer_id_, 0); expected.get2.Init(kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, - kTransferBufferId, 0); + transfer_buffer_id_, 0); FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f); @@ -960,7 +993,7 @@ TEST_F(GLES2ImplementationTest, ReservedIds) { GetError get; }; Cmds expected; - expected.get.Init(kTransferBufferId, 0); + expected.get.Init(transfer_buffer_id_, 0); // One call to flush to wait for GetError EXPECT_CALL(*command_buffer_, OnFlush(_)) @@ -998,15 +1031,15 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { Cmds expected; expected.read1.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - kTransferBufferId, + transfer_buffer_id_, AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), - kTransferBufferId, 0); + transfer_buffer_id_, 0); expected.set_token1.Init(GetNextToken()); expected.read2.Init( 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - kTransferBufferId, + transfer_buffer_id_, AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), - kTransferBufferId, 0); + transfer_buffer_id_, 0); expected.set_token2.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); @@ -1033,9 +1066,9 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) { Cmds expected; expected.read.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - kTransferBufferId, + transfer_buffer_id_, AllocateTransferBuffer(kWidth * kHeight * kBytesPerPixel), - kTransferBufferId, 0); + transfer_buffer_id_, 0); expected.set_token.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); @@ -1058,7 +1091,7 @@ TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) { uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, kTransferBufferId, offset); + kTarget, kOffset, kSize, transfer_buffer_id_, offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( @@ -1083,7 +1116,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, kTransferBufferId, offset); + kTarget, kOffset, kSize, GetNextFreeTransferBufferId(), offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( @@ -1138,7 +1171,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) { Cmds expected; expected.tex.Init( GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat, - kType, kTransferBufferId, offset, GL_FALSE); + kType, GetNextFreeTransferBufferId(), offset, GL_FALSE); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapTexSubImage2DCHROMIUM( @@ -1273,8 +1306,8 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { const uint32 kResultsOffset = AllocateTransferBuffer(kResultsSize); Cmds expected; expected.get_multiple.Init( - kTransferBufferId, kPnamesOffset, kNumPnames, - kTransferBufferId, kResultsOffset, kResultsSize); + transfer_buffer_id_, kPnamesOffset, kNumPnames, + transfer_buffer_id_, kResultsOffset, kResultsSize); expected.set_token.Init(GetNextToken()); const GLint kSentinel = 0x12345678; @@ -1383,9 +1416,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, kTransferBufferId, 0); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), kTransferBufferId, 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); @@ -1424,9 +1457,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, kTransferBufferId, 0); + expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), kTransferBufferId, 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); @@ -1602,7 +1635,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { Cmds expected; expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - kTransferBufferId, offset); + transfer_buffer_id_, offset); expected.set_token.Init(GetNextToken()); gl_->TexImage2D( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, @@ -1617,7 +1650,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { Cmds2 expected2; expected2.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - kTransferBufferId, offset2); + transfer_buffer_id_, offset2); expected2.set_token.Init(GetNextToken()); const void* commands2 = GetPut(); gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); @@ -1674,11 +1707,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, - kTransferBufferId, offset1, 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, - kTransferBufferId, offset2, true); + transfer_buffer_id_, offset2, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1707,11 +1740,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - kTransferBufferId, offset3, 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, - kTransferBufferId, offset4, true); + transfer_buffer_id_, offset4, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1777,19 +1810,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType, - kTransferBufferId, offset1, true); + 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, - kTransferBufferId, offset2, true); + 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, - kTransferBufferId, offset3, true); + 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, - kTransferBufferId, offset4, true); + transfer_buffer_id_, offset4, true); expected.set_token4.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1828,19 +1861,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType, - kTransferBufferId, offset1, true); + 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, - kTransferBufferId, offset2, true); + 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, - kTransferBufferId, offset3, true); + 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, - kTransferBufferId, offset4, true); + transfer_buffer_id_, offset4, true); expected.set_token4.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1908,10 +1941,10 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { kType, 0, NULL); expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset, kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType, - kTransferBufferId, offset1, 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, kTransferBufferId, + kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, transfer_buffer_id_, offset2, false); expected.set_token2.Init(GetNextToken()); @@ -2020,7 +2053,7 @@ TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) { }; Cmds expected; - expected.create_stream.Init(kTextureId, kTransferBufferId, kResultOffset); + expected.create_stream.Init(kTextureId, transfer_buffer_id_, kResultOffset); EXPECT_CALL(*command_buffer_, OnFlush(_)) .WillOnce(SetMemoryAtOffset(kResultOffset, kResult)) diff --git a/gpu/command_buffer/client/mapped_memory_unittest.cc b/gpu/command_buffer/client/mapped_memory_unittest.cc index 81b6655..c18ec9f 100644 --- a/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -42,15 +42,9 @@ class MappedMemoryTestBase : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(kBufferSize); - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + command_buffer_->Initialize(); - parser_ = new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - api_mock_.get()); + parser_ = new CommandParser(api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -61,6 +55,12 @@ class MappedMemoryTestBase : public testing::Test { helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); + + // Note: parser->SetBuffer would normally be called through + // helper_->Initialize but currently it needs a GpuCommandBufferStub as the + // CommandBuffer instead of the CommandBufferService for that to happen. + Buffer ring_buffer = helper_->get_ring_buffer(); + parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size); } int32 GetToken() { diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc index eb5a0cb..8b8e46e 100644 --- a/gpu/command_buffer/client/ring_buffer_test.cc +++ b/gpu/command_buffer/client/ring_buffer_test.cc @@ -65,15 +65,9 @@ class BaseRingBufferTest : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(kBufferSize); - Buffer ring_buffer = command_buffer_->GetRingBuffer(); + command_buffer_->Initialize(); - parser_ = new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - api_mock_.get()); + parser_ = new CommandParser(api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -88,6 +82,12 @@ class BaseRingBufferTest : public testing::Test { helper_.reset(new CommandBufferHelper(command_buffer_.get())); helper_->Initialize(kBufferSize); + + // Note: parser->SetBuffer would normally be called through + // helper_->Initialize but currently it needs a GpuCommandBufferStub as the + // CommandBuffer instead of the CommandBufferService for that to happen. + Buffer ring_buffer = helper_->get_ring_buffer(); + parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size); } int32 GetToken() { diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h index 76124c8..e44df7f 100644 --- a/gpu/command_buffer/common/command_buffer.h +++ b/gpu/command_buffer/common/command_buffer.h @@ -67,13 +67,7 @@ class CommandBuffer { } // Initialize the command buffer with the given size. - virtual bool Initialize(int32 size) = 0; - - // Initialize the command buffer using the given preallocated buffer. - virtual bool Initialize(base::SharedMemory* buffer, int32 size) = 0; - - // Gets the ring buffer for the command buffer. - virtual Buffer GetRingBuffer() = 0; + virtual bool Initialize() = 0; // Returns the current status. virtual State GetState() = 0; @@ -92,6 +86,10 @@ class CommandBuffer { // have been executed. virtual State FlushSync(int32 put_offset, int32 last_known_get) = 0; + // Sets the buffer commands are read from. + // Also resets the get and put offsets to 0. + virtual void SetGetBuffer(int32 transfer_buffer_id) = 0; + // Sets the current get offset. This can be called from any thread. virtual void SetGetOffset(int32 get_offset) = 0; diff --git a/gpu/command_buffer/common/command_buffer_mock.cc b/gpu/command_buffer/common/command_buffer_mock.cc index d92c2c3..6ed2eee 100644 --- a/gpu/command_buffer/common/command_buffer_mock.cc +++ b/gpu/command_buffer/common/command_buffer_mock.cc @@ -7,8 +7,6 @@ namespace gpu { MockCommandBuffer::MockCommandBuffer() { - ON_CALL(*this, GetRingBuffer()) - .WillByDefault(testing::Return(Buffer())); ON_CALL(*this, GetTransferBuffer(testing::_)) .WillByDefault(testing::Return(Buffer())); } diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h index 321c40d..0379340 100644 --- a/gpu/command_buffer/common/command_buffer_mock.h +++ b/gpu/command_buffer/common/command_buffer_mock.h @@ -21,13 +21,12 @@ class MockCommandBuffer : public CommandBuffer { MockCommandBuffer(); virtual ~MockCommandBuffer(); - MOCK_METHOD1(Initialize, bool(int32 size)); - MOCK_METHOD2(Initialize, bool(base::SharedMemory* buffer, int32 size)); - MOCK_METHOD0(GetRingBuffer, Buffer()); + MOCK_METHOD0(Initialize, bool()); MOCK_METHOD0(GetState, State()); MOCK_METHOD0(GetLastState, State()); MOCK_METHOD1(Flush, void(int32 put_offset)); MOCK_METHOD2(FlushSync, State(int32 put_offset, int32 last_known_get)); + MOCK_METHOD1(SetGetBuffer, void(int32 transfer_buffer_id)); MOCK_METHOD1(SetGetOffset, void(int32 get_offset)); MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request)); MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle)); diff --git a/gpu/command_buffer/service/cmd_buffer_engine.h b/gpu/command_buffer/service/cmd_buffer_engine.h index 59e99ab..6aefe82 100644 --- a/gpu/command_buffer/service/cmd_buffer_engine.h +++ b/gpu/command_buffer/service/cmd_buffer_engine.h @@ -29,6 +29,9 @@ class CommandBufferEngine { // Sets the token value. virtual void set_token(int32 token) = 0; + // Sets the shared memory buffer used for commands. + virtual bool SetGetBuffer(int32 transfer_buffer_id) = 0; + // Sets the "get" pointer. Return false if offset is out of range. virtual bool SetGetOffset(int32 offset) = 0; diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc index fba06e6..b5383af 100644 --- a/gpu/command_buffer/service/cmd_parser.cc +++ b/gpu/command_buffer/service/cmd_parser.cc @@ -10,23 +10,29 @@ namespace gpu { -CommandParser::CommandParser(void *shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size, - CommandBufferOffset start_get, - AsyncAPIInterface *handler) - : get_(start_get), - put_(start_get), +CommandParser::CommandParser(AsyncAPIInterface* handler) + : get_(0), + put_(0), + buffer_(NULL), + entry_count_(0), handler_(handler) { +} + +void CommandParser::SetBuffer( + void* shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size) { // check proper alignments. DCHECK_EQ(0, (reinterpret_cast<intptr_t>(shm_address)) % 4); DCHECK_EQ(0, offset % 4); DCHECK_EQ(0u, size % 4); // check that the command buffer fits into the memory buffer. DCHECK_GE(shm_size, offset + size); - char * buffer_begin = static_cast<char *>(shm_address) + offset; - buffer_ = reinterpret_cast<CommandBufferEntry *>(buffer_begin); + get_ = 0; + put_ = 0; + char* buffer_begin = static_cast<char*>(shm_address) + offset; + buffer_ = reinterpret_cast<CommandBufferEntry*>(buffer_begin); entry_count_ = size / 4; } diff --git a/gpu/command_buffer/service/cmd_parser.h b/gpu/command_buffer/service/cmd_parser.h index fe3eb12..567b7f6 100644 --- a/gpu/command_buffer/service/cmd_parser.h +++ b/gpu/command_buffer/service/cmd_parser.h @@ -18,12 +18,14 @@ class AsyncAPIInterface; // buffer, to implement some asynchronous RPC mechanism. class CommandParser { public: - CommandParser(void *shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size, - CommandBufferOffset start_get, - AsyncAPIInterface *handler); + explicit CommandParser(AsyncAPIInterface* handler); + + // Sets the buffer to read commands from. + void SetBuffer( + void* shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size); // Gets the "get" pointer. The get pointer is an index into the command // buffer considered as an array of CommandBufferEntry. @@ -63,9 +65,9 @@ class CommandParser { private: CommandBufferOffset get_; CommandBufferOffset put_; - CommandBufferEntry *buffer_; + CommandBufferEntry* buffer_; int32 entry_count_; - AsyncAPIInterface *handler_; + AsyncAPIInterface* handler_; }; // This class defines the interface for an asynchronous API handler, that diff --git a/gpu/command_buffer/service/cmd_parser_test.cc b/gpu/command_buffer/service/cmd_parser_test.cc index 857ca8e..b86b0af 100644 --- a/gpu/command_buffer/service/cmd_parser_test.cc +++ b/gpu/command_buffer/service/cmd_parser_test.cc @@ -48,12 +48,10 @@ class CommandParserTest : public testing::Test { size_t command_buffer_size = entry_count * sizeof(CommandBufferEntry); // NOLINT DCHECK_LE(command_buffer_size, shm_size); - return new CommandParser(buffer(), - shm_size, - 0, - command_buffer_size, - 0, - api_mock()); + CommandParser* parser = new CommandParser(api_mock()); + + parser->SetBuffer(buffer(), shm_size, 0, command_buffer_size); + return parser; } unsigned int buffer_entry_count() { return 20; } @@ -288,4 +286,34 @@ TEST_F(CommandParserTest, TestError) { Mock::VerifyAndClearExpectations(api_mock()); } +TEST_F(CommandParserTest, SetBuffer) { + scoped_ptr<CommandParser> parser(MakeParser(3)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add a single command, no args + header.size = 2; + header.command = 123; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 456; + + CommandBufferEntry param_array[1]; + param_array[0].value_int32 = 456; + + parser->set_put(put); + AddDoCommandExpect(error::kNoError, 123, 1, param_array); + EXPECT_EQ(error::kNoError, parser->ProcessAllCommands()); + // We should have advanced 2 entries + EXPECT_EQ(2, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + scoped_array<CommandBufferEntry> buffer2(new CommandBufferEntry[2]); + parser->SetBuffer( + buffer2.get(), sizeof(CommandBufferEntry) * 2, 0, + sizeof(CommandBufferEntry) * 2); + // The put and get should have reset to 0. + EXPECT_EQ(0, parser->get()); + EXPECT_EQ(0, parser->put()); +} + } // namespace gpu diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc index d126883..4047d1c 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc @@ -14,7 +14,8 @@ using ::base::SharedMemory; namespace gpu { CommandBufferService::CommandBufferService() - : num_entries_(0), + : ring_buffer_id_(-1), + num_entries_(0), get_offset_(0), put_offset_(0), token_(0), @@ -25,71 +26,16 @@ CommandBufferService::CommandBufferService() } CommandBufferService::~CommandBufferService() { - delete ring_buffer_.shared_memory; - for (size_t i = 0; i < registered_objects_.size(); ++i) { if (registered_objects_[i].shared_memory) delete registered_objects_[i].shared_memory; } } -bool CommandBufferService::Initialize(int32 size) { - // Fail if already initialized. - if (ring_buffer_.shared_memory) { - LOG(ERROR) << "Failed because already initialized."; - return false; - } - - if (size <= 0 || size > kMaxCommandBufferSize) { - LOG(ERROR) << "Failed because command buffer size was invalid."; - return false; - } - - num_entries_ = size / sizeof(CommandBufferEntry); - - SharedMemory shared_memory; - if (!shared_memory.CreateAnonymous(size)) { - LOG(ERROR) << "Failed to create shared memory for command buffer."; - return true; - } - - return Initialize(&shared_memory, size); -} - -bool CommandBufferService::Initialize(base::SharedMemory* buffer, int32 size) { - // Fail if already initialized. - if (ring_buffer_.shared_memory) { - LOG(ERROR) << "Failed because already initialized."; - return false; - } - - base::SharedMemoryHandle shared_memory_handle; - if (!buffer->ShareToProcess(base::GetCurrentProcessHandle(), - &shared_memory_handle)) { - LOG(ERROR) << "Failed to duplicate command buffer shared memory handle."; - return false; - } - - ring_buffer_.shared_memory = new base::SharedMemory(shared_memory_handle, - false); - if (!ring_buffer_.shared_memory->Map(size)) { - LOG(ERROR) << "Failed because ring buffer could not be created or mapped "; - delete ring_buffer_.shared_memory; - ring_buffer_.shared_memory = NULL; - return false; - } - - ring_buffer_.ptr = ring_buffer_.shared_memory->memory(); - ring_buffer_.size = size; - num_entries_ = size / sizeof(CommandBufferEntry); - +bool CommandBufferService::Initialize() { return true; } -Buffer CommandBufferService::GetRingBuffer() { - return ring_buffer_; -} - CommandBufferService::State CommandBufferService::GetState() { State state; state.num_entries = num_entries_; @@ -134,6 +80,20 @@ void CommandBufferService::Flush(int32 put_offset) { put_offset_change_callback_.Run(); } +void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) { + DCHECK_EQ(-1, ring_buffer_id_); + DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. + ring_buffer_ = GetTransferBuffer(transfer_buffer_id); + DCHECK(ring_buffer_.ptr); + ring_buffer_id_ = transfer_buffer_id; + num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry); + put_offset_ = 0; + SetGetOffset(0); + if (!get_buffer_change_callback_.is_null()) { + get_buffer_change_callback_.Run(ring_buffer_id_); + } +} + void CommandBufferService::SetGetOffset(int32 get_offset) { DCHECK(get_offset >= 0 && get_offset < num_entries_); get_offset_ = get_offset; @@ -223,6 +183,14 @@ void CommandBufferService::DestroyTransferBuffer(int32 handle) { registered_objects_[handle] = Buffer(); unused_registered_object_elements_.insert(handle); + if (handle == ring_buffer_id_) { + ring_buffer_id_ = -1; + ring_buffer_ = Buffer(); + num_entries_ = 0; + get_offset_ = 0; + put_offset_ = 0; + } + // Remove all null objects from the end of the vector. This allows the vector // to shrink when, for example, all objects are unregistered. Note that this // loop never removes element zero, which is always NULL. @@ -266,6 +234,11 @@ void CommandBufferService::SetPutOffsetChangeCallback( put_offset_change_callback_ = callback; } +void CommandBufferService::SetGetBufferChangeCallback( + const GetBufferChangedCallback& callback) { + get_buffer_change_callback_ = callback; +} + void CommandBufferService::SetParseErrorCallback( const base::Closure& callback) { parse_error_callback_ = callback; diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index b48bd90..d7ea6fc 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h @@ -21,17 +21,17 @@ namespace gpu { // API to manage the put and get pointers. class CommandBufferService : public CommandBuffer { public: + typedef base::Callback<bool(int32)> GetBufferChangedCallback; CommandBufferService(); virtual ~CommandBufferService(); // CommandBuffer implementation: - virtual bool Initialize(int32 size) OVERRIDE; - virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE; - virtual Buffer GetRingBuffer() OVERRIDE; + 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(int32 transfer_buffer_id) OVERRIDE; virtual void SetGetOffset(int32 get_offset) OVERRIDE; virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE; virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -52,14 +52,19 @@ class CommandBufferService : public CommandBuffer { // attempting to write more to the command buffer. Takes ownership of // callback. virtual void SetPutOffsetChangeCallback(const base::Closure& callback); + // Sets a callback that is called whenever the get buffer is changed. + virtual void SetGetBufferChangeCallback( + const GetBufferChangedCallback& callback); virtual void SetParseErrorCallback(const base::Closure& callback); private: + int32 ring_buffer_id_; Buffer ring_buffer_; int32 num_entries_; int32 get_offset_; int32 put_offset_; base::Closure put_offset_change_callback_; + GetBufferChangedCallback get_buffer_change_callback_; base::Closure parse_error_callback_; std::vector<Buffer> registered_objects_; std::set<int32> unused_registered_object_elements_; diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc index a240948..571ffa0 100644 --- a/gpu/command_buffer/service/common_decoder_unittest.cc +++ b/gpu/command_buffer/service/common_decoder_unittest.cc @@ -116,6 +116,12 @@ class MockCommandBufferEngine : public CommandBufferEngine { } // Overridden from CommandBufferEngine. + virtual bool SetGetBuffer(int32 transfer_buffer_id) { + NOTREACHED(); + return false; + } + + // Overridden from CommandBufferEngine. virtual bool SetGetOffset(int32 offset) { if (static_cast<size_t>(offset) < kBufferSize) { get_offset_ = offset; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 92abfc0..a57df77 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -431,6 +431,11 @@ class GLES2DecoderTestBase : public testing::Test { DCHECK(false); } + virtual bool SetGetBuffer(int32 /* transfer_buffer_id */) OVERRIDE { + DCHECK(false); + return false; + } + // Overridden from CommandBufferEngine. virtual bool SetGetOffset(int32 offset) OVERRIDE { DCHECK(false); diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index f37c1a0..610f401 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -29,21 +29,6 @@ GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, decoder_(decoder), parser_(parser), unscheduled_count_(0) { - // Map the ring buffer and create the parser. - if (!parser) { - Buffer ring_buffer = command_buffer_->GetRingBuffer(); - if (ring_buffer.ptr) { - parser_.reset(new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - decoder_)); - } else { - parser_.reset(new CommandParser(NULL, 0, 0, 0, 0, - decoder_)); - } - } } GpuScheduler::~GpuScheduler() { @@ -150,6 +135,26 @@ void GpuScheduler::set_token(int32 token) { command_buffer_->SetToken(token); } +bool GpuScheduler::SetGetBuffer(int32 transfer_buffer_id) { + Buffer ring_buffer = command_buffer_->GetTransferBuffer(transfer_buffer_id); + if (!ring_buffer.ptr) { + return false; + } + + if (!parser_.get()) { + parser_.reset(new CommandParser(decoder_)); + } + + parser_->SetBuffer( + ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size); + + SetGetOffset(0); + return true; +} + bool GpuScheduler::SetGetOffset(int32 offset) { if (parser_->set_get(offset)) { command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 5256e49..9b7d9cd 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -51,6 +51,7 @@ class GpuScheduler // Implementation of CommandBufferEngine. virtual Buffer GetSharedMemoryBuffer(int32 shm_id) OVERRIDE; virtual void set_token(int32 token) OVERRIDE; + virtual bool SetGetBuffer(int32 transfer_buffer_id) OVERRIDE; virtual bool SetGetOffset(int32 offset) OVERRIDE; virtual int32 GetGetOffset() OVERRIDE; diff --git a/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/gpu/command_buffer/service/gpu_scheduler_unittest.cc index 2d230ec..cf881e6 100644 --- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc +++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc @@ -30,6 +30,8 @@ const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry); class GpuSchedulerTest : public testing::Test { protected: + static const int32 kTransferBufferId = 123; + virtual void SetUp() { shared_memory_.reset(new ::base::SharedMemory); shared_memory_->CreateAndMapAnonymous(kRingBufferSize); @@ -39,28 +41,20 @@ class GpuSchedulerTest : public testing::Test { memset(buffer_, 0, kRingBufferSize); command_buffer_.reset(new MockCommandBuffer); - ON_CALL(*command_buffer_.get(), GetRingBuffer()) - .WillByDefault(Return(shared_memory_buffer_)); CommandBuffer::State default_state; default_state.num_entries = kRingBufferEntries; ON_CALL(*command_buffer_.get(), GetState()) .WillByDefault(Return(default_state)); - async_api_.reset(new StrictMock<AsyncAPIMock>); - decoder_.reset(new gles2::MockGLES2Decoder()); - - parser_ = new CommandParser(buffer_, - kRingBufferEntries, - 0, - kRingBufferEntries, - 0, - async_api_.get()); - scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(), - parser_)); + NULL)); + EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) + .WillOnce(Return(shared_memory_buffer_)); + EXPECT_CALL(*command_buffer_, SetGetOffset(0)); + EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); } virtual void TearDown() { @@ -82,8 +76,6 @@ class GpuSchedulerTest : public testing::Test { Buffer shared_memory_buffer_; int32* buffer_; scoped_ptr<gles2::MockGLES2Decoder> decoder_; - CommandParser* parser_; - scoped_ptr<AsyncAPIMock> async_api_; scoped_ptr<GpuScheduler> scheduler_; }; @@ -100,6 +92,24 @@ TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) { scheduler_->PutChanged(); } +TEST_F(GpuSchedulerTest, GetSetBuffer) { + CommandBuffer::State state; + + // Set the get offset to something not 0. + EXPECT_CALL(*command_buffer_, SetGetOffset(2)); + scheduler_->SetGetOffset(2); + EXPECT_EQ(2, scheduler_->GetGetOffset()); + + // Set the buffer. + EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) + .WillOnce(Return(shared_memory_buffer_)); + EXPECT_CALL(*command_buffer_, SetGetOffset(0)); + EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); + + // Check the get offset was reset. + EXPECT_EQ(0, scheduler_->GetGetOffset()); +} + TEST_F(GpuSchedulerTest, ProcessesOneCommand) { CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); header[0].command = 7; @@ -113,7 +123,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) { .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetParseError(_)) @@ -136,11 +146,11 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { EXPECT_CALL(*command_buffer_, GetState()) .WillRepeatedly(Return(state)); - EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) + EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetGetOffset(3)); @@ -158,11 +168,12 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { EXPECT_CALL(*command_buffer_, GetState()) .WillRepeatedly(Return(state)); - EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0])) .WillOnce(Return( error::kUnknownCommand)); EXPECT_CALL(*command_buffer_, SetGetOffset(1)); + EXPECT_CALL(*command_buffer_, SetContextLostReason(_)); EXPECT_CALL(*decoder_, GetContextLostReason()) .WillOnce(Return(error::kUnknown)); EXPECT_CALL(*command_buffer_, diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 526f9da..48ed58c 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -54,7 +54,7 @@ void Window::OnPaint() { bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { command_buffer_.reset(new CommandBufferService); - if (!command_buffer_->Initialize(kCommandBufferSize)) { + if (!command_buffer_->Initialize()) { return false; } diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 18c9727..928d5fd 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -32,7 +32,7 @@ Display::~Display() { bool Display::Initialize() { scoped_ptr<gpu::CommandBufferService> command_buffer( new gpu::CommandBufferService); - if (!command_buffer->Initialize(kCommandBufferSize)) + if (!command_buffer->Initialize()) return false; int32 transfer_buffer_id = |