diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-12 23:29:40 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-12 23:29:40 +0000 |
commit | 503b3a2ed9be72b3697f1c02cdc7efd29fec987a (patch) | |
tree | f715ec00989bded6c3bdb3919cace05a7d33fc05 | |
parent | 6e6f8836c975eebd3620974c3de6d564967821e9 (diff) | |
download | chromium_src-503b3a2ed9be72b3697f1c02cdc7efd29fec987a.zip chromium_src-503b3a2ed9be72b3697f1c02cdc7efd29fec987a.tar.gz chromium_src-503b3a2ed9be72b3697f1c02cdc7efd29fec987a.tar.bz2 |
Revert "Revert 113479 - Revert "Revert 113250 - Add CommandBuffer::SetGetBuffer""
This reverts commit 84677847c10d0319d8d996aea9b310add85c0bd3.
TEST=ran browser tests on OSX
BUG=103989
TBR=apatrick@chromiu.org
Review URL: http://codereview.chromium.org/8919014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114114 0039d316-1c4b-4281-b951-d872f2087c98
47 files changed, 511 insertions, 541 deletions
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index ff2ab82..8d17117 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -87,6 +87,8 @@ 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); @@ -163,8 +165,6 @@ void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { } void GpuCommandBufferStub::OnInitialize( - base::SharedMemoryHandle ring_buffer, - int32 size, IPC::Message* reply_message) { DCHECK(!command_buffer_.get()); @@ -172,19 +172,7 @@ void GpuCommandBufferStub::OnInitialize( command_buffer_.reset(new gpu::CommandBufferService); -#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)) { + if (!command_buffer_->Initialize()) { DLOG(ERROR) << "CommandBufferService failed to initialize.\n"; OnInitializeFailed(reply_message); return; @@ -266,6 +254,9 @@ void GpuCommandBufferStub::OnInitialize( command_buffer_->SetPutOffsetChangeCallback( base::Bind(&gpu::GpuScheduler::PutChanged, base::Unretained(scheduler_.get()))); + command_buffer_->SetGetBufferChangeCallback( + base::Bind(&gpu::GpuScheduler::SetGetBuffer, + base::Unretained(scheduler_.get()))); command_buffer_->SetParseErrorCallback( base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); scheduler_->SetScheduledCallback( @@ -291,6 +282,12 @@ void GpuCommandBufferStub::OnInitialize( "offscreen", surface_->IsOffscreen()); } +void GpuCommandBufferStub::OnSetGetBuffer( + int32 shm_id, IPC::Message* reply_message) { + command_buffer_->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 50e2b23..8fbfb79 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -93,9 +93,8 @@ class GpuCommandBufferStub void OnInitializeFailed(IPC::Message* reply_message); // Message handlers: - void OnInitialize(base::SharedMemoryHandle ring_buffer, - int32 size, - IPC::Message* reply_message); + void OnInitialize(IPC::Message* reply_message); + void OnSetGetBuffer(int32 shm_id, 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 e5cab60..7099747 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -311,11 +311,13 @@ 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_ROUTED2_1(GpuCommandBufferMsg_Initialize, - base::SharedMemoryHandle /* ring_buffer */, - int32 /* size */, +IPC_SYNC_MESSAGE_ROUTED0_1(GpuCommandBufferMsg_Initialize, 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 86420ae..d51f840 100644 --- a/content/renderer/gpu/command_buffer_proxy.cc +++ b/content/renderer/gpu/command_buffer_proxy.cc @@ -25,8 +25,7 @@ using gpu::Buffer; CommandBufferProxy::CommandBufferProxy( GpuChannelHost* channel, int route_id) - : num_entries_(0), - channel_(channel), + : channel_(channel), route_id_(route_id), flush_count_(0) { } @@ -93,41 +92,13 @@ void CommandBufferProxy::SetChannelErrorCallback( channel_error_callback_ = callback; } -bool CommandBufferProxy::Initialize(int32 size) { - DCHECK(!ring_buffer_.get()); - +bool CommandBufferProxy::Initialize() { 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_, - buffer->handle(), - size, - &result))) { + if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, &result))) { LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; return false; } @@ -137,39 +108,9 @@ bool CommandBufferProxy::Initialize(base::SharedMemory* buffer, int32 size) { 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) { @@ -214,6 +155,13 @@ 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 551e1ca..6591621 100644 --- a/content/renderer/gpu/command_buffer_proxy.h +++ b/content/renderer/gpu/command_buffer_proxy.h @@ -43,13 +43,12 @@ class CommandBufferProxy : public gpu::CommandBuffer, int route_id() const { return route_id_; } // CommandBuffer implementation: - virtual bool Initialize(int32 size) OVERRIDE; - virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE; - virtual gpu::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 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, @@ -104,10 +103,6 @@ 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 03f6715..8fa9262 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(kCommandBufferSize)) { + if (!command_buffer_->Initialize()) { Destroy(); return false; } 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 eb1db7e..9282e73 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -24,21 +24,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() { @@ -48,6 +33,13 @@ void GpuScheduler::PutChanged() { TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this); CommandBuffer::State state = command_buffer_->GetState(); + + // If there is no parser, exit. + if (!parser_.get()) { + DCHECK_EQ(state.get_offset, state.put_offset); + return; + } + parser_->set_put(state.put_offset); if (state.error != error::kNoError) return; @@ -122,6 +114,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 de18b61..f7fd49e 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -54,6 +54,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 = diff --git a/ppapi/c/trusted/ppb_graphics_3d_trusted.h b/ppapi/c/trusted/ppb_graphics_3d_trusted.h index d6a6481..353b6dd 100644 --- a/ppapi/c/trusted/ppb_graphics_3d_trusted.h +++ b/ppapi/c/trusted/ppb_graphics_3d_trusted.h @@ -59,12 +59,10 @@ struct PPB_Graphics3DTrusted { const int32_t* attrib_list); // Initializes the command buffer with the given size. - PP_Bool (*InitCommandBuffer)(PP_Resource context_id, int32_t size); + PP_Bool (*InitCommandBuffer)(PP_Resource context_id); - // Gets the ring buffer for the command buffer. - PP_Bool (*GetRingBuffer)(PP_Resource context_id, - int* shm_handle, - uint32_t* shm_size); + // Sets the buffer used for commands. + PP_Bool (*SetGetBuffer)(PP_Resource context, int32_t transfer_buffer_id); // 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 62ea1eb..f678be1 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,40 +244,26 @@ 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, size); + resource_id); rpc->result = NACL_SRPC_RESULT_OK; } - -void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( +void PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_SetGetBuffer( NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, - NaClSrpcImcDescType* shm_desc, - int32_t* shm_size) { - DebugPrintf("PPB_Graphics3DTrusted_GetRingBuffer\n"); - nacl::DescWrapperFactory factory; - nacl::scoped_ptr<nacl::DescWrapper> desc_wrapper; + int32_t transfer_buffer_id) { + DebugPrintf("PPB_Graphics3DTrusted_SetGetBuffer\n"); NaClSrpcClosureRunner runner(done); rpc->result = NACL_SRPC_RESULT_APP_ERROR; - - 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; + ppapi_proxy::PPBGraphics3DTrustedInterface()->SetGetBuffer( + resource_id, transfer_buffer_id); 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 e151312..4a83a04 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,38 +25,18 @@ CommandBufferNacl::~CommandBufferNacl() { iface_core_->ReleaseResource(graphics_3d_); } -bool CommandBufferNacl::Initialize(int32 size) { +bool CommandBufferNacl::Initialize() { DebugPrintf("CommandBufferNacl::Initialize\n"); int32_t success; NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel(); NaClSrpcError retval = PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( - channel, graphics_3d_, size, &success); + channel, graphics_3d_, &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; @@ -110,6 +90,13 @@ 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 a699241..20e3836 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,16 +22,12 @@ class CommandBufferNacl : public gpu::CommandBuffer { virtual ~CommandBufferNacl(); // CommandBuffer implementation. - 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 bool Initialize(); 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 6d06126..e00e9f9 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 @@ -211,12 +211,9 @@ 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(kRingBufferSize)) { + if (command_buffer_->Initialize()) { gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); - gpu::Buffer buffer = command_buffer_->GetRingBuffer(); - DebugPrintf("PluginGraphics3D::InitFromBrowserResource: buffer size: %d\n", - buffer.size); - if (gles2_helper_->Initialize(buffer.size)) { + if (gles2_helper_->Initialize(kRingBufferSize)) { // 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 fe0b499..0cb9b57 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,16 +77,15 @@ # Initialize the command buffer. {'name': 'PPB_Graphics3DTrusted_InitCommandBuffer', 'inputs': [['resource_id', 'PP_Resource'], - ['size', 'int32_t'] ], 'outputs': [['success', 'int32_t']] # PP_Bool }, - # Get the ring buffer. - {'name': 'PPB_Graphics3DTrusted_GetRingBuffer', - 'inputs': [['resource_id', 'PP_Resource']], - 'outputs': [['shm_desc', 'handle'], - ['shm_size', 'int32_t'] - ] + # Set the buffer used for commands. + {'name': 'PPB_Graphics3DTrusted_SetGetBuffer', + 'inputs': [['resource_id', 'PP_Resource'], + ['shm_id', 'int32_t'], + ], + 'outputs': [] }, # Get command buffer state. {'name': 'PPB_Graphics3DTrusted_GetState', @@ -142,6 +141,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 20ebd55..e5739ba 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,7 +1435,6 @@ 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", @@ -1443,29 +1442,26 @@ NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcError retval; retval = NaClSrpcInvokeBySignature( channel, - "PPB_Graphics3DTrusted_InitCommandBuffer:ii:i", + "PPB_Graphics3DTrusted_InitCommandBuffer:i:i", resource_id, - size, success ); return retval; } -NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetRingBuffer( +NaClSrpcError PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_SetGetBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, - NaClSrpcImcDescType* shm_desc, - int32_t* shm_size) { + int32_t transfer_buffer_id) { VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(), ("%s: PPAPI calls are not supported off the main thread\n", __FUNCTION__)); NaClSrpcError retval; retval = NaClSrpcInvokeBySignature( channel, - "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", + "PPB_Graphics3DTrusted_SetGetBuffer:ii:", resource_id, - shm_desc, - shm_size + transfer_buffer_id ); 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 54187d0..b40fd2d 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,23 +1160,22 @@ static void PPB_Graphics3DTrusted_InitCommandBufferDispatcher( rpc, done, inputs[0]->u.ival, - inputs[1]->u.ival, &(outputs[0]->u.ival) ); } -static void PPB_Graphics3DTrusted_GetRingBufferDispatcher( +static void PPB_Graphics3DTrusted_SetGetBufferDispatcher( NaClSrpcRpc* rpc, NaClSrpcArg** inputs, NaClSrpcArg** outputs, NaClSrpcClosure* done ) { - PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_GetRingBuffer( + UNREFERENCED_PARAMETER(outputs); + PpbGraphics3DRpcServer::PPB_Graphics3DTrusted_SetGetBuffer( rpc, done, inputs[0]->u.ival, - &(outputs[0]->u.hval), - &(outputs[1]->u.ival) + inputs[1]->u.ival ); } @@ -2619,8 +2618,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:ii:i", PPB_Graphics3DTrusted_InitCommandBufferDispatcher }, - { "PPB_Graphics3DTrusted_GetRingBuffer:i:hi", PPB_Graphics3DTrusted_GetRingBufferDispatcher }, + { "PPB_Graphics3DTrusted_InitCommandBuffer:i:i", PPB_Graphics3DTrusted_InitCommandBufferDispatcher }, + { "PPB_Graphics3DTrusted_SetGetBuffer:ii:", PPB_Graphics3DTrusted_SetGetBufferDispatcher }, { "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 25feea6..588be46 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,14 +590,12 @@ class PpbGraphics3DRpcServer { NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, - int32_t size, int32_t* success); - static void PPB_Graphics3DTrusted_GetRingBuffer( + static void PPB_Graphics3DTrusted_SetGetBuffer( NaClSrpcRpc* rpc, NaClSrpcClosure* done, PP_Resource resource_id, - NaClSrpcImcDescType* shm_desc, - int32_t* shm_size); + int32_t shm_id); 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 aa2f7d0..1eee263 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,13 +515,11 @@ class PpbGraphics3DRpcClient { static NaClSrpcError PPB_Graphics3DTrusted_InitCommandBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, - int32_t size, int32_t* success); - static NaClSrpcError PPB_Graphics3DTrusted_GetRingBuffer( + static NaClSrpcError PPB_Graphics3DTrusted_SetGetBuffer( NaClSrpcChannel* channel, PP_Resource resource_id, - NaClSrpcImcDescType* shm_desc, - int32_t* shm_size); + int32_t shm_id); 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 32ac229..67d0166 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -834,10 +834,11 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBGraphics3D_Create, PP_Instance /* instance */, std::vector<int32_t> /* attrib_list */, ppapi::HostResource /* result */) -IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer, +IPC_SYNC_MESSAGE_ROUTED1_0(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer, + ppapi::HostResource /* context */) +IPC_SYNC_MESSAGE_ROUTED2_0(PpapiHostMsg_PPBGraphics3D_SetGetBuffer, ppapi::HostResource /* context */, - int32 /* size */, - base::SharedMemoryHandle /* ring_buffer */) + int32 /* transfer_buffer_id */) 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 8203e8d..b5a2dee 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_3d_proxy.cc @@ -31,13 +31,12 @@ class CommandBuffer : public gpu::CommandBuffer { virtual ~CommandBuffer(); // gpu::CommandBuffer implementation: - virtual bool Initialize(int32 size); - virtual bool Initialize(base::SharedMemory* buffer, int32 size); - virtual gpu::Buffer GetRingBuffer(); + virtual bool Initialize(); 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, @@ -53,9 +52,6 @@ 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_; @@ -69,8 +65,7 @@ class CommandBuffer : public gpu::CommandBuffer { CommandBuffer::CommandBuffer(const HostResource& resource, PluginDispatcher* dispatcher) - : num_entries_(0), - resource_(resource), + : resource_(resource), dispatcher_(dispatcher) { } @@ -84,47 +79,9 @@ CommandBuffer::~CommandBuffer() { } } -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; +bool CommandBuffer::Initialize() { + return Send(new PpapiHostMsg_PPBGraphics3D_InitCommandBuffer( + API_ID_PPB_GRAPHICS_3D, resource_)); } gpu::CommandBuffer::State CommandBuffer::GetState() { @@ -175,6 +132,13 @@ 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(); @@ -338,17 +302,17 @@ bool Graphics3D::Init() { return false; command_buffer_.reset(new CommandBuffer(host_resource(), dispatcher)); - if (!command_buffer_->Initialize(kCommandBufferSize)) + if (!command_buffer_->Initialize()) return false; return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize); } -PP_Bool Graphics3D::InitCommandBuffer(int32_t size) { +PP_Bool Graphics3D::InitCommandBuffer() { return PP_FALSE; } -PP_Bool Graphics3D::GetRingBuffer(int* shm_handle, uint32_t* shm_size) { +PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) { return PP_FALSE; } @@ -449,6 +413,8 @@ 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, @@ -488,22 +454,21 @@ void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance, } void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer( - const HostResource& context, - int32 size, - base::SharedMemoryHandle* ring_buffer) { - *ring_buffer = base::SharedMemory::NULLHandle(); + const HostResource& context) { EnterHostFromHostResource<PPB_Graphics3D_API> enter(context); if (enter.failed()) return; - if (!enter.object()->InitCommandBuffer(size)) + if (!enter.object()->InitCommandBuffer()) return; +} - 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::OnMsgSetGetBuffer( + const HostResource& context, + int32 transfer_buffer_id) { + EnterHostFromHostResource<PPB_Graphics3D_API> enter(context); + if (enter.succeeded()) + enter.object()->SetGetBuffer(transfer_buffer_id); } 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 887ae46..5a6c334 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 PPB_Graphics3D_Shared { } // Graphics3DTrusted API. These are not implemented in the proxy. - virtual PP_Bool InitCommandBuffer(int32_t size) OVERRIDE; - virtual PP_Bool GetRingBuffer(int* shm_handle, uint32_t* shm_size) OVERRIDE; + virtual PP_Bool InitCommandBuffer() OVERRIDE; + virtual PP_Bool SetGetBuffer(int32_t shm_id) 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, - int32 size, - base::SharedMemoryHandle* ring_buffer); + void OnMsgInitCommandBuffer(const HostResource& context); + void OnMsgSetGetBuffer(const HostResource& context, + int32 id); 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 73e8178..4e1980a 100644 --- a/ppapi/thunk/ppb_graphics_3d_api.h +++ b/ppapi/thunk/ppb_graphics_3d_api.h @@ -25,9 +25,8 @@ class PPAPI_THUNK_EXPORT PPB_Graphics3D_API { virtual int32_t SwapBuffers(PP_CompletionCallback callback) = 0; // Graphics3DTrusted API. - virtual PP_Bool InitCommandBuffer(int32_t size) = 0; - virtual PP_Bool GetRingBuffer(int* shm_handle, - uint32_t* shm_size) = 0; + virtual PP_Bool InitCommandBuffer() = 0; + virtual PP_Bool SetGetBuffer(int32_t shm_id) = 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 5cc9661..bea32ab 100644 --- a/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc +++ b/ppapi/thunk/ppb_graphics_3d_trusted_thunk.cc @@ -30,20 +30,18 @@ PP_Resource CreateRaw(PP_Instance instance, instance, share_context, attrib_list); } -PP_Bool InitCommandBuffer(PP_Resource context, int32_t size) { +PP_Bool InitCommandBuffer(PP_Resource context) { EnterGraphics3D enter(context, true); if (enter.failed()) return PP_FALSE; - return enter.object()->InitCommandBuffer(size); + return enter.object()->InitCommandBuffer(); } -PP_Bool GetRingBuffer(PP_Resource context, - int* shm_handle, - uint32_t* shm_size) { +PP_Bool SetGetBuffer(PP_Resource context, int32_t transfer_buffer_id) { EnterGraphics3D enter(context, true); if (enter.failed()) return PP_FALSE; - return enter.object()->GetRingBuffer(shm_handle, shm_size); + return enter.object()->SetGetBuffer(transfer_buffer_id); } PP_Graphics3DTrustedState GetState(PP_Resource context) { @@ -103,7 +101,7 @@ PP_Graphics3DTrustedState FlushSyncFast(PP_Resource context, const PPB_Graphics3DTrusted g_ppb_graphics_3d_trusted_thunk = { &CreateRaw, &InitCommandBuffer, - &GetRingBuffer, + &SetGetBuffer, &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 9daaa74..dd1db2e 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -86,6 +86,7 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> { ~GLInProcessContext(); void PumpCommands(); + bool GetBufferChanged(int32 transfer_buffer_id); // Create a GLInProcessContext that renders directly to a view. The view and // the associated window must not be destroyed until the returned @@ -311,6 +312,10 @@ void GLInProcessContext::PumpCommands() { CHECK(state.error == ::gpu::error::kNoError); } +bool GLInProcessContext::GetBufferChanged(int32 transfer_buffer_id) { + return gpu_scheduler_->SetGetBuffer(transfer_buffer_id); +} + uint32 GLInProcessContext::GetParentTextureId() { return parent_texture_id_; } @@ -457,7 +462,7 @@ bool GLInProcessContext::Initialize(bool onscreen, } command_buffer_.reset(new CommandBufferService); - if (!command_buffer_->Initialize(kCommandBufferSize)) { + if (!command_buffer_->Initialize()) { LOG(ERROR) << "Could not initialize command buffer."; Destroy(); return false; @@ -523,6 +528,9 @@ bool GLInProcessContext::Initialize(bool onscreen, command_buffer_->SetPutOffsetChangeCallback( base::Bind(&GLInProcessContext::PumpCommands, base::Unretained(this))); + command_buffer_->SetGetBufferChangeCallback( + base::Bind( + &GLInProcessContext::GetBufferChanged, base::Unretained(this))); // Create the GLES2 helper, which writes the command buffer protocol. gles2_helper_.reset(new GLES2CmdHelper(command_buffer_.get())); diff --git a/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc b/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc index a9a811b..87b25a1 100644 --- a/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_graphics_3d_impl.cc @@ -88,14 +88,13 @@ PPB_Graphics3D_API* PPB_Graphics3D_Impl::AsPPB_Graphics3D_API() { return this; } -PP_Bool PPB_Graphics3D_Impl::InitCommandBuffer(int32_t size) { - return PP_FromBool(GetCommandBuffer()->Initialize(size)); +PP_Bool PPB_Graphics3D_Impl::InitCommandBuffer() { + return PP_FromBool(GetCommandBuffer()->Initialize()); } -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_Bool PPB_Graphics3D_Impl::SetGetBuffer(int32_t transfer_buffer_id) { + GetCommandBuffer()->SetGetBuffer(transfer_buffer_id); + return PP_TRUE; } PP_Graphics3DTrustedState PPB_Graphics3D_Impl::GetState() { @@ -192,7 +191,7 @@ bool PPB_Graphics3D_Impl::Init(PP_Resource share_context, return false; gpu::CommandBuffer* command_buffer = GetCommandBuffer(); - if (!command_buffer->Initialize(kCommandBufferSize)) + if (!command_buffer->Initialize()) 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 728f58a..088b2f9 100644 --- a/webkit/plugins/ppapi/ppb_graphics_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_graphics_3d_impl.h @@ -29,9 +29,8 @@ 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(int32_t size) OVERRIDE; - virtual PP_Bool GetRingBuffer(int* shm_handle, - uint32_t* shm_size) OVERRIDE; + virtual PP_Bool InitCommandBuffer() OVERRIDE; + virtual PP_Bool SetGetBuffer(int32_t transfer_buffer_id) OVERRIDE; virtual PP_Graphics3DTrustedState GetState() OVERRIDE; virtual int32_t CreateTransferBuffer(uint32_t size) OVERRIDE; virtual PP_Bool DestroyTransferBuffer(int32_t id) OVERRIDE; |