diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:02:36 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:02:36 +0000 |
commit | c77ea36637f9494c048f6c8035f3cf8a389da93d (patch) | |
tree | f1feccf837765ba30c4f46e11b8f7b0b996a5cbd /gpu | |
parent | 23fc99cca22572abe60eced18b90b5693c2f64f7 (diff) | |
download | chromium_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
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper.cc | 31 | ||||
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper_test.cc | 57 | ||||
-rw-r--r-- | gpu/command_buffer/client/fenced_allocator_test.cc | 16 | ||||
-rw-r--r-- | gpu/command_buffer/common/command_buffer.h | 61 | ||||
-rw-r--r-- | gpu/command_buffer/common/command_buffer_mock.h | 12 | ||||
-rw-r--r-- | gpu/command_buffer/common/constants.h | 14 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.cc | 56 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.h | 15 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service_unittest.cc | 70 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_processor.cc | 22 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_processor_unittest.cc | 131 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.cc | 97 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.h | 14 |
14 files changed, 237 insertions, 364 deletions
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_; |