summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 22:06:18 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 22:06:18 +0000
commitbb62ce3d7922d0bd07b066f6460c7cd00f946011 (patch)
tree22657f3db7f64c7b8ace37bb2a3d4d1e2426cba0 /gpu
parent481a6d899f7c9a4d3e029fa6553f6bec589b5564 (diff)
downloadchromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.zip
chromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.tar.gz
chromium_src-bb62ce3d7922d0bd07b066f6460c7cd00f946011.tar.bz2
Revert "Revert 113250 - Add CommandBuffer::SetGetBuffer"
This reverts commit bd45bd252aeb8babac62547a5c605fbf64287cd3. TEST=ran webkit tests in DRT and webgl tests in chrome BUG=103989 Review URL: http://codereview.chromium.org/8758026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.cc24
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.h10
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper_test.cc16
-rw-r--r--gpu/command_buffer/client/fenced_allocator_test.cc16
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc235
-rw-r--r--gpu/command_buffer/client/mapped_memory_unittest.cc16
-rw-r--r--gpu/command_buffer/client/ring_buffer_test.cc16
-rw-r--r--gpu/command_buffer/common/command_buffer.h12
-rw-r--r--gpu/command_buffer/common/command_buffer_mock.cc2
-rw-r--r--gpu/command_buffer/common/command_buffer_mock.h5
-rw-r--r--gpu/command_buffer/service/cmd_buffer_engine.h3
-rw-r--r--gpu/command_buffer/service/cmd_parser.cc26
-rw-r--r--gpu/command_buffer/service/cmd_parser.h18
-rw-r--r--gpu/command_buffer/service/cmd_parser_test.cc40
-rw-r--r--gpu/command_buffer/service/command_buffer_service.cc87
-rw-r--r--gpu/command_buffer/service/command_buffer_service.h11
-rw-r--r--gpu/command_buffer/service/common_decoder_unittest.cc6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h5
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.cc35
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h1
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_unittest.cc49
-rw-r--r--gpu/demos/framework/window.cc2
-rw-r--r--gpu/gles2_conform_support/egl/display.cc2
23 files changed, 368 insertions, 269 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 6328923..d43efc3 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -17,6 +17,8 @@ const double kFlushDelay = 1.0 / (5.0 * 60.0);
CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
: command_buffer_(command_buffer),
+ ring_buffer_id_(-1),
+ ring_buffer_size_(0),
entries_(NULL),
total_entry_count_(0),
usable_entry_count_(0),
@@ -27,14 +29,25 @@ CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
last_flush_time_(0) {
}
-bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
- ring_buffer_ = command_buffer_->GetRingBuffer();
+bool CommandBufferHelper::AllocateRingBuffer() {
+ int32 id = command_buffer_->CreateTransferBuffer(ring_buffer_size_, -1);
+ if (id < 0) {
+ return false;
+ }
+
+ ring_buffer_ = command_buffer_->GetTransferBuffer(id);
if (!ring_buffer_.ptr)
return false;
+ ring_buffer_id_ = id;
+ command_buffer_->SetGetBuffer(id);
+
+ // TODO(gman): Do we really need to call GetState here? We know get & put = 0
+ // Also do we need to check state.num_entries?
CommandBuffer::State state = command_buffer_->GetState();
entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
- int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry);
+ int32 num_ring_buffer_entries =
+ ring_buffer_size_ / sizeof(CommandBufferEntry);
if (num_ring_buffer_entries > state.num_entries) {
return false;
}
@@ -48,6 +61,11 @@ bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
return true;
}
+bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
+ ring_buffer_size_ = ring_buffer_size;
+ return AllocateRingBuffer();
+}
+
CommandBufferHelper::~CommandBufferHelper() {
}
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h
index b6f45e2..5fbf462 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.h
+++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -214,6 +214,10 @@ class CommandBufferHelper {
return command_buffer_;
}
+ Buffer get_ring_buffer() const {
+ return ring_buffer_;
+ }
+
private:
// Waits until get changes, updating the value of get_.
void WaitForGetChange();
@@ -224,9 +228,13 @@ class CommandBufferHelper {
usable_entry_count_;
}
+ bool AllocateRingBuffer();
+
CommandBuffer* command_buffer_;
+ int32 ring_buffer_id_;
+ int32 ring_buffer_size_;
Buffer ring_buffer_;
- CommandBufferEntry *entries_;
+ CommandBufferEntry* entries_;
int32 total_entry_count_; // the total number of entries
int32 usable_entry_count_; // the usable number (ie, minus space for jump)
int32 token_;
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
index 3b314c4..216bb60 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -66,15 +66,9 @@ class CommandBufferHelperTest : public testing::Test {
.WillRepeatedly(Return(error::kNoError));
command_buffer_.reset(new CommandBufferService);
- command_buffer_->Initialize(kCommandBufferSizeBytes);
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ command_buffer_->Initialize();
- parser_ = new CommandParser(ring_buffer.ptr,
- ring_buffer.size,
- 0,
- ring_buffer.size,
- 0,
- api_mock_.get());
+ parser_ = new CommandParser(api_mock_.get());
do_jump_command_.reset(new DoJumpCommand(parser_));
EXPECT_CALL(*api_mock_, DoCommand(cmd::kJump, _, _))
@@ -90,6 +84,12 @@ class CommandBufferHelperTest : public testing::Test {
helper_.reset(new CommandBufferHelper(command_buffer_.get()));
helper_->Initialize(kCommandBufferSizeBytes);
+
+ // Note: parser->SetBuffer would normally be called through
+ // helper_->Initialize but currently it needs a GpuCommandBufferStub as the
+ // CommandBuffer instead of the CommandBufferService for that to happen.
+ Buffer ring_buffer = helper_->get_ring_buffer();
+ parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size);
}
virtual void TearDown() {
diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc
index 417b26a..ebd8ff6 100644
--- a/gpu/command_buffer/client/fenced_allocator_test.cc
+++ b/gpu/command_buffer/client/fenced_allocator_test.cc
@@ -45,15 +45,9 @@ class BaseFencedAllocatorTest : public testing::Test {
Return(error::kNoError)));
command_buffer_.reset(new CommandBufferService);
- command_buffer_->Initialize(kBufferSize);
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ command_buffer_->Initialize();
- parser_ = new CommandParser(ring_buffer.ptr,
- ring_buffer.size,
- 0,
- ring_buffer.size,
- 0,
- api_mock_.get());
+ parser_ = new CommandParser(api_mock_.get());
gpu_scheduler_.reset(new GpuScheduler(
command_buffer_.get(), NULL, parser_));
@@ -64,6 +58,12 @@ class BaseFencedAllocatorTest : public testing::Test {
helper_.reset(new CommandBufferHelper(command_buffer_.get()));
helper_->Initialize(kBufferSize);
+
+ // Note: parser->SetBuffer would normally be called through
+ // helper_->Initialize but currently it needs a GpuCommandBufferStub as the
+ // CommandBuffer instead of the CommandBufferService for that to happen.
+ Buffer ring_buffer = helper_->get_ring_buffer();
+ parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size);
}
int32 GetToken() {
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 5ce2a8b..4c6013d 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -15,34 +15,30 @@
#define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
#endif
+using testing::_;
+using testing::DoAll;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Mock;
+using testing::Sequence;
+using testing::Truly;
+using testing::Return;
+
namespace gpu {
class GLES2MockCommandBufferHelper : public CommandBuffer {
public:
- static const int32 kTransferBufferId = 0x123;
+ static const int32 kTransferBufferBaseId = 0x123;
+ static const int32 kMaxTransferBuffers = 6;
GLES2MockCommandBufferHelper() { }
virtual ~GLES2MockCommandBufferHelper() { }
// CommandBuffer implementation:
- virtual bool Initialize(int32 size) {
- ring_buffer_.reset(new CommandBufferEntry[size]);
- ring_buffer_buffer_.ptr = ring_buffer_.get();
- ring_buffer_buffer_.size = size;
- state_.num_entries = size / sizeof(ring_buffer_[0]);
- state_.token = 10000; // All token checks in the tests should pass.
+ virtual bool Initialize() {
return true;
}
- virtual bool Initialize(base::SharedMemory* buffer, int32 size) {
- GPU_NOTREACHED();
- return false;
- }
-
- virtual Buffer GetRingBuffer() {
- return ring_buffer_buffer_;
- }
-
virtual State GetState() {
return state_;
}
@@ -58,28 +54,57 @@ class GLES2MockCommandBufferHelper : public CommandBuffer {
virtual State FlushSync(int32 put_offset, int32 last_known_get) {
state_.put_offset = put_offset;
state_.get_offset = put_offset;
- OnFlush(transfer_buffer_buffer_.ptr);
+ // Warning: This is a hack. We just happen to know that the default
+ // transfer buffer will be the first transfer buffer.
+ OnFlush(transfer_buffer_buffers_[0].ptr);
return state_;
}
+ virtual void SetGetBuffer(int transfer_buffer_id) {
+ ring_buffer_buffer_ = GetTransferBuffer(transfer_buffer_id);
+ ring_buffer_ = static_cast<CommandBufferEntry*>(ring_buffer_buffer_.ptr);
+ state_.num_entries = ring_buffer_buffer_.size / sizeof(ring_buffer_[0]);
+ state_.token = 10000; // All token checks in the tests should pass.
+ }
+
virtual void SetGetOffset(int32 get_offset) {
state_.get_offset = get_offset;
}
+ // Get's the Id of the next transfer buffer that will be returned
+ // by CreateTransferBuffer. This is useful for testing expected ids.
+ int32 GetNextFreeTransferBufferId() {
+ for (size_t ii = 0; ii < arraysize(transfer_buffers_); ++ii) {
+ if (!transfer_buffers_[ii].get()) {
+ return kTransferBufferBaseId + ii;
+ }
+ }
+ return -1;
+ }
+
virtual int32 CreateTransferBuffer(size_t size, int32 id_request) {
- transfer_buffer_.reset(new int8[size]);
- transfer_buffer_buffer_.ptr = transfer_buffer_.get();
- transfer_buffer_buffer_.size = size;
- return kTransferBufferId;
+ int32 id = GetNextFreeTransferBufferId();
+ if (id >= 0) {
+ int32 ndx = id - kTransferBufferBaseId;
+ transfer_buffers_[ndx].reset(new int8[size]);
+ transfer_buffer_buffers_[ndx].ptr = transfer_buffers_[ndx].get();
+ transfer_buffer_buffers_[ndx].size = size;
+ }
+ return id;
}
- virtual void DestroyTransferBuffer(int32 /* id */) {
- GPU_NOTREACHED();
+ void DestroyTransferBufferHelper(int32 id) {
+ GPU_DCHECK_GE(id, kTransferBufferBaseId);
+ GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
+ id -= kTransferBufferBaseId;
+ transfer_buffers_[id].reset();
+ transfer_buffer_buffers_[id] = Buffer();
}
virtual Buffer GetTransferBuffer(int32 id) {
- GPU_DCHECK_EQ(id, kTransferBufferId);
- return transfer_buffer_buffer_;
+ GPU_DCHECK_GE(id, kTransferBufferBaseId);
+ GPU_DCHECK_LT(id, kTransferBufferBaseId + kMaxTransferBuffers);
+ return transfer_buffer_buffers_[id - kTransferBufferBaseId];
}
virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
@@ -107,39 +132,41 @@ class GLES2MockCommandBufferHelper : public CommandBuffer {
virtual void OnFlush(void* transfer_buffer) = 0;
private:
- scoped_array<int8> transfer_buffer_;
- Buffer transfer_buffer_buffer_;
- scoped_array<CommandBufferEntry> ring_buffer_;
+ scoped_array<int8> transfer_buffers_[kMaxTransferBuffers];
+ Buffer transfer_buffer_buffers_[kMaxTransferBuffers];
+ CommandBufferEntry* ring_buffer_;
Buffer ring_buffer_buffer_;
State state_;
};
class MockGLES2CommandBuffer : public GLES2MockCommandBufferHelper {
public:
+ MockGLES2CommandBuffer() {
+ DelegateToFake();
+ }
+
virtual ~MockGLES2CommandBuffer() {
}
// This is so we can use all the gmock functions when Flush is called.
MOCK_METHOD1(OnFlush, void(void* result));
MOCK_METHOD1(DestroyTransferBuffer, void(int32 id));
+
+ void DelegateToFake() {
+ ON_CALL(*this, DestroyTransferBuffer(_))
+ .WillByDefault(Invoke(
+ this, &GLES2MockCommandBufferHelper::DestroyTransferBufferHelper));
+ }
};
// GCC requires these declarations, but MSVC requires they not be present
#ifndef _MSC_VER
-const int32 GLES2MockCommandBufferHelper::kTransferBufferId;
+const int32 GLES2MockCommandBufferHelper::kTransferBufferBaseId;
+const int32 GLES2MockCommandBufferHelper::kMaxTransferBuffers;
#endif
namespace gles2 {
-using testing::_;
-using testing::DoAll;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Mock;
-using testing::Sequence;
-using testing::Truly;
-using testing::Return;
-
ACTION_P(SetMemory, obj) {
memcpy(arg0, &obj, sizeof(obj));
}
@@ -194,8 +221,6 @@ class GLES2CommandBufferTestBase : public testing::Test {
static const int32 kCommandBufferSizeBytes =
kNumCommandEntries * sizeof(CommandBufferEntry);
static const size_t kTransferBufferSize = 256;
- static const int32 kTransferBufferId =
- GLES2MockCommandBufferHelper::kTransferBufferId;
static const uint8 kInitialValue = 0xBD;
GLES2CommandBufferTestBase()
@@ -203,7 +228,8 @@ class GLES2CommandBufferTestBase : public testing::Test {
token_(0),
offset_(0),
initial_offset_(0),
- alignment_(0) {
+ alignment_(0),
+ transfer_buffer_id_(-1) {
}
void SetupCommandBuffer(unsigned int offset, unsigned alignment) {
@@ -212,11 +238,11 @@ class GLES2CommandBufferTestBase : public testing::Test {
alignment_ = alignment;
command_buffer_.reset(new MockGLES2CommandBuffer());
- command_buffer_->Initialize(kCommandBufferSizeBytes);
+ command_buffer_->Initialize();
- EXPECT_EQ(kTransferBufferId,
- command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1));
- transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId);
+ transfer_buffer_id_ =
+ command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
+ transfer_buffer_ = command_buffer_->GetTransferBuffer(transfer_buffer_id_);
ClearTransferBuffer();
helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
@@ -232,7 +258,7 @@ class GLES2CommandBufferTestBase : public testing::Test {
}
void ClearCommands() {
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ Buffer ring_buffer = helper_->get_ring_buffer();
memset(ring_buffer.ptr, kInitialValue, ring_buffer.size);
}
@@ -253,6 +279,10 @@ class GLES2CommandBufferTestBase : public testing::Test {
return ++token_;
}
+ int32 GetNextFreeTransferBufferId() {
+ return command_buffer_->GetNextFreeTransferBufferId();
+ }
+
uint32 AllocateTransferBuffer(size_t size) {
if (offset_ + size > kTransferBufferSize) {
offset_ = initial_offset_;
@@ -280,6 +310,7 @@ class GLES2CommandBufferTestBase : public testing::Test {
uint32 offset_;
uint32 initial_offset_;
uint32 alignment_;
+ int32 transfer_buffer_id_;
};
// GCC requires these declarations, but MSVC requires they not be present
@@ -287,7 +318,6 @@ class GLES2CommandBufferTestBase : public testing::Test {
const int32 GLES2CommandBufferTestBase::kNumCommandEntries;
const int32 GLES2CommandBufferTestBase::kCommandBufferSizeBytes;
const size_t GLES2CommandBufferTestBase::kTransferBufferSize;
-const int32 GLES2CommandBufferTestBase::kTransferBufferId;
const uint8 GLES2CommandBufferTestBase::kInitialValue;
#endif
@@ -303,9 +333,12 @@ class TransferBufferTest : public GLES2CommandBufferTestBase {
GLES2Implementation::kStartingOffset,
GLES2Implementation::kAlignment);
+ transfer_buffer_id_ =
+ command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1);
+
transfer_buffer_.reset(new TransferBuffer(
helper_.get(),
- kTransferBufferId,
+ transfer_buffer_id_,
GetTransferAddressFromOffset(0, 0),
kTransferBufferSize,
kStartingOffset,
@@ -327,7 +360,7 @@ const unsigned int TransferBufferTest::kAlignment;
TEST_F(TransferBufferTest, Basic) {
EXPECT_TRUE(transfer_buffer_->HaveBuffer());
- EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId());
+ EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
}
TEST_F(TransferBufferTest, Free) {
@@ -341,7 +374,7 @@ TEST_F(TransferBufferTest, Free) {
// See it's freed.
EXPECT_FALSE(transfer_buffer_->HaveBuffer());
// See that it gets reallocated.
- EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId());
+ EXPECT_EQ(transfer_buffer_id_, transfer_buffer_->GetShmId());
EXPECT_TRUE(transfer_buffer_->HaveBuffer());
// Free buffer.
@@ -473,7 +506,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
helper_.get(),
kTransferBufferSize,
transfer_buffer_.ptr,
- kTransferBufferId,
+ transfer_buffer_id_,
shared_resources,
bind_generates_resource));
}
@@ -482,7 +515,7 @@ class GLES2ImplementationTest : public GLES2CommandBufferTestBase {
.Times(1)
.RetiresOnSaturation();
helper_->CommandBufferHelper::Finish();
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ Buffer ring_buffer = helper_->get_ring_buffer();
commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) +
command_buffer_->GetState().put_offset;
ClearCommands();
@@ -525,16 +558,16 @@ TEST_F(GLES2ImplementationTest, ShaderSource) {
Cmds expected;
expected.set_bucket_size.Init(kBucketId, kSourceSize);
expected.set_bucket_data1.Init(
- kBucketId, 0, kString1Size, kTransferBufferId,
+ kBucketId, 0, kString1Size, transfer_buffer_id_,
AllocateTransferBuffer(kPaddedString1Size));
expected.set_token1.Init(GetNextToken());
expected.set_bucket_data2.Init(
- kBucketId, kString1Size, kString2Size, kTransferBufferId,
+ kBucketId, kString1Size, kString2Size, transfer_buffer_id_,
AllocateTransferBuffer(kPaddedString2Size));
expected.set_token2.Init(GetNextToken());
expected.set_bucket_data3.Init(
kBucketId, kString1Size + kString2Size,
- kString3Size, kTransferBufferId,
+ kString3Size, transfer_buffer_id_,
AllocateTransferBuffer(kPaddedString3Size));
expected.set_token3.Init(GetNextToken());
expected.shader_source_bucket.Init(kShaderId, kBucketId);
@@ -564,9 +597,9 @@ TEST_F(GLES2ImplementationTest, GetShaderSource) {
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_shader_source.Init(kShaderId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0);
+ expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), kTransferBufferId, offset);
+ kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
char buf[sizeof(kString) + 1];
@@ -628,13 +661,13 @@ TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
AllocateTransferBuffer(kSize1));
expected.set_token1.Init(GetNextToken());
expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
AllocateTransferBuffer(kSize2));
expected.set_token2.Init(GetNextToken());
expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
@@ -704,19 +737,19 @@ TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
expected.set_index_size.Init(
GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data0.Init(
- GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, kTransferBufferId,
+ GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, transfer_buffer_id_,
AllocateTransferBuffer(kIndexSize));
expected.set_token0.Init(GetNextToken());
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
AllocateTransferBuffer(kSize1));
expected.set_token1.Init(GetNextToken());
expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
AllocateTransferBuffer(kSize2));
expected.set_token2.Init(GetNextToken());
expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
@@ -780,17 +813,17 @@ TEST_F(GLES2ImplementationTest,
expected.enable2.Init(kAttribIndex2);
expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
- kIndexOffset, kTransferBufferId, 0);
+ kIndexOffset, transfer_buffer_id_, 0);
expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset1, kSize1, transfer_buffer_id_,
AllocateTransferBuffer(kSize1));
expected.set_token1.Init(GetNextToken());
expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId,
+ GL_ARRAY_BUFFER, kEmuOffset2, kSize2, transfer_buffer_id_,
AllocateTransferBuffer(kSize2));
expected.set_token2.Init(GetNextToken());
expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
@@ -837,7 +870,7 @@ TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
kStride2, kOffset2);
expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER,
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
// One call to flush to way for GetVertexAttribPointerv
EXPECT_CALL(*command_buffer_, OnFlush(_))
@@ -894,10 +927,10 @@ TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
kStride2, kOffset2);
expected.get1.Init(kAttribIndex2,
GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
expected.get2.Init(kAttribIndex1,
GL_CURRENT_VERTEX_ATTRIB,
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
@@ -960,7 +993,7 @@ TEST_F(GLES2ImplementationTest, ReservedIds) {
GetError get;
};
Cmds expected;
- expected.get.Init(kTransferBufferId, 0);
+ expected.get.Init(transfer_buffer_id_, 0);
// One call to flush to wait for GetError
EXPECT_CALL(*command_buffer_, OnFlush(_))
@@ -998,15 +1031,15 @@ TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
Cmds expected;
expected.read1.Init(
0, 0, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId,
+ transfer_buffer_id_,
AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel),
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
expected.set_token1.Init(GetNextToken());
expected.read2.Init(
0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId,
+ transfer_buffer_id_,
AllocateTransferBuffer(kWidth * kHeight / 2 * kBytesPerPixel),
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
expected.set_token2.Init(GetNextToken());
scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
@@ -1033,9 +1066,9 @@ TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
Cmds expected;
expected.read.Init(
0, 0, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId,
+ transfer_buffer_id_,
AllocateTransferBuffer(kWidth * kHeight * kBytesPerPixel),
- kTransferBufferId, 0);
+ transfer_buffer_id_, 0);
expected.set_token.Init(GetNextToken());
scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
@@ -1058,7 +1091,7 @@ TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
uint32 offset = 0;
Cmds expected;
expected.buf.Init(
- kTarget, kOffset, kSize, kTransferBufferId, offset);
+ kTarget, kOffset, kSize, transfer_buffer_id_, offset);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapBufferSubDataCHROMIUM(
@@ -1083,7 +1116,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
uint32 offset = 0;
Cmds expected;
expected.buf.Init(
- kTarget, kOffset, kSize, kTransferBufferId, offset);
+ kTarget, kOffset, kSize, GetNextFreeTransferBufferId(), offset);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapBufferSubDataCHROMIUM(
@@ -1138,7 +1171,7 @@ TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
Cmds expected;
expected.tex.Init(
GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
- kType, kTransferBufferId, offset, GL_FALSE);
+ kType, GetNextFreeTransferBufferId(), offset, GL_FALSE);
expected.set_token.Init(GetNextToken());
void* mem = gl_->MapTexSubImage2DCHROMIUM(
@@ -1273,8 +1306,8 @@ TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
const uint32 kResultsOffset = AllocateTransferBuffer(kResultsSize);
Cmds expected;
expected.get_multiple.Init(
- kTransferBufferId, kPnamesOffset, kNumPnames,
- kTransferBufferId, kResultsOffset, kResultsSize);
+ transfer_buffer_id_, kPnamesOffset, kNumPnames,
+ transfer_buffer_id_, kResultsOffset, kResultsSize);
expected.set_token.Init(GetNextToken());
const GLint kSentinel = 0x12345678;
@@ -1383,9 +1416,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_program_info.Init(kProgramId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0);
+ expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), kTransferBufferId, offset);
+ kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
@@ -1424,9 +1457,9 @@ TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
Cmds expected;
expected.set_bucket_size1.Init(kBucketId, 0);
expected.get_program_info.Init(kProgramId, kBucketId);
- expected.get_bucket_size.Init(kBucketId, kTransferBufferId, 0);
+ expected.get_bucket_size.Init(kBucketId, transfer_buffer_id_, 0);
expected.get_bucket_data.Init(
- kBucketId, 0, sizeof(kString), kTransferBufferId, offset);
+ kBucketId, 0, sizeof(kString), transfer_buffer_id_, offset);
expected.set_token1.Init(GetNextToken());
expected.set_bucket_size2.Init(kBucketId, 0);
gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
@@ -1602,7 +1635,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) {
Cmds expected;
expected.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- kTransferBufferId, offset);
+ transfer_buffer_id_, offset);
expected.set_token.Init(GetNextToken());
gl_->TexImage2D(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
@@ -1617,7 +1650,7 @@ TEST_F(GLES2ImplementationTest, TexImage2D) {
Cmds2 expected2;
expected2.tex_image_2d.Init(
kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
- kTransferBufferId, offset2);
+ transfer_buffer_id_, offset2);
expected2.set_token.Init(GetNextToken());
const void* commands2 = GetPut();
gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
@@ -1674,11 +1707,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId, offset1, true);
+ transfer_buffer_id_, offset1, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId, offset2, true);
+ transfer_buffer_id_, offset2, true);
expected.set_token2.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
@@ -1707,11 +1740,11 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId, offset3, true);
+ transfer_buffer_id_, offset3, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
- kTransferBufferId, offset4, true);
+ transfer_buffer_id_, offset4, true);
expected.set_token2.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
@@ -1777,19 +1810,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) {
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset1, true);
+ transfer_buffer_id_, offset1, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset2, true);
+ transfer_buffer_id_, offset2, true);
expected.set_token2.Init(GetNextToken());
expected.tex_sub_image_2d3.Init(
kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset3, true);
+ transfer_buffer_id_, offset3, true);
expected.set_token3.Init(GetNextToken());
expected.tex_sub_image_2d4.Init(
kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset4, true);
+ transfer_buffer_id_, offset4, true);
expected.set_token4.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
@@ -1828,19 +1861,19 @@ TEST_F(GLES2ImplementationTest, TexImage2DSubRows) {
0, 0);
expected.tex_sub_image_2d1.Init(
kTarget, kLevel, 0, 1, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset1, true);
+ transfer_buffer_id_, offset1, true);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(
kTarget, kLevel, kWidth / 2, 1, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset2, true);
+ transfer_buffer_id_, offset2, true);
expected.set_token2.Init(GetNextToken());
expected.tex_sub_image_2d3.Init(
kTarget, kLevel, 0, 0, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset3, true);
+ transfer_buffer_id_, offset3, true);
expected.set_token3.Init(GetNextToken());
expected.tex_sub_image_2d4.Init(
kTarget, kLevel, kWidth / 2, 0, kWidth / 2, 1, kFormat, kType,
- kTransferBufferId, offset4, true);
+ transfer_buffer_id_, offset4, true);
expected.set_token4.Init(GetNextToken());
// TODO(gman): Make it possible to run this test
@@ -1908,10 +1941,10 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
kType, 0, NULL);
expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
- kTransferBufferId, offset1, false);
+ transfer_buffer_id_, offset1, false);
expected.set_token1.Init(GetNextToken());
expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
- kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, kTransferBufferId,
+ kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, transfer_buffer_id_,
offset2, false);
expected.set_token2.Init(GetNextToken());
@@ -2020,7 +2053,7 @@ TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) {
};
Cmds expected;
- expected.create_stream.Init(kTextureId, kTransferBufferId, kResultOffset);
+ expected.create_stream.Init(kTextureId, transfer_buffer_id_, kResultOffset);
EXPECT_CALL(*command_buffer_, OnFlush(_))
.WillOnce(SetMemoryAtOffset(kResultOffset, kResult))
diff --git a/gpu/command_buffer/client/mapped_memory_unittest.cc b/gpu/command_buffer/client/mapped_memory_unittest.cc
index 81b6655..c18ec9f 100644
--- a/gpu/command_buffer/client/mapped_memory_unittest.cc
+++ b/gpu/command_buffer/client/mapped_memory_unittest.cc
@@ -42,15 +42,9 @@ class MappedMemoryTestBase : public testing::Test {
Return(error::kNoError)));
command_buffer_.reset(new CommandBufferService);
- command_buffer_->Initialize(kBufferSize);
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ command_buffer_->Initialize();
- parser_ = new CommandParser(ring_buffer.ptr,
- ring_buffer.size,
- 0,
- ring_buffer.size,
- 0,
- api_mock_.get());
+ parser_ = new CommandParser(api_mock_.get());
gpu_scheduler_.reset(new GpuScheduler(
command_buffer_.get(), NULL, parser_));
@@ -61,6 +55,12 @@ class MappedMemoryTestBase : public testing::Test {
helper_.reset(new CommandBufferHelper(command_buffer_.get()));
helper_->Initialize(kBufferSize);
+
+ // Note: parser->SetBuffer would normally be called through
+ // helper_->Initialize but currently it needs a GpuCommandBufferStub as the
+ // CommandBuffer instead of the CommandBufferService for that to happen.
+ Buffer ring_buffer = helper_->get_ring_buffer();
+ parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size);
}
int32 GetToken() {
diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc
index eb5a0cb..8b8e46e 100644
--- a/gpu/command_buffer/client/ring_buffer_test.cc
+++ b/gpu/command_buffer/client/ring_buffer_test.cc
@@ -65,15 +65,9 @@ class BaseRingBufferTest : public testing::Test {
Return(error::kNoError)));
command_buffer_.reset(new CommandBufferService);
- command_buffer_->Initialize(kBufferSize);
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
+ command_buffer_->Initialize();
- parser_ = new CommandParser(ring_buffer.ptr,
- ring_buffer.size,
- 0,
- ring_buffer.size,
- 0,
- api_mock_.get());
+ parser_ = new CommandParser(api_mock_.get());
gpu_scheduler_.reset(new GpuScheduler(
command_buffer_.get(), NULL, parser_));
@@ -88,6 +82,12 @@ class BaseRingBufferTest : public testing::Test {
helper_.reset(new CommandBufferHelper(command_buffer_.get()));
helper_->Initialize(kBufferSize);
+
+ // Note: parser->SetBuffer would normally be called through
+ // helper_->Initialize but currently it needs a GpuCommandBufferStub as the
+ // CommandBuffer instead of the CommandBufferService for that to happen.
+ Buffer ring_buffer = helper_->get_ring_buffer();
+ parser_->SetBuffer(ring_buffer.ptr, ring_buffer.size, 0, ring_buffer.size);
}
int32 GetToken() {
diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h
index 76124c8..e44df7f 100644
--- a/gpu/command_buffer/common/command_buffer.h
+++ b/gpu/command_buffer/common/command_buffer.h
@@ -67,13 +67,7 @@ class CommandBuffer {
}
// Initialize the command buffer with the given size.
- virtual bool Initialize(int32 size) = 0;
-
- // Initialize the command buffer using the given preallocated buffer.
- virtual bool Initialize(base::SharedMemory* buffer, int32 size) = 0;
-
- // Gets the ring buffer for the command buffer.
- virtual Buffer GetRingBuffer() = 0;
+ virtual bool Initialize() = 0;
// Returns the current status.
virtual State GetState() = 0;
@@ -92,6 +86,10 @@ class CommandBuffer {
// have been executed.
virtual State FlushSync(int32 put_offset, int32 last_known_get) = 0;
+ // Sets the buffer commands are read from.
+ // Also resets the get and put offsets to 0.
+ virtual void SetGetBuffer(int32 transfer_buffer_id) = 0;
+
// Sets the current get offset. This can be called from any thread.
virtual void SetGetOffset(int32 get_offset) = 0;
diff --git a/gpu/command_buffer/common/command_buffer_mock.cc b/gpu/command_buffer/common/command_buffer_mock.cc
index d92c2c3..6ed2eee 100644
--- a/gpu/command_buffer/common/command_buffer_mock.cc
+++ b/gpu/command_buffer/common/command_buffer_mock.cc
@@ -7,8 +7,6 @@
namespace gpu {
MockCommandBuffer::MockCommandBuffer() {
- ON_CALL(*this, GetRingBuffer())
- .WillByDefault(testing::Return(Buffer()));
ON_CALL(*this, GetTransferBuffer(testing::_))
.WillByDefault(testing::Return(Buffer()));
}
diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h
index 321c40d..0379340 100644
--- a/gpu/command_buffer/common/command_buffer_mock.h
+++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -21,13 +21,12 @@ class MockCommandBuffer : public CommandBuffer {
MockCommandBuffer();
virtual ~MockCommandBuffer();
- MOCK_METHOD1(Initialize, bool(int32 size));
- MOCK_METHOD2(Initialize, bool(base::SharedMemory* buffer, int32 size));
- MOCK_METHOD0(GetRingBuffer, Buffer());
+ MOCK_METHOD0(Initialize, bool());
MOCK_METHOD0(GetState, State());
MOCK_METHOD0(GetLastState, State());
MOCK_METHOD1(Flush, void(int32 put_offset));
MOCK_METHOD2(FlushSync, State(int32 put_offset, int32 last_known_get));
+ MOCK_METHOD1(SetGetBuffer, void(int32 transfer_buffer_id));
MOCK_METHOD1(SetGetOffset, void(int32 get_offset));
MOCK_METHOD2(CreateTransferBuffer, int32(size_t size, int32 id_request));
MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle));
diff --git a/gpu/command_buffer/service/cmd_buffer_engine.h b/gpu/command_buffer/service/cmd_buffer_engine.h
index 59e99ab..6aefe82 100644
--- a/gpu/command_buffer/service/cmd_buffer_engine.h
+++ b/gpu/command_buffer/service/cmd_buffer_engine.h
@@ -29,6 +29,9 @@ class CommandBufferEngine {
// Sets the token value.
virtual void set_token(int32 token) = 0;
+ // Sets the shared memory buffer used for commands.
+ virtual bool SetGetBuffer(int32 transfer_buffer_id) = 0;
+
// Sets the "get" pointer. Return false if offset is out of range.
virtual bool SetGetOffset(int32 offset) = 0;
diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc
index fba06e6..b5383af 100644
--- a/gpu/command_buffer/service/cmd_parser.cc
+++ b/gpu/command_buffer/service/cmd_parser.cc
@@ -10,23 +10,29 @@
namespace gpu {
-CommandParser::CommandParser(void *shm_address,
- size_t shm_size,
- ptrdiff_t offset,
- size_t size,
- CommandBufferOffset start_get,
- AsyncAPIInterface *handler)
- : get_(start_get),
- put_(start_get),
+CommandParser::CommandParser(AsyncAPIInterface* handler)
+ : get_(0),
+ put_(0),
+ buffer_(NULL),
+ entry_count_(0),
handler_(handler) {
+}
+
+void CommandParser::SetBuffer(
+ void* shm_address,
+ size_t shm_size,
+ ptrdiff_t offset,
+ size_t size) {
// check proper alignments.
DCHECK_EQ(0, (reinterpret_cast<intptr_t>(shm_address)) % 4);
DCHECK_EQ(0, offset % 4);
DCHECK_EQ(0u, size % 4);
// check that the command buffer fits into the memory buffer.
DCHECK_GE(shm_size, offset + size);
- char * buffer_begin = static_cast<char *>(shm_address) + offset;
- buffer_ = reinterpret_cast<CommandBufferEntry *>(buffer_begin);
+ get_ = 0;
+ put_ = 0;
+ char* buffer_begin = static_cast<char*>(shm_address) + offset;
+ buffer_ = reinterpret_cast<CommandBufferEntry*>(buffer_begin);
entry_count_ = size / 4;
}
diff --git a/gpu/command_buffer/service/cmd_parser.h b/gpu/command_buffer/service/cmd_parser.h
index fe3eb12..567b7f6 100644
--- a/gpu/command_buffer/service/cmd_parser.h
+++ b/gpu/command_buffer/service/cmd_parser.h
@@ -18,12 +18,14 @@ class AsyncAPIInterface;
// buffer, to implement some asynchronous RPC mechanism.
class CommandParser {
public:
- CommandParser(void *shm_address,
- size_t shm_size,
- ptrdiff_t offset,
- size_t size,
- CommandBufferOffset start_get,
- AsyncAPIInterface *handler);
+ explicit CommandParser(AsyncAPIInterface* handler);
+
+ // Sets the buffer to read commands from.
+ void SetBuffer(
+ void* shm_address,
+ size_t shm_size,
+ ptrdiff_t offset,
+ size_t size);
// Gets the "get" pointer. The get pointer is an index into the command
// buffer considered as an array of CommandBufferEntry.
@@ -63,9 +65,9 @@ class CommandParser {
private:
CommandBufferOffset get_;
CommandBufferOffset put_;
- CommandBufferEntry *buffer_;
+ CommandBufferEntry* buffer_;
int32 entry_count_;
- AsyncAPIInterface *handler_;
+ AsyncAPIInterface* handler_;
};
// This class defines the interface for an asynchronous API handler, that
diff --git a/gpu/command_buffer/service/cmd_parser_test.cc b/gpu/command_buffer/service/cmd_parser_test.cc
index 857ca8e..b86b0af 100644
--- a/gpu/command_buffer/service/cmd_parser_test.cc
+++ b/gpu/command_buffer/service/cmd_parser_test.cc
@@ -48,12 +48,10 @@ class CommandParserTest : public testing::Test {
size_t command_buffer_size = entry_count *
sizeof(CommandBufferEntry); // NOLINT
DCHECK_LE(command_buffer_size, shm_size);
- return new CommandParser(buffer(),
- shm_size,
- 0,
- command_buffer_size,
- 0,
- api_mock());
+ CommandParser* parser = new CommandParser(api_mock());
+
+ parser->SetBuffer(buffer(), shm_size, 0, command_buffer_size);
+ return parser;
}
unsigned int buffer_entry_count() { return 20; }
@@ -288,4 +286,34 @@ TEST_F(CommandParserTest, TestError) {
Mock::VerifyAndClearExpectations(api_mock());
}
+TEST_F(CommandParserTest, SetBuffer) {
+ scoped_ptr<CommandParser> parser(MakeParser(3));
+ CommandBufferOffset put = parser->put();
+ CommandHeader header;
+
+ // add a single command, no args
+ header.size = 2;
+ header.command = 123;
+ buffer()[put++].value_header = header;
+ buffer()[put++].value_int32 = 456;
+
+ CommandBufferEntry param_array[1];
+ param_array[0].value_int32 = 456;
+
+ parser->set_put(put);
+ AddDoCommandExpect(error::kNoError, 123, 1, param_array);
+ EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
+ // We should have advanced 2 entries
+ EXPECT_EQ(2, parser->get());
+ Mock::VerifyAndClearExpectations(api_mock());
+
+ scoped_array<CommandBufferEntry> buffer2(new CommandBufferEntry[2]);
+ parser->SetBuffer(
+ buffer2.get(), sizeof(CommandBufferEntry) * 2, 0,
+ sizeof(CommandBufferEntry) * 2);
+ // The put and get should have reset to 0.
+ EXPECT_EQ(0, parser->get());
+ EXPECT_EQ(0, parser->put());
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc
index d126883..4047d1c 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -14,7 +14,8 @@ using ::base::SharedMemory;
namespace gpu {
CommandBufferService::CommandBufferService()
- : num_entries_(0),
+ : ring_buffer_id_(-1),
+ num_entries_(0),
get_offset_(0),
put_offset_(0),
token_(0),
@@ -25,71 +26,16 @@ CommandBufferService::CommandBufferService()
}
CommandBufferService::~CommandBufferService() {
- delete ring_buffer_.shared_memory;
-
for (size_t i = 0; i < registered_objects_.size(); ++i) {
if (registered_objects_[i].shared_memory)
delete registered_objects_[i].shared_memory;
}
}
-bool CommandBufferService::Initialize(int32 size) {
- // Fail if already initialized.
- if (ring_buffer_.shared_memory) {
- LOG(ERROR) << "Failed because already initialized.";
- return false;
- }
-
- if (size <= 0 || size > kMaxCommandBufferSize) {
- LOG(ERROR) << "Failed because command buffer size was invalid.";
- return false;
- }
-
- num_entries_ = size / sizeof(CommandBufferEntry);
-
- SharedMemory shared_memory;
- if (!shared_memory.CreateAnonymous(size)) {
- LOG(ERROR) << "Failed to create shared memory for command buffer.";
- return true;
- }
-
- return Initialize(&shared_memory, size);
-}
-
-bool CommandBufferService::Initialize(base::SharedMemory* buffer, int32 size) {
- // Fail if already initialized.
- if (ring_buffer_.shared_memory) {
- LOG(ERROR) << "Failed because already initialized.";
- return false;
- }
-
- base::SharedMemoryHandle shared_memory_handle;
- if (!buffer->ShareToProcess(base::GetCurrentProcessHandle(),
- &shared_memory_handle)) {
- LOG(ERROR) << "Failed to duplicate command buffer shared memory handle.";
- return false;
- }
-
- ring_buffer_.shared_memory = new base::SharedMemory(shared_memory_handle,
- false);
- if (!ring_buffer_.shared_memory->Map(size)) {
- LOG(ERROR) << "Failed because ring buffer could not be created or mapped ";
- delete ring_buffer_.shared_memory;
- ring_buffer_.shared_memory = NULL;
- return false;
- }
-
- ring_buffer_.ptr = ring_buffer_.shared_memory->memory();
- ring_buffer_.size = size;
- num_entries_ = size / sizeof(CommandBufferEntry);
-
+bool CommandBufferService::Initialize() {
return true;
}
-Buffer CommandBufferService::GetRingBuffer() {
- return ring_buffer_;
-}
-
CommandBufferService::State CommandBufferService::GetState() {
State state;
state.num_entries = num_entries_;
@@ -134,6 +80,20 @@ void CommandBufferService::Flush(int32 put_offset) {
put_offset_change_callback_.Run();
}
+void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) {
+ DCHECK_EQ(-1, ring_buffer_id_);
+ DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty.
+ ring_buffer_ = GetTransferBuffer(transfer_buffer_id);
+ DCHECK(ring_buffer_.ptr);
+ ring_buffer_id_ = transfer_buffer_id;
+ num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry);
+ put_offset_ = 0;
+ SetGetOffset(0);
+ if (!get_buffer_change_callback_.is_null()) {
+ get_buffer_change_callback_.Run(ring_buffer_id_);
+ }
+}
+
void CommandBufferService::SetGetOffset(int32 get_offset) {
DCHECK(get_offset >= 0 && get_offset < num_entries_);
get_offset_ = get_offset;
@@ -223,6 +183,14 @@ void CommandBufferService::DestroyTransferBuffer(int32 handle) {
registered_objects_[handle] = Buffer();
unused_registered_object_elements_.insert(handle);
+ if (handle == ring_buffer_id_) {
+ ring_buffer_id_ = -1;
+ ring_buffer_ = Buffer();
+ num_entries_ = 0;
+ get_offset_ = 0;
+ put_offset_ = 0;
+ }
+
// Remove all null objects from the end of the vector. This allows the vector
// to shrink when, for example, all objects are unregistered. Note that this
// loop never removes element zero, which is always NULL.
@@ -266,6 +234,11 @@ void CommandBufferService::SetPutOffsetChangeCallback(
put_offset_change_callback_ = callback;
}
+void CommandBufferService::SetGetBufferChangeCallback(
+ const GetBufferChangedCallback& callback) {
+ get_buffer_change_callback_ = callback;
+}
+
void CommandBufferService::SetParseErrorCallback(
const base::Closure& callback) {
parse_error_callback_ = callback;
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h
index b48bd90..d7ea6fc 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -21,17 +21,17 @@ namespace gpu {
// API to manage the put and get pointers.
class CommandBufferService : public CommandBuffer {
public:
+ typedef base::Callback<bool(int32)> GetBufferChangedCallback;
CommandBufferService();
virtual ~CommandBufferService();
// CommandBuffer implementation:
- virtual bool Initialize(int32 size) OVERRIDE;
- virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE;
- virtual Buffer GetRingBuffer() OVERRIDE;
+ virtual bool Initialize() OVERRIDE;
virtual State GetState() OVERRIDE;
virtual State GetLastState() OVERRIDE;
virtual void Flush(int32 put_offset) OVERRIDE;
virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE;
+ virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE;
virtual void SetGetOffset(int32 get_offset) OVERRIDE;
virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE;
virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
@@ -52,14 +52,19 @@ class CommandBufferService : public CommandBuffer {
// attempting to write more to the command buffer. Takes ownership of
// callback.
virtual void SetPutOffsetChangeCallback(const base::Closure& callback);
+ // Sets a callback that is called whenever the get buffer is changed.
+ virtual void SetGetBufferChangeCallback(
+ const GetBufferChangedCallback& callback);
virtual void SetParseErrorCallback(const base::Closure& callback);
private:
+ int32 ring_buffer_id_;
Buffer ring_buffer_;
int32 num_entries_;
int32 get_offset_;
int32 put_offset_;
base::Closure put_offset_change_callback_;
+ GetBufferChangedCallback get_buffer_change_callback_;
base::Closure parse_error_callback_;
std::vector<Buffer> registered_objects_;
std::set<int32> unused_registered_object_elements_;
diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc
index a240948..571ffa0 100644
--- a/gpu/command_buffer/service/common_decoder_unittest.cc
+++ b/gpu/command_buffer/service/common_decoder_unittest.cc
@@ -116,6 +116,12 @@ class MockCommandBufferEngine : public CommandBufferEngine {
}
// Overridden from CommandBufferEngine.
+ virtual bool SetGetBuffer(int32 transfer_buffer_id) {
+ NOTREACHED();
+ return false;
+ }
+
+ // Overridden from CommandBufferEngine.
virtual bool SetGetOffset(int32 offset) {
if (static_cast<size_t>(offset) < kBufferSize) {
get_offset_ = offset;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 92abfc0..a57df77 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -431,6 +431,11 @@ class GLES2DecoderTestBase : public testing::Test {
DCHECK(false);
}
+ virtual bool SetGetBuffer(int32 /* transfer_buffer_id */) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+
// Overridden from CommandBufferEngine.
virtual bool SetGetOffset(int32 offset) OVERRIDE {
DCHECK(false);
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc
index f37c1a0..610f401 100644
--- a/gpu/command_buffer/service/gpu_scheduler.cc
+++ b/gpu/command_buffer/service/gpu_scheduler.cc
@@ -29,21 +29,6 @@ GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
decoder_(decoder),
parser_(parser),
unscheduled_count_(0) {
- // Map the ring buffer and create the parser.
- if (!parser) {
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
- if (ring_buffer.ptr) {
- parser_.reset(new CommandParser(ring_buffer.ptr,
- ring_buffer.size,
- 0,
- ring_buffer.size,
- 0,
- decoder_));
- } else {
- parser_.reset(new CommandParser(NULL, 0, 0, 0, 0,
- decoder_));
- }
- }
}
GpuScheduler::~GpuScheduler() {
@@ -150,6 +135,26 @@ void GpuScheduler::set_token(int32 token) {
command_buffer_->SetToken(token);
}
+bool GpuScheduler::SetGetBuffer(int32 transfer_buffer_id) {
+ Buffer ring_buffer = command_buffer_->GetTransferBuffer(transfer_buffer_id);
+ if (!ring_buffer.ptr) {
+ return false;
+ }
+
+ if (!parser_.get()) {
+ parser_.reset(new CommandParser(decoder_));
+ }
+
+ parser_->SetBuffer(
+ ring_buffer.ptr,
+ ring_buffer.size,
+ 0,
+ ring_buffer.size);
+
+ SetGetOffset(0);
+ return true;
+}
+
bool GpuScheduler::SetGetOffset(int32 offset) {
if (parser_->set_get(offset)) {
command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h
index 5256e49..9b7d9cd 100644
--- a/gpu/command_buffer/service/gpu_scheduler.h
+++ b/gpu/command_buffer/service/gpu_scheduler.h
@@ -51,6 +51,7 @@ class GpuScheduler
// Implementation of CommandBufferEngine.
virtual Buffer GetSharedMemoryBuffer(int32 shm_id) OVERRIDE;
virtual void set_token(int32 token) OVERRIDE;
+ virtual bool SetGetBuffer(int32 transfer_buffer_id) OVERRIDE;
virtual bool SetGetOffset(int32 offset) OVERRIDE;
virtual int32 GetGetOffset() OVERRIDE;
diff --git a/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/gpu/command_buffer/service/gpu_scheduler_unittest.cc
index 2d230ec..cf881e6 100644
--- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc
@@ -30,6 +30,8 @@ const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry);
class GpuSchedulerTest : public testing::Test {
protected:
+ static const int32 kTransferBufferId = 123;
+
virtual void SetUp() {
shared_memory_.reset(new ::base::SharedMemory);
shared_memory_->CreateAndMapAnonymous(kRingBufferSize);
@@ -39,28 +41,20 @@ class GpuSchedulerTest : public testing::Test {
memset(buffer_, 0, kRingBufferSize);
command_buffer_.reset(new MockCommandBuffer);
- ON_CALL(*command_buffer_.get(), GetRingBuffer())
- .WillByDefault(Return(shared_memory_buffer_));
CommandBuffer::State default_state;
default_state.num_entries = kRingBufferEntries;
ON_CALL(*command_buffer_.get(), GetState())
.WillByDefault(Return(default_state));
- async_api_.reset(new StrictMock<AsyncAPIMock>);
-
decoder_.reset(new gles2::MockGLES2Decoder());
-
- parser_ = new CommandParser(buffer_,
- kRingBufferEntries,
- 0,
- kRingBufferEntries,
- 0,
- async_api_.get());
-
scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
decoder_.get(),
- parser_));
+ NULL));
+ EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
+ .WillOnce(Return(shared_memory_buffer_));
+ EXPECT_CALL(*command_buffer_, SetGetOffset(0));
+ EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
}
virtual void TearDown() {
@@ -82,8 +76,6 @@ class GpuSchedulerTest : public testing::Test {
Buffer shared_memory_buffer_;
int32* buffer_;
scoped_ptr<gles2::MockGLES2Decoder> decoder_;
- CommandParser* parser_;
- scoped_ptr<AsyncAPIMock> async_api_;
scoped_ptr<GpuScheduler> scheduler_;
};
@@ -100,6 +92,24 @@ TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) {
scheduler_->PutChanged();
}
+TEST_F(GpuSchedulerTest, GetSetBuffer) {
+ CommandBuffer::State state;
+
+ // Set the get offset to something not 0.
+ EXPECT_CALL(*command_buffer_, SetGetOffset(2));
+ scheduler_->SetGetOffset(2);
+ EXPECT_EQ(2, scheduler_->GetGetOffset());
+
+ // Set the buffer.
+ EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
+ .WillOnce(Return(shared_memory_buffer_));
+ EXPECT_CALL(*command_buffer_, SetGetOffset(0));
+ EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
+
+ // Check the get offset was reset.
+ EXPECT_EQ(0, scheduler_->GetGetOffset());
+}
+
TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
header[0].command = 7;
@@ -113,7 +123,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
.WillRepeatedly(Return(state));
EXPECT_CALL(*command_buffer_, SetGetOffset(2));
- EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
+ EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
.WillOnce(Return(error::kNoError));
EXPECT_CALL(*command_buffer_, SetParseError(_))
@@ -136,11 +146,11 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
EXPECT_CALL(*command_buffer_, GetState())
.WillRepeatedly(Return(state));
- EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
+ EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
.WillOnce(Return(error::kNoError));
EXPECT_CALL(*command_buffer_, SetGetOffset(2));
- EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2]))
+ EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2]))
.WillOnce(Return(error::kNoError));
EXPECT_CALL(*command_buffer_, SetGetOffset(3));
@@ -158,11 +168,12 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
EXPECT_CALL(*command_buffer_, GetState())
.WillRepeatedly(Return(state));
- EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0]))
+ EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0]))
.WillOnce(Return(
error::kUnknownCommand));
EXPECT_CALL(*command_buffer_, SetGetOffset(1));
+ EXPECT_CALL(*command_buffer_, SetContextLostReason(_));
EXPECT_CALL(*decoder_, GetContextLostReason())
.WillOnce(Return(error::kUnknown));
EXPECT_CALL(*command_buffer_,
diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc
index 526f9da..48ed58c 100644
--- a/gpu/demos/framework/window.cc
+++ b/gpu/demos/framework/window.cc
@@ -54,7 +54,7 @@ void Window::OnPaint() {
bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) {
command_buffer_.reset(new CommandBufferService);
- if (!command_buffer_->Initialize(kCommandBufferSize)) {
+ if (!command_buffer_->Initialize()) {
return false;
}
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 18c9727..928d5fd 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -32,7 +32,7 @@ Display::~Display() {
bool Display::Initialize() {
scoped_ptr<gpu::CommandBufferService> command_buffer(
new gpu::CommandBufferService);
- if (!command_buffer->Initialize(kCommandBufferSize))
+ if (!command_buffer->Initialize())
return false;
int32 transfer_buffer_id =