summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.cc41
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.h5
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper_test.cc63
-rw-r--r--gpu/command_buffer/service/cmd_parser.cc6
4 files changed, 75 insertions, 40 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 72724d7..ceec30e 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -12,7 +12,8 @@ namespace gpu {
CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
: command_buffer_(command_buffer),
entries_(NULL),
- entry_count_(0),
+ total_entry_count_(0),
+ usable_entry_count_(0),
token_(0),
last_token_read_(-1),
get_(0),
@@ -30,7 +31,12 @@ bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
if (num_ring_buffer_entries > state.num_entries) {
return false;
}
- entry_count_ = num_ring_buffer_entries;
+
+ const int32 kJumpEntries =
+ sizeof(cmd::Jump) / sizeof(*entries_); // NOLINT
+
+ total_entry_count_ = num_ring_buffer_entries;
+ usable_entry_count_ = total_entry_count_ - kJumpEntries;
put_ = state.put_offset;
SynchronizeState(state);
return true;
@@ -99,16 +105,16 @@ void CommandBufferHelper::WaitForToken(int32 token) {
// Waits for available entries, basically waiting until get >= put + count + 1.
// It actually waits for contiguous entries, so it may need to wrap the buffer
-// around, adding noops. Thus this function may change the value of put_.
-// The function will return early if an error occurs, in which case the
-// available space may not be available.
+// around, adding a jump. Thus this function may change the value of put_. The
+// function will return early if an error occurs, in which case the available
+// space may not be available.
void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
- CHECK(count < entry_count_);
- if (put_ + count > entry_count_) {
+ CHECK(count < usable_entry_count_);
+ if (put_ + count > usable_entry_count_) {
// There's not enough room between the current put and the end of the
- // buffer, so we need to wrap. We will add noops all the way to the end,
- // but we need to make sure get wraps first, actually that get is 1 or
- // more (since put will wrap to 0 after we add the noops).
+ // buffer, so we need to wrap. We will add a jump back to the start, but we
+ // need to make sure get wraps first, actually that get is 1 or more (since
+ // put will wrap to 0 after we add the jump).
DCHECK_LE(1, put_);
Flush();
while (get_ > put_ || get_ == 0) {
@@ -117,14 +123,8 @@ void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
if (!Flush())
return;
}
- // Insert Noops to fill out buffer.
- int32 num_entries = entry_count_ - put_;
- while (num_entries > 0) {
- int32 num_to_skip = std::min(CommandHeader::kMaxSize, num_entries);
- cmd::Noop::Set(&entries_[put_], num_to_skip);
- put_ += num_to_skip;
- num_entries -= num_to_skip;
- }
+ // Insert a jump back to the beginning.
+ cmd::Jump::Set(&entries_[put_], 0);
put_ = 0;
}
// If we have enough room, return immediatly.
@@ -143,8 +143,9 @@ CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
WaitForAvailableEntries(entries);
CommandBufferEntry* space = &entries_[put_];
put_ += entries;
- DCHECK_LE(put_, entry_count_);
- if (put_ == entry_count_) {
+ DCHECK_LE(put_, usable_entry_count_);
+ if (put_ == usable_entry_count_) {
+ cmd::Jump::Set(&entries_[put_], 0);
put_ = 0;
}
return space;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h
index cc93057..49ff97e 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.h
+++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -202,7 +202,7 @@ class CommandBufferHelper {
// Returns the number of available entries (they may not be contiguous).
int32 AvailableEntries() {
- return (get_ - put_ - 1 + entry_count_) % entry_count_;
+ return (get_ - put_ - 1 + usable_entry_count_) % usable_entry_count_;
}
// Synchronize with current service state.
@@ -211,7 +211,8 @@ class CommandBufferHelper {
CommandBuffer* command_buffer_;
Buffer ring_buffer_;
CommandBufferEntry *entries_;
- int32 entry_count_;
+ int32 total_entry_count_; // the total number of entries
+ int32 usable_entry_count_; // the usable number (ie, minus space for jump)
int32 token_;
int32 last_token_read_;
int32 get_;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
index a61d83b..1f3b53e 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -24,20 +24,42 @@ using testing::DoAll;
using testing::Invoke;
using testing::_;
-const int32 kNumCommandEntries = 10;
+const int32 kTotalNumCommandEntries = 12;
+const int32 kUsableNumCommandEntries = 10;
const int32 kCommandBufferSizeBytes =
- kNumCommandEntries * sizeof(CommandBufferEntry);
+ kTotalNumCommandEntries * sizeof(CommandBufferEntry);
+const int32 kUnusedCommandId = 5; // we use 0 and 2 currently.
// Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper,
// using a CommandBufferEngine with a mock AsyncAPIInterface for its interface
// (calling it directly, not through the RPC mechanism).
class CommandBufferHelperTest : public testing::Test {
protected:
+ // Helper so mock can handle the Jump command.
+ class DoJumpCommand {
+ public:
+ explicit DoJumpCommand(CommandParser* parser)
+ : parser_(parser) {
+ }
+
+ error::Error DoCommand(
+ unsigned int command,
+ unsigned int arg_count,
+ const void* cmd_data) {
+ const cmd::Jump* jump_cmd = static_cast<const cmd::Jump*>(cmd_data);
+ parser_->set_get(jump_cmd->offset);
+ return error::kNoError;
+ };
+
+ private:
+ CommandParser* parser_;
+ };
+
virtual void SetUp() {
api_mock_.reset(new AsyncAPIMock);
// ignore noops in the mock - we don't want to inspect the internals of the
// helper.
- EXPECT_CALL(*api_mock_, DoCommand(0, _, _))
+ EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, _, _))
.WillRepeatedly(Return(error::kNoError));
command_buffer_.reset(new CommandBufferService);
@@ -51,6 +73,11 @@ class CommandBufferHelperTest : public testing::Test {
0,
api_mock_.get());
+ do_jump_command_.reset(new DoJumpCommand(parser_));
+ EXPECT_CALL(*api_mock_, DoCommand(cmd::kJump, _, _))
+ .WillRepeatedly(
+ Invoke(do_jump_command_.get(), &DoJumpCommand::DoCommand));
+
gpu_processor_.reset(new GPUProcessor(
command_buffer_.get(), NULL, parser_, 1));
command_buffer_->SetPutOffsetChangeCallback(NewCallback(
@@ -104,7 +131,7 @@ class CommandBufferHelperTest : public testing::Test {
// put to the limit) and the bottom side (from 0 to get).
if (put >= parser_put) {
// we're on the top side, check we are below the limit.
- EXPECT_GE(kNumCommandEntries, limit);
+ EXPECT_GE(kTotalNumCommandEntries, limit);
} else {
// we're on the bottom side, check we are below get.
EXPECT_GT(parser_get, limit);
@@ -135,6 +162,7 @@ class CommandBufferHelperTest : public testing::Test {
CommandParser* parser_;
scoped_ptr<CommandBufferHelper> helper_;
Sequence sequence_;
+ scoped_ptr<DoJumpCommand> do_jump_command_;
};
// Checks that commands in the buffer are properly executed, and that the
@@ -147,17 +175,17 @@ TEST_F(CommandBufferHelperTest, TestCommandProcessing) {
EXPECT_EQ(0, GetGetOffset());
// Add 3 commands through the helper
- AddCommandWithExpect(error::kNoError, 1, 0, NULL);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId, 0, NULL);
CommandBufferEntry args1[2];
args1[0].value_uint32 = 3;
args1[1].value_float = 4.f;
- AddCommandWithExpect(error::kNoError, 2, 2, args1);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args1);
CommandBufferEntry args2[2];
args2[0].value_uint32 = 5;
args2[1].value_float = 6.f;
- AddCommandWithExpect(error::kNoError, 3, 2, args2);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId, 2, args2);
helper_->Flush();
// Check that the engine has work to do now.
@@ -184,7 +212,7 @@ TEST_F(CommandBufferHelperTest, TestCommandWrapping) {
args1[1].value_float = 4.f;
for (unsigned int i = 0; i < 5; ++i) {
- AddCommandWithExpect(error::kNoError, i + 1, 2, args1);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + i, 2, args1);
}
helper_->Finish();
@@ -200,7 +228,7 @@ TEST_F(CommandBufferHelperTest, TestCommandWrapping) {
TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) {
const int32 kCommandSize = 5;
const size_t kNumArgs = kCommandSize - 1;
- COMPILE_ASSERT(kNumCommandEntries % kCommandSize == 0,
+ COMPILE_ASSERT(kUsableNumCommandEntries % kCommandSize == 0,
Not_multiple_of_num_command_entries);
CommandBufferEntry args1[kNumArgs];
for (size_t ii = 0; ii < kNumArgs; ++ii) {
@@ -208,7 +236,8 @@ TEST_F(CommandBufferHelperTest, TestCommandWrappingExactMultiple) {
}
for (unsigned int i = 0; i < 5; ++i) {
- AddCommandWithExpect(error::kNoError, i + 1, kNumArgs, args1);
+ AddCommandWithExpect(
+ error::kNoError, i + kUnusedCommandId, kNumArgs, args1);
}
helper_->Finish();
@@ -227,10 +256,10 @@ TEST_F(CommandBufferHelperTest, TestAvailableEntries) {
args[1].value_float = 4.f;
// Add 2 commands through the helper - 8 entries
- AddCommandWithExpect(error::kNoError, 1, 0, NULL);
- AddCommandWithExpect(error::kNoError, 2, 0, NULL);
- AddCommandWithExpect(error::kNoError, 3, 2, args);
- AddCommandWithExpect(error::kNoError, 4, 2, args);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 1, 0, NULL);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 2, 0, NULL);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
// Ask for 5 entries.
helper_->WaitForAvailableEntries(5);
@@ -239,7 +268,7 @@ TEST_F(CommandBufferHelperTest, TestAvailableEntries) {
CheckFreeSpace(put, 5);
// Add more commands.
- AddCommandWithExpect(error::kNoError, 5, 2, args);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 5, 2, args);
// Wait until everything is done done.
helper_->Finish();
@@ -258,7 +287,7 @@ TEST_F(CommandBufferHelperTest, TestToken) {
args[1].value_float = 4.f;
// Add a first command.
- AddCommandWithExpect(error::kNoError, 3, 2, args);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
// keep track of the buffer position.
CommandBufferOffset command1_put = get_helper_put();
int32 token = helper_->InsertToken();
@@ -267,7 +296,7 @@ TEST_F(CommandBufferHelperTest, TestToken) {
.WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
Return(error::kNoError)));
// Add another command.
- AddCommandWithExpect(error::kNoError, 4, 2, args);
+ AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
helper_->WaitForToken(token);
// check that the get pointer is beyond the first command.
EXPECT_LE(command1_put, GetGetOffset());
diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc
index 191ddfa..a4b4755 100644
--- a/gpu/command_buffer/service/cmd_parser.cc
+++ b/gpu/command_buffer/service/cmd_parser.cc
@@ -58,7 +58,11 @@ error::Error CommandParser::ProcessCommand() {
if (result != error::kNoError) {
ReportError(header.command, result);
}
- get_ = (get + header.size) % entry_count_;
+
+ // If get was not set somewhere else advance it.
+ if (get == get_) {
+ get_ = (get + header.size) % entry_count_;
+ }
return result;
}