diff options
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r-- | gpu/command_buffer/service/cmd_parser.cc | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/cmd_parser_test.cc | 24 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.cc | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/common_decoder.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/common_decoder_unittest.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 63 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 59 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.cc | 170 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.h | 35 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler_unittest.cc | 62 | ||||
-rw-r--r-- | gpu/command_buffer/service/mocks.cc | 19 | ||||
-rw-r--r-- | gpu/command_buffer/service/mocks.h | 14 |
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 { |