| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 03a2a4fdad2bf1a201aca6c4808f7735a2b640cb..ff84b0281d9e3b99c8628a543a9e56450e0ac9d0 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -652,6 +652,11 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
| const FenceSyncReleaseCallback& callback) override;
|
| void SetWaitFenceSyncCallback(const WaitFenceSyncCallback& callback) override;
|
|
|
| + void SetDescheduleUntilFinishedCallback(
|
| + const NoParamCallback& callback) override;
|
| + void SetRescheduleAfterFinishedCallback(
|
| + const NoParamCallback& callback) override;
|
| +
|
| void SetIgnoreCachedStateForTest(bool ignore) override;
|
| void SetForceShaderNameHashingForTest(bool force) override;
|
| uint32_t GetAndClearBackbufferClearBitsForTest() override;
|
| @@ -1962,6 +1967,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
| void ProcessPendingReadPixels(bool did_finish);
|
| void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
|
|
|
| + // Checks to see if the inserted fence has completed.
|
| + void ProcessDescheduleUntilFinished();
|
| +
|
| void DoBindFragmentInputLocationCHROMIUM(GLuint program_id,
|
| GLint location,
|
| const std::string& name);
|
| @@ -2101,6 +2109,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
|
|
| FenceSyncReleaseCallback fence_sync_release_callback_;
|
| WaitFenceSyncCallback wait_fence_sync_callback_;
|
| + NoParamCallback deschedule_until_finished_callback_;
|
| + NoParamCallback reschedule_after_finished_callback_;
|
|
|
| ShaderCacheCallback shader_cache_callback_;
|
|
|
| @@ -2196,6 +2206,11 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
|
|
| std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
|
|
|
| + // After this fence is inserted, both the GpuChannelMessageQueue and
|
| + // CommandExecutor are descheduled. Once the fence has completed, both get
|
| + // rescheduled.
|
| + std::unique_ptr<gl::GLFence> deschedule_until_finished_fence_;
|
| +
|
| // Used to validate multisample renderbuffers if needed
|
| GLuint validation_texture_;
|
| GLuint validation_fbo_multisample_;
|
| @@ -4177,6 +4192,16 @@ void GLES2DecoderImpl::SetWaitFenceSyncCallback(
|
| wait_fence_sync_callback_ = callback;
|
| }
|
|
|
| +void GLES2DecoderImpl::SetDescheduleUntilFinishedCallback(
|
| + const NoParamCallback& callback) {
|
| + deschedule_until_finished_callback_ = callback;
|
| +}
|
| +
|
| +void GLES2DecoderImpl::SetRescheduleAfterFinishedCallback(
|
| + const NoParamCallback& callback) {
|
| + reschedule_after_finished_callback_ = callback;
|
| +}
|
| +
|
| bool GLES2DecoderImpl::GetServiceTextureId(uint32_t client_texture_id,
|
| uint32_t* service_texture_id) {
|
| TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
|
| @@ -13653,6 +13678,28 @@ bool GLES2DecoderImpl::CheckResetStatus() {
|
| return false;
|
| }
|
|
|
| +error::Error GLES2DecoderImpl::HandleDescheduleUntilFinishedCHROMIUM(
|
| + uint32_t immediate_data_size,
|
| + const void* cmd_data) {
|
| + if (deschedule_until_finished_callback_.is_null() ||
|
| + reschedule_after_finished_callback_.is_null()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
|
| + "glDescheduleUntilFinishedCHROMIUM",
|
| + "Not fully implemented.");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + deschedule_until_finished_fence_.reset(gl::GLFence::Create());
|
| + DCHECK(deschedule_until_finished_fence_);
|
| + if (deschedule_until_finished_fence_->HasCompleted()) {
|
| + deschedule_until_finished_fence_.reset();
|
| + return error::kNoError;
|
| + }
|
| +
|
| + deschedule_until_finished_callback_.Run();
|
| + return error::kDeferLaterCommands;
|
| +}
|
| +
|
| error::Error GLES2DecoderImpl::HandleInsertFenceSyncCHROMIUM(
|
| uint32_t immediate_data_size,
|
| const void* cmd_data) {
|
| @@ -13779,14 +13826,27 @@ void GLES2DecoderImpl::ProcessPendingReadPixels(bool did_finish) {
|
| }
|
| }
|
|
|
| +void GLES2DecoderImpl::ProcessDescheduleUntilFinished() {
|
| + if (!deschedule_until_finished_fence_)
|
| + return;
|
| +
|
| + if (!deschedule_until_finished_fence_->HasCompleted())
|
| + return;
|
| +
|
| + deschedule_until_finished_fence_.reset();
|
| + reschedule_after_finished_callback_.Run();
|
| +}
|
| +
|
| bool GLES2DecoderImpl::HasMoreIdleWork() const {
|
| - return !pending_readpixel_fences_.empty() ||
|
| + return deschedule_until_finished_fence_ ||
|
| + !pending_readpixel_fences_.empty() ||
|
| gpu_tracer_->HasTracesToProcess();
|
| }
|
|
|
| void GLES2DecoderImpl::PerformIdleWork() {
|
| gpu_tracer_->ProcessTraces();
|
| ProcessPendingReadPixels(false);
|
| + ProcessDescheduleUntilFinished();
|
| }
|
|
|
| error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32_t immediate_data_size,
|
|
|