diff options
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_; |