summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r--gpu/command_buffer/service/cmd_parser.cc2
-rw-r--r--gpu/command_buffer/service/cmd_parser_test.cc24
-rw-r--r--gpu/command_buffer/service/command_buffer_service.cc10
-rw-r--r--gpu/command_buffer/service/command_buffer_service.h5
-rw-r--r--gpu/command_buffer/service/common_decoder.cc6
-rw-r--r--gpu/command_buffer/service/common_decoder_unittest.cc6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc63
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h5
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc59
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h3
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.cc170
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h35
-rw-r--r--gpu/command_buffer/service/gpu_scheduler_unittest.cc62
-rw-r--r--gpu/command_buffer/service/mocks.cc19
-rw-r--r--gpu/command_buffer/service/mocks.h14
16 files changed, 94 insertions, 392 deletions
diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc
index 9ed3fca..fba06e6 100644
--- a/gpu/command_buffer/service/cmd_parser.cc
+++ b/gpu/command_buffer/service/cmd_parser.cc
@@ -64,7 +64,7 @@ error::Error CommandParser::ProcessCommand() {
}
// If get was not set somewhere else advance it.
- if (result != error::kWaiting && get == get_)
+ if (get == get_)
get_ = (get + header.size) % entry_count_;
return result;
}
diff --git a/gpu/command_buffer/service/cmd_parser_test.cc b/gpu/command_buffer/service/cmd_parser_test.cc
index 315a475..857ca8e 100644
--- a/gpu/command_buffer/service/cmd_parser_test.cc
+++ b/gpu/command_buffer/service/cmd_parser_test.cc
@@ -288,28 +288,4 @@ TEST_F(CommandParserTest, TestError) {
Mock::VerifyAndClearExpectations(api_mock());
}
-TEST_F(CommandParserTest, TestWaiting) {
- const unsigned int kNumEntries = 5;
- scoped_ptr<CommandParser> parser(MakeParser(kNumEntries));
- CommandBufferOffset put = parser->put();
- CommandHeader header;
-
- // Generate a command with size 1.
- header.size = 1;
- header.command = 3;
- buffer()[put++].value_header = header;
-
- parser->set_put(put);
- // A command that returns kWaiting should not advance the get pointer.
- AddDoCommandExpect(error::kWaiting, 3, 0, NULL);
- EXPECT_EQ(error::kWaiting, parser->ProcessAllCommands());
- EXPECT_EQ(0, parser->get());
- Mock::VerifyAndClearExpectations(api_mock());
- // Not waiting should advance the get pointer.
- AddDoCommandExpect(error::kNoError, 3, 0, NULL);
- EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
- EXPECT_EQ(put, parser->get());
- Mock::VerifyAndClearExpectations(api_mock());
-}
-
} // namespace gpu
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc
index 064341d..26ccbee 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -104,6 +104,10 @@ CommandBufferService::State CommandBufferService::GetState() {
return state;
}
+CommandBufferService::State CommandBufferService::GetLastState() {
+ return GetState();
+}
+
CommandBufferService::State CommandBufferService::FlushSync(
int32 put_offset, int32 last_known_get) {
if (put_offset < 0 || put_offset > num_entries_) {
@@ -114,7 +118,7 @@ CommandBufferService::State CommandBufferService::FlushSync(
put_offset_ = put_offset;
if (put_offset_change_callback_.get()) {
- put_offset_change_callback_->Run(last_known_get == get_offset_);
+ put_offset_change_callback_->Run();
}
return GetState();
@@ -129,7 +133,7 @@ void CommandBufferService::Flush(int32 put_offset) {
put_offset_ = put_offset;
if (put_offset_change_callback_.get()) {
- put_offset_change_callback_->Run(false);
+ put_offset_change_callback_->Run();
}
}
@@ -261,7 +265,7 @@ void CommandBufferService::SetContextLostReason(
}
void CommandBufferService::SetPutOffsetChangeCallback(
- Callback1<bool>::Type* callback) {
+ 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 9c52531..c388e9f 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -29,6 +29,7 @@ class CommandBufferService : public CommandBuffer {
virtual bool Initialize(base::SharedMemory* buffer, int32 size);
virtual Buffer GetRingBuffer();
virtual State GetState();
+ virtual State GetLastState();
virtual void Flush(int32 put_offset);
virtual State FlushSync(int32 put_offset, int32 last_known_get);
virtual void SetGetOffset(int32 get_offset);
@@ -50,7 +51,7 @@ class CommandBufferService : public CommandBuffer {
// writer a means of waiting for the reader to make some progress before
// attempting to write more to the command buffer. Takes ownership of
// callback.
- virtual void SetPutOffsetChangeCallback(Callback1<bool>::Type* callback);
+ virtual void SetPutOffsetChangeCallback(Callback0::Type* callback);
virtual void SetParseErrorCallback(Callback0::Type* callback);
private:
@@ -58,7 +59,7 @@ class CommandBufferService : public CommandBuffer {
int32 num_entries_;
int32 get_offset_;
int32 put_offset_;
- scoped_ptr<Callback1<bool>::Type> put_offset_change_callback_;
+ scoped_ptr<Callback0::Type> put_offset_change_callback_;
scoped_ptr<Callback0::Type> parse_error_callback_;
std::vector<Buffer> registered_objects_;
std::set<int32> unused_registered_object_elements_;
diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc
index 35eaf66..7b28603 100644
--- a/gpu/command_buffer/service/common_decoder.cc
+++ b/gpu/command_buffer/service/common_decoder.cc
@@ -330,10 +330,4 @@ error::Error CommonDecoder::HandleGetBucketData(
return error::kNoError;
}
-error::Error CommonDecoder::HandleYieldScheduler(
- uint32 immediate_data_size,
- const cmd::YieldScheduler& args) {
- return error::kYield;
-}
-
} // namespace gpu
diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc
index 9b53a56..8f88398 100644
--- a/gpu/command_buffer/service/common_decoder_unittest.cc
+++ b/gpu/command_buffer/service/common_decoder_unittest.cc
@@ -556,11 +556,5 @@ TEST_F(CommonDecoderTest, GetBucketData) {
EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
}
-TEST_F(CommonDecoderTest, YieldScheduler) {
- cmd::YieldScheduler cmd;
- cmd.Init();
- EXPECT_EQ(error::kYield, ExecuteCmd(cmd));
-}
-
} // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e989af6..d5bd745 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -478,7 +478,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback);
virtual void SetSwapBuffersCallback(Callback0::Type* callback);
- virtual void SetLatchCallback(const base::Callback<void(bool)>& callback);;
virtual bool GetServiceTextureId(uint32 client_texture_id,
uint32* service_texture_id);
@@ -1271,7 +1270,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
scoped_ptr<Callback1<gfx::Size>::Type> resize_callback_;
scoped_ptr<Callback0::Type> swap_buffers_callback_;
- base::Callback<void(bool)> latch_callback_;
// The format of the back buffer_
GLenum back_buffer_color_format_;
@@ -2356,11 +2354,6 @@ void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) {
swap_buffers_callback_.reset(callback);
}
-void GLES2DecoderImpl::SetLatchCallback(
- const base::Callback<void(bool)>& callback) {
- latch_callback_ = callback;
-}
-
bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
uint32* service_texture_id) {
TextureManager::TextureInfo* texture =
@@ -6527,62 +6520,6 @@ error::Error GLES2DecoderImpl::HandleSwapBuffers(
return error::kNoError;
}
-error::Error GLES2DecoderImpl::HandleSetLatchCHROMIUM(
- uint32 immediate_data_size, const gles2::SetLatchCHROMIUM& c) {
- TRACE_EVENT1("gpu", "SetLatch", "latch_id", c.latch_id);
- // Ensure the side effects of previous commands are visible to other contexts.
- // There is no need to do this for ANGLE because it uses a
- // single D3D device for all contexts.
- if (!IsAngle())
- glFlush();
-
- int32 shm_id = gpu::kLatchSharedMemoryId;
- uint32 latch_id = c.latch_id;
- uint32 shm_offset = 0;
- base::subtle::Atomic32* latch;
- if (!SafeMultiplyUint32(latch_id, sizeof(*latch), &shm_offset)) {
- return error::kOutOfBounds;
- }
- latch = GetSharedMemoryAs<base::subtle::Atomic32*>(
- shm_id, shm_offset, sizeof(*latch));
- if (!latch) {
- return error::kOutOfBounds;
- }
- base::subtle::Atomic32 old =
- base::subtle::NoBarrier_CompareAndSwap(latch, 0, 1);
- DCHECK(old == 0);
- if (!latch_callback_.is_null())
- latch_callback_.Run(true);
- return error::kNoError;
-}
-
-error::Error GLES2DecoderImpl::HandleWaitLatchCHROMIUM(
- uint32 immediate_data_size, const gles2::WaitLatchCHROMIUM& c) {
- TRACE_EVENT1("gpu", "WaitLatch", "latch_id", c.latch_id);
- int32 shm_id = gpu::kLatchSharedMemoryId;
- uint32 latch_id = c.latch_id;
- uint32 shm_offset = 0;
- base::subtle::Atomic32* latch;
- if (!SafeMultiplyUint32(latch_id, sizeof(*latch), &shm_offset)) {
- return error::kOutOfBounds;
- }
- latch = GetSharedMemoryAs<base::subtle::Atomic32*>(
- shm_id, shm_offset, sizeof(*latch));
- if (!latch) {
- return error::kOutOfBounds;
- }
-
- base::subtle::Atomic32 old =
- base::subtle::NoBarrier_CompareAndSwap(latch, 1, 0);
- if (old == 0) {
- if (!latch_callback_.is_null())
- latch_callback_.Run(false);
- return error::kWaiting;
- } else {
- return error::kNoError;
- }
-}
-
error::Error GLES2DecoderImpl::HandleCommandBufferEnableCHROMIUM(
uint32 immediate_data_size, const gles2::CommandBufferEnableCHROMIUM& c) {
Bucket* bucket = GetBucket(c.bucket_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index abd2b85..23c5e3a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -110,11 +110,6 @@ class GLES2Decoder : public CommonDecoder {
// Sets a callback which is called when a SwapBuffers command is processed.
virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0;
- // Sets a callback which is called after a Set/WaitLatch command is processed.
- // The bool parameter will be true for SetLatch, and false for a WaitLatch
- // that is blocked. An unblocked WaitLatch will not trigger a callback.
- virtual void SetLatchCallback(const base::Callback<void(bool)>& callback) = 0;
-
// Get the service texture ID corresponding to a client texture ID.
// If no such record is found then return false.
virtual bool GetServiceTextureId(uint32 client_texture_id,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index eadfbcd..b5997f5 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -2893,65 +2893,6 @@ TEST_F(GLES2DecoderWithShaderTest, VertexAttribPointer) {
}
}
-TEST_F(GLES2DecoderTest, SetLatch) {
- bool isAngle = false;
-#if defined(OS_WIN)
- isAngle = (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
-#endif
- if (!isAngle) {
- EXPECT_CALL(*gl_, Flush()).Times(3);
- }
- const uint32 kLatchId = 1;
- base::subtle::Atomic32* latches = static_cast<base::subtle::Atomic32*>(
- shared_memory_base_);
- const uint32 kInvalidLatchId = kSharedBufferSize / sizeof(*latches);
- const uint32 kLastValidLatchId = kInvalidLatchId - 1;
- latches[kLatchId] = 0;
- latches[kLastValidLatchId] = 0;
- SetLatchCHROMIUM cmd;
- // Check out of range latch id.
- cmd.Init(kInvalidLatchId);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(kLatchId);
- // Check valid latch.
- EXPECT_EQ(0, latches[kLatchId]);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(1, latches[kLatchId]);
- // Check last valid latch.
- EXPECT_EQ(0, latches[kLastValidLatchId]);
- cmd.Init(kLastValidLatchId);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(1, latches[kLastValidLatchId]);
-}
-
-TEST_F(GLES2DecoderTest, WaitLatch) {
- const uint32 kLatchId = 1;
- base::subtle::Atomic32* latches = static_cast<base::subtle::Atomic32*>(
- shared_memory_base_);
- const uint32 kInvalidLatchId = kSharedBufferSize / sizeof(*latches);
- const uint32 kLastValidLatchId = kInvalidLatchId - 1;
- latches[kLatchId] = 0;
- latches[kLastValidLatchId] = 0;
- WaitLatchCHROMIUM cmd;
- // Check out of range latch id.
- cmd.Init(kInvalidLatchId);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- // Check valid latch.
- cmd.Init(kLatchId);
- EXPECT_EQ(0, latches[kLatchId]);
- EXPECT_EQ(error::kWaiting, ExecuteCmd(cmd));
- latches[kLatchId] = 1;
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(0, latches[kLatchId]);
- // Check last valid latch.
- cmd.Init(kLastValidLatchId);
- EXPECT_EQ(0, latches[kLastValidLatchId]);
- EXPECT_EQ(error::kWaiting, ExecuteCmd(cmd));
- latches[kLastValidLatchId] = 1;
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(0, latches[kLastValidLatchId]);
-}
-
TEST_F(GLES2DecoderTest, SetSurfaceCHROMIUMChangesSurfaceForExistentSurface) {
const int kSurfaceId = 1;
scoped_refptr<gfx::GLSurfaceStub> surface(new gfx::GLSurfaceStub);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index c5f5594..05f80a3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -1712,7 +1712,6 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
// TODO(gman): RequestExtensionCHROMIUM
-// TODO(gman): SetLatchCHROMIUM
-
+// TODO(gman): SetSurfaceCHROMIUM
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index 54bfdf6..cab6b33 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -10,9 +10,6 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
-// TODO(gman): WaitLatchCHROMIUM
-
-// TODO(gman): SetSurfaceCHROMIUM
// TODO(gman): GetMultipleIntegervCHROMIUM
// TODO(gman): GetProgramInfoCHROMIUM
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc
index 9365118..fbdb16b 100644
--- a/gpu/command_buffer/service/gpu_scheduler.cc
+++ b/gpu/command_buffer/service/gpu_scheduler.cc
@@ -19,41 +19,37 @@ using ::base::SharedMemory;
namespace gpu {
-GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
- SurfaceManager* surface_manager,
- gles2::ContextGroup* group)
- : command_buffer_(command_buffer),
- commands_per_update_(100),
- unscheduled_count_(0),
-#if defined(OS_MACOSX) || defined(TOUCH_UI)
- swap_buffers_count_(0),
- acknowledged_swap_buffers_count_(0),
-#endif
- method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+GpuScheduler* GpuScheduler::Create(CommandBuffer* command_buffer,
+ SurfaceManager* surface_manager,
+ gles2::ContextGroup* group) {
DCHECK(command_buffer);
- decoder_.reset(gles2::GLES2Decoder::Create(surface_manager, group));
- decoder_->set_engine(this);
+
+ gles2::GLES2Decoder* decoder =
+ gles2::GLES2Decoder::Create(surface_manager, group);
+
+ GpuScheduler* scheduler = new GpuScheduler(command_buffer,
+ decoder,
+ NULL);
+
+ decoder->set_engine(scheduler);
+
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableGPUServiceLogging)) {
- decoder_->set_debug(true);
+ decoder->set_debug(true);
}
+
+ return scheduler;
}
-GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
- gles2::GLES2Decoder* decoder,
- CommandParser* parser,
- int commands_per_update)
- : command_buffer_(command_buffer),
- commands_per_update_(commands_per_update),
- unscheduled_count_(0),
-#if defined(OS_MACOSX) || defined(TOUCH_UI)
- swap_buffers_count_(0),
- acknowledged_swap_buffers_count_(0),
-#endif
- method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+GpuScheduler* GpuScheduler::CreateForTests(CommandBuffer* command_buffer,
+ gles2::GLES2Decoder* decoder,
+ CommandParser* parser) {
DCHECK(command_buffer);
- decoder_.reset(decoder);
- parser_.reset(parser);
+ GpuScheduler* scheduler = new GpuScheduler(command_buffer,
+ decoder,
+ parser);
+
+ return scheduler;
}
GpuScheduler::~GpuScheduler() {
@@ -82,11 +78,6 @@ bool GpuScheduler::InitializeCommon(
}
#endif
- // Do not limit to a certain number of commands before scheduling another
- // update when rendering onscreen.
- if (!surface->IsOffscreen())
- commands_per_update_ = INT_MAX;
-
// Map the ring buffer and create the parser.
Buffer ring_buffer = command_buffer_->GetRingBuffer();
if (ring_buffer.ptr) {
@@ -144,29 +135,16 @@ const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1;
}
#endif
-void GpuScheduler::PutChanged(bool sync) {
+void GpuScheduler::PutChanged() {
TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this);
- CommandBuffer::State state = command_buffer_->GetState();
- parser_->set_put(state.put_offset);
- if (sync)
- ProcessCommands();
- else
- ScheduleProcessCommands();
-}
+ DCHECK(IsScheduled());
-void GpuScheduler::ProcessCommands() {
- TRACE_EVENT1("gpu", "GpuScheduler:ProcessCommands", "this", this);
CommandBuffer::State state = command_buffer_->GetState();
+ parser_->set_put(state.put_offset);
if (state.error != error::kNoError)
return;
- if (unscheduled_count_ > 0) {
- TRACE_EVENT1("gpu", "EarlyOut_Unscheduled",
- "unscheduled_count_", unscheduled_count_);
- return;
- }
-
if (decoder_.get()) {
if (!decoder_->MakeCurrent()) {
LOG(ERROR) << "Context lost because MakeCurrent failed.";
@@ -184,60 +162,30 @@ void GpuScheduler::ProcessCommands() {
#if defined(OS_MACOSX) || defined(TOUCH_UI)
// Don't swamp the browser process with SwapBuffers calls it can't handle.
- if (do_rate_limiting &&
- swap_buffers_count_ - acknowledged_swap_buffers_count_ >=
- kMaxOutstandingSwapBuffersCallsPerOnscreenContext) {
- TRACE_EVENT0("gpu", "EarlyOut_OSX_Throttle");
- // Stop doing work on this command buffer. In the GPU process,
- // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK
- // message causes ProcessCommands to be scheduled again.
- return;
- }
+ DCHECK(!do_rate_limiting ||
+ swap_buffers_count_ - acknowledged_swap_buffers_count_ == 0);
#endif
- base::TimeTicks start_time = base::TimeTicks::Now();
- base::TimeDelta elapsed;
- bool is_break = false;
error::Error error = error::kNoError;
- do {
- int commands_processed = 0;
- while (commands_processed < commands_per_update_ &&
- !parser_->IsEmpty()) {
- error = parser_->ProcessCommand();
-
- // TODO(piman): various classes duplicate various pieces of state, leading
- // to needlessly complex update logic. It should be possible to simply
- // share the state across all of them.
- command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
-
- if (error == error::kWaiting || error == error::kYield) {
- is_break = true;
- break;
- } else if (error::IsError(error)) {
- command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
- command_buffer_->SetParseError(error);
- return;
- }
-
- if (unscheduled_count_ > 0) {
- is_break = true;
- break;
- }
-
- ++commands_processed;
- if (command_processed_callback_.get()) {
- command_processed_callback_->Run();
- }
+ while (!parser_->IsEmpty()) {
+ error = parser_->ProcessCommand();
+
+ // TODO(piman): various classes duplicate various pieces of state, leading
+ // to needlessly complex update logic. It should be possible to simply
+ // share the state across all of them.
+ command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
+
+ if (error::IsError(error)) {
+ command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
+ command_buffer_->SetParseError(error);
+ return;
}
- elapsed = base::TimeTicks::Now() - start_time;
- } while(!is_break &&
- !parser_->IsEmpty() &&
- elapsed.InMicroseconds() < kMinimumSchedulerQuantumMicros);
-
- if (unscheduled_count_ == 0 &&
- error != error::kWaiting &&
- !parser_->IsEmpty()) {
- ScheduleProcessCommands();
+
+ if (command_processed_callback_.get())
+ command_processed_callback_->Run();
+
+ if (unscheduled_count_ > 0)
+ return;
}
}
@@ -249,12 +197,8 @@ void GpuScheduler::SetScheduled(bool scheduled) {
--unscheduled_count_;
DCHECK_GE(unscheduled_count_, 0);
- if (unscheduled_count_ == 0) {
- if (scheduled_callback_.get())
- scheduled_callback_->Run();
-
- ScheduleProcessCommands();
- }
+ if (unscheduled_count_ == 0 && scheduled_callback_.get())
+ scheduled_callback_->Run();
} else {
++unscheduled_count_;
}
@@ -320,10 +264,18 @@ void GpuScheduler::SetTokenCallback(
set_token_callback_ = callback;
}
-void GpuScheduler::ScheduleProcessCommands() {
- MessageLoop::current()->PostTask(
- FROM_HERE,
- method_factory_.NewRunnableMethod(&GpuScheduler::ProcessCommands));
+GpuScheduler::GpuScheduler(CommandBuffer* command_buffer,
+ gles2::GLES2Decoder* decoder,
+ CommandParser* parser)
+ : command_buffer_(command_buffer),
+ decoder_(decoder),
+ parser_(parser),
+ unscheduled_count_(0),
+#if defined(OS_MACOSX) || defined(TOUCH_UI)
+ swap_buffers_count_(0),
+ acknowledged_swap_buffers_count_(0),
+#endif
+ method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
void GpuScheduler::WillResize(gfx::Size size) {
diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h
index d34e67f..4ebbab9 100644
--- a/gpu/command_buffer/service/gpu_scheduler.h
+++ b/gpu/command_buffer/service/gpu_scheduler.h
@@ -43,20 +43,15 @@ class ContextGroup;
// posts tasks to the current message loop to do additional work.
class GpuScheduler : public CommandBufferEngine {
public:
- // Scheduler quantum: makes ProcessCommands continue until the specified time
- // has passed, or the command buffer yields or runs out of commands.
- static const int kMinimumSchedulerQuantumMicros = 2000;
-
// If a group is not passed in one will be created.
- GpuScheduler(CommandBuffer* command_buffer,
- SurfaceManager* surface_manager,
- gles2::ContextGroup* group);
+ static GpuScheduler* Create(CommandBuffer* command_buffer,
+ SurfaceManager* surface_manager,
+ gles2::ContextGroup* group);
// This constructor is for unit tests.
- GpuScheduler(CommandBuffer* command_buffer,
- gles2::GLES2Decoder* decoder,
- CommandParser* parser,
- int commands_per_update);
+ static GpuScheduler* CreateForTests(CommandBuffer* command_buffer,
+ gles2::GLES2Decoder* decoder,
+ CommandParser* parser);
virtual ~GpuScheduler();
@@ -74,7 +69,7 @@ class GpuScheduler : public CommandBufferEngine {
bool SetParent(GpuScheduler* parent_scheduler, uint32 parent_texture_id);
- void PutChanged(bool sync);
+ void PutChanged();
// Sets whether commands should be processed by this scheduler. Setting to
// false unschedules. Setting to true reschedules. Whether or not the
@@ -152,13 +147,6 @@ class GpuScheduler : public CommandBufferEngine {
void SetCommandProcessedCallback(Callback0::Type* callback);
- // Sets a callback which is called after a Set/WaitLatch command is processed.
- // The bool parameter will be true for SetLatch, and false for a WaitLatch
- // that is blocked. An unblocked WaitLatch will not trigger a callback.
- void SetLatchCallback(const base::Callback<void(bool)>& callback) {
- decoder_->SetLatchCallback(callback);
- }
-
// Sets a callback which is called when set_token() is called, and passes the
// just-set token to the callback. DCHECKs that no callback has previously
// been registered for this notification.
@@ -179,8 +167,10 @@ class GpuScheduler : public CommandBufferEngine {
private:
- // Helper which causes a call to ProcessCommands to be scheduled later.
- void ScheduleProcessCommands();
+ // If a group is not passed in one will be created.
+ GpuScheduler(CommandBuffer* command_buffer,
+ gles2::GLES2Decoder* decoder,
+ CommandParser* parser);
// Called via a callback just before we are supposed to call the
// user's resize callback.
@@ -189,15 +179,12 @@ class GpuScheduler : public CommandBufferEngine {
// Called via a callback just before we are supposed to call the
// user's swap buffers callback.
void WillSwapBuffers();
- void ProcessCommands();
// The GpuScheduler holds a weak reference to the CommandBuffer. The
// CommandBuffer owns the GpuScheduler and holds a strong reference to it
// through the ProcessCommands callback.
CommandBuffer* command_buffer_;
- int commands_per_update_;
-
scoped_ptr<gles2::GLES2Decoder> decoder_;
scoped_ptr<CommandParser> parser_;
diff --git a/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/gpu/command_buffer/service/gpu_scheduler_unittest.cc
index 3d21f90..4fb54b4 100644
--- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc
+++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc
@@ -44,7 +44,7 @@ class GpuSchedulerTest : public testing::Test {
ON_CALL(*command_buffer_.get(), GetState())
.WillByDefault(Return(default_state));
- async_api_.reset(new StrictMock<SpecializedDoCommandAsyncAPIMock>);
+ async_api_.reset(new StrictMock<AsyncAPIMock>);
decoder_ = new gles2::MockGLES2Decoder();
@@ -55,10 +55,9 @@ class GpuSchedulerTest : public testing::Test {
0,
async_api_.get());
- scheduler_.reset(new GpuScheduler(command_buffer_.get(),
- decoder_,
- parser_,
- 2));
+ scheduler_.reset(gpu::GpuScheduler::CreateForTests(command_buffer_.get(),
+ decoder_,
+ parser_));
EXPECT_CALL(*decoder_, Destroy())
.Times(1)
@@ -97,7 +96,7 @@ TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) {
EXPECT_CALL(*command_buffer_, SetParseError(_))
.Times(0);
- scheduler_->PutChanged(true);
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
@@ -119,7 +118,7 @@ TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
EXPECT_CALL(*command_buffer_, SetParseError(_))
.Times(0);
- scheduler_->PutChanged(true);
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
@@ -144,7 +143,7 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
.WillOnce(Return(error::kNoError));
EXPECT_CALL(*command_buffer_, SetGetOffset(3));
- scheduler_->PutChanged(true);
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, SchedulerSetsTheGLContext) {
@@ -157,48 +156,7 @@ TEST_F(GpuSchedulerTest, SchedulerSetsTheGLContext) {
EXPECT_CALL(*command_buffer_, GetState())
.WillRepeatedly(Return(state));
- scheduler_->PutChanged(true);
-}
-
-TEST_F(GpuSchedulerTest, PostsTaskToFinishRemainingCommands) {
- unsigned int pauseCmd = SpecializedDoCommandAsyncAPIMock::kTestQuantumCommand;
- CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
- header[0].command = 7;
- header[0].size = 2;
- buffer_[1] = 123;
- header[2].command = pauseCmd;
- header[2].size = 1;
- header[3].command = 9;
- header[3].size = 1;
-
- CommandBuffer::State state;
-
- state.put_offset = 4;
- EXPECT_CALL(*command_buffer_, GetState())
- .WillRepeatedly(Return(state));
-
- EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0]))
- .WillOnce(Return(error::kNoError));
- EXPECT_CALL(*command_buffer_, SetGetOffset(2));
-
- EXPECT_CALL(*async_api_, DoCommand(pauseCmd, 0, &buffer_[2]))
- .WillOnce(Return(error::kNoError));
- EXPECT_CALL(*command_buffer_, SetGetOffset(3));
-
- scheduler_->PutChanged(true);
-
- // ProcessCommands is called a second time when the pending task is run.
-
- state.put_offset = 4;
- EXPECT_CALL(*command_buffer_, GetState())
- .WillRepeatedly(Return(state));
-
- EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3]))
- .WillOnce(Return(error::kNoError));
-
- EXPECT_CALL(*command_buffer_, SetGetOffset(4));
-
- MessageLoop::current()->RunAllPending();
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
@@ -222,7 +180,7 @@ TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
EXPECT_CALL(*command_buffer_,
SetParseError(error::kUnknownCommand));
- scheduler_->PutChanged(true);
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) {
@@ -232,7 +190,7 @@ TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) {
EXPECT_CALL(*command_buffer_, GetState())
.WillRepeatedly(Return(state));
- scheduler_->PutChanged(true);
+ scheduler_->PutChanged();
}
TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) {
diff --git a/gpu/command_buffer/service/mocks.cc b/gpu/command_buffer/service/mocks.cc
index 70898b3..46a8977 100644
--- a/gpu/command_buffer/service/mocks.cc
+++ b/gpu/command_buffer/service/mocks.cc
@@ -27,25 +27,6 @@ void AsyncAPIMock::SetToken(unsigned int command,
engine_->set_token(args->token);
}
-SpecializedDoCommandAsyncAPIMock::SpecializedDoCommandAsyncAPIMock() {}
-
-SpecializedDoCommandAsyncAPIMock::~SpecializedDoCommandAsyncAPIMock() {}
-
-error::Error SpecializedDoCommandAsyncAPIMock::DoCommand(
- unsigned int command,
- unsigned int arg_count,
- const void* cmd_data) {
- if (command == kTestQuantumCommand) {
- // Surpass the GpuScheduler scheduling quantum.
- base::TimeTicks start_time = base::TimeTicks::Now();
- while ((base::TimeTicks::Now() - start_time).InMicroseconds() <
- GpuScheduler::kMinimumSchedulerQuantumMicros) {
- base::PlatformThread::Sleep(1);
- }
- }
- return AsyncAPIMock::DoCommand(command, arg_count, cmd_data);
-}
-
namespace gles2 {
MockShaderTranslator::MockShaderTranslator() {}
diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h
index f526c01..0d341bd 100644
--- a/gpu/command_buffer/service/mocks.h
+++ b/gpu/command_buffer/service/mocks.h
@@ -69,20 +69,6 @@ class AsyncAPIMock : public AsyncAPIInterface {
CommandBufferEngine *engine_;
};
-// Allows specialized behavior per command in DoCommand.
-class SpecializedDoCommandAsyncAPIMock : public AsyncAPIMock {
- public:
- // Cause DoCommand to sleep more than the GpuScheduler time quantum.
- static const unsigned int kTestQuantumCommand = 333;
-
- SpecializedDoCommandAsyncAPIMock();
- virtual ~SpecializedDoCommandAsyncAPIMock();
-
- virtual error::Error DoCommand(unsigned int command,
- unsigned int arg_count,
- const void* cmd_data);
-};
-
namespace gles2 {
class MockShaderTranslator : public ShaderTranslatorInterface {