diff options
Diffstat (limited to 'gpu/command_buffer')
9 files changed, 47 insertions, 27 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 3426e3f..af6d353 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -872,7 +872,10 @@ _FUNCTION_INFO = { 'error_value': 'GL_FRAMEBUFFER_UNSUPPORTED', 'result': ['GLenum'], }, - 'Clear': {'decoder_func': 'DoClear'}, + 'Clear': { + 'type': 'Manual', + 'cmd_args': 'GLbitfield mask' + }, 'ClearColor': {'decoder_func': 'DoClearColor'}, 'ClearDepthf': { 'decoder_func': 'DoClearDepthf', diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 953f87f..ca3a9e7 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -971,6 +971,12 @@ GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUM( return result; } +void GLES2Implementation::Clear(GLbitfield mask) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << this << "] glClear(" << mask << ")"); + helper_->Clear(mask); +} + void GLES2Implementation::DrawElements( GLenum mode, GLsizei count, GLenum type, const void* indices) { GPU_CLIENT_SINGLE_THREAD_CHECK(); diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index ee673ce..5432345 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -120,11 +120,7 @@ GLenum CheckFramebufferStatus(GLenum target) { return *result; } -void Clear(GLbitfield mask) { - GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG("[" << this << "] glClear(" << mask << ")"); - helper_->Clear(mask); -} +void Clear(GLbitfield mask); void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GPU_CLIENT_SINGLE_THREAD_CHECK(); diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h index 38a8c32..a2eeb74 100644 --- a/gpu/command_buffer/common/constants.h +++ b/gpu/command_buffer/common/constants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,12 +21,13 @@ namespace error { kUnknownCommand, kInvalidArguments, kLostContext, - kGenericError + kGenericError, + kDeferCommandUntilLater }; // Return true if the given error code is an actual error. inline bool IsError(Error error) { - return error != kNoError; + return error != kNoError && error != kDeferCommandUntilLater; } // Provides finer grained information about why the context was lost. diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc index a58d5a5..0ca1e61 100644 --- a/gpu/command_buffer/service/cmd_parser.cc +++ b/gpu/command_buffer/service/cmd_parser.cc @@ -79,7 +79,7 @@ error::Error CommandParser::ProcessCommand() { } // If get was not set somewhere else advance it. - if (get == get_) + if (get == get_ && result != error::kDeferCommandUntilLater) get_ = (get + header.size) % entry_count_; if (trace_gl_commands_) diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index bc7b9b8..0f2ef5c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1003,7 +1003,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLenum DoCheckFramebufferStatus(GLenum target); // Wrapper for glClear - void DoClear(GLbitfield mask); + error::Error DoClear(GLbitfield mask); // Wrappers for clear and mask settings functions. void DoClearColor( @@ -1356,6 +1356,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, void RenderWarning(const std::string& msg); void PerformanceWarning(const std::string& msg); + bool ShouldDeferDraws() { + return !offscreen_target_frame_buffer_.get() && + bound_draw_framebuffer_ == NULL && + surface_->DeferDraws(); + } + // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -4243,13 +4249,22 @@ error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM( return error::kNoError; } -void GLES2DecoderImpl::DoClear(GLbitfield mask) { +error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { + if (ShouldDeferDraws()) + return error::kDeferCommandUntilLater; if (CheckBoundFramebuffersValid("glClear")) { UNSHIPPED_TRACE_EVENT_INSTANT2("test_gpu", "DoClear", "red", clear_red_, "green", clear_green_); ApplyDirtyState(); glClear(mask); } + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleClear( + uint32 immediate_data_size, const gles2::Clear& c) { + GLbitfield mask = static_cast<GLbitfield>(c.mask); + return DoClear(mask); } void GLES2DecoderImpl::DoFramebufferRenderbuffer( @@ -5492,6 +5507,8 @@ error::Error GLES2DecoderImpl::DoDrawArrays( GLint first, GLsizei count, GLsizei primcount) { + if (ShouldDeferDraws()) + return error::kDeferCommandUntilLater; if (!validators_->draw_mode.IsValid(mode)) { SetGLError(GL_INVALID_ENUM, function_name, "mode GL_INVALID_ENUM"); return error::kNoError; @@ -5593,6 +5610,8 @@ error::Error GLES2DecoderImpl::DoDrawElements( GLenum type, int32 offset, GLsizei primcount) { + if (ShouldDeferDraws()) + return error::kDeferCommandUntilLater; if (!bound_element_array_buffer_) { SetGLError(GL_INVALID_OPERATION, function_name, "No element array buffer bound"); @@ -8204,6 +8223,10 @@ error::Error GLES2DecoderImpl::HandleShaderBinary( error::Error GLES2DecoderImpl::HandleSwapBuffers( uint32 immediate_data_size, const gles2::SwapBuffers& c) { bool is_offscreen = !!offscreen_target_frame_buffer_.get(); + if (!is_offscreen && surface_->DeferSwapBuffers()) { + return error::kDeferCommandUntilLater; + } + int this_frame_number = frame_number_++; // TRACE_EVENT for gpu tests: TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffers", diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index ab06503..dc85cc2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -223,13 +223,6 @@ error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus( return error::kNoError; } -error::Error GLES2DecoderImpl::HandleClear( - uint32 immediate_data_size, const gles2::Clear& c) { - GLbitfield mask = static_cast<GLbitfield>(c.mask); - DoClear(mask); - return error::kNoError; -} - error::Error GLES2DecoderImpl::HandleClearColor( uint32 immediate_data_size, const gles2::ClearColor& c) { GLclampf red = static_cast<GLclampf>(c.red); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 495b16a..bd7dbd7 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -290,15 +290,8 @@ TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgsBadSharedMemoryId) { cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, kInvalidSharedMemoryOffset); EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); } +// TODO(gman): Clear -TEST_F(GLES2DecoderTest1, ClearValidArgs) { - EXPECT_CALL(*gl_, Clear(1)); - SpecializedSetup<Clear, 0>(true); - Clear cmd; - cmd.Init(1); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); -} TEST_F(GLES2DecoderTest1, ClearColorValidArgs) { EXPECT_CALL(*gl_, ClearColor(1, 2, 3, 4)); diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index 85d4f75..de83617 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -80,6 +80,11 @@ void GpuScheduler::PutChanged() { error = parser_->ProcessCommand(); + if (error == error::kDeferCommandUntilLater) { + DCHECK(unscheduled_count_ > 0); + return; + } + // 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. |