diff options
author | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 20:21:44 +0000 |
---|---|---|
committer | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 20:21:44 +0000 |
commit | bd45bd252aeb8babac62547a5c605fbf64287cd3 (patch) | |
tree | 97cbf2f8bec035b6cf77c723a4b3b89c61338d79 | |
parent | 32b6bae0bccbf704fbd07085e6334af7c90957f2 (diff) | |
download | chromium_src-bd45bd252aeb8babac62547a5c605fbf64287cd3.zip chromium_src-bd45bd252aeb8babac62547a5c605fbf64287cd3.tar.gz chromium_src-bd45bd252aeb8babac62547a5c605fbf64287cd3.tar.bz2 |
Revert 113250 - Add CommandBuffer::SetGetBuffer
As well as remove CommandBuffer::GetRingBuffer and
change CommandBuffer::Initialize
Before this change the service allocated and managed the command buffer.
After this change the client uses CreateTransferBuffer, GetTransferBuffer,
end potentially DeleteTransferBufffer to manage the command buffer.
Another CL will actually make the client delete the command buffer
on demand.
TEST=unit tests and run some samples and a NaCl 3D game
BUG=103989
Review URL: http://codereview.chromium.org/8566059
TBR=gman@chromium.org
Review URL: http://codereview.chromium.org/8827005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113255 0039d316-1c4b-4281-b951-d872f2087c98
47 files changed, 541 insertions, 485 deletions
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 6a8b4af..af478e0 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -87,8 +87,6 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, OnInitialize); - IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, - OnSetGetBuffer); IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent, OnSetParent); IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState); @@ -161,6 +159,8 @@ void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { } void GpuCommandBufferStub::OnInitialize( + base::SharedMemoryHandle ring_buffer, + int32 size, IPC::Message* reply_message) { DCHECK(!command_buffer_.get()); @@ -168,7 +168,19 @@ void GpuCommandBufferStub::OnInitialize( command_buffer_.reset(new gpu::CommandBufferService); - if (!command_buffer_->Initialize()) { +#if defined(OS_WIN) + // Windows dups the shared memory handle it receives into the current process + // and closes it when this variable goes out of scope. + base::SharedMemory shared_memory(ring_buffer, + false, + channel_->renderer_process()); +#else + // POSIX receives a dup of the shared memory handle and closes the dup when + // this variable goes out of scope. + base::SharedMemory shared_memory(ring_buffer, false); +#endif + + if (!command_buffer_->Initialize(&shared_memory, size)) { DLOG(ERROR) << "CommandBufferService failed to initialize.\n"; OnInitializeFailed(reply_message); return; @@ -275,12 +287,6 @@ void GpuCommandBufferStub::OnInitialize( "offscreen", surface_->IsOffscreen()); } -void GpuCommandBufferStub::OnSetGetBuffer( - int32 shm_id, IPC::Message* reply_message) { - scheduler_->SetGetBuffer(shm_id); - Send(reply_message); -} - void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, uint32 parent_texture_id, IPC::Message* reply_message) { diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 2124192..f581593 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -90,8 +90,9 @@ class GpuCommandBufferStub void OnInitializeFailed(IPC::Message* reply_message); // Message handlers: - void OnInitialize(IPC::Message* reply_message); - void OnSetGetBuffer(int32 shm_id, IPC::Message* reply_message); + void OnInitialize(base::SharedMemoryHandle ring_buffer, + int32 size, + IPC::Message* reply_message); void OnSetParent(int32 parent_route_id, uint32 parent_texture_id, IPC::Message* reply_message); diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 7099747..e5cab60 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -311,13 +311,11 @@ IPC_MESSAGE_CONTROL0(GpuChannelMsg_CloseChannel) // Initialize a command buffer with the given number of command entries. // Returns the shared memory handle for the command buffer mapped to the // calling process. -IPC_SYNC_MESSAGE_ROUTED0_1(GpuCommandBufferMsg_Initialize, +IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_Initialize, + base::SharedMemoryHandle /* ring_buffer */, + int32 /* size */, bool /* result */) -// Sets the shared memory buffer used for commands. -IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_SetGetBuffer, - int32 /* shm_id */) - // Sets the parent command buffer. This allows the parent and child to share // textures. IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_SetParent, diff --git a/content/renderer/gpu/command_buffer_proxy.cc b/content/renderer/gpu/command_buffer_proxy.cc index d51f840..86420ae 100644 --- a/content/renderer/gpu/command_buffer_proxy.cc +++ b/content/renderer/gpu/command_buffer_proxy.cc @@ -25,7 +25,8 @@ using gpu::Buffer; CommandBufferProxy::CommandBufferProxy( GpuChannelHost* channel, int route_id) - : channel_(channel), + : num_entries_(0), + channel_(channel), route_id_(route_id), flush_count_(0) { } @@ -92,13 +93,41 @@ void CommandBufferProxy::SetChannelErrorCallback( channel_error_callback_ = callback; } -bool CommandBufferProxy::Initialize() { +bool CommandBufferProxy::Initialize(int32 size) { + DCHECK(!ring_buffer_.get()); + ChildThread* child_thread = ChildThread::current(); if (!child_thread) return false; + base::SharedMemoryHandle handle; + if (!child_thread->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( + size, + &handle))) { + return false; + } + + if (!base::SharedMemory::IsHandleValid(handle)) + return false; + +#if defined(OS_POSIX) + handle.auto_close = false; +#endif + + // Take ownership of shared memory. This will close the handle if Send below + // fails. Otherwise, callee takes ownership before this variable + // goes out of scope. + base::SharedMemory shared_memory(handle, false); + + return Initialize(&shared_memory, size); +} + +bool CommandBufferProxy::Initialize(base::SharedMemory* buffer, int32 size) { bool result; - if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, &result))) { + if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, + buffer->handle(), + size, + &result))) { LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; return false; } @@ -108,9 +137,39 @@ bool CommandBufferProxy::Initialize() { return false; } + base::SharedMemoryHandle handle; + if (!buffer->GiveToProcess(base::GetCurrentProcessHandle(), &handle)) { + LOG(ERROR) << "Failed to duplicate command buffer handle."; + return false; + } + + ring_buffer_.reset(new base::SharedMemory(handle, false)); + if (!ring_buffer_->Map(size)) { + LOG(ERROR) << "Failed to map shared memory for command buffer."; + ring_buffer_.reset(); + return false; + } + + num_entries_ = size / sizeof(gpu::CommandBufferEntry); return true; } +Buffer CommandBufferProxy::GetRingBuffer() { + DCHECK(ring_buffer_.get()); + // Return locally cached ring buffer. + Buffer buffer; + if (ring_buffer_.get()) { + buffer.ptr = ring_buffer_->memory(); + buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); + buffer.shared_memory = ring_buffer_.get(); + } else { + buffer.ptr = NULL; + buffer.size = 0; + buffer.shared_memory = NULL; + } + return buffer; +} + gpu::CommandBuffer::State CommandBufferProxy::GetState() { // Send will flag state with lost context if IPC fails. if (last_state_.error == gpu::error::kNoError) { @@ -155,13 +214,6 @@ gpu::CommandBuffer::State CommandBufferProxy::FlushSync(int32 put_offset, return last_state_; } -void CommandBufferProxy::SetGetBuffer(int32 shm_id) { - if (last_state_.error != gpu::error::kNoError) - return; - - Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id)); -} - void CommandBufferProxy::SetGetOffset(int32 get_offset) { // Not implemented in proxy. NOTREACHED(); diff --git a/content/renderer/gpu/command_buffer_proxy.h b/content/renderer/gpu/command_buffer_proxy.h index 6591621..551e1ca 100644 --- a/content/renderer/gpu/command_buffer_proxy.h +++ b/content/renderer/gpu/command_buffer_proxy.h @@ -43,12 +43,13 @@ class CommandBufferProxy : public gpu::CommandBuffer, int route_id() const { return route_id_; } // CommandBuffer implementation: - virtual bool Initialize() OVERRIDE; + virtual bool Initialize(int32 size) OVERRIDE; + virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE; + virtual gpu::Buffer GetRingBuffer() 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 shm_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, @@ -103,6 +104,10 @@ class CommandBufferProxy : public gpu::CommandBuffer, void OnDestroyed(gpu::error::ContextLostReason reason); void OnEchoAck(); + // As with the service, the client takes ownership of the ring buffer. + int32 num_entries_; + scoped_ptr<base::SharedMemory> ring_buffer_; + // Local cache of id to transfer buffer mapping. typedef std::map<int32, gpu::Buffer> TransferBufferMap; TransferBufferMap transfer_buffers_; diff --git a/content/renderer/gpu/renderer_gl_context.cc b/content/renderer/gpu/renderer_gl_context.cc index 8fa9262..03f6715 100644 --- a/content/renderer/gpu/renderer_gl_context.cc +++ b/content/renderer/gpu/renderer_gl_context.cc @@ -380,7 +380,7 @@ bool RendererGLContext::Initialize(bool onscreen, TRACE_EVENT0("gpu", "RendererGLContext::Initialize::InitializeCommandBuffer"); // Initiaize the command buffer. - if (!command_buffer_->Initialize()) { + if (!command_buffer_->Initialize(kCommandBufferSize)) { Destroy(); return false; } diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index d43efc3..6328923 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -17,8 +17,6 @@ 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), @@ -29,25 +27,14 @@ CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) last_flush_time_(0) { } -bool CommandBufferHelper::AllocateRingBuffer() { - int32 id = command_buffer_->CreateTransferBuffer(ring_buffer_size_, -1); - if (id < 0) { - return false; - } - - ring_buffer_ = command_buffer_->GetTransferBuffer(id); +bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { + ring_buffer_ = command_buffer_->GetRingBuffer(); 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; } @@ -61,11 +48,6 @@ bool CommandBufferHelper::AllocateRingBuffer() { 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 5fbf462..b6f45e2 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/gpu/command_buffer/client/cmd_buffer_helper.h @@ -214,10 +214,6 @@ 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(); @@ -228,13 +224,9 @@ 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 216bb60..3b314c4 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -66,9 +66,15 @@ class CommandBufferHelperTest : public testing::Test { .WillRepeatedly(Return(error::kNoError)); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(); + command_buffer_->Initialize(kCommandBufferSizeBytes); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); - parser_ = new CommandParser(api_mock_.get()); + parser_ = new CommandParser(ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size, + 0, + api_mock_.get()); do_jump_command_.reset(new DoJumpCommand(parser_)); EXPECT_CALL(*api_mock_, DoCommand(cmd::kJump, _, _)) @@ -84,12 +90,6 @@ 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 ebd8ff6..417b26a 100644 --- a/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/gpu/command_buffer/client/fenced_allocator_test.cc @@ -45,9 +45,15 @@ class BaseFencedAllocatorTest : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(); + command_buffer_->Initialize(kBufferSize); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); - parser_ = new CommandParser(api_mock_.get()); + parser_ = new CommandParser(ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size, + 0, + api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -58,12 +64,6 @@ 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 4c6013d..5ce2a8b 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -15,30 +15,34 @@ #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 kTransferBufferBaseId = 0x123; - static const int32 kMaxTransferBuffers = 6; + static const int32 kTransferBufferId = 0x123; GLES2MockCommandBufferHelper() { } virtual ~GLES2MockCommandBufferHelper() { } // CommandBuffer implementation: - virtual bool Initialize() { + 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. 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_; } @@ -54,57 +58,28 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { 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); + OnFlush(transfer_buffer_buffer_.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; + transfer_buffer_.reset(new int8[size]); + transfer_buffer_buffer_.ptr = transfer_buffer_.get(); + transfer_buffer_buffer_.size = size; + return kTransferBufferId; } - 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 void DestroyTransferBuffer(int32 /* id */) { + GPU_NOTREACHED(); } virtual Buffer GetTransferBuffer(int32 id) { - GPU_DCHECK_GE(id, kTransferBufferBaseId); - GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers); - return transfer_buffer_buffers_[id - kTransferBufferBaseId]; + GPU_DCHECK_EQ(id, kTransferBufferId); + return transfer_buffer_buffer_; } virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -132,41 +107,39 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { virtual void OnFlush(void* transfer_buffer) = 0; private: - scoped_array<int8> transfer_buffers_[kMaxTransferBuffers]; - Buffer transfer_buffer_buffers_[kMaxTransferBuffers]; - CommandBufferEntry* ring_buffer_; + scoped_array<int8> transfer_buffer_; + Buffer transfer_buffer_buffer_; + scoped_array<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; +const int32 GLES2MockCommandBufferHelper::kTransferBufferId; #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)); } @@ -221,6 +194,8 @@ 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() @@ -228,8 +203,7 @@ class GLES2CommandBufferTestBase : public testing::Test { token_(0), offset_(0), initial_offset_(0), - alignment_(0), - transfer_buffer_id_(-1) { + alignment_(0) { } void SetupCommandBuffer(unsigned int offset, unsigned alignment) { @@ -238,11 +212,11 @@ class GLES2CommandBufferTestBase : public testing::Test { alignment_ = alignment; command_buffer_.reset(new MockGLES2CommandBuffer()); - command_buffer_->Initialize(); + command_buffer_->Initialize(kCommandBufferSizeBytes); - transfer_buffer_id_ = - command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); - transfer_buffer_ = command_buffer_->GetTransferBuffer(transfer_buffer_id_); + EXPECT_EQ(kTransferBufferId, + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); + transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); ClearTransferBuffer(); helper_.reset(new GLES2CmdHelper(command_buffer_.get())); @@ -258,7 +232,7 @@ class GLES2CommandBufferTestBase : public testing::Test { } void ClearCommands() { - Buffer ring_buffer = helper_->get_ring_buffer(); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); } @@ -279,10 +253,6 @@ 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_; @@ -310,7 +280,6 @@ 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 @@ -318,6 +287,7 @@ 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 @@ -333,12 +303,9 @@ class TransferBufferTest : public GLES2CommandBufferTestBase { GLES2Implementation::kStartingOffset, GLES2Implementation::kAlignment); - transfer_buffer_id_ = - command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); - transfer_buffer_.reset(new TransferBuffer( helper_.get(), - transfer_buffer_id_, + kTransferBufferId, GetTransferAddressFromOffset(0, 0), kTransferBufferSize, kStartingOffset, @@ -360,7 +327,7 @@ const unsigned int TransferBufferTest::kAlignment; TEST_F(TransferBufferTest, Basic) { EXPECT_TRUE(transfer_buffer_->HaveBuffer()); - EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); + EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); } TEST_F(TransferBufferTest, Free) { @@ -374,7 +341,7 @@ TEST_F(TransferBufferTest, Free) { // See it's freed. EXPECT_FALSE(transfer_buffer_->HaveBuffer()); // See that it gets reallocated. - EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId()); + EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); EXPECT_TRUE(transfer_buffer_->HaveBuffer()); // Free buffer. @@ -506,7 +473,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase { helper_.get(), kTransferBufferSize, transfer_buffer_.ptr, - transfer_buffer_id_, + kTransferBufferId, shared_resources, bind_generates_resource)); } @@ -515,7 +482,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase { .Times(1) .RetiresOnSaturation(); helper_->CommandBufferHelper::Finish(); - Buffer ring_buffer = helper_->get_ring_buffer(); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + command_buffer_->GetState().put_offset; ClearCommands(); @@ -558,16 +525,16 @@ TEST_F(GLES2ImplementationTest, ShaderSource) { Cmds expected; expected.set_bucket_size.Init(kBucketId, kSourceSize); expected.set_bucket_data1.Init( - kBucketId, 0, kString1Size, transfer_buffer_id_, + kBucketId, 0, kString1Size, kTransferBufferId, AllocateTransferBuffer(kPaddedString1Size)); expected.set_token1.Init(GetNextToken()); expected.set_bucket_data2.Init( - kBucketId, kString1Size, kString2Size, transfer_buffer_id_, + kBucketId, kString1Size, kString2Size, kTransferBufferId, AllocateTransferBuffer(kPaddedString2Size)); expected.set_token2.Init(GetNextToken()); expected.set_bucket_data3.Init( kBucketId, kString1Size + kString2Size, - kString3Size, transfer_buffer_id_, + kString3Size, kTransferBufferId, AllocateTransferBuffer(kPaddedString3Size)); expected.set_token3.Init(GetNextToken()); expected.shader_source_bucket.Init(kShaderId, kBucketId); @@ -597,9 +564,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, transfer_buffer_id_, 0); + expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); + kBucketId, 0, sizeof(kString), kTransferBufferId, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); char buf[sizeof(kString) + 1]; @@ -661,13 +628,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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, 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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -737,19 +704,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, transfer_buffer_id_, + GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, kTransferBufferId, 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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, 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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -813,17 +780,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, transfer_buffer_id_, 0); + kIndexOffset, kTransferBufferId, 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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, 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, transfer_buffer_id_, + GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, AllocateTransferBuffer(kSize2)); expected.set_token2.Init(GetNextToken()); expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, @@ -870,7 +837,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, - transfer_buffer_id_, 0); + kTransferBufferId, 0); // One call to flush to way for GetVertexAttribPointerv EXPECT_CALL(*command_buffer_, OnFlush(_)) @@ -927,10 +894,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) { kStride2, kOffset2); expected.get1.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, - transfer_buffer_id_, 0); + kTransferBufferId, 0); expected.get2.Init(kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, - transfer_buffer_id_, 0); + kTransferBufferId, 0); FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f); @@ -993,7 +960,7 @@ TEST_F(GLES2ImplementationTest, ReservedIds) { GetError get; }; Cmds expected; - expected.get.Init(transfer_buffer_id_, 0); + expected.get.Init(kTransferBufferId, 0); // One call to flush to wait for GetError EXPECT_CALL(*command_buffer_, OnFlush(_)) @@ -1031,15 +998,15 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { Cmds expected; expected.read1.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, + kTransferBufferId, AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), - transfer_buffer_id_, 0); + kTransferBufferId, 0); expected.set_token1.Init(GetNextToken()); expected.read2.Init( 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, + kTransferBufferId, AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel), - transfer_buffer_id_, 0); + kTransferBufferId, 0); expected.set_token2.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); @@ -1066,9 +1033,9 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) { Cmds expected; expected.read.Init( 0, 0, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, + kTransferBufferId, AllocateTransferBuffer(kWidth * kHeight * kBytesPerPixel), - transfer_buffer_id_, 0); + kTransferBufferId, 0); expected.set_token.Init(GetNextToken()); scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); @@ -1091,7 +1058,7 @@ TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) { uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, transfer_buffer_id_, offset); + kTarget, kOffset, kSize, kTransferBufferId, offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( @@ -1116,7 +1083,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { uint32 offset = 0; Cmds expected; expected.buf.Init( - kTarget, kOffset, kSize, GetNextFreeTransferBufferId(), offset); + kTarget, kOffset, kSize, kTransferBufferId, offset); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapBufferSubDataCHROMIUM( @@ -1171,7 +1138,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) { Cmds expected; expected.tex.Init( GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat, - kType, GetNextFreeTransferBufferId(), offset, GL_FALSE); + kType, kTransferBufferId, offset, GL_FALSE); expected.set_token.Init(GetNextToken()); void* mem = gl_->MapTexSubImage2DCHROMIUM( @@ -1306,8 +1273,8 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { const uint32 kResultsOffset = AllocateTransferBuffer(kResultsSize); Cmds expected; expected.get_multiple.Init( - transfer_buffer_id_, kPnamesOffset, kNumPnames, - transfer_buffer_id_, kResultsOffset, kResultsSize); + kTransferBufferId, kPnamesOffset, kNumPnames, + kTransferBufferId, kResultsOffset, kResultsSize); expected.set_token.Init(GetNextToken()); const GLint kSentinel = 0x12345678; @@ -1416,9 +1383,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, transfer_buffer_id_, 0); + expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); + kBucketId, 0, sizeof(kString), kTransferBufferId, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf); @@ -1457,9 +1424,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, transfer_buffer_id_, 0); + expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0); expected.get_bucket_data.Init( - kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset); + kBucketId, 0, sizeof(kString), kTransferBufferId, offset); expected.set_token1.Init(GetNextToken()); expected.set_bucket_size2.Init(kBucketId, 0); gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf); @@ -1635,7 +1602,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { Cmds expected; expected.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - transfer_buffer_id_, offset); + kTransferBufferId, offset); expected.set_token.Init(GetNextToken()); gl_->TexImage2D( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, @@ -1650,7 +1617,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) { Cmds2 expected2; expected2.tex_image_2d.Init( kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, - transfer_buffer_id_, offset2); + kTransferBufferId, offset2); expected2.set_token.Init(GetNextToken()); const void* commands2 = GetPut(); gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); @@ -1707,11 +1674,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, offset1, true); + kTransferBufferId, offset1, true); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init( kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, offset2, true); + kTransferBufferId, offset2, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1740,11 +1707,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, offset3, true); + kTransferBufferId, offset3, true); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init( kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, - transfer_buffer_id_, offset4, true); + kTransferBufferId, offset4, true); expected.set_token2.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1810,19 +1777,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType, - transfer_buffer_id_, offset1, true); + kTransferBufferId, 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); + kTransferBufferId, 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); + kTransferBufferId, 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); + kTransferBufferId, offset4, true); expected.set_token4.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1861,19 +1828,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) { 0, 0); expected.tex_sub_image_2d1.Init( kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType, - transfer_buffer_id_, offset1, true); + kTransferBufferId, 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); + kTransferBufferId, 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); + kTransferBufferId, 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); + kTransferBufferId, offset4, true); expected.set_token4.Init(GetNextToken()); // TODO(gman): Make it possible to run this test @@ -1941,10 +1908,10 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { kType, 0, NULL); expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset, kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType, - transfer_buffer_id_, offset1, false); + kTransferBufferId, offset1, false); expected.set_token1.Init(GetNextToken()); expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset, - kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, transfer_buffer_id_, + kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, kTransferBufferId, offset2, false); expected.set_token2.Init(GetNextToken()); @@ -2053,7 +2020,7 @@ TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) { }; Cmds expected; - expected.create_stream.Init(kTextureId, transfer_buffer_id_, kResultOffset); + expected.create_stream.Init(kTextureId, kTransferBufferId, 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 c18ec9f..81b6655 100644 --- a/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -42,9 +42,15 @@ class MappedMemoryTestBase : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(); + command_buffer_->Initialize(kBufferSize); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); - parser_ = new CommandParser(api_mock_.get()); + parser_ = new CommandParser(ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size, + 0, + api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -55,12 +61,6 @@ 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 8b8e46e..eb5a0cb 100644 --- a/gpu/command_buffer/client/ring_buffer_test.cc +++ b/gpu/command_buffer/client/ring_buffer_test.cc @@ -65,9 +65,15 @@ class BaseRingBufferTest : public testing::Test { Return(error::kNoError))); command_buffer_.reset(new CommandBufferService); - command_buffer_->Initialize(); + command_buffer_->Initialize(kBufferSize); + Buffer ring_buffer = command_buffer_->GetRingBuffer(); - parser_ = new CommandParser(api_mock_.get()); + parser_ = new CommandParser(ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size, + 0, + api_mock_.get()); gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); @@ -82,12 +88,6 @@ 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 e44df7f..76124c8 100644 --- a/gpu/command_buffer/common/command_buffer.h +++ b/gpu/command_buffer/common/command_buffer.h @@ -67,7 +67,13 @@ class CommandBuffer { } // Initialize the command buffer with the given size. - virtual bool Initialize() = 0; + 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; // Returns the current status. virtual State GetState() = 0; @@ -86,10 +92,6 @@ 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 6ed2eee..d92c2c3 100644 --- a/gpu/command_buffer/common/command_buffer_mock.cc +++ b/gpu/command_buffer/common/command_buffer_mock.cc @@ -7,6 +7,8 @@ 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 0379340..321c40d 100644 --- a/gpu/command_buffer/common/command_buffer_mock.h +++ b/gpu/command_buffer/common/command_buffer_mock.h @@ -21,12 +21,13 @@ class MockCommandBuffer : public CommandBuffer { MockCommandBuffer(); virtual ~MockCommandBuffer(); - MOCK_METHOD0(Initialize, bool()); + MOCK_METHOD1(Initialize, bool(int32 size)); + MOCK_METHOD2(Initialize, bool(base::SharedMemory* buffer, int32 size)); + MOCK_METHOD0(GetRingBuffer, Buffer()); 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 6aefe82..59e99ab 100644 --- a/gpu/command_buffer/service/cmd_buffer_engine.h +++ b/gpu/command_buffer/service/cmd_buffer_engine.h @@ -29,9 +29,6 @@ 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 b5383af..fba06e6 100644 --- a/gpu/command_buffer/service/cmd_parser.cc +++ b/gpu/command_buffer/service/cmd_parser.cc @@ -10,29 +10,23 @@ namespace gpu { -CommandParser::CommandParser(AsyncAPIInterface* handler) - : get_(0), - put_(0), - buffer_(NULL), - entry_count_(0), +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), 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); - get_ = 0; - put_ = 0; - char* buffer_begin = static_cast<char*>(shm_address) + offset; - buffer_ = reinterpret_cast<CommandBufferEntry*>(buffer_begin); + 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 567b7f6..fe3eb12 100644 --- a/gpu/command_buffer/service/cmd_parser.h +++ b/gpu/command_buffer/service/cmd_parser.h @@ -18,14 +18,12 @@ class AsyncAPIInterface; // buffer, to implement some asynchronous RPC mechanism. class CommandParser { public: - 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); + CommandParser(void *shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size, + CommandBufferOffset start_get, + AsyncAPIInterface *handler); // Gets the "get" pointer. The get pointer is an index into the command // buffer considered as an array of CommandBufferEntry. @@ -65,9 +63,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 b86b0af..857ca8e 100644 --- a/gpu/command_buffer/service/cmd_parser_test.cc +++ b/gpu/command_buffer/service/cmd_parser_test.cc @@ -48,10 +48,12 @@ class CommandParserTest : public testing::Test { size_t command_buffer_size = entry_count * sizeof(CommandBufferEntry); // NOLINT DCHECK_LE(command_buffer_size, shm_size); - CommandParser* parser = new CommandParser(api_mock()); - - parser->SetBuffer(buffer(), shm_size, 0, command_buffer_size); - return parser; + return new CommandParser(buffer(), + shm_size, + 0, + command_buffer_size, + 0, + api_mock()); } unsigned int buffer_entry_count() { return 20; } @@ -286,34 +288,4 @@ 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 7ad5994..d126883 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc @@ -14,8 +14,7 @@ using ::base::SharedMemory; namespace gpu { CommandBufferService::CommandBufferService() - : ring_buffer_id_(-1), - num_entries_(0), + : num_entries_(0), get_offset_(0), put_offset_(0), token_(0), @@ -26,16 +25,71 @@ 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() { +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); + return true; } +Buffer CommandBufferService::GetRingBuffer() { + return ring_buffer_; +} + CommandBufferService::State CommandBufferService::GetState() { State state; state.num_entries = num_entries_; @@ -80,17 +134,6 @@ 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); -} - void CommandBufferService::SetGetOffset(int32 get_offset) { DCHECK(get_offset >= 0 && get_offset < num_entries_); get_offset_ = get_offset; @@ -180,14 +223,6 @@ 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. diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index 187c785..b48bd90 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h @@ -25,12 +25,13 @@ class CommandBufferService : public CommandBuffer { virtual ~CommandBufferService(); // CommandBuffer implementation: - virtual bool Initialize() OVERRIDE; + virtual bool Initialize(int32 size) OVERRIDE; + virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE; + virtual Buffer GetRingBuffer() 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, @@ -54,7 +55,6 @@ class CommandBufferService : public CommandBuffer { virtual void SetParseErrorCallback(const base::Closure& callback); private: - int32 ring_buffer_id_; Buffer ring_buffer_; int32 num_entries_; int32 get_offset_; diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc index 571ffa0..a240948 100644 --- a/gpu/command_buffer/service/common_decoder_unittest.cc +++ b/gpu/command_buffer/service/common_decoder_unittest.cc @@ -116,12 +116,6 @@ 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 a57df77..92abfc0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -431,11 +431,6 @@ 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 468f817..f37c1a0 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -29,6 +29,21 @@ 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() { @@ -135,29 +150,6 @@ void GpuScheduler::set_token(int32 token) { command_buffer_->SetToken(token); } -bool GpuScheduler::SetGetBuffer(int32 transfer_buffer_id) { - // NOTE: This seems kind of strange. We need to update both the parser - // AND the command buffer. - 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); - - command_buffer_->SetGetBuffer(transfer_buffer_id); - 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 9b7d9cd..5256e49 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -51,7 +51,6 @@ 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 e9d64c8..2d230ec 100644 --- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc +++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc @@ -30,8 +30,6 @@ 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); @@ -41,21 +39,28 @@ 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(), - NULL)); - EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId)) - .WillOnce(Return(shared_memory_buffer_)); - EXPECT_CALL(*command_buffer_, SetGetBuffer(kTransferBufferId)); - EXPECT_CALL(*command_buffer_, SetGetOffset(0)); - EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId)); + parser_)); } virtual void TearDown() { @@ -77,6 +82,8 @@ 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_; }; @@ -93,25 +100,6 @@ 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_, SetGetBuffer(kTransferBufferId)); - 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; @@ -125,7 +113,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) { .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetParseError(_)) @@ -148,11 +136,11 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { EXPECT_CALL(*command_buffer_, GetState()) .WillRepeatedly(Return(state)); - EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0])) + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2])) + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) .WillOnce(Return(error::kNoError)); EXPECT_CALL(*command_buffer_, SetGetOffset(3)); @@ -170,12 +158,11 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { EXPECT_CALL(*command_buffer_, GetState()) .WillRepeatedly(Return(state)); - EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0])) + EXPECT_CALL(*async_api_, 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 48ed58c..526f9da 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()) { + if (!command_buffer_->Initialize(kCommandBufferSize)) { return false; } diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 928d5fd..18c9727 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()) + if (!command_buffer->Initialize(kCommandBufferSize)) return false; int32 transfer_buffer_id = diff --git a/ppapi/c/trusted/ppb_graphics_3d_trusted.h b/ppapi/c/trusted/ppb_graphics_3d_trusted.h index 353b6dd..d6a6481 100644 --- a/ppapi/c/trusted/ppb_graphics_3d_trusted.h +++ b/ppapi/c/trusted/ppb_graphics_3d_trusted.h @@ -59,10 +59,12 @@ struct PPB_Graphics3DTrusted { const int32_t* attrib_list); // Initializes the command buffer with the given size. - PP_Bool (*InitCommandBuffer)(PP_Resource context_id); + PP_Bool (*InitCommandBuffer)(PP_Resource context_id, int32_t size); - // Sets the buffer used for commands. - PP_Bool (*SetGetBuffer)(PP_Resource context, int32_t transfer_buffer_id); + // Gets the ring buffer for the command buffer. + PP_Bool (*GetRingBuffer)(PP_Resource context_id, + int* shm_handle, + uint32_t* shm_size); // Returns the current state. struct PP_Graphics3DTrustedState (*GetState)(PP_Resource context); diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc index f678be1..62ea1eb 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc +++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_graphics_3d_rpc_server.cc @@ -244,26 +244,40 @@ void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, + int32_t size, int32_t* success) { DebugPrintf("PPB_Graphics3DTrusted_InitCommandBuffer(...) resource_id: %d\n", resource_id); NaClSrpcClosureRunner runner(done); rpc->result = NACL_SRPC_RESULT_APP_ERROR; + if ((size > kMaxAllowedBufferSize) || (size < 0)) + return; *success = ppapi_proxy::PPBGraphics3DTrustedInterface()->InitCommandBuffer( - resource_id); + resource_id, size); rpc->result = NACL_SRPC_RESULT_OK; } -void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_SetGetBuffer( + +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, - int32_t transfer_buffer_id) { - DebugPrintf("PPB_Graphics3DTrusted_SetGetBuffer\n"); + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { + DebugPrintf("PPB_Graphics3DTrusted_GetRingBuffer\n"); + nacl::DescWrapperFactory factory; + nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper; NaClSrpcClosureRunner runner(done); rpc->result = NACL_SRPC_RESULT_APP_ERROR; - ppapi_proxy::PPBGraphics3DTrustedInterface()->SetGetBuffer( - resource_id, transfer_buffer_id); + + int native_handle = 0; + uint32_t native_size = 0; + ppapi_proxy::PPBGraphics3DTrustedInterface()->GetRingBuffer( + resource_id, &native_handle, &native_size); + desc_wrapper.reset(factory.ImportShmHandle( + (NaClHandle)native_handle, native_size)); + *shm_desc = desc_wrapper->desc(); + *shm_size = native_size; rpc->result = NACL_SRPC_RESULT_OK; } diff --git a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc index 4a83a04..e151312 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc +++ b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.cc @@ -25,18 +25,38 @@ CommandBufferNacl::~CommandBufferNacl() { iface_core_->ReleaseResource(graphics_3d_); } -bool CommandBufferNacl::Initialize() { +bool CommandBufferNacl::Initialize(int32 size) { DebugPrintf("CommandBufferNacl::Initialize\n"); int32_t success; NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); NaClSrpcError retval = PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( - channel, graphics_3d_, &success); + channel, graphics_3d_, size, &success); DebugPrintf("CommandBufferNaCl::Initialize returned success=%s\n", (PP_TRUE == success) ? "TRUE" : "FALSE"); return NACL_SRPC_RESULT_OK == retval && PP_TRUE == success; } +gpu::Buffer CommandBufferNacl::GetRingBuffer() { + DebugPrintf("CommandBufferNacl::GetRingBuffer\n"); + if (!buffer_.ptr) { + DebugPrintf("CommandBufferNacl::GetRingBuffer: Fetching\n"); + int shm_handle = -1; + int32_t shm_size = 0; + + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); + NaClSrpcError retval = + PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetRingBuffer( + channel, graphics_3d_, &shm_handle, &shm_size); + if (NACL_SRPC_RESULT_OK != retval) { + shm_handle = -1; + } + buffer_ = BufferFromShm(shm_handle, shm_size); + } + + return buffer_; +} + gpu::CommandBuffer::State CommandBufferNacl::GetState() { DebugPrintf("CommandBufferNacl::GetState\n"); PP_Graphics3DTrustedState state; @@ -90,13 +110,6 @@ gpu::CommandBuffer::State CommandBufferNacl::FlushSync(int32 put_offset, return last_state_; } -void CommandBufferNacl::SetGetBuffer(int32 transfer_buffer_id) { - DebugPrintf("CommandBufferNacl::SetGetBuffer\n"); - NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); - PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_SetGetBuffer( - channel, graphics_3d_, transfer_buffer_id); -} - void CommandBufferNacl::SetGetOffset(int32 get_offset) { DebugPrintf("CommandBufferNacl::SetGetOffset\n"); // Not implemented by proxy. diff --git a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h index 20e3836..a699241 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h +++ b/ppapi/native_client/src/shared/ppapi_proxy/command_buffer_nacl.h @@ -22,12 +22,16 @@ class CommandBufferNacl : public gpu::CommandBuffer { virtual ~CommandBufferNacl(); // CommandBuffer implementation. - virtual bool Initialize(); + virtual bool Initialize(int32 size); + virtual bool Initialize(base::SharedMemory* buffer, int32 size) { + // TODO(neb): support for nacl if neccessary + return false; + } + virtual gpu::Buffer GetRingBuffer(); virtual State GetState(); virtual State GetLastState(); virtual void Flush(int32 put_offset); virtual State FlushSync(int32 put_offset, int32 last_known_get); - virtual void SetGetBuffer(int32 transfer_buffer_id); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size, int32 id_request); virtual int32 RegisterTransferBuffer(base::SharedMemory* buffer, diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc index ead08dd..c77902b 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_graphics_3d.cc @@ -212,9 +212,12 @@ bool PluginGraphics3D::InitFromBrowserResource(PP_Resource res) { // Create and initialize the objects required to issue GLES2 calls. command_buffer_.reset(new CommandBufferNacl(res, PluginCore::GetInterface())); - if (command_buffer_->Initialize()) { + if (command_buffer_->Initialize(kRingBufferSize)) { gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); - if (gles2_helper_->Initialize(kRingBufferSize)) { + gpu::Buffer buffer = command_buffer_->GetRingBuffer(); + DebugPrintf("PluginGraphics3D::InitFromBrowserResource: buffer size: %d\n", + buffer.size); + if (gles2_helper_->Initialize(buffer.size)) { // Request id -1 to signify 'don't care' int32 transfer_buffer_id = command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc index 0cb9b57..fe0b499 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_graphics_3d.srpc @@ -77,15 +77,16 @@ # Initialize the command buffer. {'name': 'PPB_Graphics3DTrusted_InitCommandBuffer', 'inputs': [['resource_id', 'PP_Resource'], + ['size', 'int32_t'] ], 'outputs': [['success', 'int32_t']] # PP_Bool }, - # Set the buffer used for commands. - {'name': 'PPB_Graphics3DTrusted_SetGetBuffer', - 'inputs': [['resource_id', 'PP_Resource'], - ['shm_id', 'int32_t'], - ], - 'outputs': [] + # Get the ring buffer. + {'name': 'PPB_Graphics3DTrusted_GetRingBuffer', + 'inputs': [['resource_id', 'PP_Resource']], + 'outputs': [['shm_desc', 'handle'], + ['shm_size', 'int32_t'] + ] }, # Get command buffer state. {'name': 'PPB_Graphics3DTrusted_GetState', @@ -141,6 +142,6 @@ ['shm_size', 'int32_t'] ] }, - # End of PPB_Graphics3DTrusted + # End of PPB_Graphics3DTrusted ] } diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc index e5739ba..20ebd55 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc @@ -1435,6 +1435,7 @@ NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateRaw( NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, + int32_t size, int32_t* success) { VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), ("%s: PPAPI calls are not supported off the main thread\n", @@ -1442,26 +1443,29 @@ NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcError retval; retval = NaClSrpcInvokeBySignature( channel, - "PPB_Graphics3DTrusted_InitCommandBuffer:i:i", + "PPB_Graphics3DTrusted_InitCommandBuffer:ii:i", resource_id, + size, success ); return retval; } -NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_SetGetBuffer( +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetRingBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, - int32_t transfer_buffer_id) { + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size) { VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), ("%s: PPAPI calls are not supported off the main thread\n", __FUNCTION__)); NaClSrpcError retval; retval = NaClSrpcInvokeBySignature( channel, - "PPB_Graphics3DTrusted_SetGetBuffer:ii:", + "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", resource_id, - transfer_buffer_id + shm_desc, + shm_size ); return retval; } diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc index b40fd2d..54187d0 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc +++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc @@ -1160,22 +1160,23 @@ static void PPB_Graphics3DTrusted_InitCommandBufferDispatcher( rpc, done, inputs[0]->u.ival, + inputs[1]->u.ival, &(outputs[0]->u.ival) ); } -static void PPB_Graphics3DTrusted_SetGetBufferDispatcher( +static void PPB_Graphics3DTrusted_GetRingBufferDispatcher( NaClSrpcRpc* rpc, NaClSrpcArg** inputs, NaClSrpcArg** outputs, NaClSrpcClosure* done ) { - UNREFERENCED_PARAMETER(outputs); - PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_SetGetBuffer( + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( rpc, done, inputs[0]->u.ival, - inputs[1]->u.ival + &(outputs[0]->u.hval), + &(outputs[1]->u.ival) ); } @@ -2618,8 +2619,8 @@ NaClSrpcHandlerDesc PpbRpcs::srpc_methods[] = { { "PPB_Graphics3D_GetError:i:i", PPB_Graphics3D_GetErrorDispatcher }, { "PPB_Graphics3D_SwapBuffers:ii:i", PPB_Graphics3D_SwapBuffersDispatcher }, { "PPB_Graphics3DTrusted_CreateRaw:iiI:i", PPB_Graphics3DTrusted_CreateRawDispatcher }, - { "PPB_Graphics3DTrusted_InitCommandBuffer:i:i", PPB_Graphics3DTrusted_InitCommandBufferDispatcher }, - { "PPB_Graphics3DTrusted_SetGetBuffer:ii:", PPB_Graphics3DTrusted_SetGetBufferDispatcher }, + { "PPB_Graphics3DTrusted_InitCommandBuffer:ii:i", PPB_Graphics3DTrusted_InitCommandBufferDispatcher }, + { "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", PPB_Graphics3DTrusted_GetRingBufferDispatcher }, { "PPB_Graphics3DTrusted_GetState:i:C", PPB_Graphics3DTrusted_GetStateDispatcher }, { "PPB_Graphics3DTrusted_Flush:ii:", PPB_Graphics3DTrusted_FlushDispatcher }, { "PPB_Graphics3DTrusted_FlushSync:ii:C", PPB_Graphics3DTrusted_FlushSyncDispatcher }, diff --git a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h index 588be46..25feea6 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h +++ b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h @@ -590,12 +590,14 @@ class PpbGraphics3DRpcServer { NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, + int32_t size, int32_t* success); - static void PPB_Graphics3DTrusted_SetGetBuffer( + static void PPB_Graphics3DTrusted_GetRingBuffer( NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, - int32_t shm_id); + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); static void PPB_Graphics3DTrusted_GetState( NaClSrpcRpc* rpc, NaClSrpcClosure* done, diff --git a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h index 1eee263..aa2f7d0 100644 --- a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h +++ b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h @@ -515,11 +515,13 @@ class PpbGraphics3DRpcClient { static NaClSrpcError PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, + int32_t size, int32_t* success); - static NaClSrpcError PPB_Graphics3DTrusted_SetGetBuffer( + static NaClSrpcError PPB_Graphics3DTrusted_GetRingBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, - int32_t shm_id); + NaClSrpcImcDescType* shm_desc, + int32_t* shm_size); static NaClSrpcError PPB_Graphics3DTrusted_GetState( NaClSrpcChannel* channel, PP_Resource resource_id, diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 7e277db..d6f0515 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -781,11 +781,10 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBGraphics3D_Create, PP_Instance /* instance */, std::vector<int32_t> /* attrib_list */, ppapi::HostResource /* result */) -IPC_SYNC_MESSAGE_ROUTED1_0(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer, - ppapi::HostResource /* context */) -IPC_SYNC_MESSAGE_ROUTED2_0(PpapiHostMsg_PPBGraphics3D_SetGetBuffer, +IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer, ppapi::HostResource /* context */, - int32 /* transfer_buffer_id */) + int32 /* size */, + base::SharedMemoryHandle /* ring_buffer */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBGraphics3D_GetState, ppapi::HostResource /* context */, gpu::CommandBuffer::State /* state */) diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.cc b/ppapi/proxy/ppb_graphics_3d_proxy.cc index b5a2dee..8203e8d 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_3d_proxy.cc @@ -31,12 +31,13 @@ class CommandBuffer : public gpu::CommandBuffer { virtual ~CommandBuffer(); // gpu::CommandBuffer implementation: - virtual bool Initialize(); + virtual bool Initialize(int32 size); + virtual bool Initialize(base::SharedMemory* buffer, int32 size); + virtual gpu::Buffer GetRingBuffer(); virtual State GetState(); virtual State GetLastState(); virtual void Flush(int32 put_offset); virtual State FlushSync(int32 put_offset, int32 last_known_get); - virtual void SetGetBuffer(int32 transfer_buffer_id); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size, int32 id_request); virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -52,6 +53,9 @@ class CommandBuffer : public gpu::CommandBuffer { bool Send(IPC::Message* msg); void UpdateState(const gpu::CommandBuffer::State& state); + int32 num_entries_; + scoped_ptr<base::SharedMemory> ring_buffer_; + typedef base::hash_map<int32, gpu::Buffer> TransferBufferMap; TransferBufferMap transfer_buffers_; @@ -65,7 +69,8 @@ class CommandBuffer : public gpu::CommandBuffer { CommandBuffer::CommandBuffer(const HostResource& resource, PluginDispatcher* dispatcher) - : resource_(resource), + : num_entries_(0), + resource_(resource), dispatcher_(dispatcher) { } @@ -79,9 +84,47 @@ CommandBuffer::~CommandBuffer() { } } -bool CommandBuffer::Initialize() { - return Send(new PpapiHostMsg_PPBGraphics3D_InitCommandBuffer( - API_ID_PPB_GRAPHICS_3D, resource_)); +bool CommandBuffer::Initialize(int32 size) { + DCHECK(!ring_buffer_.get()); + + // Initialize the service. Assuming we are sandboxed, the GPU + // process is responsible for duplicating the handle. This might not be true + // for NaCl. + base::SharedMemoryHandle handle; + if (Send(new PpapiHostMsg_PPBGraphics3D_InitCommandBuffer( + API_ID_PPB_GRAPHICS_3D, resource_, size, &handle)) && + base::SharedMemory::IsHandleValid(handle)) { + ring_buffer_.reset(new base::SharedMemory(handle, false)); + if (ring_buffer_->Map(size)) { + num_entries_ = size / sizeof(gpu::CommandBufferEntry); + return true; + } + + ring_buffer_.reset(); + } + + return false; +} + +bool CommandBuffer::Initialize(base::SharedMemory* buffer, int32 size) { + // Not implemented in proxy. + NOTREACHED(); + return false; +} + +gpu::Buffer CommandBuffer::GetRingBuffer() { + // Return locally cached ring buffer. + gpu::Buffer buffer; + if (ring_buffer_.get()) { + buffer.ptr = ring_buffer_->memory(); + buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); + buffer.shared_memory = ring_buffer_.get(); + } else { + buffer.ptr = NULL; + buffer.size = 0; + buffer.shared_memory = NULL; + } + return buffer; } gpu::CommandBuffer::State CommandBuffer::GetState() { @@ -132,13 +175,6 @@ gpu::CommandBuffer::State CommandBuffer::FlushSync(int32 put_offset, return last_state_; } -void CommandBuffer::SetGetBuffer(int32 transfer_buffer_id) { - if (last_state_.error == gpu::error::kNoError) { - Send(new PpapiHostMsg_PPBGraphics3D_SetGetBuffer( - API_ID_PPB_GRAPHICS_3D, resource_, transfer_buffer_id)); - } -} - void CommandBuffer::SetGetOffset(int32 get_offset) { // Not implemented in proxy. NOTREACHED(); @@ -302,17 +338,17 @@ bool Graphics3D::Init() { return false; command_buffer_.reset(new CommandBuffer(host_resource(), dispatcher)); - if (!command_buffer_->Initialize()) + if (!command_buffer_->Initialize(kCommandBufferSize)) return false; return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize); } -PP_Bool Graphics3D::InitCommandBuffer() { +PP_Bool Graphics3D::InitCommandBuffer(int32_t size) { return PP_FALSE; } -PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) { +PP_Bool Graphics3D::GetRingBuffer(int* shm_handle, uint32_t* shm_size) { return PP_FALSE; } @@ -413,8 +449,6 @@ bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) { OnMsgCreate) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer, OnMsgInitCommandBuffer) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer, - OnMsgSetGetBuffer) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState, OnMsgGetState) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush, @@ -454,21 +488,22 @@ void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance, } void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer( - const HostResource& context) { + const HostResource& context, + int32 size, + base::SharedMemoryHandle* ring_buffer) { + *ring_buffer = base::SharedMemory::NULLHandle(); EnterHostFromHostResource<PPB_Graphics3D_API> enter(context); if (enter.failed()) return; - if (!enter.object()->InitCommandBuffer()) + if (!enter.object()->InitCommandBuffer(size)) return; -} -void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer( - const HostResource& context, - int32 transfer_buffer_id) { - EnterHostFromHostResource<PPB_Graphics3D_API> enter(context); - if (enter.succeeded()) - enter.object()->SetGetBuffer(transfer_buffer_id); + int shm_handle; + uint32_t shm_size; + if (!enter.object()->GetRingBuffer(&shm_handle, &shm_size)) + return; + *ring_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle); } void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context, diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h index bb54b61..472c2a7 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.h +++ b/ppapi/proxy/ppb_graphics_3d_proxy.h @@ -36,8 +36,8 @@ class Graphics3D : public Resource, public Graphics3DImpl { } // Graphics3DTrusted API. These are not implemented in the proxy. - virtual PP_Bool InitCommandBuffer() OVERRIDE; - virtual PP_Bool SetGetBuffer(int32_t shm_id) OVERRIDE; + virtual PP_Bool InitCommandBuffer(int32_t size) OVERRIDE; + virtual PP_Bool GetRingBuffer(int* shm_handle, uint32_t* shm_size) OVERRIDE; virtual PP_Graphics3DTrustedState GetState() OVERRIDE; virtual PP_Bool Flush(int32_t put_offset) OVERRIDE; virtual PP_Graphics3DTrustedState FlushSync(int32_t put_offset) OVERRIDE; @@ -79,9 +79,9 @@ class PPB_Graphics3D_Proxy : public InterfaceProxy { void OnMsgCreate(PP_Instance instance, const std::vector<int32_t>& attribs, HostResource* result); - void OnMsgInitCommandBuffer(const HostResource& context); - void OnMsgSetGetBuffer(const HostResource& context, - int32 id); + void OnMsgInitCommandBuffer(const HostResource& context, + int32 size, + base::SharedMemoryHandle* ring_buffer); void OnMsgGetState(const HostResource& context, gpu::CommandBuffer::State* state); void OnMsgFlush(const HostResource& context, diff --git a/ppapi/thunk/ppb_graphics_3d_api.h b/ppapi/thunk/ppb_graphics_3d_api.h index 4e1980a..73e8178 100644 --- a/ppapi/thunk/ppb_graphics_3d_api.h +++ b/ppapi/thunk/ppb_graphics_3d_api.h @@ -25,8 +25,9 @@ class PPAPI_THUNK_EXPORT PPB_Graphics3D_API { virtual int32_t SwapBuffers(PP_CompletionCallback callback) = 0; // Graphics3DTrusted API. - virtual PP_Bool InitCommandBuffer() = 0; - virtual PP_Bool SetGetBuffer(int32_t shm_id) = 0; + virtual PP_Bool InitCommandBuffer(int32_t size) = 0; + virtual PP_Bool GetRingBuffer(int* shm_handle, + uint32_t* shm_size) = 0; virtual PP_Graphics3DTrustedState GetState() = 0; virtual int32_t CreateTransferBuffer(uint32_t size) = 0; virtual PP_Bool DestroyTransferBuffer(int32_t id) = 0; diff --git a/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc b/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc index bea32ab..5cc9661 100644 --- a/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc +++ b/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc @@ -30,18 +30,20 @@ PP_Resource CreateRaw(PP_Instance instance, instance, share_context, attrib_list); } -PP_Bool InitCommandBuffer(PP_Resource context) { +PP_Bool InitCommandBuffer(PP_Resource context, int32_t size) { EnterGraphics3D enter(context, true); if (enter.failed()) return PP_FALSE; - return enter.object()->InitCommandBuffer(); + return enter.object()->InitCommandBuffer(size); } -PP_Bool SetGetBuffer(PP_Resource context, int32_t transfer_buffer_id) { +PP_Bool GetRingBuffer(PP_Resource context, + int* shm_handle, + uint32_t* shm_size) { EnterGraphics3D enter(context, true); if (enter.failed()) return PP_FALSE; - return enter.object()->SetGetBuffer(transfer_buffer_id); + return enter.object()->GetRingBuffer(shm_handle, shm_size); } PP_Graphics3DTrustedState GetState(PP_Resource context) { @@ -101,7 +103,7 @@ PP_Graphics3DTrustedState FlushSyncFast(PP_Resource context, const PPB_Graphics3DTrusted g_ppb_graphics_3d_trusted_thunk = { &CreateRaw, &InitCommandBuffer, - &SetGetBuffer, + &GetRingBuffer, &GetState, &CreateTransferBuffer, &DestroyTransferBuffer, diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc index d6ac041..9daaa74 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -457,7 +457,7 @@ bool GLInProcessContext::Initialize(bool onscreen, } command_buffer_.reset(new CommandBufferService); - if (!command_buffer_->Initialize()) { + if (!command_buffer_->Initialize(kCommandBufferSize)) { LOG(ERROR) << "Could not initialize command buffer."; Destroy(); return false; diff --git a/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc b/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc index 7e179a3..2794436 100644 --- a/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc @@ -87,13 +87,14 @@ PPB_Graphics3D_API* PPB_Graphics3D_Impl::AsPPB_Graphics3D_API() { return this; } -PP_Bool PPB_Graphics3D_Impl::InitCommandBuffer() { - return PP_FromBool(GetCommandBuffer()->Initialize()); +PP_Bool PPB_Graphics3D_Impl::InitCommandBuffer(int32_t size) { + return PP_FromBool(GetCommandBuffer()->Initialize(size)); } -PP_Bool PPB_Graphics3D_Impl::SetGetBuffer(int32_t transfer_buffer_id) { - GetCommandBuffer()->SetGetBuffer(transfer_buffer_id); - return PP_TRUE; +PP_Bool PPB_Graphics3D_Impl::GetRingBuffer(int* shm_handle, + uint32_t* shm_size) { + gpu::Buffer buffer = GetCommandBuffer()->GetRingBuffer(); + return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size); } PP_Graphics3DTrustedState PPB_Graphics3D_Impl::GetState() { @@ -190,7 +191,7 @@ bool PPB_Graphics3D_Impl::Init(PP_Resource share_context, return false; gpu::CommandBuffer* command_buffer = GetCommandBuffer(); - if (!command_buffer->Initialize()) + if (!command_buffer->Initialize(kCommandBufferSize)) return false; return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize); diff --git a/webkit/plugins/ppapi/ppb_graphics_3d_impl.h b/webkit/plugins/ppapi/ppb_graphics_3d_impl.h index 2a341b7..250911b 100644 --- a/webkit/plugins/ppapi/ppb_graphics_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_graphics_3d_impl.h @@ -29,8 +29,9 @@ class PPB_Graphics3D_Impl : public ::ppapi::Resource, virtual ::ppapi::thunk::PPB_Graphics3D_API* AsPPB_Graphics3D_API() OVERRIDE; // PPB_Graphics3D_API trusted implementation. - virtual PP_Bool InitCommandBuffer() OVERRIDE; - virtual PP_Bool SetGetBuffer(int32_t transfer_buffer_id) OVERRIDE; + virtual PP_Bool InitCommandBuffer(int32_t size) OVERRIDE; + virtual PP_Bool GetRingBuffer(int* shm_handle, + uint32_t* shm_size) OVERRIDE; virtual PP_Graphics3DTrustedState GetState() OVERRIDE; virtual int32_t CreateTransferBuffer(uint32_t size) OVERRIDE; virtual PP_Bool DestroyTransferBuffer(int32_t id) OVERRIDE; |