diff options
author | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-28 23:37:14 +0000 |
---|---|---|
committer | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-28 23:37:14 +0000 |
commit | ef16c174a500a841cf6a120dc4ef9fca89fac9f9 (patch) | |
tree | 8491a815c314e161a462f42c41c374403ce6ec8c | |
parent | d0a7409f5ad0c075d5208ea0eb93ff07868c6168 (diff) | |
download | chromium_src-ef16c174a500a841cf6a120dc4ef9fca89fac9f9.zip chromium_src-ef16c174a500a841cf6a120dc4ef9fca89fac9f9.tar.gz chromium_src-ef16c174a500a841cf6a120dc4ef9fca89fac9f9.tar.bz2 |
Rework FlushSync to return early if commands have been processed since the last update
BUG=80480
TEST=
Review URL: http://codereview.chromium.org/6883179
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83442 0039d316-1c4b-4281-b951-d872f2087c98
38 files changed, 211 insertions, 1439 deletions
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index de5e48a..d78f4bc 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -54,7 +54,8 @@ GpuCommandBufferStub::GpuCommandBufferStub( route_id_(route_id), renderer_id_(renderer_id), render_view_id_(render_view_id), - watchdog_(watchdog) { + watchdog_(watchdog), + task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } GpuCommandBufferStub::~GpuCommandBufferStub() { @@ -72,7 +73,6 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState); - IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer, @@ -135,7 +135,7 @@ void GpuCommandBufferStub::OnInitialize( parent_texture_id_)) { command_buffer_->SetPutOffsetChangeCallback( NewCallback(scheduler_.get(), - &gpu::GpuScheduler::ProcessCommands)); + &gpu::GpuScheduler::PutChanged)); scheduler_->SetSwapBuffersCallback( NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); scheduler_->SetLatchCallback(base::Bind( @@ -176,17 +176,16 @@ void GpuCommandBufferStub::OnCommandProcessed() { void GpuCommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) { *state = command_buffer_->GetState(); -} - -void GpuCommandBufferStub::OnAsyncGetState() { - gpu::CommandBuffer::State state = command_buffer_->GetState(); - Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); + if (state->error == gpu::error::kLostContext && + gfx::GLContext::LosesAllContextsOnContextLost()) + channel_->LoseAllContexts(); } void GpuCommandBufferStub::OnFlush(int32 put_offset, + int32 last_known_get, gpu::CommandBuffer::State* state) { GPU_TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnFlush"); - *state = command_buffer_->FlushSync(put_offset); + *state = command_buffer_->FlushSync(put_offset, last_known_get); if (state->error == gpu::error::kLostContext && gfx::GLContext::LosesAllContextsOnContextLost()) channel_->LoseAllContexts(); @@ -194,12 +193,11 @@ void GpuCommandBufferStub::OnFlush(int32 put_offset, void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) { GPU_TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnAsyncFlush"); - gpu::CommandBuffer::State state = command_buffer_->FlushSync(put_offset); - if (state.error == gpu::error::kLostContext && - gfx::GLContext::LosesAllContextsOnContextLost()) - channel_->LoseAllContexts(); - else - Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); + command_buffer_->Flush(put_offset); + // TODO(piman): Do this everytime the scheduler finishes processing a batch of + // commands. + MessageLoop::current()->PostTask(FROM_HERE, + task_factory_.NewRunnableMethod(&GpuCommandBufferStub::ReportState)); } void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, @@ -346,4 +344,16 @@ void GpuCommandBufferStub::ViewResized() { #endif } +void GpuCommandBufferStub::ReportState() { + gpu::CommandBuffer::State state = command_buffer_->GetState(); + if (state.error == gpu::error::kLostContext && + gfx::GLContext::LosesAllContextsOnContextLost()) { + channel_->LoseAllContexts(); + } else { + IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); + msg->set_unblock(true); + Send(msg); + } +} + #endif // defined(ENABLE_GPU) diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 76df806..796ad8b 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/process.h" +#include "base/task.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/gpu_scheduler.h" #include "ipc/ipc_channel.h" @@ -81,8 +82,9 @@ class GpuCommandBufferStub int32 size, bool* result); void OnGetState(gpu::CommandBuffer::State* state); - void OnAsyncGetState(); - void OnFlush(int32 put_offset, gpu::CommandBuffer::State* state); + void OnFlush(int32 put_offset, + int32 last_known_get, + gpu::CommandBuffer::State* state); void OnAsyncFlush(int32 put_offset); void OnCreateTransferBuffer(int32 size, int32 id_request, int32* id); void OnRegisterTransferBuffer(base::SharedMemoryHandle transfer_buffer, @@ -104,6 +106,7 @@ class GpuCommandBufferStub #endif // defined(OS_MACOSX) void ResizeCallback(gfx::Size size); + void ReportState(); // The lifetime of objects of this class is managed by a GpuChannel. The // GpuChannels destroy all the GpuCommandBufferStubs that they own when they @@ -127,6 +130,7 @@ class GpuCommandBufferStub scoped_ptr<gpu::CommandBufferService> command_buffer_; scoped_ptr<gpu::GpuScheduler> scheduler_; GpuWatchdog* watchdog_; + ScopedRunnableMethodFactory<GpuCommandBufferStub> task_factory_; DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub); }; diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index a5f6337..3dc7958 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -342,14 +342,11 @@ IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_Initialize, IPC_SYNC_MESSAGE_ROUTED0_1(GpuCommandBufferMsg_GetState, gpu::CommandBuffer::State /* state */) -// Get the current state of the command buffer asynchronously. State is -// returned via UpdateState message. -IPC_MESSAGE_ROUTED0(GpuCommandBufferMsg_AsyncGetState) - // Synchronize the put and get offsets of both processes. Caller passes its // current put offset. Current state (including get offset) is returned. -IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_Flush, +IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_Flush, int32 /* put_offset */, + int32 /* last_known_get */, gpu::CommandBuffer::State /* state */) // Asynchronously synchronize the put and get offsets of both processes. diff --git a/content/renderer/command_buffer_proxy.cc b/content/renderer/command_buffer_proxy.cc index 42af276..6a1c06c 100644 --- a/content/renderer/command_buffer_proxy.cc +++ b/content/renderer/command_buffer_proxy.cc @@ -140,23 +140,37 @@ Buffer CommandBufferProxy::GetRingBuffer() { gpu::CommandBuffer::State CommandBufferProxy::GetState() { // Send will flag state with lost context if IPC fails. - if (last_state_.error == gpu::error::kNoError) - Send(new GpuCommandBufferMsg_GetState(route_id_, &last_state_)); + if (last_state_.error == gpu::error::kNoError) { + gpu::CommandBuffer::State state; + if (Send(new GpuCommandBufferMsg_GetState(route_id_, &state))) + OnUpdateState(state); + } return last_state_; } void CommandBufferProxy::Flush(int32 put_offset) { - AsyncFlush(put_offset, NULL); + if (last_state_.error != gpu::error::kNoError) + return; + + Send(new GpuCommandBufferMsg_AsyncFlush(route_id_, put_offset)); } -gpu::CommandBuffer::State CommandBufferProxy::FlushSync(int32 put_offset) { +gpu::CommandBuffer::State CommandBufferProxy::FlushSync(int32 put_offset, + int32 last_known_get) { GPU_TRACE_EVENT0("gpu", "CommandBufferProxy::FlushSync"); - // Send will flag state with lost context if IPC fails. - if (last_state_.error == gpu::error::kNoError) { - Send(new GpuCommandBufferMsg_Flush(route_id_, - put_offset, - &last_state_)); + if (last_known_get == last_state_.get_offset) { + // Send will flag state with lost context if IPC fails. + if (last_state_.error == gpu::error::kNoError) { + gpu::CommandBuffer::State state; + if (Send(new GpuCommandBufferMsg_Flush(route_id_, + put_offset, + last_known_get, + &state))) + OnUpdateState(state); + } + } else { + Flush(put_offset); } return last_state_; @@ -345,37 +359,6 @@ void CommandBufferProxy::SetWindowSize(const gfx::Size& size) { } #endif -void CommandBufferProxy::AsyncGetState(Task* completion_task) { - if (last_state_.error != gpu::error::kNoError) - return; - - IPC::Message* message = new GpuCommandBufferMsg_AsyncGetState(route_id_); - - // Do not let a synchronous flush hold up this message. If this handler is - // deferred until after the synchronous flush completes, it will overwrite the - // cached last_state_ with out-of-date data. - message->set_unblock(true); - - if (Send(message)) - pending_async_flush_tasks_.push(linked_ptr<Task>(completion_task)); -} - -void CommandBufferProxy::AsyncFlush(int32 put_offset, Task* completion_task) { - if (last_state_.error != gpu::error::kNoError) - return; - - IPC::Message* message = new GpuCommandBufferMsg_AsyncFlush(route_id_, - put_offset); - - // Do not let a synchronous flush hold up this message. If this handler is - // deferred until after the synchronous flush completes, it will overwrite the - // cached last_state_ with out-of-date data. - message->set_unblock(true); - - if (Send(message)) - pending_async_flush_tasks_.push(linked_ptr<Task>(completion_task)); -} - bool CommandBufferProxy::Send(IPC::Message* msg) { // Caller should not intentionally send a message if the context is lost. DCHECK(last_state_.error == gpu::error::kNoError); @@ -399,16 +382,8 @@ bool CommandBufferProxy::Send(IPC::Message* msg) { } void CommandBufferProxy::OnUpdateState(const gpu::CommandBuffer::State& state) { - last_state_ = state; - - linked_ptr<Task> task = pending_async_flush_tasks_.front(); - pending_async_flush_tasks_.pop(); - - if (task.get()) { - // Although we need need to update last_state_ while potentially waiting - // for a synchronous flush to complete, we do not need to invoke the - // callback synchonously. Also, post it as a non nestable task so it is - // always invoked by the outermost message loop. - MessageLoop::current()->PostNonNestableTask(FROM_HERE, task.release()); - } + // Handle wraparound. It works as long as we don't have more than 2B state + // updates in flight across which reordering occurs. + if (state.generation - last_state_.generation < 0x80000000U) + last_state_ = state; } diff --git a/content/renderer/command_buffer_proxy.h b/content/renderer/command_buffer_proxy.h index e63150c..9cbd033 100644 --- a/content/renderer/command_buffer_proxy.h +++ b/content/renderer/command_buffer_proxy.h @@ -49,7 +49,7 @@ class CommandBufferProxy : public gpu::CommandBuffer, virtual gpu::Buffer GetRingBuffer(); virtual State GetState(); virtual void Flush(int32 put_offset); - virtual State FlushSync(int32 put_offset); + virtual State FlushSync(int32 put_offset, int32 last_known_get); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size, int32 id_request); virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -82,14 +82,6 @@ class CommandBufferProxy : public gpu::CommandBuffer, return last_state_; } - // Get the state asynchronously. The task is posted when the state is - // updated. Takes ownership of the task object. - void AsyncGetState(Task* completion_task); - - // Flush the command buffer asynchronously. The task is posted when the flush - // completes. Takes ownership of the task object. - void AsyncFlush(int32 put_offset, Task* completion_task); - private: // Send an IPC message over the GPU channel. This is private to fully @@ -115,10 +107,6 @@ class CommandBufferProxy : public gpu::CommandBuffer, IPC::Channel::Sender* channel_; int route_id_; - // Pending asynchronous flush callbacks. - typedef std::queue<linked_ptr<Task> > AsyncFlushTaskQueue; - AsyncFlushTaskQueue pending_async_flush_tasks_; - scoped_ptr<Task> notify_repaint_task_; scoped_ptr<Callback0::Type> swap_buffers_callback_; diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index 8da55b69..1054055 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -49,7 +49,7 @@ CommandBufferHelper::~CommandBufferHelper() { bool CommandBufferHelper::FlushSync() { last_put_sent_ = put_; - CommandBuffer::State state = command_buffer_->FlushSync(put_); + CommandBuffer::State state = command_buffer_->FlushSync(put_, get_); SynchronizeState(state); return state.error == error::kNoError; } diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc index 1daa942..56eaa0a 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -80,7 +80,7 @@ class CommandBufferHelperTest : public testing::Test { gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_, 1)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_scheduler_.get(), &GpuScheduler::ProcessCommands)); + gpu_scheduler_.get(), &GpuScheduler::PutChanged)); api_mock_->set_engine(gpu_scheduler_.get()); diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc index 533e867..3bf9bd8 100644 --- a/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/gpu/command_buffer/client/fenced_allocator_test.cc @@ -54,7 +54,7 @@ class BaseFencedAllocatorTest : public testing::Test { gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_, INT_MAX)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_scheduler_.get(), &GpuScheduler::ProcessCommands)); + gpu_scheduler_.get(), &GpuScheduler::PutChanged)); api_mock_->set_engine(gpu_scheduler_.get()); diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc index 096a9d3..54a3b89 100644 --- a/gpu/command_buffer/client/gles2_demo.cc +++ b/gpu/command_buffer/client/gles2_demo.cc @@ -68,7 +68,7 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) { } command_buffer->SetPutOffsetChangeCallback( - NewCallback(gpu_scheduler, &GpuScheduler::ProcessCommands)); + NewCallback(gpu_scheduler, &GpuScheduler::PutChanged)); GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); if (!helper->Initialize(size)) { diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 5665b96..68f2e6b 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -50,7 +50,7 @@ class GLES2MockCommandBufferHelper : public CommandBuffer { state_.put_offset = put_offset; } - virtual State FlushSync(int32 put_offset) { + 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); diff --git a/gpu/command_buffer/client/mapped_memory_unittest.cc b/gpu/command_buffer/client/mapped_memory_unittest.cc index 93e63e7..067c8e6 100644 --- a/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -52,7 +52,7 @@ class MappedMemoryTestBase : public testing::Test { gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_, INT_MAX)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_scheduler_.get(), &GpuScheduler::ProcessCommands)); + gpu_scheduler_.get(), &GpuScheduler::PutChanged)); api_mock_->set_engine(gpu_scheduler_.get()); diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc index e3c14c7..1ccd979 100644 --- a/gpu/command_buffer/client/ring_buffer_test.cc +++ b/gpu/command_buffer/client/ring_buffer_test.cc @@ -55,7 +55,7 @@ class BaseRingBufferTest : public testing::Test { gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_, INT_MAX)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_scheduler_.get(), &GpuScheduler::ProcessCommands)); + gpu_scheduler_.get(), &GpuScheduler::PutChanged)); api_mock_->set_engine(gpu_scheduler_.get()); diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h index 4cbcef1..d438f72 100644 --- a/gpu/command_buffer/common/command_buffer.h +++ b/gpu/command_buffer/common/command_buffer.h @@ -27,7 +27,8 @@ class CommandBuffer { get_offset(0), put_offset(0), token(-1), - error(error::kNoError) { + error(error::kNoError), + generation(0) { } // Size of the command buffer in command buffer entries. @@ -48,6 +49,11 @@ class CommandBuffer { // Error status. error::Error error; + + // Generation index of this state. The generation index is incremented every + // time a new state is retrieved from the command processor, so that + // consistency can be kept even if IPC messages are processed out-of-order. + uint32 generation; }; CommandBuffer() { @@ -75,10 +81,11 @@ class CommandBuffer { // The writer calls this to update its put offset. This function returns the // reader's most recent get offset. Does not return until after the put offset // change callback has been invoked. Returns -1 if the put offset is invalid. - // As opposed to Flush(), this function guarantees that the reader has - // processed some commands before returning (assuming the command buffer isn't - // empty and there is no error). - virtual State FlushSync(int32 put_offset) = 0; + // If last_known_get is different from the reader's current get pointer, this + // function will return immediately, otherwise it guarantees that the reader + // has processed some commands before returning (assuming the command buffer + // isn't empty and there is no error). + virtual State FlushSync(int32 put_offset, int32 last_known_get) = 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.h b/gpu/command_buffer/common/command_buffer_mock.h index 8281f7f..4da8e82 100644 --- a/gpu/command_buffer/common/command_buffer_mock.h +++ b/gpu/command_buffer/common/command_buffer_mock.h @@ -26,7 +26,7 @@ class MockCommandBuffer : public CommandBuffer { MOCK_METHOD0(GetRingBuffer, Buffer()); MOCK_METHOD0(GetState, State()); MOCK_METHOD1(Flush, void(int32 put_offset)); - MOCK_METHOD1(FlushSync, State(int32 put_offset)); + MOCK_METHOD2(FlushSync, State(int32 put_offset, int32 last_known_get)); 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/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc index 86453eb..bc36fa3 100644 --- a/gpu/command_buffer/service/command_buffer_service.cc +++ b/gpu/command_buffer/service/command_buffer_service.cc @@ -19,6 +19,7 @@ CommandBufferService::CommandBufferService() get_offset_(0), put_offset_(0), token_(0), + generation_(0), error_(error::kNoError) { // Element zero is always NULL. registered_objects_.push_back(Buffer()); @@ -97,11 +98,13 @@ CommandBufferService::State CommandBufferService::GetState() { state.put_offset = put_offset_; state.token = token_; state.error = error_; + state.generation = ++generation_; return state; } -CommandBufferService::State CommandBufferService::FlushSync(int32 put_offset) { +CommandBufferService::State CommandBufferService::FlushSync( + int32 put_offset, int32 last_known_get) { if (put_offset < 0 || put_offset > num_entries_) { error_ = gpu::error::kOutOfBounds; return GetState(); @@ -110,14 +113,23 @@ CommandBufferService::State CommandBufferService::FlushSync(int32 put_offset) { put_offset_ = put_offset; if (put_offset_change_callback_.get()) { - put_offset_change_callback_->Run(); + put_offset_change_callback_->Run(last_known_get == get_offset_); } return GetState(); } void CommandBufferService::Flush(int32 put_offset) { - FlushSync(put_offset); + if (put_offset < 0 || put_offset > num_entries_) { + error_ = gpu::error::kOutOfBounds; + return; + } + + put_offset_ = put_offset; + + if (put_offset_change_callback_.get()) { + put_offset_change_callback_->Run(false); + } } void CommandBufferService::SetGetOffset(int32 get_offset) { @@ -241,7 +253,7 @@ void CommandBufferService::SetParseError(error::Error error) { } void CommandBufferService::SetPutOffsetChangeCallback( - Callback0::Type* callback) { + Callback1<bool>::Type* callback) { put_offset_change_callback_.reset(callback); } diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h index a83a4e5..a9bc9dfc 100644 --- a/gpu/command_buffer/service/command_buffer_service.h +++ b/gpu/command_buffer/service/command_buffer_service.h @@ -30,7 +30,7 @@ class CommandBufferService : public CommandBuffer { virtual Buffer GetRingBuffer(); virtual State GetState(); virtual void Flush(int32 put_offset); - virtual State FlushSync(int32 put_offset); + virtual State FlushSync(int32 put_offset, int32 last_known_get); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size, int32 id_request); virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -41,27 +41,26 @@ class CommandBufferService : public CommandBuffer { virtual void SetToken(int32 token); virtual void SetParseError(error::Error error); - // Sets a callback that should be posted on another thread whenever the put - // offset is changed. The callback must not return until some progress has - // been made (unless the command buffer is empty), i.e. the - // get offset must have changed. It need not process the entire command - // buffer though. This allows concurrency between the writer and the reader - // while giving the writer a means of waiting for the reader to make some - // progress before attempting to write more to the command buffer. Avoiding - // the use of a synchronization primitive like a condition variable to - // synchronize reader and writer reduces the risk of deadlock. - // Takes ownership of callback. The callback is invoked on the plugin thread. - virtual void SetPutOffsetChangeCallback(Callback0::Type* callback); + // Sets a callback that is called whenever the put offset is changed. When + // called with sync==true, the callback must not return until some progress + // has been made (unless the command buffer is empty), i.e. the get offset + // must have changed. It need not process the entire command buffer though. + // This allows concurrency between the writer and the reader while giving the + // writer a means of waiting for the reader to make some progress before + // attempting to write more to the command buffer. Takes ownership of + // callback. + virtual void SetPutOffsetChangeCallback(Callback1<bool>::Type* callback); private: Buffer ring_buffer_; int32 num_entries_; int32 get_offset_; int32 put_offset_; - scoped_ptr<Callback0::Type> put_offset_change_callback_; + scoped_ptr<Callback1<bool>::Type> put_offset_change_callback_; std::vector<Buffer> registered_objects_; std::set<int32> unused_registered_object_elements_; int32 token_; + uint32 generation_; error::Error error_; }; diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index be47663..c1b7aaa 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -117,6 +117,16 @@ const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; } #endif +void GpuScheduler::PutChanged(bool sync) { + CommandBuffer::State state = command_buffer_->GetState(); + parser_->set_put(state.put_offset); + + if (sync) + ProcessCommands(); + else + ScheduleProcessCommands(); +} + void GpuScheduler::ProcessCommands() { GPU_TRACE_EVENT0("gpu", "GpuScheduler:ProcessCommands"); CommandBuffer::State state = command_buffer_->GetState(); @@ -134,8 +144,6 @@ void GpuScheduler::ProcessCommands() { } } - parser_->set_put(state.put_offset); - #if defined(OS_MACOSX) bool do_rate_limiting = surface_.get() != NULL; // Don't swamp the browser process with SwapBuffers calls it can't handle. diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 04784a7..ebb2368 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -61,7 +61,7 @@ class GpuScheduler : public CommandBufferEngine { void Destroy(); void DestroyCommon(); - virtual void ProcessCommands(); + void PutChanged(bool sync); // Sets whether commands should be processed by this scheduler. Setting to // false unschedules. Setting to true reschedules. Whether or not the @@ -108,14 +108,14 @@ class GpuScheduler : public CommandBufferEngine { // Sets a callback that is called when a glResizeCHROMIUM command // is processed. - virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback); + void SetResizeCallback(Callback1<gfx::Size>::Type* callback); // Sets a callback which is called when a SwapBuffers command is processed. // Must be called after Initialize(). // It is not defined on which thread this callback is called. - virtual void SetSwapBuffersCallback(Callback0::Type* callback); + void SetSwapBuffersCallback(Callback0::Type* callback); - virtual void SetCommandProcessedCallback(Callback0::Type* callback); + void SetCommandProcessedCallback(Callback0::Type* callback); // Sets a callback which is called after a Set/WaitLatch command is processed. // The bool parameter will be true for SetLatch, and false for a WaitLatch @@ -145,7 +145,8 @@ class GpuScheduler : public CommandBufferEngine { // Called via a callback just before we are supposed to call the // user's swap buffers callback. - virtual void WillSwapBuffers(); + void WillSwapBuffers(); + void ProcessCommands(); // The GpuScheduler holds a weak reference to the CommandBuffer. The // CommandBuffer owns the GpuScheduler and holds a strong reference to it diff --git a/gpu/command_buffer/service/gpu_scheduler_mock.h b/gpu/command_buffer/service/gpu_scheduler_mock.h index 4bc1bb5..ed308e0 100644 --- a/gpu/command_buffer/service/gpu_scheduler_mock.h +++ b/gpu/command_buffer/service/gpu_scheduler_mock.h @@ -16,7 +16,6 @@ class MockGpuScheduler : public GpuScheduler { : GpuScheduler(command_buffer) { } - MOCK_METHOD0(ProcessCommands, void()); MOCK_METHOD1(GetSharedMemoryBuffer, Buffer(int32 shm_id)); MOCK_METHOD1(set_token, void(int32 token)); diff --git a/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/gpu/command_buffer/service/gpu_scheduler_unittest.cc index b992fa7..a7f17b9 100644 --- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc +++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc @@ -92,13 +92,13 @@ TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) { state.put_offset = 0; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(0)); EXPECT_CALL(*command_buffer_, SetParseError(_)) .Times(0); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, ProcessesOneCommand) { @@ -111,7 +111,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) { state.put_offset = 2; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(2)); EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) @@ -120,7 +120,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) { EXPECT_CALL(*command_buffer_, SetParseError(_)) .Times(0); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { @@ -135,7 +135,7 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { state.put_offset = 3; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(3)); EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) @@ -144,7 +144,7 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) .WillOnce(Return(error::kNoError)); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, SchedulerSetsTheGLContext) { @@ -155,11 +155,11 @@ TEST_F(GpuSchedulerTest, SchedulerSetsTheGLContext) { CommandBuffer::State state; state.put_offset = 0; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*command_buffer_, SetGetOffset(0)); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, PostsTaskToFinishRemainingCommands) { @@ -176,7 +176,7 @@ TEST_F(GpuSchedulerTest, PostsTaskToFinishRemainingCommands) { state.put_offset = 4; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) .WillOnce(Return(error::kNoError)); @@ -186,13 +186,13 @@ TEST_F(GpuSchedulerTest, PostsTaskToFinishRemainingCommands) { EXPECT_CALL(*command_buffer_, SetGetOffset(3)); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); // ProcessCommands is called a second time when the pending task is run. state.put_offset = 4; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) .WillOnce(Return(error::kNoError)); @@ -211,7 +211,7 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { state.put_offset = 1; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) .WillOnce(Return( @@ -220,7 +220,7 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { EXPECT_CALL(*command_buffer_, SetParseError(error::kUnknownCommand)); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) { @@ -228,9 +228,9 @@ TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) { state.error = error::kGenericError; EXPECT_CALL(*command_buffer_, GetState()) - .WillOnce(Return(state)); + .WillRepeatedly(Return(state)); - scheduler_->ProcessCommands(); + scheduler_->PutChanged(true); } TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) { diff --git a/gpu/demos/framework/Plugin_Info.plist b/gpu/demos/framework/Plugin_Info.plist deleted file mode 100644 index 4a4e455..0000000 --- a/gpu/demos/framework/Plugin_Info.plist +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleGetInfoString</key> - <string>Copyright 2010 Google, Inc.</string> - <key>CFBundleIdentifier</key> - <string>com.google.peppergpudemoplugin</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>BRPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>CFPlugInDynamicRegisterFunction</key> - <string></string> - <key>CFPlugInDynamicRegistration</key> - <string>NO</string> - <key>WebPluginDescription</key> - <string>Simple Pepper plug-in that demonstrates 3D rendering.</string> - <key>WebPluginMIMETypes</key> - <dict> - <key>pepper-application/x-gpu-demo</key> - <dict> - <key>WebPluginExtensions</key> - <array> - <string>peppergpudemo</string> - </array> - <key>WebPluginTypeDescription</key> - <string>Pepper GPU Demo</string> - </dict> - </dict> - <key>WebPluginName</key> - <string>Pepper GPU Demo</string> -</dict> -</plist> diff --git a/gpu/demos/framework/plugin.cc b/gpu/demos/framework/plugin.cc deleted file mode 100644 index db605e6..0000000 --- a/gpu/demos/framework/plugin.cc +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/demos/framework/plugin.h" - -#include <cassert> -#include "gpu/demos/framework/demo_factory.h" - -using gpu::demos::Plugin; - -namespace { -const int32 kCommandBufferSize = 1024 * 1024; -NPExtensions* g_extensions = NULL; - -// Plugin class functions. -NPObject* PluginAllocate(NPP npp, NPClass* the_class) { - Plugin* plugin = new Plugin(npp); - return plugin; -} - -void PluginDeallocate(NPObject* header) { - Plugin* plugin = static_cast<Plugin*>(header); - delete plugin; -} - -void PluginInvalidate(NPObject* obj) { -} - -bool PluginHasMethod(NPObject* obj, NPIdentifier name) { - return false; -} - -bool PluginInvoke(NPObject* header, - NPIdentifier name, - const NPVariant* args, uint32 arg_count, - NPVariant* result) { - return false; -} - -bool PluginInvokeDefault(NPObject* obj, - const NPVariant* args, uint32 arg_count, - NPVariant* result) { - VOID_TO_NPVARIANT(*result); - return true; -} - -bool PluginHasProperty(NPObject* obj, NPIdentifier name) { - return false; -} - -bool PluginGetProperty(NPObject* obj, - NPIdentifier name, - NPVariant* result) { - return false; -} - -bool PluginSetProperty(NPObject* obj, - NPIdentifier name, - const NPVariant* variant) { - return false; -} - -NPClass plugin_class = { - NP_CLASS_STRUCT_VERSION, - PluginAllocate, - PluginDeallocate, - PluginInvalidate, - PluginHasMethod, - PluginInvoke, - PluginInvokeDefault, - PluginHasProperty, - PluginGetProperty, - PluginSetProperty, -}; - -void TickCallback(void* data) { - reinterpret_cast<gpu::demos::Plugin*>(data)->Tick(); -} - -void RepaintCallback(NPP npp, NPDeviceContext3D* /* context */) { - Plugin* plugin = static_cast<Plugin*>(npp->pdata); - plugin->Paint(); -} -} - -namespace gpu { -namespace demos { - -NPNetscapeFuncs* g_browser; - -Plugin::Plugin(NPP npp) - : npp_(npp), - device3d_(NULL), - pgl_context_(NULL), - demo_(CreateDemo()) { - memset(&context3d_, 0, sizeof(context3d_)); -} - -Plugin::~Plugin() { - // Destroy demo while GL context is current and before it is destroyed. - pglMakeCurrent(pgl_context_); - demo_.reset(); - pglMakeCurrent(PGL_NO_CONTEXT); - - DestroyContext(); -} - -NPClass* Plugin::GetPluginClass() { - return &plugin_class; -} - -void Plugin::New(NPMIMEType pluginType, - int16 argc, char* argn[], char* argv[]) { - if (!g_extensions) { - g_browser->getvalue(npp_, NPNVPepperExtensions, &g_extensions); - assert(g_extensions); - } - - device3d_ = g_extensions->acquireDevice(npp_, NPPepper3DDevice); - assert(device3d_); -} - -void Plugin::SetWindow(const NPWindow& window) { - demo_->InitWindowSize(window.width, window.height); - - if (!pgl_context_) { - if (!CreateContext()) - return; - - // Schedule first call to Tick. - if (demo_->IsAnimated()) - g_browser->pluginthreadasynccall(npp_, TickCallback, this); - } -} - -int32 Plugin::HandleEvent(const NPPepperEvent& event) { - return 0; -} - -void Plugin::Tick() { - Paint(); - - // Schedule another call to Tick. - g_browser->pluginthreadasynccall(npp_, TickCallback, this); -} - -void Plugin::Paint() { - if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) { - DestroyContext(); - if (!CreateContext()) - return; - - pglMakeCurrent(pgl_context_); - } - - demo_->Draw(); - pglSwapBuffers(); - pglMakeCurrent(PGL_NO_CONTEXT); -} - -bool Plugin::CreateContext() { - assert(!pgl_context_); - - // Initialize a 3D context. - NPDeviceContext3DConfig config; - config.commandBufferSize = kCommandBufferSize; - if (NPERR_NO_ERROR != device3d_->initializeContext(npp_, - &config, - &context3d_)) { - DestroyContext(); - return false; - } - - context3d_.repaintCallback = RepaintCallback; - - // Create a PGL context. - pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_); - if (!pgl_context_) { - DestroyContext(); - return false; - } - - // Initialize demo. - pglMakeCurrent(pgl_context_); - if (!demo_->InitGL()) { - DestroyContext(); - return false; - } - - pglMakeCurrent(PGL_NO_CONTEXT); - - return true; -} - -void Plugin::DestroyContext() { - if (pgl_context_) { - pglDestroyContext(pgl_context_); - pgl_context_ = NULL; - } - - if (context3d_.commandBuffer) { - device3d_->destroyContext(npp_, &context3d_); - memset(&context3d_, 0, sizeof(context3d_)); - } -} - -} // namespace demos -} // namespace gpu diff --git a/gpu/demos/framework/plugin.def b/gpu/demos/framework/plugin.def deleted file mode 100644 index ddc24ce..0000000 --- a/gpu/demos/framework/plugin.def +++ /dev/null @@ -1,4 +0,0 @@ -EXPORTS - NP_GetEntryPoints @1 - NP_Initialize @2 - NP_Shutdown @3 diff --git a/gpu/demos/framework/plugin.h b/gpu/demos/framework/plugin.h deleted file mode 100644 index c892d2c..0000000 --- a/gpu/demos/framework/plugin.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_DEMOS_FRAMEWORK_PLUGIN_H_ -#define GPU_DEMOS_FRAMEWORK_PLUGIN_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "gpu/demos/framework/demo.h" -#include "gpu/pgl/pgl.h" -#include "third_party/npapi/bindings/nphostapi.h" - -namespace gpu { -namespace demos { - -// Acts as a framework for pepper3d demos. It is in fact a pepper plugin with -// a pepper3d device. It delegates all rendering tasks to demo object. -class Plugin : public NPObject { - public: - explicit Plugin(NPP npp); - ~Plugin(); - - static NPClass* GetPluginClass(); - - NPP npp() const { return npp_; } - void New(NPMIMEType pluginType, int16 argc, char* argn[], char* argv[]); - void SetWindow(const NPWindow& window); - int32 HandleEvent(const NPPepperEvent& event); - - // Called continuously for animated demos. - void Tick(); - - // Called by the browser to paint the window. - void Paint(); - - private: - bool CreateContext(); - void DestroyContext(); - - // This class object needs to be safely casted to NPObject* and cross - // c-c++ module boundaries. To accomplish that this class should not have - // any virtual member function. - NPP npp_; - - NPDevice* device3d_; - NPDeviceContext3D context3d_; - PGLContext pgl_context_; - scoped_ptr<Demo> demo_; - - DISALLOW_COPY_AND_ASSIGN(Plugin); -}; - -extern NPNetscapeFuncs* g_browser; - -} // namespace demos -} // namespace gpu -#endif // GPU_DEMOS_FRAMEWORK_PLUGIN_H_ diff --git a/gpu/demos/framework/plugin.rc b/gpu/demos/framework/plugin.rc deleted file mode 100644 index ee6b4fa..0000000 --- a/gpu/demos/framework/plugin.rc +++ /dev/null @@ -1,35 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-1 VERSIONINFO
- FILEVERSION 1,0,0,1
- PRODUCTVERSION 1,0,0,1
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x7L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Pepper GPU Demo"
- VALUE "FileVersion", "1, 0, 0, 1"
- VALUE "LegalCopyright", "Copyright (C) 2010"
- VALUE "ProductName", "Pepper GPU Demo"
- VALUE "ProductVersion", "1, 0, 0, 1"
- VALUE "MIMEType", "pepper-application/x-gpu-demo"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 974a5ee..a0eedcc 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -69,7 +69,7 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { } command_buffer->SetPutOffsetChangeCallback( - NewCallback(gpu_scheduler, &GpuScheduler::ProcessCommands)); + NewCallback(gpu_scheduler, &GpuScheduler::PutChanged)); GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); if (!helper->Initialize(kCommandBufferSize)) { diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 7faead9..86cc084 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -353,30 +353,6 @@ ], }, { - 'target_name': 'pgl', - 'type': 'static_library', - 'dependencies': [ - 'command_buffer_client', - 'gles2_c_lib', - '../third_party/npapi/npapi.gyp:npapi', - ], - 'include_dirs': [ - '..', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '../third_party/npapi/bindings', - ], - }, - 'sources': [ - 'pgl/command_buffer_pepper.cc', - 'pgl/command_buffer_pepper.h', - 'pgl/pgl_proc_address.cc', - 'pgl/pgl.cc', - 'pgl/pgl.h', - ], - }, - { 'target_name': 'gpu_ipc', 'type': 'static_library', 'dependencies': [ diff --git a/gpu/ipc/gpu_command_buffer_traits.cc b/gpu/ipc/gpu_command_buffer_traits.cc index eecf19f..66d4189 100644 --- a/gpu/ipc/gpu_command_buffer_traits.cc +++ b/gpu/ipc/gpu_command_buffer_traits.cc @@ -13,6 +13,7 @@ void ParamTraits<gpu::CommandBuffer::State> ::Write(Message* m, WriteParam(m, p.put_offset); WriteParam(m, p.token); WriteParam(m, static_cast<int32>(p.error)); + WriteParam(m, p.generation); } bool ParamTraits<gpu::CommandBuffer::State> ::Read(const Message* m, @@ -23,7 +24,8 @@ bool ParamTraits<gpu::CommandBuffer::State> ::Read(const Message* m, ReadParam(m, iter, &p->get_offset) && ReadParam(m, iter, &p->put_offset) && ReadParam(m, iter, &p->token) && - ReadParam(m, iter, &temp)) { + ReadParam(m, iter, &temp) && + ReadParam(m, iter, &p->generation)) { p->error = static_cast<gpu::error::Error>(temp); return true; } else { diff --git a/gpu/pgl/command_buffer_pepper.cc b/gpu/pgl/command_buffer_pepper.cc deleted file mode 100644 index 38b642e..0000000 --- a/gpu/pgl/command_buffer_pepper.cc +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/pgl/command_buffer_pepper.h" - -#include "gpu/command_buffer/common/logging.h" - -using base::SharedMemory; -using gpu::Buffer; -using gpu::CommandBuffer; - -CommandBufferPepper::CommandBufferPepper(NPP npp, - NPDevice* device, - NPDeviceContext3D* context) - : npp_(npp), - device_(device), - context_(context) { -} - -CommandBufferPepper::~CommandBufferPepper() { -} - -// Not implemented in CommandBufferPepper. -bool CommandBufferPepper::Initialize(int32 size) { - GPU_NOTREACHED(); - return false; -} - -bool CommandBufferPepper::Initialize(base::SharedMemory* buffer, int32 size) { - GPU_NOTREACHED(); - return false; -} - -Buffer CommandBufferPepper::GetRingBuffer() { - Buffer buffer; -#if defined(ENABLE_NEW_NPDEVICE_API) - NPDeviceBuffer np_buffer; - device_->mapBuffer(npp_, - context_, - NP3DCommandBufferId, - &np_buffer); - buffer.ptr = np_buffer.ptr; - buffer.size = np_buffer.size; -#else - buffer.ptr = context_->commandBuffer; - buffer.size = context_->commandBufferSize * sizeof(int32); -#endif - return buffer; -} - -CommandBuffer::State CommandBufferPepper::GetState() { -#if defined(ENABLE_NEW_NPDEVICE_API) - int32 output_attribs[] = { - NP3DAttrib_CommandBufferSize, 0, - NP3DAttrib_GetOffset, 0, - NP3DAttrib_PutOffset, 0, - NP3DAttrib_Token, 0, - NPAttrib_Error, 0, - NPAttrib_End - }; - device_->synchronizeContext(npp_, - context_, - NPDeviceSynchronizationMode_Immediate, - NULL, - output_attribs, - NULL, - NULL); - - CommandBuffer::State state; - state.num_entries = output_attribs[1]; - state.get_offset = output_attribs[3]; - state.put_offset = output_attribs[5]; - state.token = output_attribs[7]; - state.error = static_cast<gpu::error::Error>( - output_attribs[9]); - - return state; -#else - context_->waitForProgress = false; - - if (NPERR_NO_ERROR != device_->flushContext(npp_, context_, NULL, NULL)) - context_->error = NPDeviceContext3DError_GenericError; - - context_->waitForProgress = true; - - return ConvertState(); -#endif // ENABLE_NEW_NPDEVICE_API -} - -void CommandBufferPepper::Flush(int32 put_offset) { - FlushSync(put_offset); -} - -CommandBuffer::State CommandBufferPepper::FlushSync(int32 put_offset) { -#if defined(ENABLE_NEW_NPDEVICE_API) - int32 input_attribs[] = { - NP3DAttrib_PutOffset, put_offset, - NPAttrib_End - }; - int32 output_attribs[] = { - NP3DAttrib_CommandBufferSize, 0, - NP3DAttrib_GetOffset, 0, - NP3DAttrib_PutOffset, 0, - NP3DAttrib_Token, 0, - NPAttrib_Error, 0, - NPAttrib_End - }; - device_->synchronizeContext(npp_, - context_, - NPDeviceSynchronizationMode_Flush, - input_attribs, - output_attribs, - NULL, - NULL); - - CommandBuffer::State state; - state.num_entries = output_attribs[1]; - state.get_offset = output_attribs[3]; - state.put_offset = output_attribs[5]; - state.token = output_attribs[7]; - state.error = static_cast<gpu::error::Error>( - output_attribs[9]); - - return state; -#else - context_->waitForProgress = true; - context_->putOffset = put_offset; - - if (NPERR_NO_ERROR != device_->flushContext(npp_, context_, NULL, NULL)) - context_->error = NPDeviceContext3DError_GenericError; - - return ConvertState(); -#endif // ENABLE_NEW_NPDEVICE_API -} - -void CommandBufferPepper::SetGetOffset(int32 get_offset) { - // Not implemented by proxy. - GPU_NOTREACHED(); -} - -int32 CommandBufferPepper::CreateTransferBuffer(size_t size, int32 id_request) { - int32_t id; - if (NPERR_NO_ERROR != device_->createBuffer(npp_, context_, size, &id)) - return -1; - - return static_cast<int32>(id); -} - -int32 CommandBufferPepper::RegisterTransferBuffer( - base::SharedMemory* shared_memory, - size_t size, - int32 id_request) { - // Not implemented by proxy. - GPU_NOTREACHED(); - return -1; -} - -void CommandBufferPepper::DestroyTransferBuffer(int32 id) { - device_->destroyBuffer(npp_, context_, id); -} - -Buffer CommandBufferPepper::GetTransferBuffer(int32 id) { - NPDeviceBuffer np_buffer; - if (NPERR_NO_ERROR != device_->mapBuffer(npp_, context_, id, &np_buffer)) - return Buffer(); - - Buffer buffer; - buffer.ptr = np_buffer.ptr; - buffer.size = np_buffer.size; - return buffer; -} - -void CommandBufferPepper::SetToken(int32 token) { - // Not implemented by proxy. - GPU_NOTREACHED(); -} - -void CommandBufferPepper::SetParseError( - gpu::error::Error error) { - // Not implemented by proxy. - GPU_NOTREACHED(); -} - -gpu::error::Error CommandBufferPepper::GetCachedError() { - int32_t attrib_list[] = { - NPAttrib_Error, 0, - NPAttrib_End - }; - device_->synchronizeContext(npp_, - context_, - NPDeviceSynchronizationMode_Cached, - NULL, - attrib_list, - NULL, - NULL); - return static_cast<gpu::error::Error>(attrib_list[1]); -} - -CommandBuffer::State CommandBufferPepper::ConvertState() { - CommandBuffer::State state; - state.num_entries = context_->commandBufferSize; - state.get_offset = context_->getOffset; - state.put_offset = context_->putOffset; - state.token = context_->token; - state.error = static_cast<gpu::error::Error>( - context_->error); - return state; -} diff --git a/gpu/pgl/command_buffer_pepper.h b/gpu/pgl/command_buffer_pepper.h deleted file mode 100644 index 446ec4a..0000000 --- a/gpu/pgl/command_buffer_pepper.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_PGL_COMMAND_BUFFER_PEPPER_H -#define GPU_PGL_COMMAND_BUFFER_PEPPER_H - -#include "gpu/command_buffer/common/command_buffer.h" -#include "third_party/npapi/bindings/npapi.h" -#include "third_party/npapi/bindings/npruntime.h" -#include "third_party/npapi/bindings/npapi_extensions.h" -#ifdef __native_client__ -#include "native_client/src/third_party/npapi/files/include/npupp.h" -#else -#include "third_party/npapi/bindings/nphostapi.h" -#endif // __native_client__ - -namespace { -class SharedMemory; -} - -// A CommandBuffer proxy implementation that uses the Pepper API to access -// the command buffer. - -class CommandBufferPepper : public gpu::CommandBuffer { - public: - CommandBufferPepper(NPP npp, - NPDevice* device, - NPDeviceContext3D* device_context); - virtual ~CommandBufferPepper(); - - // CommandBuffer implementation. - virtual bool Initialize(int32 size); - virtual bool Initialize(base::SharedMemory* buffer, int32 size); - virtual gpu::Buffer GetRingBuffer(); - virtual State GetState(); - virtual void Flush(int32 put_offset); - virtual State FlushSync(int32 put_offset); - virtual void SetGetOffset(int32 get_offset); - virtual int32 CreateTransferBuffer(size_t size, int32 id_request); - virtual void DestroyTransferBuffer(int32 id); - virtual gpu::Buffer GetTransferBuffer(int32 handle); - virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, - size_t size, - int32 id_request); - virtual void SetToken(int32 token); - virtual void SetParseError(gpu::error::Error error); - - gpu::error::Error GetCachedError(); - - private: - CommandBuffer::State ConvertState(); - - NPP npp_; - NPDevice* device_; - NPDeviceContext3D* context_; -}; - -#endif // GPU_PGL_COMMAND_BUFFER_PEPPER_H diff --git a/gpu/pgl/pgl.cc b/gpu/pgl/pgl.cc deleted file mode 100644 index d98cb62..0000000 --- a/gpu/pgl/pgl.cc +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "gpu/pgl/pgl.h" - -#include "build/build_config.h" -#include "gpu/command_buffer/client/gles2_cmd_helper.h" -#include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/thread_local.h" -#include "gpu/pgl/command_buffer_pepper.h" - -namespace { -const int32 kTransferBufferSize = 512 * 1024; - -class PGLContextImpl { - public: - PGLContextImpl(NPP npp, - NPDevice* device, - NPDeviceContext3D* device_context); - ~PGLContextImpl(); - - // Initlaize a PGL context with a transfer buffer of a particular size. - PGLBoolean Initialize(int32 transfer_buffer_size); - - // Destroy all resources associated with the PGL context. - void Destroy(); - - // Make a PGL context current for the calling thread. - static PGLBoolean MakeCurrent(PGLContextImpl* pgl_context); - - // Display all content rendered since last call to SwapBuffers. - PGLBoolean SwapBuffers(); - - // Get the current error code. - PGLInt GetError(); - - private: - PGLContextImpl(const PGLContextImpl&); - void operator=(const PGLContextImpl&); - - NPP npp_; - NPDevice* device_; - NPDeviceContext3D* device_context_; - CommandBufferPepper* command_buffer_; - gpu::gles2::GLES2CmdHelper* gles2_helper_; - int32 transfer_buffer_id_; - gpu::gles2::GLES2Implementation* gles2_implementation_; -}; - -gpu::ThreadLocalKey g_pgl_context_key; -bool g_pgl_context_key_allocated = false; - -PGLContextImpl::PGLContextImpl(NPP npp, - NPDevice* device, - NPDeviceContext3D* device_context) - : npp_(npp), - device_(device), - device_context_(device_context), - command_buffer_(NULL), - gles2_helper_(NULL), - transfer_buffer_id_(0), - gles2_implementation_(NULL) { -} - -PGLContextImpl::~PGLContextImpl() { - Destroy(); -} - -PGLBoolean PGLContextImpl::Initialize(int32 transfer_buffer_size) { - // Create and initialize the objects required to issue GLES2 calls. - command_buffer_ = new CommandBufferPepper( - npp_, device_, device_context_); - gles2_helper_ = new gpu::gles2::GLES2CmdHelper(command_buffer_); - gpu::Buffer buffer = command_buffer_->GetRingBuffer(); - if (gles2_helper_->Initialize(buffer.size)) { - transfer_buffer_id_ = - command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); - gpu::Buffer transfer_buffer = - command_buffer_->GetTransferBuffer(transfer_buffer_id_); - if (transfer_buffer.ptr) { - gles2_implementation_ = new gpu::gles2::GLES2Implementation( - gles2_helper_, - transfer_buffer.size, - transfer_buffer.ptr, - transfer_buffer_id_, - false); - return PGL_TRUE; - } - } - - // Tear everything down if initialization failed. - Destroy(); - return PGL_FALSE; -} - -void PGLContextImpl::Destroy() { - delete gles2_implementation_; - gles2_implementation_ = NULL; - - if (command_buffer_ && transfer_buffer_id_ != 0) { - command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); - transfer_buffer_id_ = 0; - } - - delete gles2_helper_; - gles2_helper_ = NULL; - - delete command_buffer_; - command_buffer_ = NULL; -} - -PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { - if (!g_pgl_context_key_allocated) - return PGL_FALSE; - - gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context); - if (pgl_context) { - gles2::SetGLContext(pgl_context->gles2_implementation_); - - // Don't request latest error status from service. Just use the locally - // cached information from the last flush. - // TODO(apatrick): I'm not sure if this should actually change the - // current context if it fails. For now it gets changed even if it fails - // becuase making GL calls with a NULL context crashes. -#if defined(ENABLE_NEW_NPDEVICE_API) - if (pgl_context->command_buffer_->GetCachedError() != gpu::error::kNoError) - return PGL_FALSE; -#else - if (pgl_context->device_context_->error != NPDeviceContext3DError_NoError) - return PGL_FALSE; -#endif - } else { - gles2::SetGLContext(NULL); - } - - return PGL_TRUE; -} - -PGLBoolean PGLContextImpl::SwapBuffers() { - // Don't request latest error status from service. Just use the locally cached - // information from the last flush. -#if defined(ENABLE_NEW_NPDEVICE_API) - if (command_buffer_->GetCachedError() != gpu::error::kNoError) - return PGL_FALSE; -#else - if (device_context_->error != NPDeviceContext3DError_NoError) - return PGL_FALSE; -#endif - - gles2_implementation_->SwapBuffers(); - return PGL_TRUE; -} - -PGLInt PGLContextImpl::GetError() { - gpu::CommandBuffer::State state = command_buffer_->GetState(); - if (state.error == gpu::error::kNoError) { - return PGL_SUCCESS; - } else { - // All command buffer errors are unrecoverable. The error is treated as a - // lost context: destroy the context and create another one. - return PGL_CONTEXT_LOST; - } -} -} // namespace anonymous - -extern "C" { -PGLBoolean pglInitialize() { - if (g_pgl_context_key_allocated) - return PGL_TRUE; - - gles2::Initialize(); - g_pgl_context_key = gpu::ThreadLocalAlloc(); - g_pgl_context_key_allocated = true; - return PGL_TRUE; -} - -PGLBoolean pglTerminate() { - if (!g_pgl_context_key_allocated) - return PGL_TRUE; - - gpu::ThreadLocalFree(g_pgl_context_key); - g_pgl_context_key_allocated = false; - g_pgl_context_key = 0; - - gles2::Terminate(); - return PGL_TRUE; -} - -PGLContext pglCreateContext(NPP npp, - NPDevice* device, - NPDeviceContext3D* device_context) { - if (!g_pgl_context_key_allocated) - return NULL; - - PGLContextImpl* pgl_context = new PGLContextImpl( - npp, device, device_context); - if (pgl_context->Initialize(kTransferBufferSize)) { - return pgl_context; - } - - delete pgl_context; - return NULL; -} - -PGLBoolean pglMakeCurrent(PGLContext pgl_context) { - return PGLContextImpl::MakeCurrent(static_cast<PGLContextImpl*>(pgl_context)); -} - -PGLContext pglGetCurrentContext(void) { - if (!g_pgl_context_key_allocated) - return NULL; - - return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key)); -} - -PGLBoolean pglSwapBuffers(void) { - PGLContextImpl* context = static_cast<PGLContextImpl*>( - pglGetCurrentContext()); - if (!context) - return PGL_FALSE; - - return context->SwapBuffers(); -} - -PGLBoolean pglDestroyContext(PGLContext pgl_context) { - if (!g_pgl_context_key_allocated) - return PGL_FALSE; - - if (!pgl_context) - return PGL_FALSE; - - if (pgl_context == pglGetCurrentContext()) - pglMakeCurrent(PGL_NO_CONTEXT); - - delete static_cast<PGLContextImpl*>(pgl_context); - return PGL_TRUE; -} - -PGLInt pglGetError() { - if (!g_pgl_context_key) - return PGL_NOT_INITIALIZED; - - PGLContextImpl* context = static_cast<PGLContextImpl*>( - pglGetCurrentContext()); - if (!context) - return PGL_BAD_CONTEXT; - - return context->GetError(); -} -} // extern "C" diff --git a/gpu/pgl/pgl.h b/gpu/pgl/pgl.h deleted file mode 100644 index e16d028..0000000 --- a/gpu/pgl/pgl.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef GPU_PGL_PGL_H -#define GPU_PGL_PGL_H - -#include <npapi.h> -#include <npapi_extensions.h> - -#define PGL_TRUE 1 -#define PGL_FALSE 0 - -#define PGL_NO_CONTEXT ((PGLContext) 0) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* PGLContext; -typedef unsigned int PGLBoolean; -typedef int32_t PGLInt; - -// These are the same error codes as used by EGL. -enum { - PGL_SUCCESS = 0x3000, - PGL_NOT_INITIALIZED = 0x3001, - PGL_BAD_CONTEXT = 0x3006, - PGL_BAD_PARAMETER = 0x300C, - PGL_CONTEXT_LOST = 0x300E -}; - -// Initialize the PGL library. This must have completed before any other PGL -// functions are invoked. -PGLBoolean pglInitialize(); - -// Terminate the PGL library. This must be called after any other PGL functions -// have completed. -PGLBoolean pglTerminate(); - -// Create A PGL context from a Pepper 3D device context. -PGLContext pglCreateContext(NPP npp, - NPDevice* device, - NPDeviceContext3D* device_context); - -// Set the current PGL context for the calling thread. -PGLBoolean pglMakeCurrent(PGLContext pgl_context); - -// Get the calling thread's current PGL context. -PGLContext pglGetCurrentContext(void); - -// Gets the address of a function. -void (*pglGetProcAddress(char const * procname))(); - -// Display everything that has been rendered since the last call. -PGLBoolean pglSwapBuffers(void); - -// Destroy the given PGL context. -PGLBoolean pglDestroyContext(PGLContext pgl_context); - -// Return the current PGL error. -PGLInt pglGetError(); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // GPU_PGL_PGL_H diff --git a/gpu/pgl/pgl_proc_address.cc b/gpu/pgl/pgl_proc_address.cc deleted file mode 100644 index aab7b2e..0000000 --- a/gpu/pgl/pgl_proc_address.cc +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains the implementation of pglGetProcAddress - -#include <string.h> -#include <GLES2/gl2.h> - -extern "C" { - -typedef void (*PGLFunctionPointer)(void); -struct PGLFunctionInfo { - PGLFunctionPointer func; - char const * const name; -}; - -void (*pglGetProcAddress(char const * procname))() { - static const struct PGLFunctionInfo gl_functions[] = { - { (PGLFunctionPointer)(&glActiveTexture), - "glActiveTexture", }, - { (PGLFunctionPointer)(&glAttachShader), - "glAttachShader", }, - { (PGLFunctionPointer)(&glBindAttribLocation), - "glBindAttribLocation", }, - { (PGLFunctionPointer)(&glBindBuffer), - "glBindBuffer", }, - { (PGLFunctionPointer)(&glBindFramebuffer), - "glBindFramebuffer", }, - { (PGLFunctionPointer)(&glBindRenderbuffer), - "glBindRenderbuffer", }, - { (PGLFunctionPointer)(&glBindTexture), - "glBindTexture", }, - { (PGLFunctionPointer)(&glBlendColor), - "glBlendColor", }, - { (PGLFunctionPointer)(&glBlendEquation), - "glBlendEquation", }, - { (PGLFunctionPointer)(&glBlendEquationSeparate), - "glBlendEquationSeparate", }, - { (PGLFunctionPointer)(&glBlendFunc), - "glBlendFunc", }, - { (PGLFunctionPointer)(&glBlendFuncSeparate), - "glBlendFuncSeparate", }, - { (PGLFunctionPointer)(&glBufferData), - "glBufferData", }, - { (PGLFunctionPointer)(&glBufferSubData), - "glBufferSubData", }, - { (PGLFunctionPointer)(&glCheckFramebufferStatus), - "glCheckFramebufferStatus", }, - { (PGLFunctionPointer)(&glClear), - "glClear", }, - { (PGLFunctionPointer)(&glClearColor), - "glClearColor", }, - { (PGLFunctionPointer)(&glClearDepthf), - "glClearDepthf", }, - { (PGLFunctionPointer)(&glClearStencil), - "glClearStencil", }, - { (PGLFunctionPointer)(&glColorMask), - "glColorMask", }, - { (PGLFunctionPointer)(&glCompileShader), - "glCompileShader", }, - { (PGLFunctionPointer)(&glCompressedTexImage2D), - "glCompressedTexImage2D", }, - { (PGLFunctionPointer)(&glCompressedTexSubImage2D), - "glCompressedTexSubImage2D", }, - { (PGLFunctionPointer)(&glCopyTexImage2D), - "glCopyTexImage2D", }, - { (PGLFunctionPointer)(&glCopyTexSubImage2D), - "glCopyTexSubImage2D", }, - { (PGLFunctionPointer)(&glCreateProgram), - "glCreateProgram", }, - { (PGLFunctionPointer)(&glCreateShader), - "glCreateShader", }, - { (PGLFunctionPointer)(&glCullFace), - "glCullFace", }, - { (PGLFunctionPointer)(&glDeleteBuffers), - "glDeleteBuffers", }, - { (PGLFunctionPointer)(&glDeleteFramebuffers), - "glDeleteFramebuffers", }, - { (PGLFunctionPointer)(&glDeleteProgram), - "glDeleteProgram", }, - { (PGLFunctionPointer)(&glDeleteRenderbuffers), - "glDeleteRenderbuffers", }, - { (PGLFunctionPointer)(&glDeleteShader), - "glDeleteShader", }, - { (PGLFunctionPointer)(&glDeleteTextures), - "glDeleteTextures", }, - { (PGLFunctionPointer)(&glDepthFunc), - "glDepthFunc", }, - { (PGLFunctionPointer)(&glDepthMask), - "glDepthMask", }, - { (PGLFunctionPointer)(&glDepthRangef), - "glDepthRangef", }, - { (PGLFunctionPointer)(&glDetachShader), - "glDetachShader", }, - { (PGLFunctionPointer)(&glDisable), - "glDisable", }, - { (PGLFunctionPointer)(&glDisableVertexAttribArray), - "glDisableVertexAttribArray", }, - { (PGLFunctionPointer)(&glDrawArrays), - "glDrawArrays", }, - { (PGLFunctionPointer)(&glDrawElements), - "glDrawElements", }, - { (PGLFunctionPointer)(&glEnable), - "glEnable", }, - { (PGLFunctionPointer)(&glEnableVertexAttribArray), - "glEnableVertexAttribArray", }, - { (PGLFunctionPointer)(&glFinish), - "glFinish", }, - { (PGLFunctionPointer)(&glFlush), - "glFlush", }, - { (PGLFunctionPointer)(&glFramebufferRenderbuffer), - "glFramebufferRenderbuffer", }, - { (PGLFunctionPointer)(&glFramebufferTexture2D), - "glFramebufferTexture2D", }, - { (PGLFunctionPointer)(&glFrontFace), - "glFrontFace", }, - { (PGLFunctionPointer)(&glGenBuffers), - "glGenBuffers", }, - { (PGLFunctionPointer)(&glGenerateMipmap), - "glGenerateMipmap", }, - { (PGLFunctionPointer)(&glGenFramebuffers), - "glGenFramebuffers", }, - { (PGLFunctionPointer)(&glGenRenderbuffers), - "glGenRenderbuffers", }, - { (PGLFunctionPointer)(&glGenTextures), - "glGenTextures", }, - { (PGLFunctionPointer)(&glGetActiveAttrib), - "glGetActiveAttrib", }, - { (PGLFunctionPointer)(&glGetActiveUniform), - "glGetActiveUniform", }, - { (PGLFunctionPointer)(&glGetAttachedShaders), - "glGetAttachedShaders", }, - { (PGLFunctionPointer)(&glGetAttribLocation), - "glGetAttribLocation", }, - { (PGLFunctionPointer)(&glGetBooleanv), - "glGetBooleanv", }, - { (PGLFunctionPointer)(&glGetBufferParameteriv), - "glGetBufferParameteriv", }, - { (PGLFunctionPointer)(&glGetError), - "glGetError", }, - { (PGLFunctionPointer)(&glGetFloatv), - "glGetFloatv", }, - { (PGLFunctionPointer)(&glGetFramebufferAttachmentParameteriv), - "glGetFramebufferAttachmentParameteriv", }, - { (PGLFunctionPointer)(&glGetIntegerv), - "glGetIntegerv", }, - { (PGLFunctionPointer)(&glGetProgramiv), - "glGetProgramiv", }, - { (PGLFunctionPointer)(&glGetProgramInfoLog), - "glGetProgramInfoLog", }, - { (PGLFunctionPointer)(&glGetRenderbufferParameteriv), - "glGetRenderbufferParameteriv", }, - { (PGLFunctionPointer)(&glGetShaderiv), - "glGetShaderiv", }, - { (PGLFunctionPointer)(&glGetShaderInfoLog), - "glGetShaderInfoLog", }, - { (PGLFunctionPointer)(&glGetShaderPrecisionFormat), - "glGetShaderPrecisionFormat", }, - { (PGLFunctionPointer)(&glGetShaderSource), - "glGetShaderSource", }, - { (PGLFunctionPointer)(&glGetString), - "glGetString", }, - { (PGLFunctionPointer)(&glGetTexParameterfv), - "glGetTexParameterfv", }, - { (PGLFunctionPointer)(&glGetTexParameteriv), - "glGetTexParameteriv", }, - { (PGLFunctionPointer)(&glGetUniformfv), - "glGetUniformfv", }, - { (PGLFunctionPointer)(&glGetUniformiv), - "glGetUniformiv", }, - { (PGLFunctionPointer)(&glGetUniformLocation), - "glGetUniformLocation", }, - { (PGLFunctionPointer)(&glGetVertexAttribfv), - "glGetVertexAttribfv", }, - { (PGLFunctionPointer)(&glGetVertexAttribiv), - "glGetVertexAttribiv", }, - { (PGLFunctionPointer)(&glGetVertexAttribPointerv), - "glGetVertexAttribPointerv", }, - { (PGLFunctionPointer)(&glHint), - "glHint", }, - { (PGLFunctionPointer)(&glIsBuffer), - "glIsBuffer", }, - { (PGLFunctionPointer)(&glIsEnabled), - "glIsEnabled", }, - { (PGLFunctionPointer)(&glIsFramebuffer), - "glIsFramebuffer", }, - { (PGLFunctionPointer)(&glIsProgram), - "glIsProgram", }, - { (PGLFunctionPointer)(&glIsRenderbuffer), - "glIsRenderbuffer", }, - { (PGLFunctionPointer)(&glIsShader), - "glIsShader", }, - { (PGLFunctionPointer)(&glIsTexture), - "glIsTexture", }, - { (PGLFunctionPointer)(&glLineWidth), - "glLineWidth", }, - { (PGLFunctionPointer)(&glLinkProgram), - "glLinkProgram", }, - { (PGLFunctionPointer)(&glPixelStorei), - "glPixelStorei", }, - { (PGLFunctionPointer)(&glPolygonOffset), - "glPolygonOffset", }, - { (PGLFunctionPointer)(&glReadPixels), - "glReadPixels", }, - { (PGLFunctionPointer)(&glReleaseShaderCompiler), - "glReleaseShaderCompiler", }, - { (PGLFunctionPointer)(&glRenderbufferStorage), - "glRenderbufferStorage", }, - { (PGLFunctionPointer)(&glSampleCoverage), - "glSampleCoverage", }, - { (PGLFunctionPointer)(&glScissor), - "glScissor", }, - { (PGLFunctionPointer)(&glShaderBinary), - "glShaderBinary", }, - { (PGLFunctionPointer)(&glShaderSource), - "glShaderSource", }, - { (PGLFunctionPointer)(&glStencilFunc), - "glStencilFunc", }, - { (PGLFunctionPointer)(&glStencilFuncSeparate), - "glStencilFuncSeparate", }, - { (PGLFunctionPointer)(&glStencilMask), - "glStencilMask", }, - { (PGLFunctionPointer)(&glStencilMaskSeparate), - "glStencilMaskSeparate", }, - { (PGLFunctionPointer)(&glStencilOp), - "glStencilOp", }, - { (PGLFunctionPointer)(&glStencilOpSeparate), - "glStencilOpSeparate", }, - { (PGLFunctionPointer)(&glTexImage2D), - "glTexImage2D", }, - { (PGLFunctionPointer)(&glTexParameterf), - "glTexParameterf", }, - { (PGLFunctionPointer)(&glTexParameterfv), - "glTexParameterfv", }, - { (PGLFunctionPointer)(&glTexParameteri), - "glTexParameteri", }, - { (PGLFunctionPointer)(&glTexParameteriv), - "glTexParameteriv", }, - { (PGLFunctionPointer)(&glTexSubImage2D), - "glTexSubImage2D", }, - { (PGLFunctionPointer)(&glUniform1f), - "glUniform1f", }, - { (PGLFunctionPointer)(&glUniform1fv), - "glUniform1fv", }, - { (PGLFunctionPointer)(&glUniform1i), - "glUniform1i", }, - { (PGLFunctionPointer)(&glUniform1iv), - "glUniform1iv", }, - { (PGLFunctionPointer)(&glUniform2f), - "glUniform2f", }, - { (PGLFunctionPointer)(&glUniform2fv), - "glUniform2fv", }, - { (PGLFunctionPointer)(&glUniform2i), - "glUniform2i", }, - { (PGLFunctionPointer)(&glUniform2iv), - "glUniform2iv", }, - { (PGLFunctionPointer)(&glUniform3f), - "glUniform3f", }, - { (PGLFunctionPointer)(&glUniform3fv), - "glUniform3fv", }, - { (PGLFunctionPointer)(&glUniform3i), - "glUniform3i", }, - { (PGLFunctionPointer)(&glUniform3iv), - "glUniform3iv", }, - { (PGLFunctionPointer)(&glUniform4f), - "glUniform4f", }, - { (PGLFunctionPointer)(&glUniform4fv), - "glUniform4fv", }, - { (PGLFunctionPointer)(&glUniform4i), - "glUniform4i", }, - { (PGLFunctionPointer)(&glUniform4iv), - "glUniform4iv", }, - { (PGLFunctionPointer)(&glUniformMatrix2fv), - "glUniformMatrix2fv", }, - { (PGLFunctionPointer)(&glUniformMatrix3fv), - "glUniformMatrix3fv", }, - { (PGLFunctionPointer)(&glUniformMatrix4fv), - "glUniformMatrix4fv", }, - { (PGLFunctionPointer)(&glUseProgram), - "glUseProgram", }, - { (PGLFunctionPointer)(&glValidateProgram), - "glValidateProgram", }, - { (PGLFunctionPointer)(&glVertexAttrib1f), - "glVertexAttrib1f", }, - { (PGLFunctionPointer)(&glVertexAttrib1fv), - "glVertexAttrib1fv", }, - { (PGLFunctionPointer)(&glVertexAttrib2f), - "glVertexAttrib2f", }, - { (PGLFunctionPointer)(&glVertexAttrib2fv), - "glVertexAttrib2fv", }, - { (PGLFunctionPointer)(&glVertexAttrib3f), - "glVertexAttrib3f", }, - { (PGLFunctionPointer)(&glVertexAttrib3fv), - "glVertexAttrib3fv", }, - { (PGLFunctionPointer)(&glVertexAttrib4f), - "glVertexAttrib4f", }, - { (PGLFunctionPointer)(&glVertexAttrib4fv), - "glVertexAttrib4fv", }, - { (PGLFunctionPointer)(&glVertexAttribPointer), - "glVertexAttribPointer", }, - { (PGLFunctionPointer)(&glViewport), - "glViewport", }, - }; - - unsigned int num_functions = sizeof(gl_functions) / sizeof(gl_functions[0]); - for (unsigned int ii = 0; ii < num_functions; ++ii) { - if (strcmp(gl_functions[ii].name, procname) == 0) { - return gl_functions[ii].func; - } - } - return NULL; -} -} // extern "C" - diff --git a/ppapi/c/dev/ppb_context_3d_trusted_dev.h b/ppapi/c/dev/ppb_context_3d_trusted_dev.h index afc860f..ce4d8d6 100644 --- a/ppapi/c/dev/ppb_context_3d_trusted_dev.h +++ b/ppapi/c/dev/ppb_context_3d_trusted_dev.h @@ -11,9 +11,9 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_stdint.h" -#define PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE_0_3 "PPB_Context3DTrusted(Dev);0.3" +#define PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE_0_4 "PPB_Context3DTrusted(Dev);0.4" #define PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE \ - PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE_0_3 + PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE_0_4 typedef enum { kNoError, @@ -44,6 +44,11 @@ struct PP_Context3DTrustedState { // Error status. PPB_Context3DTrustedError error; + + // Generation index of this state. The generation index is incremented every + // time a new state is retrieved from the command processor, so that + // consistency can be kept even if IPC messages are processed out-of-order. + uint32_t generation; }; struct PPB_Context3DTrusted_Dev { @@ -89,6 +94,13 @@ struct PPB_Context3DTrusted_Dev { int32_t id, int* shm_handle, uint32_t* shm_size); + + // Like FlushSync, but returns before processing commands if the get offset is + // different than last_known_get. Allows synchronization with the command + // processor without forcing immediate command execution. + struct PP_Context3DTrustedState (*FlushSyncFast)(PP_Resource context, + int32_t put_offset, + int32_t last_known_get); }; #endif // PPAPI_C_DEV_PPB_CONTEXT_3D_TRUSTED_DEV_H_ diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 32dfdf2..6bbd8bd 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -316,9 +316,10 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBContext3D_GetState, pp::proxy::HostResource /* context */, gpu::CommandBuffer::State /* state */) -IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBContext3D_Flush, +IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBContext3D_Flush, pp::proxy::HostResource /* context */, int32 /* put_offset */, + int32 /* last_known_get */, gpu::CommandBuffer::State /* state */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBContext3D_AsyncFlush, diff --git a/ppapi/proxy/ppb_context_3d_proxy.cc b/ppapi/proxy/ppb_context_3d_proxy.cc index 396ccf6..fce162b 100644 --- a/ppapi/proxy/ppb_context_3d_proxy.cc +++ b/ppapi/proxy/ppb_context_3d_proxy.cc @@ -155,6 +155,7 @@ gpu::CommandBuffer::State GPUStateFromPPState( state.put_offset = s.put_offset; state.token = s.token; state.error = static_cast<gpu::error::Error>(s.error); + state.generation = s.generation; return state; } @@ -181,7 +182,7 @@ class PepperCommandBuffer : public gpu::CommandBuffer { virtual gpu::Buffer GetRingBuffer(); virtual State GetState(); virtual void Flush(int32 put_offset); - virtual State FlushSync(int32 put_offset); + virtual State FlushSync(int32 put_offset, int32 last_known_get); virtual void SetGetOffset(int32 get_offset); virtual int32 CreateTransferBuffer(size_t size, int32 id_request); virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -194,6 +195,7 @@ class PepperCommandBuffer : public gpu::CommandBuffer { private: bool Send(IPC::Message* msg); + void UpdateState(const gpu::CommandBuffer::State& state); int32 num_entries_; scoped_ptr<base::SharedMemory> ring_buffer_; @@ -268,8 +270,10 @@ gpu::Buffer PepperCommandBuffer::GetRingBuffer() { gpu::CommandBuffer::State PepperCommandBuffer::GetState() { // Send will flag state with lost context if IPC fails. if (last_state_.error == gpu::error::kNoError) { - Send(new PpapiHostMsg_PPBContext3D_GetState( - INTERFACE_ID_PPB_CONTEXT_3D, resource_, &last_state_)); + gpu::CommandBuffer::State state; + if (Send(new PpapiHostMsg_PPBContext3D_GetState( + INTERFACE_ID_PPB_CONTEXT_3D, resource_, &state))) + UpdateState(state); } return last_state_; @@ -289,11 +293,19 @@ void PepperCommandBuffer::Flush(int32 put_offset) { Send(message); } -gpu::CommandBuffer::State PepperCommandBuffer::FlushSync(int32 put_offset) { - // Send will flag state with lost context if IPC fails. - if (last_state_.error == gpu::error::kNoError) { - Send(new PpapiHostMsg_PPBContext3D_Flush( - INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset, &last_state_)); +gpu::CommandBuffer::State PepperCommandBuffer::FlushSync( + int32 put_offset, int32 last_known_get) { + if (last_known_get == last_state_.get_offset) { + // Send will flag state with lost context if IPC fails. + if (last_state_.error == gpu::error::kNoError) { + gpu::CommandBuffer::State state; + if (Send(new PpapiHostMsg_PPBContext3D_Flush( + INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset, + last_known_get, &state))) + UpdateState(state); + } + } else { + Flush(put_offset); } return last_state_; @@ -400,6 +412,13 @@ bool PepperCommandBuffer::Send(IPC::Message* msg) { return false; } +void PepperCommandBuffer::UpdateState(const gpu::CommandBuffer::State& state) { + // Handle wraparound. It works as long as we don't have more than 2B state + // updates in flight across which reordering occurs. + if (state.generation - last_state_.generation < 0x80000000U) + last_state_ = state; +} + Context3D::Context3D(const HostResource& resource) : PluginResource(resource), draw_(NULL), @@ -571,9 +590,10 @@ void PPB_Context3D_Proxy::OnMsgGetState(const HostResource& context, void PPB_Context3D_Proxy::OnMsgFlush(const HostResource& context, int32 put_offset, + int32 last_known_get, gpu::CommandBuffer::State* state) { - PP_Context3DTrustedState pp_state = - ppb_context_3d_trusted()->FlushSync(context.host_resource(), put_offset); + PP_Context3DTrustedState pp_state = ppb_context_3d_trusted()->FlushSyncFast( + context.host_resource(), put_offset, last_known_get); *state = GPUStateFromPPState(pp_state); } diff --git a/ppapi/proxy/ppb_context_3d_proxy.h b/ppapi/proxy/ppb_context_3d_proxy.h index 117dbe0..3e2f953 100644 --- a/ppapi/proxy/ppb_context_3d_proxy.h +++ b/ppapi/proxy/ppb_context_3d_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -100,6 +100,7 @@ class PPB_Context3D_Proxy : public InterfaceProxy { gpu::CommandBuffer::State* state); void OnMsgFlush(const HostResource& context, int32 put_offset, + int32 last_known_get, gpu::CommandBuffer::State* state); void OnMsgAsyncFlush(const HostResource& context, int32 put_offset); diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.cc b/webkit/plugins/ppapi/ppb_context_3d_impl.cc index 7d3b498..3c581c6 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.cc @@ -46,7 +46,8 @@ PP_Context3DTrustedState PPStateFromGPUState(gpu::CommandBuffer::State s) { s.get_offset, s.put_offset, s.token, - static_cast<PPB_Context3DTrustedError>(s.error) + static_cast<PPB_Context3DTrustedError>(s.error), + s.generation }; return state; } @@ -191,7 +192,9 @@ PP_Context3DTrustedState FlushSync(PP_Resource context_id, int32_t put_offset) { return error_state; } - return PPStateFromGPUState(context->command_buffer()->FlushSync(put_offset)); + gpu::CommandBuffer::State state = context->command_buffer()->GetState(); + return PPStateFromGPUState( + context->command_buffer()->FlushSync(put_offset, state.get_offset)); } int32_t CreateTransferBuffer(PP_Resource context_id, uint32_t size) { @@ -225,6 +228,18 @@ PP_Bool GetTransferBuffer(PP_Resource context_id, ? PP_TRUE : PP_FALSE; } +PP_Context3DTrustedState FlushSyncFast( + PP_Resource context_id, int32_t put_offset, int32 last_known_get) { + scoped_refptr<PPB_Context3D_Impl> context( + Resource::GetAs<PPB_Context3D_Impl>(context_id)); + if (!context.get() || !context->command_buffer()) { + PP_Context3DTrustedState error_state = { 0 }; + return error_state; + } + + return PPStateFromGPUState( + context->command_buffer()->FlushSync(put_offset, last_known_get)); +} } // namespace PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) @@ -254,7 +269,8 @@ const PPB_Context3DTrusted_Dev* PPB_Context3D_Impl::GetTrustedInterface() { &FlushSync, &CreateTransferBuffer, &DestroyTransferBuffer, - &GetTransferBuffer + &GetTransferBuffer, + &FlushSyncFast, }; return &iface; } |