summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-29 22:02:36 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-29 22:02:36 +0000
commitc77ea36637f9494c048f6c8035f3cf8a389da93d (patch)
treef1feccf837765ba30c4f46e11b8f7b0b996a5cbd
parent23fc99cca22572abe60eced18b90b5693c2f64f7 (diff)
downloadchromium_src-c77ea36637f9494c048f6c8035f3cf8a389da93d.zip
chromium_src-c77ea36637f9494c048f6c8035f3cf8a389da93d.tar.gz
chromium_src-c77ea36637f9494c048f6c8035f3cf8a389da93d.tar.bz2
Redesigned CommandBuffer and NPDevice3D interfaces.
All status is now in the Device3D context. It can be retreived with fewer IPC messages. It can be now be accessed off the main plugin thread, which is necessary to run OpenGL in another thread. TEST=none BUG=none Review URL: http://codereview.chromium.org/555020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37545 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/command_buffer_messages.h33
-rw-r--r--chrome/common/command_buffer_messages_internal.h34
-rw-r--r--chrome/plugin/command_buffer_stub.cc33
-rw-r--r--chrome/plugin/command_buffer_stub.h9
-rw-r--r--chrome/renderer/command_buffer_proxy.cc69
-rw-r--r--chrome/renderer/command_buffer_proxy.h12
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc61
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h10
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.cc31
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.h5
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper_test.cc57
-rw-r--r--gpu/command_buffer/client/fenced_allocator_test.cc16
-rw-r--r--gpu/command_buffer/common/command_buffer.h61
-rw-r--r--gpu/command_buffer/common/command_buffer_mock.h12
-rw-r--r--gpu/command_buffer/common/constants.h14
-rw-r--r--gpu/command_buffer/service/command_buffer_service.cc56
-rw-r--r--gpu/command_buffer/service/command_buffer_service.h15
-rw-r--r--gpu/command_buffer/service/command_buffer_service_unittest.cc70
-rw-r--r--gpu/command_buffer/service/gpu_processor.cc22
-rw-r--r--gpu/command_buffer/service/gpu_processor_unittest.cc131
-rw-r--r--gpu/pgl/command_buffer_pepper.cc97
-rw-r--r--gpu/pgl/command_buffer_pepper.h14
-rw-r--r--third_party/npapi/bindings/npapi_extensions.h20
23 files changed, 346 insertions, 536 deletions
diff --git a/chrome/common/command_buffer_messages.h b/chrome/common/command_buffer_messages.h
index 2c586d0..7e3ae9c 100644
--- a/chrome/common/command_buffer_messages.h
+++ b/chrome/common/command_buffer_messages.h
@@ -5,6 +5,39 @@
#ifndef CHROME_COMMON_COMMAND_BUFFER_MESSAGES_H_
#define CHROME_COMMON_COMMAND_BUFFER_MESSAGES_H_
+#include "chrome/common/common_param_traits.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+
+namespace IPC {
+template <>
+struct ParamTraits<gpu::CommandBuffer::State> {
+ typedef gpu::CommandBuffer::State param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p.size);
+ m->WriteInt(p.get_offset);
+ m->WriteInt(p.put_offset);
+ m->WriteInt(p.token);
+ m->WriteInt(p.error);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int32 temp;
+ if (m->ReadInt(iter, &p->size) &&
+ m->ReadInt(iter, &p->get_offset) &&
+ m->ReadInt(iter, &p->put_offset) &&
+ m->ReadInt(iter, &p->token) &&
+ m->ReadInt(iter, &temp)) {
+ p->error = static_cast<gpu::parse_error::ParseError>(temp);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"<CommandBuffer::State>");
+ }
+};
+} // namespace IPC
+
#define MESSAGES_INTERNAL_FILE "chrome/common/command_buffer_messages_internal.h"
#include "ipc/ipc_message_macros.h"
diff --git a/chrome/common/command_buffer_messages_internal.h b/chrome/common/command_buffer_messages_internal.h
index cbcda79..274223b5 100644
--- a/chrome/common/command_buffer_messages_internal.h
+++ b/chrome/common/command_buffer_messages_internal.h
@@ -13,23 +13,16 @@ IPC_BEGIN_MESSAGES(CommandBuffer)
int32 /* size */,
base::SharedMemoryHandle /* ring_buffer */)
- // Get the number of command entries in the command buffer.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetSize,
- int32 /* size */)
+ // Get the current state of the command buffer, optionally reseting the
+ // parse error.
+ IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetState,
+ gpu::CommandBuffer::State /* state */)
// Synchronize the put and get offsets of both processes. Caller passes its
// current put offset. Current get offset is returned.
- IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_SyncOffsets,
+ IPC_SYNC_MESSAGE_ROUTED1_1(CommandBufferMsg_Flush,
int32 /* put_offset */,
- int32 /* get_offset */)
-
- // Get the current get offset.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetGetOffset,
- int32 /* get_offset */)
-
- // Get the current put offset.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetPutOffset,
- int32 /* put_offset */)
+ gpu::CommandBuffer::State /* state */)
// Create a shared memory transfer buffer. Returns an id that can be used to
// identify the transfer buffer from a comment.
@@ -48,19 +41,4 @@ IPC_BEGIN_MESSAGES(CommandBuffer)
base::SharedMemoryHandle /* transfer_buffer */,
size_t /* size */)
- // Get the most recently processed token. Used for implementing fences.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetToken,
- int32 /* token */)
-
- // Get the current parse error. Calling this resets the parse error if it is
- // recoverable.
- // TODO(apatrick): Switch to the parse_error::ParseError enum now that NPAPI
- // no longer limits to restricted set of datatypes.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_ResetParseError,
- int32 /* parse_error */)
-
- // Get the current error status.
- IPC_SYNC_MESSAGE_ROUTED0_1(CommandBufferMsg_GetErrorStatus,
- bool /* status */)
-
IPC_END_MESSAGES(CommandBuffer)
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index 4a9dd5c..4b062e8 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -69,16 +69,13 @@ void CommandBufferStub::OnInitialize(int32 size,
base::CloseProcessHandle(peer_handle);
}
-void CommandBufferStub::OnSyncOffsets(int32 put_offset, int32* get_offset) {
- *get_offset = command_buffer_->SyncOffsets(put_offset);
+void CommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
+ *state = command_buffer_->GetState();
}
-void CommandBufferStub::OnGetGetOffset(int32* get_offset) {
- *get_offset = command_buffer_->GetGetOffset();
-}
-
-void CommandBufferStub::OnGetPutOffset(int32* put_offset) {
- *put_offset = command_buffer_->GetPutOffset();
+void CommandBufferStub::OnFlush(int32 put_offset,
+ gpu::CommandBuffer::State* state) {
+ *state = command_buffer_->Flush(put_offset);
}
void CommandBufferStub::OnCreateTransferBuffer(int32 size, int32* id) {
@@ -111,33 +108,17 @@ void CommandBufferStub::OnGetTransferBuffer(
base::CloseProcessHandle(peer_handle);
}
-void CommandBufferStub::OnGetToken(int32* token) {
- *token = command_buffer_->GetToken();
-}
-
-void CommandBufferStub::OnResetParseError(int32* parse_error) {
- *parse_error = command_buffer_->ResetParseError();
-}
-
-void CommandBufferStub::OnGetErrorStatus(bool* error_status) {
- *error_status = command_buffer_->GetErrorStatus();
-}
-
void CommandBufferStub::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, msg)
IPC_MESSAGE_HANDLER(CommandBufferMsg_Initialize, OnInitialize);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_SyncOffsets, OnSyncOffsets);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetGetOffset, OnGetGetOffset);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetPutOffset, OnGetPutOffset);
+ IPC_MESSAGE_HANDLER(CommandBufferMsg_GetState, OnGetState);
+ IPC_MESSAGE_HANDLER(CommandBufferMsg_Flush, OnFlush);
IPC_MESSAGE_HANDLER(CommandBufferMsg_CreateTransferBuffer,
OnCreateTransferBuffer);
IPC_MESSAGE_HANDLER(CommandBufferMsg_DestroyTransferBuffer,
OnDestroyTransferBuffer);
IPC_MESSAGE_HANDLER(CommandBufferMsg_GetTransferBuffer,
OnGetTransferBuffer);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetToken, OnGetToken);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_ResetParseError, OnResetParseError);
- IPC_MESSAGE_HANDLER(CommandBufferMsg_GetErrorStatus, OnGetErrorStatus);
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index 4608d0e..1001ce9 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -9,6 +9,7 @@
#include "app/gfx/native_widget_types.h"
#include "base/ref_counted.h"
+#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/gpu_processor.h"
#include "ipc/ipc_channel.h"
@@ -37,17 +38,13 @@ class CommandBufferStub : public IPC::Channel::Listener,
private:
// Message handlers:
void OnInitialize(int32 size, base::SharedMemoryHandle* ring_buffer);
- void OnSyncOffsets(int32 put_offset, int32* get_offset);
- void OnGetGetOffset(int32* get_offset);
- void OnGetPutOffset(int32* put_offset);
+ void OnGetState(gpu::CommandBuffer::State* state);
+ void OnFlush(int32 put_offset, gpu::CommandBuffer::State* state);
void OnCreateTransferBuffer(int32 size, int32* id);
void OnDestroyTransferBuffer(int32 id);
void OnGetTransferBuffer(int32 id,
base::SharedMemoryHandle* transfer_buffer,
size_t* size);
- void OnGetToken(int32* token);
- void OnResetParseError(int32* parse_error);
- void OnGetErrorStatus(bool* error_status);
scoped_refptr<PluginChannel> channel_;
gfx::PluginWindowHandle window_;
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index 5b97e3c..e63ca5a 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -71,27 +71,18 @@ Buffer CommandBufferProxy::GetRingBuffer() {
return buffer;
}
-int32 CommandBufferProxy::GetSize() {
- // Return locally cached size.
- return size_;
+gpu::CommandBuffer::State CommandBufferProxy::GetState() {
+ gpu::CommandBuffer::State state;
+ Send(new CommandBufferMsg_GetState(route_id_, &state));
+ return state;
}
-int32 CommandBufferProxy::SyncOffsets(int32 put_offset) {
- int32 get_offset;
- if (Send(new CommandBufferMsg_SyncOffsets(route_id_,
- put_offset,
- &get_offset)))
- return get_offset;
-
- return -1;
-}
-
-int32 CommandBufferProxy::GetGetOffset() {
- int32 get_offset;
- if (Send(new CommandBufferMsg_GetGetOffset(route_id_, &get_offset)))
- return get_offset;
-
- return -1;
+gpu::CommandBuffer::State CommandBufferProxy::Flush(int32 put_offset) {
+ gpu::CommandBuffer::State state;
+ Send(new CommandBufferMsg_Flush(route_id_,
+ put_offset,
+ &state));
+ return state;
}
void CommandBufferProxy::SetGetOffset(int32 get_offset) {
@@ -99,14 +90,6 @@ void CommandBufferProxy::SetGetOffset(int32 get_offset) {
NOTREACHED();
}
-int32 CommandBufferProxy::GetPutOffset() {
- int put_offset;
- if (Send(new CommandBufferMsg_GetPutOffset(route_id_, &put_offset)))
- return put_offset;
-
- return -1;
-}
-
int32 CommandBufferProxy::CreateTransferBuffer(size_t size) {
int32 id;
if (Send(new CommandBufferMsg_CreateTransferBuffer(route_id_, size, &id)))
@@ -176,41 +159,13 @@ Buffer CommandBufferProxy::GetTransferBuffer(int32 id) {
return buffer;
}
-int32 CommandBufferProxy::GetToken() {
- int32 token;
- if (Send(new CommandBufferMsg_GetToken(route_id_, &token)))
- return token;
-
- return -1;
-}
-
void CommandBufferProxy::SetToken(int32 token) {
// Not implemented in proxy.
NOTREACHED();
}
-int32 CommandBufferProxy::ResetParseError() {
- int32 parse_error;
- if (Send(new CommandBufferMsg_ResetParseError(route_id_, &parse_error)))
- return parse_error;
-
- return -1;
-}
-
-void CommandBufferProxy::SetParseError(int32 parse_error) {
- // Not implemented in proxy.
- NOTREACHED();
-}
-
-bool CommandBufferProxy::GetErrorStatus() {
- bool status;
- if (Send(new CommandBufferMsg_GetErrorStatus(route_id_, &status)))
- return status;
-
- return true;
-}
-
-void CommandBufferProxy::RaiseErrorStatus() {
+void CommandBufferProxy::SetParseError(
+ gpu::parse_error::ParseError parse_error) {
// Not implemented in proxy.
NOTREACHED();
}
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index 0be704a..849f540 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -35,20 +35,14 @@ class CommandBufferProxy : public gpu::CommandBuffer,
// CommandBuffer implementation:
virtual bool Initialize(int32 size);
virtual gpu::Buffer GetRingBuffer();
- virtual int32 GetSize();
- virtual int32 SyncOffsets(int32 put_offset);
- virtual int32 GetGetOffset();
+ virtual State GetState();
+ virtual State Flush(int32 put_offset);
virtual void SetGetOffset(int32 get_offset);
- virtual int32 GetPutOffset();
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);
virtual gpu::Buffer GetTransferBuffer(int32 handle);
- virtual int32 GetToken();
virtual void SetToken(int32 token);
- virtual int32 ResetParseError();
- virtual void SetParseError(int32 parse_error);
- virtual bool GetErrorStatus();
- virtual void RaiseErrorStatus();
+ virtual void SetParseError(gpu::parse_error::ParseError parse_error);
private:
// As with the service, the client takes ownership of the ring buffer.
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 68e611d..d25364f 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -352,13 +352,15 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
if (command_buffer_.get()) {
// Initialize the proxy command buffer.
if (command_buffer_->Initialize(config->commandBufferEntries)) {
+ // Get the initial command buffer state.
+ gpu::CommandBuffer::State state = command_buffer_->GetState();
+
// Initialize the 3D context.
context->reserved = NULL;
Buffer ring_buffer = command_buffer_->GetRingBuffer();
context->commandBuffer = ring_buffer.ptr;
- context->commandBufferEntries = command_buffer_->GetSize();
- context->getOffset = command_buffer_->GetGetOffset();
- context->putOffset = command_buffer_->GetPutOffset();
+ context->commandBufferEntries = state.size;
+ Synchronize3DContext(context, state);
// Ensure the service knows the window size before rendering anything.
nested_delegate_->UpdateGeometry(window_rect_, clip_rect_);
@@ -392,32 +394,7 @@ NPError WebPluginDelegatePepper::Device3DGetStateContext(
NPDeviceContext3D* context,
int32 state,
int32* value) {
-#if defined(ENABLE_GPU)
- if (!command_buffer_.get())
- return NPERR_GENERIC_ERROR;
-
- switch (state) {
- case NPDeviceContext3DState_GetOffset:
- context->getOffset = *value = command_buffer_->GetGetOffset();
- break;
- case NPDeviceContext3DState_PutOffset:
- *value = command_buffer_->GetPutOffset();
- break;
- case NPDeviceContext3DState_Token:
- *value = command_buffer_->GetToken();
- break;
- case NPDeviceContext3DState_ParseError:
- *value = command_buffer_->ResetParseError();
- break;
- case NPDeviceContext3DState_ErrorStatus:
- *value = command_buffer_->GetErrorStatus() ? 1 : 0;
- break;
- default:
- return NPERR_GENERIC_ERROR;
- };
-#endif // ENABLE_GPU
-
- return NPERR_NO_ERROR;
+ return NPERR_GENERIC_ERROR;
}
NPError WebPluginDelegatePepper::Device3DFlushContext(
@@ -426,8 +403,16 @@ NPError WebPluginDelegatePepper::Device3DFlushContext(
NPDeviceFlushContextCallbackPtr callback,
void* user_data) {
#if defined(ENABLE_GPU)
- DCHECK(callback == NULL);
- context->getOffset = command_buffer_->SyncOffsets(context->putOffset);
+ gpu::CommandBuffer::State state;
+ // Only flush if new commands have been put in the command buffer. Otherwise
+ // update the state to the current service state.
+ if (context->putOffset == last_command_buffer_put_offset_) {
+ state = command_buffer_->GetState();
+ } else {
+ last_command_buffer_put_offset_ = context->putOffset;
+ state = command_buffer_->Flush(context->putOffset);
+ }
+ Synchronize3DContext(context, state);
#endif // ENABLE_GPU
return NPERR_NO_ERROR;
}
@@ -556,7 +541,8 @@ WebPluginDelegatePepper::WebPluginDelegatePepper(
: render_view_(render_view),
plugin_(NULL),
instance_(instance),
- nested_delegate_(NULL) {
+ nested_delegate_(NULL),
+ last_command_buffer_put_offset_(-1) {
// For now we keep a window struct, although it isn't used.
memset(&window_, 0, sizeof(window_));
// All Pepper plugins are windowless and transparent.
@@ -720,3 +706,14 @@ bool WebPluginDelegatePepper::HandleInputEvent(const WebInputEvent& event,
}
return instance()->NPP_HandleEvent(&npevent) != 0;
}
+
+#if defined(ENABLE_GPU)
+void WebPluginDelegatePepper::Synchronize3DContext(
+ NPDeviceContext3D* context,
+ gpu::CommandBuffer::State state) {
+ context->getOffset = state.get_offset;
+ context->putOffset = state.put_offset;
+ context->token = state.token;
+ context->error = static_cast<int32>(state.error);
+}
+#endif // ENABLE_GPU
diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h
index 91e35b6..b2ac3c6 100644
--- a/chrome/renderer/webplugin_delegate_pepper.h
+++ b/chrome/renderer/webplugin_delegate_pepper.h
@@ -164,6 +164,12 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
// Closes down and destroys our plugin instance.
void DestroyInstance();
+#if defined(ENABLE_GPU)
+ // Synchronize a 3D context state with the service.
+ void Synchronize3DContext(NPDeviceContext3D* context,
+ gpu::CommandBuffer::State state);
+#endif
+
base::WeakPtr<RenderView> render_view_;
webkit_glue::WebPlugin* plugin_;
@@ -190,6 +196,10 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate {
scoped_ptr<CommandBufferProxy> command_buffer_;
#endif
+ // Used to track whether additional commands have been put in the command
+ // buffer since the last flush.
+ int32 last_command_buffer_put_offset_;
+
DISALLOW_COPY_AND_ASSIGN(WebPluginDelegatePepper);
};
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 0651ee6..d58338e 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -24,12 +24,11 @@ bool CommandBufferHelper::Initialize() {
if (!ring_buffer_.ptr)
return false;
+ CommandBuffer::State state = command_buffer_->GetState();
entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
- entry_count_ = command_buffer_->GetSize();
- get_ = command_buffer_->GetGetOffset();
- put_ = command_buffer_->GetPutOffset();
- last_token_read_ = command_buffer_->GetToken();
-
+ entry_count_ = state.size;
+ put_ = state.put_offset;
+ SynchronizeState(state);
return true;
}
@@ -37,8 +36,9 @@ CommandBufferHelper::~CommandBufferHelper() {
}
bool CommandBufferHelper::Flush() {
- get_ = command_buffer_->SyncOffsets(put_);
- return !command_buffer_->GetErrorStatus();
+ CommandBuffer::State state = command_buffer_->Flush(put_);
+ SynchronizeState(state);
+ return state.error == parse_error::kParseNoError;
}
// Calls Flush() and then waits until the buffer is empty. Break early if the
@@ -46,7 +46,7 @@ bool CommandBufferHelper::Flush() {
bool CommandBufferHelper::Finish() {
do {
// Do not loop forever if the flush fails, meaning the command buffer reader
- // has shutdown).
+ // has shutdown.
if (!Flush())
return false;
} while (put_ != get_);
@@ -67,7 +67,6 @@ int32 CommandBufferHelper::InsertToken() {
if (token_ == 0) {
// we wrapped
Finish();
- last_token_read_ = command_buffer_->GetToken();
DCHECK_EQ(token_, last_token_read_);
}
return token_;
@@ -82,7 +81,6 @@ void CommandBufferHelper::WaitForToken(int32 token) {
if (last_token_read_ >= token) return; // fast path.
if (token > token_) return; // we wrapped
Flush();
- last_token_read_ = command_buffer_->GetToken();
while (last_token_read_ < token) {
if (get_ == put_) {
LOG(FATAL) << "Empty command buffer while waiting on a token.";
@@ -92,7 +90,6 @@ void CommandBufferHelper::WaitForToken(int32 token) {
// has shutdown.
if (!Flush())
return;
- last_token_read_ = command_buffer_->GetToken();
}
}
@@ -145,9 +142,15 @@ CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
return space;
}
-parse_error::ParseError CommandBufferHelper::GetParseError() {
- int32 parse_error = command_buffer_->ResetParseError();
- return static_cast<parse_error::ParseError>(parse_error);
+parse_error::ParseError CommandBufferHelper::GetError() {
+ CommandBuffer::State state = command_buffer_->GetState();
+ SynchronizeState(state);
+ return static_cast<parse_error::ParseError>(state.error);
+}
+
+void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) {
+ get_ = state.get_offset;
+ last_token_read_ = state.token;
}
} // namespace gpu
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h
index df56e2e..d26d927 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.h
+++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -103,7 +103,7 @@ class CommandBufferHelper {
return *reinterpret_cast<T*>(data);
}
- parse_error::ParseError GetParseError();
+ parse_error::ParseError GetError();
// Common Commands
void Noop(uint32 skip_count) {
@@ -127,6 +127,9 @@ class CommandBufferHelper {
return (get_ - put_ - 1 + entry_count_) % entry_count_;
}
+ // Synchronize with current service state.
+ void SynchronizeState(CommandBuffer::State state);
+
CommandBuffer* command_buffer_;
Buffer ring_buffer_;
CommandBufferEntry *entries_;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
index 96f7004..3134051 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -111,6 +111,18 @@ class CommandBufferHelperTest : public testing::Test {
}
}
+ int32 GetGetOffset() {
+ return command_buffer_->GetState().get_offset;
+ }
+
+ int32 GetPutOffset() {
+ return command_buffer_->GetState().put_offset;
+ }
+
+ parse_error::ParseError GetError() {
+ return command_buffer_->GetState().error;
+ }
+
CommandBufferOffset get_helper_put() { return helper_->put_; }
base::AtExitManager at_exit_manager_;
@@ -128,9 +140,8 @@ TEST_F(CommandBufferHelperTest, TestCommandProcessing) {
// Check initial state of the engine - it should have been configured by the
// helper.
EXPECT_TRUE(parser_ != NULL);
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
- EXPECT_EQ(0, command_buffer_->GetGetOffset());
+ EXPECT_EQ(parse_error::kParseNoError, GetError());
+ EXPECT_EQ(0, GetGetOffset());
// Add 3 commands through the helper
AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL);
@@ -158,8 +169,7 @@ TEST_F(CommandBufferHelperTest, TestCommandProcessing) {
Mock::VerifyAndClearExpectations(api_mock_.get());
// Check the error status.
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
+ EXPECT_EQ(parse_error::kParseNoError, GetError());
}
// Checks that commands in the buffer are properly executed when wrapping the
@@ -179,34 +189,7 @@ TEST_F(CommandBufferHelperTest, TestCommandWrapping) {
Mock::VerifyAndClearExpectations(api_mock_.get());
// Check the error status.
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
-}
-
-
-// Checks that commands in the buffer are properly executed, even if they
-// generate a recoverable error. Check that the error status is properly set,
-// and reset when queried.
-TEST_F(CommandBufferHelperTest, TestRecoverableError) {
- CommandBufferEntry args[2];
- args[0].value_uint32 = 3;
- args[1].value_float = 4.f;
-
- // Create a command buffer with 3 commands, 2 of them generating errors
- AddCommandWithExpect(parse_error::kParseNoError, 1, 2, args);
- AddCommandWithExpect(parse_error::kParseUnknownCommand, 2, 2, args);
- AddCommandWithExpect(parse_error::kParseInvalidArguments, 3, 2,
- args);
-
- helper_->Finish();
- // Check that the commands did happen.
- Mock::VerifyAndClearExpectations(api_mock_.get());
-
- // Check that the error status was set to the first error.
- EXPECT_EQ(parse_error::kParseUnknownCommand,
- command_buffer_->ResetParseError());
- // Check that the error status was reset after the query.
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
+ EXPECT_EQ(parse_error::kParseNoError, GetError());
}
// Checks that asking for available entries work, and that the parser
@@ -238,8 +221,7 @@ TEST_F(CommandBufferHelperTest, TestAvailableEntries) {
Mock::VerifyAndClearExpectations(api_mock_.get());
// Check the error status.
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
+ EXPECT_EQ(parse_error::kParseNoError, GetError());
}
// Checks that the InsertToken/WaitForToken work.
@@ -261,15 +243,14 @@ TEST_F(CommandBufferHelperTest, TestToken) {
AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args);
helper_->WaitForToken(token);
// check that the get pointer is beyond the first command.
- EXPECT_LE(command1_put, command_buffer_->GetGetOffset());
+ EXPECT_LE(command1_put, GetGetOffset());
helper_->Finish();
// Check that the commands did happen.
Mock::VerifyAndClearExpectations(api_mock_.get());
// Check the error status.
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
- EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError());
+ EXPECT_EQ(parse_error::kParseNoError, GetError());
}
} // namespace gpu
diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc
index a086463..8ef3bb4 100644
--- a/gpu/command_buffer/client/fenced_allocator_test.cc
+++ b/gpu/command_buffer/client/fenced_allocator_test.cc
@@ -61,6 +61,10 @@ class BaseFencedAllocatorTest : public testing::Test {
helper_->Initialize();
}
+ int32 GetToken() {
+ return command_buffer_->GetState().token;
+ }
+
virtual void TearDown() {
helper_.release();
}
@@ -187,7 +191,7 @@ TEST_F(FencedAllocatorTest, TestFreePendingToken) {
// The way we hooked up the helper and engine, it won't process commands
// until it has to wait for something. Which means the token shouldn't have
// passed yet at this point.
- EXPECT_GT(token, command_buffer_->GetToken());
+ EXPECT_GT(token, GetToken());
// This allocation will need to reclaim the space freed above, so that should
// process the commands until the token is passed.
@@ -196,7 +200,7 @@ TEST_F(FencedAllocatorTest, TestFreePendingToken) {
EXPECT_GE(kBufferSize, offsets[0]+kSize);
EXPECT_TRUE(allocator_->CheckConsistency());
// Check that the token has indeed passed.
- EXPECT_LE(token, command_buffer_->GetToken());
+ EXPECT_LE(token, GetToken());
// Free up everything.
for (unsigned int i = 0; i < kAllocCount; ++i) {
@@ -292,13 +296,13 @@ TEST_F(FencedAllocatorTest, TestGetLargestFreeOrPendingSize) {
// The way we hooked up the helper and engine, it won't process commands
// until it has to wait for something. Which means the token shouldn't have
// passed yet at this point.
- EXPECT_GT(token, command_buffer_->GetToken());
+ EXPECT_GT(token, GetToken());
// This allocation will need to reclaim the space freed above, so that should
// process the commands until the token is passed, but it will succeed.
offset = allocator_->Alloc(kBufferSize);
ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
// Check that the token has indeed passed.
- EXPECT_LE(token, command_buffer_->GetToken());
+ EXPECT_LE(token, GetToken());
allocator_->Free(offset);
// Everything now has been freed...
@@ -443,7 +447,7 @@ TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) {
// The way we hooked up the helper and engine, it won't process commands
// until it has to wait for something. Which means the token shouldn't have
// passed yet at this point.
- EXPECT_GT(token, command_buffer_->GetToken());
+ EXPECT_GT(token, GetToken());
// This allocation will need to reclaim the space freed above, so that should
// process the commands until the token is passed.
@@ -451,7 +455,7 @@ TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) {
EXPECT_TRUE(pointers[0]);
EXPECT_TRUE(allocator_->CheckConsistency());
// Check that the token has indeed passed.
- EXPECT_LE(token, command_buffer_->GetToken());
+ EXPECT_LE(token, GetToken());
// Free up everything.
for (unsigned int i = 0; i < kAllocCount; ++i) {
diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h
index 7126e53..85e7596 100644
--- a/gpu/command_buffer/common/command_buffer.h
+++ b/gpu/command_buffer/common/command_buffer.h
@@ -7,12 +7,42 @@
#include "base/basictypes.h"
#include "gpu/command_buffer/common/buffer.h"
+#include "gpu/command_buffer/common/constants.h"
namespace gpu {
// Common interface for CommandBuffer implementations.
class CommandBuffer {
public:
+ struct State {
+ State()
+ : size(0),
+ get_offset(0),
+ put_offset(0),
+ token(-1),
+ error(parse_error::kParseNoError) {
+ }
+
+ // Size of the command buffer in command buffer entries.
+ int32 size;
+
+ // The offset (in entries) from which the reader is reading.
+ int32 get_offset;
+
+ // The offset (in entries) at which the writer is writing.
+ int32 put_offset;
+
+ // The current token value. This is used by the writer to defer
+ // changes to shared memory objects until the reader has reached a certain
+ // point in the command buffer. The reader is responsible for updating the
+ // token value, for example in response to an asynchronous set token command
+ // embedded in the command buffer. The default token value is zero.
+ int32 token;
+
+ // Error status.
+ parse_error::ParseError error;
+ };
+
CommandBuffer() {
}
@@ -26,22 +56,17 @@ class CommandBuffer {
// Gets the ring buffer for the command buffer.
virtual Buffer GetRingBuffer() = 0;
- virtual int32 GetSize() = 0;
+ // Returns the current status.
+ virtual State GetState() = 0;
// 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.
- virtual int32 SyncOffsets(int32 put_offset) = 0;
-
- // Returns the current get offset. This can be called from any thread.
- virtual int32 GetGetOffset() = 0;
+ virtual State Flush(int32 put_offset) = 0;
// Sets the current get offset. This can be called from any thread.
virtual void SetGetOffset(int32 get_offset) = 0;
- // Returns the current put offset. This can be called from any thread.
- virtual int32 GetPutOffset() = 0;
-
// Create a transfer buffer and return a handle that uniquely
// identifies it or -1 on error.
virtual int32 CreateTransferBuffer(size_t size) = 0;
@@ -52,29 +77,11 @@ class CommandBuffer {
// Get the transfer buffer associated with a handle.
virtual Buffer GetTransferBuffer(int32 handle) = 0;
- // Get the current token value. This is used for by the writer to defer
- // changes to shared memory objects until the reader has reached a certain
- // point in the command buffer. The reader is responsible for updating the
- // token value, for example in response to an asynchronous set token command
- // embedded in the command buffer. The default token value is zero.
- virtual int32 GetToken() = 0;
-
// Allows the reader to update the current token value.
virtual void SetToken(int32 token) = 0;
- // Get the current parse error and reset it to zero. Zero means no error. Non-
- // zero means error. The default error status is zero.
- virtual int32 ResetParseError() = 0;
-
// Allows the reader to set the current parse error.
- virtual void SetParseError(int32 parse_error) = 0;
-
- // Returns whether the command buffer is in the error state.
- virtual bool GetErrorStatus() = 0;
-
- // Allows the reader to set the error status. Once in an error state, the
- // command buffer cannot recover and ceases to process commands.
- virtual void RaiseErrorStatus() = 0;
+ virtual void SetParseError(parse_error::ParseError) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(CommandBuffer);
diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h
index 6295c85..6795975 100644
--- a/gpu/command_buffer/common/command_buffer_mock.h
+++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -23,20 +23,14 @@ class MockCommandBuffer : public CommandBuffer {
MOCK_METHOD1(Initialize, bool(int32 size));
MOCK_METHOD0(GetRingBuffer, Buffer());
- MOCK_METHOD0(GetSize, int32());
- MOCK_METHOD1(SyncOffsets, int32(int32 put_offset));
- MOCK_METHOD0(GetGetOffset, int32());
+ MOCK_METHOD0(GetState, State());
+ MOCK_METHOD1(Flush, State(int32 put_offset));
MOCK_METHOD1(SetGetOffset, void(int32 get_offset));
- MOCK_METHOD0(GetPutOffset, int32());
MOCK_METHOD1(CreateTransferBuffer, int32(size_t size));
MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle));
MOCK_METHOD1(GetTransferBuffer, Buffer(int32 handle));
- MOCK_METHOD0(GetToken, int32());
MOCK_METHOD1(SetToken, void(int32 token));
- MOCK_METHOD0(ResetParseError, int32());
- MOCK_METHOD1(SetParseError, void(int32 parse_erro));
- MOCK_METHOD0(GetErrorStatus, bool());
- MOCK_METHOD0(RaiseErrorStatus, void());
+ MOCK_METHOD1(SetParseError, void(parse_error::ParseError parse_error));
private:
DISALLOW_COPY_AND_ASSIGN(MockCommandBuffer);
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h
index e07dd0f..ad7836b 100644
--- a/gpu/command_buffer/common/constants.h
+++ b/gpu/command_buffer/common/constants.h
@@ -12,18 +12,7 @@ namespace gpu {
typedef int32 CommandBufferOffset;
const CommandBufferOffset kInvalidCommandBufferOffset = -1;
-// Status of the command buffer service. It does not process commands
-// (meaning: get will not change) unless in kParsing state.
-namespace parser_status {
- enum ParserStatus {
- kNotConnected, // The service is not connected - initial state.
- kNoBuffer, // The service is connected but no buffer was set.
- kParsing, // The service is connected, and parsing commands from the
- // buffer.
- kParseError, // Parsing stopped because a parse error was found.
- };
-}
-
+// TODO(apatrick): rename to something more generic like just Error.
namespace parse_error {
enum ParseError {
kParseNoError,
@@ -31,6 +20,7 @@ namespace parse_error {
kParseOutOfBounds,
kParseUnknownCommand,
kParseInvalidArguments,
+ kParseGenericError,
};
}
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc
index f0a96e1..053a22b 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -17,8 +17,7 @@ CommandBufferService::CommandBufferService()
get_offset_(0),
put_offset_(0),
token_(0),
- parse_error_(0),
- error_status_(false) {
+ error_(parse_error::kParseNoError) {
// Element zero is always NULL.
registered_objects_.push_back(linked_ptr<SharedMemory>());
}
@@ -54,13 +53,22 @@ Buffer CommandBufferService::GetRingBuffer() {
return buffer;
}
-int32 CommandBufferService::GetSize() {
- return size_;
+CommandBufferService::State CommandBufferService::GetState() {
+ State state;
+ state.size = size_;
+ state.get_offset = get_offset_;
+ state.put_offset = put_offset_;
+ state.token = token_;
+ state.error = error_;
+
+ return state;
}
-int32 CommandBufferService::SyncOffsets(int32 put_offset) {
- if (put_offset < 0 || put_offset >= size_)
- return -1;
+CommandBufferService::State CommandBufferService::Flush(int32 put_offset) {
+ if (put_offset < 0 || put_offset >= size_) {
+ error_ = gpu::parse_error::kParseOutOfBounds;
+ return GetState();
+ }
put_offset_ = put_offset;
@@ -68,11 +76,7 @@ int32 CommandBufferService::SyncOffsets(int32 put_offset) {
put_offset_change_callback_->Run();
}
- return get_offset_;
-}
-
-int32 CommandBufferService::GetGetOffset() {
- return get_offset_;
+ return GetState();
}
void CommandBufferService::SetGetOffset(int32 get_offset) {
@@ -80,10 +84,6 @@ void CommandBufferService::SetGetOffset(int32 get_offset) {
get_offset_ = get_offset;
}
-int32 CommandBufferService::GetPutOffset() {
- return put_offset_;
-}
-
int32 CommandBufferService::CreateTransferBuffer(size_t size) {
linked_ptr<SharedMemory> buffer(new SharedMemory);
if (!buffer->Create(std::wstring(), false, false, size))
@@ -150,34 +150,16 @@ Buffer CommandBufferService::GetTransferBuffer(int32 handle) {
return buffer;
}
-int32 CommandBufferService::GetToken() {
- return token_;
-}
-
void CommandBufferService::SetToken(int32 token) {
token_ = token;
}
-int32 CommandBufferService::ResetParseError() {
- int32 last_error = parse_error_;
- parse_error_ = 0;
- return last_error;
-}
-
-void CommandBufferService::SetParseError(int32 parse_error) {
- if (parse_error_ == 0) {
- parse_error_ = parse_error;
+void CommandBufferService::SetParseError(parse_error::ParseError error) {
+ if (error_ == parse_error::kParseNoError) {
+ error_ = error;
}
}
-bool CommandBufferService::GetErrorStatus() {
- return error_status_;
-}
-
-void CommandBufferService::RaiseErrorStatus() {
- error_status_ = true;
-}
-
void CommandBufferService::SetPutOffsetChangeCallback(
Callback0::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 aec7c14..3e58d7e 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -26,20 +26,14 @@ class CommandBufferService : public CommandBuffer {
// CommandBuffer implementation:
virtual bool Initialize(int32 size);
virtual Buffer GetRingBuffer();
- virtual int32 GetSize();
- virtual int32 SyncOffsets(int32 put_offset);
- virtual int32 GetGetOffset();
+ virtual State GetState();
+ virtual State Flush(int32 put_offset);
virtual void SetGetOffset(int32 get_offset);
- virtual int32 GetPutOffset();
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);
virtual Buffer GetTransferBuffer(int32 handle);
- virtual int32 GetToken();
virtual void SetToken(int32 token);
- virtual int32 ResetParseError();
- virtual void SetParseError(int32 parse_error);
- virtual bool GetErrorStatus();
- virtual void RaiseErrorStatus();
+ virtual void SetParseError(parse_error::ParseError);
// 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
@@ -62,8 +56,7 @@ class CommandBufferService : public CommandBuffer {
std::vector<linked_ptr< base::SharedMemory> > registered_objects_;
std::set<int32> unused_registered_object_elements_;
int32 token_;
- int32 parse_error_;
- bool error_status_;
+ parse_error::ParseError error_;
};
} // namespace gpu
diff --git a/gpu/command_buffer/service/command_buffer_service_unittest.cc b/gpu/command_buffer/service/command_buffer_service_unittest.cc
index 98ec0ec..ea0193b 100644
--- a/gpu/command_buffer/service/command_buffer_service_unittest.cc
+++ b/gpu/command_buffer/service/command_buffer_service_unittest.cc
@@ -23,6 +23,22 @@ class CommandBufferServiceTest : public testing::Test {
command_buffer_.reset(new CommandBufferService);
}
+ int32 GetGetOffset() {
+ return command_buffer_->GetState().get_offset;
+ }
+
+ int32 GetPutOffset() {
+ return command_buffer_->GetState().put_offset;
+ }
+
+ int32 GetToken() {
+ return command_buffer_->GetState().token;
+ }
+
+ int32 GetError() {
+ return command_buffer_->GetState().error;
+ }
+
scoped_ptr<CommandBufferService> command_buffer_;
};
@@ -33,9 +49,12 @@ TEST_F(CommandBufferServiceTest, NullRingBufferByDefault) {
TEST_F(CommandBufferServiceTest, InitializesCommandBuffer) {
EXPECT_TRUE(command_buffer_->Initialize(1024));
EXPECT_TRUE(NULL != command_buffer_->GetRingBuffer().ptr);
- EXPECT_EQ(1024, command_buffer_->GetSize());
- EXPECT_EQ(1024 * sizeof(CommandBufferEntry),
- command_buffer_->GetRingBuffer().size);
+ CommandBuffer::State state = command_buffer_->GetState();
+ EXPECT_EQ(1024, state.size);
+ EXPECT_EQ(0, state.get_offset);
+ EXPECT_EQ(0, state.put_offset);
+ EXPECT_EQ(0, state.token);
+ EXPECT_EQ(parse_error::kParseNoError, state.error);
}
TEST_F(CommandBufferServiceTest, InitializationSizeIsInEntriesNotBytes) {
@@ -51,11 +70,6 @@ TEST_F(CommandBufferServiceTest, InitializeFailsSecondTime) {
EXPECT_FALSE(command_buffer_->Initialize(1024));
}
-TEST_F(CommandBufferServiceTest, GetAndPutOffsetsDefaultToZero) {
- EXPECT_EQ(0, command_buffer_->GetGetOffset());
- EXPECT_EQ(0, command_buffer_->GetPutOffset());
-}
-
class MockCallback : public CallbackRunner<Tuple0> {
public:
MOCK_METHOD1(RunWithParams, void(const Tuple0&));
@@ -69,20 +83,21 @@ TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) {
command_buffer_->SetPutOffsetChangeCallback(put_offset_change_callback);
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
- EXPECT_EQ(0, command_buffer_->SyncOffsets(2));
- EXPECT_EQ(2, command_buffer_->GetPutOffset());
+ EXPECT_EQ(0, command_buffer_->Flush(2).get_offset);
+ EXPECT_EQ(2, GetPutOffset());
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
- EXPECT_EQ(0, command_buffer_->SyncOffsets(4));
- EXPECT_EQ(4, command_buffer_->GetPutOffset());
+ EXPECT_EQ(0, command_buffer_->Flush(4).get_offset);
+ EXPECT_EQ(4, GetPutOffset());
command_buffer_->SetGetOffset(2);
- EXPECT_EQ(2, command_buffer_->GetGetOffset());
+ EXPECT_EQ(2, GetGetOffset());
EXPECT_CALL(*put_offset_change_callback, RunWithParams(_));
- EXPECT_EQ(2, command_buffer_->SyncOffsets(6));
+ EXPECT_EQ(2, command_buffer_->Flush(6).get_offset);
- EXPECT_EQ(-1, command_buffer_->SyncOffsets(-1));
- EXPECT_EQ(-1, command_buffer_->SyncOffsets(1024));
+ EXPECT_NE(parse_error::kParseNoError, command_buffer_->Flush(-1).error);
+ EXPECT_NE(parse_error::kParseNoError,
+ command_buffer_->Flush(1024).error);
}
TEST_F(CommandBufferServiceTest, ZeroHandleMapsToNull) {
@@ -153,31 +168,20 @@ TEST_F(CommandBufferServiceTest, UnregistersTwoLastRegisteredHandles) {
}
TEST_F(CommandBufferServiceTest, DefaultTokenIsZero) {
- EXPECT_EQ(0, command_buffer_->GetToken());
+ EXPECT_EQ(0, GetToken());
}
TEST_F(CommandBufferServiceTest, CanSetToken) {
command_buffer_->SetToken(7);
- EXPECT_EQ(7, command_buffer_->GetToken());
+ EXPECT_EQ(7, GetToken());
}
TEST_F(CommandBufferServiceTest, DefaultParseErrorIsNoError) {
- EXPECT_EQ(0, command_buffer_->ResetParseError());
-}
-
-TEST_F(CommandBufferServiceTest, CanSetAndResetParseError) {
- command_buffer_->SetParseError(1);
- EXPECT_EQ(1, command_buffer_->ResetParseError());
- EXPECT_EQ(0, command_buffer_->ResetParseError());
-}
-
-TEST_F(CommandBufferServiceTest, DefaultErrorStatusIsFalse) {
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
+ EXPECT_EQ(0, GetError());
}
-TEST_F(CommandBufferServiceTest, CanRaiseErrorStatus) {
- command_buffer_->RaiseErrorStatus();
- EXPECT_TRUE(command_buffer_->GetErrorStatus());
+TEST_F(CommandBufferServiceTest, CanSetParseError) {
+ command_buffer_->SetParseError(parse_error::kParseInvalidSize);
+ EXPECT_EQ(1, GetError());
}
-
} // namespace gpu
diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc
index 8697c8b..30f07ef 100644
--- a/gpu/command_buffer/service/gpu_processor.cc
+++ b/gpu/command_buffer/service/gpu_processor.cc
@@ -32,7 +32,8 @@ GPUProcessor::~GPUProcessor() {
}
void GPUProcessor::ProcessCommands() {
- if (command_buffer_->GetErrorStatus())
+ CommandBuffer::State state = command_buffer_->GetState();
+ if (state.error != parse_error::kParseNoError)
return;
if (decoder_.get()) {
@@ -41,26 +42,15 @@ void GPUProcessor::ProcessCommands() {
return;
}
- parser_->set_put(command_buffer_->GetPutOffset());
+ parser_->set_put(state.put_offset);
int commands_processed = 0;
while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) {
parse_error::ParseError parse_error = parser_->ProcessCommand();
- switch (parse_error) {
- case parse_error::kParseUnknownCommand:
- case parse_error::kParseInvalidArguments:
- command_buffer_->SetParseError(parse_error);
- break;
-
- case parse_error::kParseInvalidSize:
- case parse_error::kParseOutOfBounds:
- command_buffer_->SetParseError(parse_error);
- command_buffer_->RaiseErrorStatus();
- return;
- case gpu::parse_error::kParseNoError:
- break;
+ if (parse_error != parse_error::kParseNoError) {
+ command_buffer_->SetParseError(parse_error);
+ return;
}
-
++commands_processed;
}
diff --git a/gpu/command_buffer/service/gpu_processor_unittest.cc b/gpu/command_buffer/service/gpu_processor_unittest.cc
index 38ba3fd..4f97acc 100644
--- a/gpu/command_buffer/service/gpu_processor_unittest.cc
+++ b/gpu/command_buffer/service/gpu_processor_unittest.cc
@@ -39,8 +39,11 @@ class GPUProcessorTest : public testing::Test {
command_buffer_.reset(new MockCommandBuffer);
ON_CALL(*command_buffer_.get(), GetRingBuffer())
.WillByDefault(Return(shared_memory_buffer_));
- ON_CALL(*command_buffer_.get(), GetSize())
- .WillByDefault(Return(kRingBufferEntries));
+
+ CommandBuffer::State default_state;
+ default_state.size = kRingBufferEntries;
+ ON_CALL(*command_buffer_.get(), GetState())
+ .WillByDefault(Return(default_state));
async_api_.reset(new StrictMock<AsyncAPIMock>);
@@ -65,6 +68,10 @@ class GPUProcessorTest : public testing::Test {
MessageLoop::current()->RunAllPending();
}
+ parse_error::ParseError GetError() {
+ return command_buffer_->GetState().error;
+ }
+
base::AtExitManager at_exit_manager;
MessageLoop message_loop;
scoped_ptr<MockCommandBuffer> command_buffer_;
@@ -78,15 +85,17 @@ class GPUProcessorTest : public testing::Test {
};
TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) {
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(0));
+ CommandBuffer::State state;
+
+ state.put_offset = 0;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*command_buffer_, SetGetOffset(0));
- processor_->ProcessCommands();
+ EXPECT_CALL(*command_buffer_, SetParseError(_))
+ .Times(0);
- EXPECT_EQ(parse_error::kParseNoError,
- command_buffer_->ResetParseError());
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
+ processor_->ProcessCommands();
}
TEST_F(GPUProcessorTest, ProcessesOneCommand) {
@@ -95,18 +104,20 @@ TEST_F(GPUProcessorTest, ProcessesOneCommand) {
header[0].size = 2;
buffer_[1] = 123;
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(2));
+ CommandBuffer::State state;
+
+ state.put_offset = 2;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*command_buffer_, SetGetOffset(2));
EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
.WillOnce(Return(parse_error::kParseNoError));
- processor_->ProcessCommands();
+ EXPECT_CALL(*command_buffer_, SetParseError(_))
+ .Times(0);
- EXPECT_EQ(parse_error::kParseNoError,
- command_buffer_->ResetParseError());
- EXPECT_FALSE(command_buffer_->GetErrorStatus());
+ processor_->ProcessCommands();
}
TEST_F(GPUProcessorTest, ProcessesTwoCommands) {
@@ -117,8 +128,11 @@ TEST_F(GPUProcessorTest, ProcessesTwoCommands) {
header[2].command = 8;
header[2].size = 1;
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(3));
+ CommandBuffer::State state;
+
+ state.put_offset = 3;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*command_buffer_, SetGetOffset(3));
EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
@@ -130,11 +144,15 @@ TEST_F(GPUProcessorTest, ProcessesTwoCommands) {
processor_->ProcessCommands();
}
-TEST_F(GPUProcessorTest, ProcessorSetsAndResetsTheGLContext) {
+TEST_F(GPUProcessorTest, ProcessorSetsTheGLContext) {
EXPECT_CALL(*decoder_, MakeCurrent())
.WillOnce(Return(true));
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(0));
+
+ CommandBuffer::State state;
+ state.put_offset = 0;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
+
EXPECT_CALL(*command_buffer_, SetGetOffset(0));
processor_->ProcessCommands();
@@ -150,8 +168,11 @@ TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) {
header[3].command = 9;
header[3].size = 1;
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(4));
+ CommandBuffer::State state;
+
+ state.put_offset = 4;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
.WillOnce(Return(parse_error::kParseNoError));
@@ -165,8 +186,9 @@ TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) {
// ProcessCommands is called a second time when the pending task is run.
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(4));
+ state.put_offset = 4;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3]))
.WillOnce(Return(parse_error::kParseNoError));
@@ -181,73 +203,28 @@ TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) {
header[0].command = 7;
header[0].size = 1;
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(1));
- EXPECT_CALL(*command_buffer_, SetGetOffset(1));
-
- EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0]))
- .WillOnce(Return(
- parse_error::kParseUnknownCommand));
-
- EXPECT_CALL(*command_buffer_,
- SetParseError(parse_error::kParseUnknownCommand));
-
- processor_->ProcessCommands();
-}
-
-TEST_F(GPUProcessorTest,
- RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) {
- CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
- header[0].command = 7;
- header[0].size = 1;
- header[1].command = 8;
- header[1].size = 1;
+ CommandBuffer::State state;
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(2));
- EXPECT_CALL(*command_buffer_, SetGetOffset(2));
+ state.put_offset = 1;
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0]))
.WillOnce(Return(
parse_error::kParseUnknownCommand));
- EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1]))
- .WillOnce(Return(parse_error::kParseNoError));
-
EXPECT_CALL(*command_buffer_,
SetParseError(parse_error::kParseUnknownCommand));
processor_->ProcessCommands();
}
-TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) {
- CommandHeader* header =
- reinterpret_cast<CommandHeader*>(&buffer_[0]);
- header[0].command = 7;
- header[0].size = 1;
- header[1].command = 8;
- header[1].size = 1;
-
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .WillOnce(Return(2));
+TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterError) {
+ CommandBuffer::State state;
+ state.error = parse_error::kParseGenericError;
- EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0]))
- .WillOnce(Return(parse_error::kParseInvalidSize));
-
- EXPECT_CALL(*command_buffer_,
- SetParseError(parse_error::kParseInvalidSize));
-
- EXPECT_CALL(*command_buffer_, RaiseErrorStatus());
-
- processor_->ProcessCommands();
-}
-
-TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) {
- EXPECT_CALL(*command_buffer_, GetErrorStatus())
- .WillOnce(Return(true));
-
- EXPECT_CALL(*command_buffer_, GetPutOffset())
- .Times(0);
+ EXPECT_CALL(*command_buffer_, GetState())
+ .WillOnce(Return(state));
processor_->ProcessCommands();
}
diff --git a/gpu/pgl/command_buffer_pepper.cc b/gpu/pgl/command_buffer_pepper.cc
index 9dd3c70..8522bbe 100644
--- a/gpu/pgl/command_buffer_pepper.cc
+++ b/gpu/pgl/command_buffer_pepper.cc
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "gpu/command_buffer/common/constants.h"
#include "gpu/pgl/command_buffer_pepper.h"
+
#ifdef __native_client__
#include <assert.h>
#define NOTREACHED() assert(0)
@@ -12,6 +14,7 @@
using base::SharedMemory;
using gpu::Buffer;
+using gpu::CommandBuffer;
CommandBufferPepper::CommandBufferPepper(NPP npp,
NPDevice* device,
@@ -37,29 +40,20 @@ Buffer CommandBufferPepper::GetRingBuffer() {
return buffer;
}
-int32 CommandBufferPepper::GetSize() {
- return context_->commandBufferEntries;
-}
-
-int32 CommandBufferPepper::SyncOffsets(int32 put_offset) {
- context_->putOffset = put_offset;
+CommandBuffer::State CommandBufferPepper::GetState() {
if (NPERR_NO_ERROR != device_->flushContext(npp_, context_, NULL, NULL))
- return -1;
+ context_->error = gpu::parse_error::kParseGenericError;
- return context_->getOffset;
+ return ConvertState();
}
-int32 CommandBufferPepper::GetGetOffset() {
- int32 value;
- if (NPERR_NO_ERROR != device_->getStateContext(
- npp_,
- context_,
- NPDeviceContext3DState_GetOffset,
- &value)) {
- return -1;
- }
+CommandBuffer::State CommandBufferPepper::Flush(int32 put_offset) {
+ context_->putOffset = put_offset;
- return value;
+ if (NPERR_NO_ERROR != device_->flushContext(npp_, context_, NULL, NULL))
+ context_->error = gpu::parse_error::kParseGenericError;
+
+ return ConvertState();
}
void CommandBufferPepper::SetGetOffset(int32 get_offset) {
@@ -67,19 +61,6 @@ void CommandBufferPepper::SetGetOffset(int32 get_offset) {
NOTREACHED();
}
-int32 CommandBufferPepper::GetPutOffset() {
- int32 value;
- if (NPERR_NO_ERROR != device_->getStateContext(
- npp_,
- context_,
- NPDeviceContext3DState_PutOffset,
- &value)) {
- return -1;
- }
-
- return value;
-}
-
int32 CommandBufferPepper::CreateTransferBuffer(size_t size) {
int32 id;
if (NPERR_NO_ERROR != device_->createBuffer(npp_, context_, size, &id))
@@ -103,56 +84,24 @@ Buffer CommandBufferPepper::GetTransferBuffer(int32 id) {
return buffer;
}
-int32 CommandBufferPepper::GetToken() {
- int32 value;
- if (NPERR_NO_ERROR != device_->getStateContext(
- npp_,
- context_,
- NPDeviceContext3DState_Token,
- &value)) {
- return -1;
- }
-
- return value;
-}
-
void CommandBufferPepper::SetToken(int32 token) {
// Not implemented by proxy.
NOTREACHED();
}
-int32 CommandBufferPepper::ResetParseError() {
- int32 value;
- if (NPERR_NO_ERROR != device_->getStateContext(
- npp_,
- context_,
- NPDeviceContext3DState_ParseError,
- &value)) {
- return -1;
- }
-
- return value;
-}
-
-void CommandBufferPepper::SetParseError(int32 parse_error) {
+void CommandBufferPepper::SetParseError(
+ gpu::parse_error::ParseError parse_error) {
// Not implemented by proxy.
NOTREACHED();
}
-bool CommandBufferPepper::GetErrorStatus() {
- int32 value;
- if (NPERR_NO_ERROR != device_->getStateContext(
- npp_,
- context_,
- NPDeviceContext3DState_ErrorStatus,
- &value)) {
- return value != 0;
- }
-
- return true;
-}
-
-void CommandBufferPepper::RaiseErrorStatus() {
- // Not implemented by proxy.
- NOTREACHED();
+CommandBuffer::State CommandBufferPepper::ConvertState() {
+ CommandBuffer::State state;
+ state.size = context_->commandBufferEntries;
+ state.get_offset = context_->getOffset;
+ state.put_offset = context_->putOffset;
+ state.token = context_->token;
+ state.error = static_cast<gpu::parse_error::ParseError>(
+ context_->error);
+ return state;
}
diff --git a/gpu/pgl/command_buffer_pepper.h b/gpu/pgl/command_buffer_pepper.h
index aa1d14b..b3efaea 100644
--- a/gpu/pgl/command_buffer_pepper.h
+++ b/gpu/pgl/command_buffer_pepper.h
@@ -28,22 +28,18 @@ class CommandBufferPepper : public gpu::CommandBuffer {
// CommandBuffer implementation.
virtual bool Initialize(int32 size);
virtual gpu::Buffer GetRingBuffer();
- virtual int32 GetSize();
- virtual int32 SyncOffsets(int32 put_offset);
- virtual int32 GetGetOffset();
+ virtual State GetState();
+ virtual State Flush(int32 put_offset);
virtual void SetGetOffset(int32 get_offset);
- virtual int32 GetPutOffset();
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);
virtual gpu::Buffer GetTransferBuffer(int32 handle);
- virtual int32 GetToken();
virtual void SetToken(int32 token);
- virtual int32 ResetParseError();
- virtual void SetParseError(int32 parse_error);
- virtual bool GetErrorStatus();
- virtual void RaiseErrorStatus();
+ virtual void SetParseError(gpu::parse_error::ParseError parse_error);
private:
+ CommandBuffer::State ConvertState();
+
NPP npp_;
NPDevice* device_;
NPDeviceContext3D* context_;
diff --git a/third_party/npapi/bindings/npapi_extensions.h b/third_party/npapi/bindings/npapi_extensions.h
index c24cd99..c60a82a 100644
--- a/third_party/npapi/bindings/npapi_extensions.h
+++ b/third_party/npapi/bindings/npapi_extensions.h
@@ -271,20 +271,6 @@ typedef struct _NPDeviceContext3DConfig {
int32 commandBufferEntries;
} NPDeviceContext3DConfig;
-typedef enum {
- // The offset the command buffer service has read to.
- NPDeviceContext3DState_GetOffset,
- // The offset the plugin instance has written to.
- NPDeviceContext3DState_PutOffset,
- // The last token processed by the command buffer service.
- NPDeviceContext3DState_Token,
- // The most recent parse error. Getting this value resets the parse error
- // if it recoverable.
- NPDeviceContext3DState_ParseError,
- // Wether the command buffer has encountered an unrecoverable error.
- NPDeviceContext3DState_ErrorStatus
-} NPDeviceContext3DState;
-
typedef struct _NPDeviceContext3D
{
void* reserved;
@@ -298,6 +284,12 @@ typedef struct _NPDeviceContext3D
// Offset in command buffer writer has reached. Synchronized on flush.
int32 putOffset;
+
+ // Last processed token. Synchronized on flush.
+ int32 token;
+
+ // Error status. Synchronized on flush.
+ int32 error;
} NPDeviceContext3D;
/* Audio --------------------------------------------------------------------*/