diff options
author | kloveless@chromium.org <kloveless@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 21:11:50 +0000 |
---|---|---|
committer | kloveless@chromium.org <kloveless@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 21:11:50 +0000 |
commit | d3eba3428254af18968db5dc81ec632b04b0c014 (patch) | |
tree | dd5c5dae04331d26709d3790bf3a9296047e812f /gpu | |
parent | 58a0644d395cdc0c1f921a527f3b6d6ba69d1977 (diff) | |
download | chromium_src-d3eba3428254af18968db5dc81ec632b04b0c014.zip chromium_src-d3eba3428254af18968db5dc81ec632b04b0c014.tar.gz chromium_src-d3eba3428254af18968db5dc81ec632b04b0c014.tar.bz2 |
Clean up of GLES2 Command Decoder by moving some of the error state into a separate class.
Review URL: https://chromiumcodereview.appspot.com/14308014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195002 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
26 files changed, 506 insertions, 330 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 6d79673..8d2a935 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -1577,7 +1577,7 @@ _FUNCTION_INFO = { }, 'GetError': { 'type': 'Is', - 'decoder_func': 'GetGLError', + 'decoder_func': 'GetErrorState()->GetGLError', 'impl_func': False, 'result': ['GLenum'], 'client_test': False, diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc index 65dd2af..7fe9d20 100644 --- a/gpu/command_buffer/service/buffer_manager.cc +++ b/gpu/command_buffer/service/buffer_manager.cc @@ -7,8 +7,8 @@ #include "base/debug/trace_event.h" #include "base/logging.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "ui/gl/gl_bindings.h" @@ -253,7 +253,7 @@ void BufferManager::SetInfo( } void BufferManager::DoBufferData( - GLES2Decoder* decoder, + ErrorState* error_state, Buffer* buffer, GLsizeiptr size, GLenum usage, @@ -266,13 +266,13 @@ void BufferManager::DoBufferData( data = zero.get(); } - GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder, "glBufferData"); + ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glBufferData"); if (IsUsageClientSideArray(usage)) { glBufferData(buffer->target(), 0, NULL, usage); } else { glBufferData(buffer->target(), size, data, usage); } - GLenum error = GLESDECODER_PEEK_GL_ERROR(decoder, "glBufferData"); + GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glBufferData"); if (error == GL_NO_ERROR) { SetInfo(buffer, size, usage, data); } else { @@ -281,14 +281,14 @@ void BufferManager::DoBufferData( } void BufferManager::DoBufferSubData( - GLES2Decoder* decoder, + ErrorState* error_state, Buffer* buffer, GLintptr offset, GLsizeiptr size, const GLvoid* data) { if (!buffer->SetRange(offset, size, data)) { - GLESDECODER_SET_GL_ERROR( - decoder, GL_INVALID_VALUE, "glBufferSubData", "out of range"); + ERRORSTATE_SET_GL_ERROR( + error_state, GL_INVALID_VALUE, "glBufferSubData", "out of range"); return; } diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index ccf2c18..7ccb3f0 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -19,8 +19,8 @@ namespace gpu { namespace gles2 { class BufferManager; +class ErrorState; class FeatureInfo; -class GLES2Decoder; // Info about Buffers currently in the system. class GPU_EXPORT Buffer : public base::RefCounted<Buffer> { @@ -194,7 +194,7 @@ class GPU_EXPORT BufferManager { // Does a glBufferData and updates the approprate accounting. Currently // assume the values have already been validated. void DoBufferData( - GLES2Decoder* decoder, + ErrorState* error_state, Buffer* buffer, GLsizeiptr size, GLenum usage, @@ -202,7 +202,7 @@ class GPU_EXPORT BufferManager { // Does a glBufferSubData and updates the approrate accounting. void DoBufferSubData( - GLES2Decoder* decoder, + ErrorState* error_state, Buffer* buffer, GLintptr offset, GLsizeiptr size, diff --git a/gpu/command_buffer/service/buffer_manager_unittest.cc b/gpu/command_buffer/service/buffer_manager_unittest.cc index 644b864..f2ada75 100644 --- a/gpu/command_buffer/service/buffer_manager_unittest.cc +++ b/gpu/command_buffer/service/buffer_manager_unittest.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/feature_info.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -29,7 +29,7 @@ class BufferManagerTestBase : public testing::Test { TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions); feature_info->Initialize(NULL); } - decoder_.reset(new MockGLES2Decoder()); + error_state_.reset(new MockErrorState()); manager_.reset(new BufferManager(memory_tracker, feature_info)); } @@ -37,7 +37,7 @@ class BufferManagerTestBase : public testing::Test { manager_->Destroy(false); manager_.reset(); ::gfx::GLInterface::SetGLInterface(NULL); - decoder_.reset(); + error_state_.reset(); gl_.reset(); } @@ -49,7 +49,7 @@ class BufferManagerTestBase : public testing::Test { Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data, GLenum error) { TestHelper::DoBufferData( - gl_.get(), decoder_.get(), manager_.get(), + gl_.get(), error_state_.get(), manager_.get(), buffer, size, usage, data, error); } @@ -58,9 +58,9 @@ class BufferManagerTestBase : public testing::Test { const GLvoid* data) { bool success = true; if (!buffer->CheckRange(offset, size)) { - EXPECT_CALL(*decoder_, SetGLError(_, _, GL_INVALID_VALUE, _, _)) - .Times(1) - .RetiresOnSaturation(); + EXPECT_CALL(*error_state_, SetGLError(_, _, GL_INVALID_VALUE, _, _)) + .Times(1) + .RetiresOnSaturation(); success = false; } else if (!buffer->IsClientSideArray()) { EXPECT_CALL(*gl_, BufferSubData( @@ -69,14 +69,14 @@ class BufferManagerTestBase : public testing::Test { .RetiresOnSaturation(); } manager_->DoBufferSubData( - decoder_.get(), buffer, offset, size, data); + error_state_.get(), buffer, offset, size, data); return success; } // Use StrictMock to make 100% sure we know how GL will be called. scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; scoped_ptr<BufferManager> manager_; - scoped_ptr<MockGLES2Decoder> decoder_; + scoped_ptr<MockErrorState> error_state_; }; class BufferManagerTest : public BufferManagerTestBase { diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc index 0e5ee26..a9274b8 100644 --- a/gpu/command_buffer/service/context_state.cc +++ b/gpu/command_buffer/service/context_state.cc @@ -6,6 +6,7 @@ #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" @@ -34,7 +35,7 @@ TextureUnit::TextureUnit() TextureUnit::~TextureUnit() { } -ContextState::ContextState(FeatureInfo* feature_info) +ContextState::ContextState(FeatureInfo* feature_info, Logger* logger) : pack_alignment(4), unpack_alignment(4), active_texture_unit(0), @@ -42,7 +43,8 @@ ContextState::ContextState(FeatureInfo* feature_info) hint_fragment_shader_derivative(GL_DONT_CARE), pack_reverse_row_order(false), fbo_binding_for_scissor_workaround_dirty_(false), - feature_info_(feature_info) { + feature_info_(feature_info), + error_state_(ErrorState::Create(logger)) { Initialize(); } @@ -161,6 +163,10 @@ void ContextState::RestoreState() const { RestoreGlobalState(); } +ErrorState* ContextState::GetErrorState() { + return error_state_.get(); +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/service/context_state.h b/gpu/command_buffer/service/context_state.h index f4e0f4c..73e6908 100644 --- a/gpu/command_buffer/service/context_state.h +++ b/gpu/command_buffer/service/context_state.h @@ -9,6 +9,7 @@ #include <vector> #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -20,6 +21,7 @@ namespace gpu { namespace gles2 { class Buffer; +class ErrorState; class FeatureInfo; class Framebuffer; class Program; @@ -91,7 +93,7 @@ struct Vec4 { }; struct GPU_EXPORT ContextState { - explicit ContextState(FeatureInfo* feature_info); + ContextState(FeatureInfo* feature_info, Logger* logger); ~ContextState(); void Initialize(); @@ -115,6 +117,8 @@ struct GPU_EXPORT ContextState { GLenum pname, GLfloat* params, GLsizei* num_written) const; bool GetEnabled(GLenum cap) const; + ErrorState* GetErrorState(); + #include "gpu/command_buffer/service/context_state_autogen.h" EnableFlags enable_flags; @@ -161,8 +165,10 @@ struct GPU_EXPORT ContextState { bool pack_reverse_row_order; mutable bool fbo_binding_for_scissor_workaround_dirty_; - FeatureInfo* feature_info_; + + private: + scoped_ptr<ErrorState> error_state_; }; } // namespace gles2 diff --git a/gpu/command_buffer/service/error_state.cc b/gpu/command_buffer/service/error_state.cc new file mode 100644 index 0000000..1e9148c --- /dev/null +++ b/gpu/command_buffer/service/error_state.cc @@ -0,0 +1,183 @@ +// Copyright (c) 2013 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. + +#include "gpu/command_buffer/service/error_state.h" + +#include <string> + +#include "base/stringprintf.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/logger.h" +#include "ui/gl/gl_bindings.h" + +namespace gpu { +namespace gles2 { + +class ErrorStateImpl : public ErrorState { + public: + explicit ErrorStateImpl(Logger* logger); + virtual ~ErrorStateImpl(); + + virtual uint32 GetGLError() OVERRIDE; + + virtual void SetGLError( + const char* filename, + int line, + unsigned int error, + const char* function_name, + const char* msg) OVERRIDE; + virtual void SetGLErrorInvalidEnum( + const char* filename, + int line, + const char* function_name, + unsigned int value, + const char* label) OVERRIDE; + virtual void SetGLErrorInvalidParam( + const char* filename, + int line, + unsigned int error, + const char* function_name, + unsigned int pname, + int param) OVERRIDE; + + virtual unsigned int PeekGLError( + const char* filename, int line, const char* function_name) OVERRIDE; + + virtual void CopyRealGLErrorsToWrapper( + const char* filename, int line, const char* function_name) OVERRIDE; + + virtual void ClearRealGLErrors( + const char* filename, int line, const char* function_name) OVERRIDE; + + private: + // The last error message set. + std::string last_error_; + // Current GL error bits. + uint32 error_bits_; + + Logger* logger_; + + DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl); +}; + +ErrorState::ErrorState() {} + +ErrorState::~ErrorState() {} + +ErrorState* ErrorState::Create(Logger* logger) { + return new ErrorStateImpl(logger); +} + +ErrorStateImpl::ErrorStateImpl(Logger* logger) + : error_bits_(0), + logger_(logger) {} + +ErrorStateImpl::~ErrorStateImpl() {} + +uint32 ErrorStateImpl::GetGLError() { + // Check the GL error first, then our wrapped error. + GLenum error = glGetError(); + if (error == GL_NO_ERROR && error_bits_ != 0) { + for (uint32 mask = 1; mask != 0; mask = mask << 1) { + if ((error_bits_ & mask) != 0) { + error = GLES2Util::GLErrorBitToGLError(mask); + break; + } + } + } + + if (error != GL_NO_ERROR) { + // There was an error, clear the corresponding wrapped error. + error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error); + } + return error; +} + +unsigned int ErrorStateImpl::PeekGLError( + const char* filename, int line, const char* function_name) { + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + SetGLError(filename, line, error, function_name, ""); + } + return error; +} + +void ErrorStateImpl::SetGLError( + const char* filename, + int line, + unsigned int error, + const char* function_name, + const char* msg) { + if (msg) { + last_error_ = msg; + logger_->LogMessage( + filename, line, + logger_->GetLogPrefix() + ": " + std::string("GL ERROR :") + + GLES2Util::GetStringEnum(error) + " : " + + function_name + ": " + msg); + } + error_bits_ |= GLES2Util::GLErrorToErrorBit(error); +} + +void ErrorStateImpl::SetGLErrorInvalidEnum( + const char* filename, + int line, + const char* function_name, + unsigned int value, + const char* label) { + SetGLError(filename, line, GL_INVALID_ENUM, function_name, + (std::string(label) + " was " + + GLES2Util::GetStringEnum(value)).c_str()); +} + +void ErrorStateImpl::SetGLErrorInvalidParam( + const char* filename, + int line, + unsigned int error, + const char* function_name, + unsigned int pname, int param) { + if (error == GL_INVALID_ENUM) { + SetGLError( + filename, line, GL_INVALID_ENUM, function_name, + (std::string("trying to set ") + + GLES2Util::GetStringEnum(pname) + " to " + + GLES2Util::GetStringEnum(param)).c_str()); + } else { + SetGLError( + filename, line, error, function_name, + (std::string("trying to set ") + + GLES2Util::GetStringEnum(pname) + " to " + + base::StringPrintf("%d", param)).c_str()); + } +} + +void ErrorStateImpl::CopyRealGLErrorsToWrapper( + const char* filename, int line, const char* function_name) { + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + SetGLError(filename, line, error, function_name, + "<- error from previous GL command"); + } +} + +void ErrorStateImpl::ClearRealGLErrors( + const char* filename, int line, const char* function_name) { + // Clears and logs all current gl errors. + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + if (error != GL_OUT_OF_MEMORY) { + // GL_OUT_OF_MEMORY can legally happen on lost device. + logger_->LogMessage( + filename, line, + logger_->GetLogPrefix() + ": " + std::string("GL ERROR :") + + GLES2Util::GetStringEnum(error) + " : " + + function_name + ": was unhandled"); + NOTREACHED() << "GL error " << error << " was unhandled."; + } + } +} + +} // namespace gles2 +} // namespace gpu + diff --git a/gpu/command_buffer/service/error_state.h b/gpu/command_buffer/service/error_state.h new file mode 100644 index 0000000..507b738 --- /dev/null +++ b/gpu/command_buffer/service/error_state.h @@ -0,0 +1,107 @@ +// Copyright (c) 2013 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. + +// This file contains the ErrorState class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_H_ + +#include "base/compiler_specific.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/gpu_export.h" + +namespace gpu { +namespace gles2 { + +class Logger; + +// Use these macro to synthesize GL errors instead of calling the error_state +// functions directly as they will propogate the __FILE__ and __LINE__. + +// Use to synthesize a GL error on the error_state. +#define ERRORSTATE_SET_GL_ERROR(error_state, error, function_name, msg) \ + error_state->SetGLError(__FILE__, __LINE__, error, function_name, msg) + +// Use to synthesize an INVALID_ENUM GL error on the error_state. Will attempt +// to expand the enum to a string. +#define ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( \ + error_state, function_name, value, label) \ + error_state->SetGLErrorInvalidEnum( \ + __FILE__, __LINE__, function_name, value, label) + +// Use to synthesize a GL error on the error_state for an invalid enum based +// parameter. Will attempt to expand the parameter to a string. +#define ERRORSTATE_SET_GL_ERROR_INVALID_PARAM( \ + error_state, error, function_name, pname, param) \ + error_state->SetGLErrorInvalidParam( \ + __FILE__, __LINE__, error, function_name, pname, param) + +// Use to move all pending error to the wrapper so on your next GL call +// you can see if that call generates an error. +#define ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, function_name) \ + error_state->CopyRealGLErrorsToWrapper(__FILE__, __LINE__, function_name) +// Use to look at the real GL error and still pass it on to the user. +#define ERRORSTATE_PEEK_GL_ERROR(error_state, function_name) \ + error_state->PeekGLError(__FILE__, __LINE__, function_name) +// Use to clear all current GL errors. FAILS if there are any. +#define ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state, function_name) \ + error_state->ClearRealGLErrors(__FILE__, __LINE__, function_name) + + +class GPU_EXPORT ErrorState { + public: + virtual ~ErrorState(); + + static ErrorState* Create(Logger* logger); + + virtual uint32 GetGLError() = 0; + + virtual void SetGLError( + const char* filename, + int line, + unsigned int error, + const char* function_name, + const char* msg) = 0; + virtual void SetGLErrorInvalidEnum( + const char* filename, + int line, + const char* function_name, + unsigned int value, + const char* label) = 0; + virtual void SetGLErrorInvalidParam( + const char* filename, + int line, + unsigned int error, + const char* function_name, + unsigned int pname, + int param) = 0; + + // Gets the GLError and stores it in our wrapper. Effectively + // this lets us peek at the error without losing it. + virtual unsigned int PeekGLError( + const char* filename, int line, const char* function_name) = 0; + + // Copies the real GL errors to the wrapper. This is so we can + // make sure there are no native GL errors before calling some GL function + // so that on return we know any error generated was for that specific + // command. + virtual void CopyRealGLErrorsToWrapper( + const char* filename, int line, const char* function_name) = 0; + + // Clear all real GL errors. This is to prevent the client from seeing any + // errors caused by GL calls that it was not responsible for issuing. + virtual void ClearRealGLErrors( + const char* filename, int line, const char* function_name) = 0; + + protected: + ErrorState(); + + DISALLOW_COPY_AND_ASSIGN(ErrorState); +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_H_ + diff --git a/gpu/command_buffer/service/error_state_mock.cc b/gpu/command_buffer/service/error_state_mock.cc new file mode 100644 index 0000000..f3925d74 --- /dev/null +++ b/gpu/command_buffer/service/error_state_mock.cc @@ -0,0 +1,17 @@ +// Copyright (c) 2013 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. + +#include "gpu/command_buffer/service/error_state_mock.h" + +namespace gpu { +namespace gles2 { + +MockErrorState::MockErrorState() + : ErrorState() {} + +MockErrorState::~MockErrorState() {} + +} // namespace gles2 +} // namespace gpu + diff --git a/gpu/command_buffer/service/error_state_mock.h b/gpu/command_buffer/service/error_state_mock.h new file mode 100644 index 0000000..00bed9a --- /dev/null +++ b/gpu/command_buffer/service/error_state_mock.h @@ -0,0 +1,48 @@ +// Copyright (c) 2013 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. + +// This file contains the mock ErrorState class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_MOCK_H_ + +#include "gpu/command_buffer/service/error_state.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu { +namespace gles2 { + +class MockErrorState : public ErrorState { + public: + MockErrorState(); + virtual ~MockErrorState(); + + MOCK_METHOD0(GetGLError, uint32()); + MOCK_METHOD5(SetGLError, void( + const char* filename, int line, + unsigned error, const char* function_name, const char* msg)); + MOCK_METHOD5(SetGLErrorInvalidEnum, void( + const char* filename, int line, + const char* function_name, unsigned value, const char* label)); + MOCK_METHOD6(SetGLErrorInvalidParam, void( + const char* filename, + int line, + unsigned error, + const char* function_name, + unsigned pname, + int param)); + MOCK_METHOD3(PeekGLError, unsigned( + const char* file, int line, const char* filename)); + MOCK_METHOD3(CopyRealGLErrorsToWrapper, void( + const char* file, int line, const char* filename)); + MOCK_METHOD3(ClearRealGLErrors, void( + const char* file, int line, const char* filename)); + + DISALLOW_COPY_AND_ASSIGN(MockErrorState); +}; +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_MOCK_H_ + diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 86bb87f..b73a776 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/feature_info.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -132,7 +132,7 @@ class FramebufferInfoTest : public testing::Test { gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); manager_.CreateFramebuffer(kClient1Id, kService1Id); - decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); + error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); framebuffer_ = manager_.GetFramebuffer(kClient1Id); ASSERT_TRUE(framebuffer_ != NULL); } @@ -148,7 +148,7 @@ class FramebufferInfoTest : public testing::Test { Framebuffer* framebuffer_; TextureManager texture_manager_; RenderbufferManager renderbuffer_manager_; - scoped_ptr<MockGLES2Decoder> decoder_; + scoped_ptr<MockErrorState> error_state_; }; // GCC requires these declarations, but MSVC requires they not be present @@ -732,7 +732,7 @@ TEST_F(FramebufferInfoTest, GetStatus) { // Check changing the format calls CheckFramebuffferStatus. TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &texture_manager_, + gl_.get(), error_state_.get(), &texture_manager_, texture2, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) @@ -752,7 +752,7 @@ TEST_F(FramebufferInfoTest, GetStatus) { .RetiresOnSaturation(); } TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &texture_manager_, + gl_.get(), error_state_.get(), &texture_manager_, texture2, GL_TEXTURE_WRAP_S, GL_REPEAT, GL_NO_ERROR); framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 9413bd1..55ea6d5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -23,7 +23,6 @@ #endif #include "base/memory/scoped_ptr.h" #include "base/string_number_conversions.h" -#include "base/stringprintf.h" #include "build/build_config.h" #define GLES2_GPU_SERVICE 1 #include "gpu/command_buffer/common/gles2_cmd_format.h" @@ -34,6 +33,7 @@ #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_state.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/framebuffer_manager.h" #include "gpu/command_buffer/service/gl_utils.h" @@ -42,7 +42,6 @@ #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/gpu_tracer.h" #include "gpu/command_buffer/service/image_manager.h" -#include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/program_manager.h" @@ -127,17 +126,20 @@ class GLES2DecoderImpl; // Local versions of the SET_GL_ERROR macros #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ - GLESDECODER_SET_GL_ERROR(this, error, function_name, msg) + ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ - GLESDECODER_SET_GL_ERROR_INVALID_ENUM(this, function_name, value, label) + ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ + function_name, value, label) #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \ - GLESDECODER_SET_GL_ERROR_INVALID_PARAM(this, error, function_name, pname) + ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \ + function_name, pname) #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \ - GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(this, function_name) + ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \ + function_name) #define LOCAL_PEEK_GL_ERROR(function_name) \ - GLESDECODER_PEEK_GL_ERROR(this, function_name) + ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name) #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \ - GLESDECODER_CLEARREAL_GL_ERRORS(this, function_name) + ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name) #define LOCAL_PERFORMANCE_WARNING(msg) \ PerformanceWarning(__FILE__, __LINE__, msg) #define LOCAL_RENDER_WARNING(msg) \ @@ -560,8 +562,6 @@ bool GLES2Decoder::IsAngle() { // cmd stuff to outside this class. class GLES2DecoderImpl : public GLES2Decoder { public: - static const int kMaxLogMessages = 256; - // Used by PrepForSetUniformByLocation to validate types. struct BaseUniformInfo { const GLenum* const valid_types; @@ -639,6 +639,7 @@ class GLES2DecoderImpl : public GLES2Decoder { const base::Callback<void(gfx::Size)>& callback) OVERRIDE; virtual Logger* GetLogger() OVERRIDE; + virtual ErrorState* GetErrorState() OVERRIDE; virtual void SetShaderCacheCallback( const ShaderCacheCallback& callback) OVERRIDE; @@ -656,8 +657,6 @@ class GLES2DecoderImpl : public GLES2Decoder { virtual bool GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id) OVERRIDE; - virtual uint32 GetGLError() OVERRIDE; - virtual uint32 GetTextureUploadCount() OVERRIDE; virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; @@ -1406,34 +1405,6 @@ class GLES2DecoderImpl : public GLES2Decoder { // false if pname is unknown. bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); - virtual void SetGLError( - const char* filename, - int line, - unsigned error, - const char* function_name, - const char* msg) OVERRIDE; - virtual void SetGLErrorInvalidEnum( - const char* filename, - int line, - const char* function_name, - unsigned value, - const char* label) OVERRIDE; - // Generates a GL error for a bad parameter. - virtual void SetGLErrorInvalidParam( - const char* filename, - int line, - unsigned error, - const char* function_name, - unsigned pname, - int param) OVERRIDE; - - virtual unsigned PeekGLError( - const char* filename, int line, const char* function_name) OVERRIDE; - virtual void CopyRealGLErrorsToWrapper( - const char* filename, int line, const char* function_name) OVERRIDE; - virtual void ClearRealGLErrors( - const char* filename, int line, const char* function_name) OVERRIDE; - // Checks if the current program and vertex attributes are valid for drawing. bool IsDrawValid( const char* function_name, GLuint max_vertex_accessed, GLsizei primcount); @@ -1661,9 +1632,6 @@ class GLES2DecoderImpl : public GLES2Decoder { // Current width and height of the offscreen frame buffer. gfx::Size offscreen_size_; - // Current GL error bits. - uint32 error_bits_; - // Util to help with GL. GLES2Util util_; @@ -1748,9 +1716,6 @@ class GLES2DecoderImpl : public GLES2Decoder { bool teximage2d_faster_than_texsubimage2d_; - // The last error message set. - std::string last_error_; - // The current decoder error. error::Error current_decoder_error_; @@ -1814,11 +1779,12 @@ ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( const char* function_name, GLES2DecoderImpl* decoder) : function_name_(function_name), decoder_(decoder) { - GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_, function_name_); + ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), + function_name_); } ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { - GLESDECODER_CLEAR_REAL_GL_ERRORS(decoder_, function_name_); + ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_); } ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, @@ -2201,8 +2167,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) : GLES2Decoder(), group_(group), logger_(&debug_marker_manager_), - state_(group_->feature_info()), - error_bits_(0), + state_(group_->feature_info(), &logger_), unpack_flip_y_(false), unpack_premultiply_alpha_(false), unpack_unpremultiply_alpha_(false), @@ -3088,25 +3053,25 @@ void GLES2DecoderImpl::UpdateParentTextureInfo() { true); parent_texture_manager->SetParameter( "UpdateParentTextureInfo", - this, + GetErrorState(), offscreen_saved_color_texture_info_, GL_TEXTURE_MAG_FILTER, GL_NEAREST); parent_texture_manager->SetParameter( "UpdateParentTextureInfo", - this, + GetErrorState(), offscreen_saved_color_texture_info_, GL_TEXTURE_MIN_FILTER, GL_NEAREST); parent_texture_manager->SetParameter( "UpdateParentTextureInfo", - this, + GetErrorState(), offscreen_saved_color_texture_info_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); parent_texture_manager->SetParameter( "UpdateParentTextureInfo", - this, + GetErrorState(), offscreen_saved_color_texture_info_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -3124,6 +3089,10 @@ Logger* GLES2DecoderImpl::GetLogger() { return &logger_; } +ErrorState* GLES2DecoderImpl::GetErrorState() { + return state_.GetErrorState(); +} + void GLES2DecoderImpl::SetShaderCacheCallback( const ShaderCacheCallback& callback) { shader_cache_callback_ = callback; @@ -5245,7 +5214,8 @@ void GLES2DecoderImpl::DoTexParameterf( } texture_manager()->SetParameter( - "glTexParameterf", this, texture, pname, static_cast<GLint>(param)); + "glTexParameterf", GetErrorState(), texture, pname, + static_cast<GLint>(param)); } void GLES2DecoderImpl::DoTexParameteri( @@ -5257,7 +5227,7 @@ void GLES2DecoderImpl::DoTexParameteri( } texture_manager()->SetParameter( - "glTexParameteri", this, texture, pname, param); + "glTexParameteri", GetErrorState(), texture, pname, param); } void GLES2DecoderImpl::DoTexParameterfv( @@ -5269,7 +5239,8 @@ void GLES2DecoderImpl::DoTexParameterfv( } texture_manager()->SetParameter( - "glTexParameterfv", this, texture, pname, static_cast<GLint>(params[0])); + "glTexParameterfv", GetErrorState(), texture, pname, + static_cast<GLint>(params[0])); } void GLES2DecoderImpl::DoTexParameteriv( @@ -5282,7 +5253,7 @@ void GLES2DecoderImpl::DoTexParameteriv( } texture_manager()->SetParameter( - "glTexParameteriv", this, texture, pname, *params); + "glTexParameteriv", GetErrorState(), texture, pname, *params); } bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) { @@ -5693,77 +5664,6 @@ void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { } } -uint32 GLES2DecoderImpl::GetGLError() { - // Check the GL error first, then our wrapped error. - GLenum error = glGetError(); - if (error == GL_NO_ERROR && error_bits_ != 0) { - for (uint32 mask = 1; mask != 0; mask = mask << 1) { - if ((error_bits_ & mask) != 0) { - error = GLES2Util::GLErrorBitToGLError(mask); - break; - } - } - } - - if (error != GL_NO_ERROR) { - // There was an error, clear the corresponding wrapped error. - error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error); - } - return error; -} - -unsigned GLES2DecoderImpl::PeekGLError( - const char* filename, int line, const char* function_name) { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - SetGLError(filename, line, error, function_name, ""); - } - return error; -} - -void GLES2DecoderImpl::SetGLError( - const char* filename, int line, - unsigned error, const char* function_name, const char* msg) { - if (msg) { - last_error_ = msg; - logger_.LogMessage(filename, line, - logger_.GetLogPrefix() + ": " + std::string("GL ERROR :") + - GLES2Util::GetStringEnum(error) + " : " + - function_name + ": " + msg); - } - error_bits_ |= GLES2Util::GLErrorToErrorBit(error); -} - -void GLES2DecoderImpl::SetGLErrorInvalidEnum( - const char* filename, int line, - const char* function_name, unsigned value, const char* label) { - SetGLError(filename, line, GL_INVALID_ENUM, function_name, - (std::string(label) + " was " + - GLES2Util::GetStringEnum(value)).c_str()); -} - -void GLES2DecoderImpl::SetGLErrorInvalidParam( - const char* filename, - int line, - unsigned error, - const char* function_name, - unsigned pname, - int param) { - if (error == GL_INVALID_ENUM) { - SetGLError( - filename, line, GL_INVALID_ENUM, function_name, - (std::string("trying to set ") + - GLES2Util::GetStringEnum(pname) + " to " + - GLES2Util::GetStringEnum(param)).c_str()); - } else { - SetGLError( - filename, line, error, function_name, - (std::string("trying to set ") + - GLES2Util::GetStringEnum(pname) + " to " + - base::StringPrintf("%d", param)).c_str()); - } -} - void GLES2DecoderImpl::RenderWarning( const char* filename, int line, const std::string& msg) { logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg); @@ -5771,8 +5671,8 @@ void GLES2DecoderImpl::RenderWarning( void GLES2DecoderImpl::PerformanceWarning( const char* filename, int line, const std::string& msg) { - logger_.LogMessage(filename, line, std::string("PERFORMANCE WARNING: ") - + msg); + logger_.LogMessage(filename, line, + std::string("PERFORMANCE WARNING: ") + msg); } void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) { @@ -5792,30 +5692,6 @@ void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) { } } -void GLES2DecoderImpl::CopyRealGLErrorsToWrapper( - const char* filename, int line, const char* function_name) { - GLenum error; - while ((error = glGetError()) != GL_NO_ERROR) { - SetGLError(filename, line, error, function_name, - "<- error from previous GL command"); - } -} - -void GLES2DecoderImpl::ClearRealGLErrors( - const char* filename, int line, const char* function_name) { - GLenum error; - while ((error = glGetError()) != GL_NO_ERROR) { - if (error != GL_OUT_OF_MEMORY) { - // GL_OUT_OF_MEMORY can legally happen on lost device. - logger_.LogMessage(filename, line, - logger_.GetLogPrefix() + ": " + std::string("GL ERROR :") + - GLES2Util::GetStringEnum(error) + " : " + - function_name + ": was unhandled"); - NOTREACHED() << "GL error " << error << " was unhandled."; - } - } -} - bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() { DCHECK(state_.current_program); // Only check if there are some unrenderable textures. @@ -7380,7 +7256,7 @@ void GLES2DecoderImpl::DoBufferData( return; } - buffer_manager()->DoBufferData(this, buffer, size, usage, data); + buffer_manager()->DoBufferData(GetErrorState(), buffer, size, usage, data); } error::Error GLES2DecoderImpl::HandleBufferData( @@ -7423,7 +7299,8 @@ void GLES2DecoderImpl::DoBufferSubData( return; } - buffer_manager()->DoBufferSubData(this, buffer, offset, size, data); + buffer_manager()->DoBufferSubData(GetErrorState(), buffer, offset, size, + data); } bool GLES2DecoderImpl::ClearLevel( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 74602ff..818ace9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -14,41 +14,10 @@ #include "base/time.h" #include "build/build_config.h" #include "gpu/command_buffer/service/common_decoder.h" +#include "gpu/command_buffer/service/logger.h" #include "ui/gfx/size.h" #include "ui/gl/gl_context.h" -// Use these macro to synthesize GL errors instead of calling the decoder -// functions directly as they will propogate the __FILE__ and __LINE__ - -// Use to synthesize a GL error on the decoder. -#define GLESDECODER_SET_GL_ERROR(decoder, error, function_name, msg) \ - decoder->SetGLError(__FILE__, __LINE__, error, function_name, msg) - -// Use to synthesize an INVALID_ENUM GL error on the decoder. Will attempt to -// expand the enum to a string. -#define GLESDECODER_SET_GL_ERROR_INVALID_ENUM( \ - decoder, function_name, value, label) \ - decoder->SetGLErrorInvalidEnum( \ - __FILE__, __LINE__, function_name, value, label) - -// Use to synthesize a GL error on the decoder for an invalid enum based -// parameter. Will attempt to expand the parameter to a string. -#define GLESDECODER_SET_GL_ERROR_INVALID_PARAM( \ - decoder, error, function_name, pname, param) \ - decoder->SetGLErrorInvalidParam( \ - __FILE__, __LINE__, error, function_name, pname, param) - -// Use to move all pending error to the wrapper so on your next GL call -// you can see if that call generates an error. -#define GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder, function_name) \ - decoder->CopyRealGLErrorsToWrapper(__FILE__, __LINE__, function_name) -// Use to look at the real GL error and still pass it on to the user. -#define GLESDECODER_PEEK_GL_ERROR(decoder, function_name) \ - decoder->PeekGLError(__FILE__, __LINE__, function_name) -// Use to clear all current GL errors. FAILS if there are any. -#define GLESDECODER_CLEAR_REAL_GL_ERRORS(decoder, function_name) \ - decoder->ClearRealGLErrors(__FILE__, __LINE__, function_name) - namespace gfx { class GLContext; class GLSurface; @@ -62,6 +31,7 @@ class StreamTextureManager; namespace gles2 { class ContextGroup; +class ErrorState; class GLES2Util; class Logger; class QueryManager; @@ -232,46 +202,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, int height, bool is_texture_immutable) = 0; - // Gets the GL error for this context. - virtual uint32 GetGLError() = 0; - - // Sets a GL error. - virtual void SetGLError( - const char* filename, - int line, - unsigned error, - const char* function_name, - const char* msg) = 0; - virtual void SetGLErrorInvalidEnum( - const char* filename, - int line, - const char* function_name, - unsigned value, - const char* label) = 0; - virtual void SetGLErrorInvalidParam( - const char* filename, - int line, - unsigned error, - const char* function_name, - unsigned pname, - int param) = 0; - - // Copies the real GL errors to the wrapper. This is so we can - // make sure there are no native GL errors before calling some GL function - // so that on return we know any error generated was for that specific - // command. - virtual void CopyRealGLErrorsToWrapper( - const char* file, int line, const char* filename) = 0; - - // Gets the GLError and stores it in our wrapper. Effectively - // this lets us peek at the error without losing it. - virtual unsigned PeekGLError( - const char* file, int line, const char* filename) = 0; - - // Clear all real GL errors. This is to prevent the client from seeing any - // errors caused by GL calls that it was not responsible for issuing. - virtual void ClearRealGLErrors( - const char* file, int line, const char* filename) = 0; + virtual ErrorState* GetErrorState() = 0; // A callback for messages from the decoder. virtual void SetShaderCacheCallback(const ShaderCacheCallback& callback) = 0; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index f145d90..8975fd8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -1048,7 +1048,7 @@ error::Error GLES2DecoderImpl::HandleGetError( if (!result_dst) { return error::kOutOfBounds; } - *result_dst = GetGLError(); + *result_dst = GetErrorState()->GetGLError(); return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 64f7f4c5..624b6f9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -25,6 +25,7 @@ class StreamTextureManager; namespace gles2 { class ContextGroup; +class ErrorState; class QueryManager; class MockGLES2Decoder : public GLES2Decoder { @@ -89,26 +90,7 @@ class MockGLES2Decoder : public GLES2Decoder { int width, int height, bool is_texture_immutable)); - MOCK_METHOD0(GetGLError, uint32()); - MOCK_METHOD5(SetGLError, void( - const char* filename, int line, - unsigned error, const char* function_name, const char* msg)); - MOCK_METHOD5(SetGLErrorInvalidEnum, void( - const char* filename, int line, - const char* function_name, unsigned value, const char* label)); - MOCK_METHOD6(SetGLErrorInvalidParam, void( - const char* filename, - int line, - unsigned error, - const char* function_name, - unsigned pname, - int param)); - MOCK_METHOD3(PeekGLError, unsigned( - const char* file, int line, const char* filename)); - MOCK_METHOD3(CopyRealGLErrorsToWrapper, void( - const char* file, int line, const char* filename)); - MOCK_METHOD3(ClearRealGLErrors, void( - const char* file, int line, const char* filename)); + MOCK_METHOD0(GetErrorState, ErrorState *()); MOCK_METHOD0(GetLogger, Logger*()); MOCK_METHOD1(SetShaderCacheCallback, diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index 198ab5a..7b41232 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc @@ -10,6 +10,7 @@ #include "base/shared_memory.h" #include "base/time.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "ui/gl/async_pixel_transfer_delegate.h" @@ -280,7 +281,7 @@ bool GetErrorQuery::Begin() { bool GetErrorQuery::End(uint32 submit_count) { MarkAsPending(submit_count); - return MarkAsCompleted(manager()->decoder()->GetGLError()); + return MarkAsCompleted(manager()->decoder()->GetErrorState()->GetGLError()); } bool GetErrorQuery::Process() { diff --git a/gpu/command_buffer/service/query_manager_unittest.cc b/gpu/command_buffer/service/query_manager_unittest.cc index 7411014..63ad4f5 100644 --- a/gpu/command_buffer/service/query_manager_unittest.cc +++ b/gpu/command_buffer/service/query_manager_unittest.cc @@ -5,6 +5,7 @@ #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/feature_info.h" @@ -552,7 +553,10 @@ TEST_F(QueryManagerTest, GetErrorQuery) { EXPECT_TRUE(manager->BeginQuery(query)); - EXPECT_CALL(*decoder_.get(), GetGLError()) + MockErrorState mock_error_state; + EXPECT_CALL(*decoder_.get(), GetErrorState()) + .WillRepeatedly(Return(&mock_error_state)); + EXPECT_CALL(mock_error_state, GetGLError()) .WillOnce(Return(GL_INVALID_ENUM)) .RetiresOnSaturation(); diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc index 06c2fd7..5b3f57c 100644 --- a/gpu/command_buffer/service/test_helper.cc +++ b/gpu/command_buffer/service/test_helper.cc @@ -11,8 +11,8 @@ #include "base/strings/string_tokenizer.h" #include "gpu/command_buffer/common/types.h" #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/gl_utils.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/texture_manager.h" @@ -498,10 +498,10 @@ void TestHelper::SetupShader( } void TestHelper::DoBufferData( - ::gfx::MockGLInterface* gl, MockGLES2Decoder* decoder, + ::gfx::MockGLInterface* gl, MockErrorState* error_state, BufferManager* manager, Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data, GLenum error) { - EXPECT_CALL(*decoder, CopyRealGLErrorsToWrapper(_, _, _)) + EXPECT_CALL(*error_state, CopyRealGLErrorsToWrapper(_, _, _)) .Times(1) .RetiresOnSaturation(); if (manager->IsUsageClientSideArray(usage)) { @@ -515,14 +515,14 @@ void TestHelper::DoBufferData( .Times(1) .RetiresOnSaturation(); } - EXPECT_CALL(*decoder, PeekGLError(_, _, _)) + EXPECT_CALL(*error_state, PeekGLError(_, _, _)) .WillOnce(Return(error)) .RetiresOnSaturation(); - manager->DoBufferData(decoder, buffer, size, usage, data); + manager->DoBufferData(error_state, buffer, size, usage, data); } void TestHelper::SetTexParameterWithExpectations( - ::gfx::MockGLInterface* gl, MockGLES2Decoder* decoder, + ::gfx::MockGLInterface* gl, MockErrorState* error_state, TextureManager* manager, Texture* texture, GLenum pname, GLint value, GLenum error) { if (error == GL_NO_ERROR) { @@ -532,15 +532,15 @@ void TestHelper::SetTexParameterWithExpectations( .RetiresOnSaturation(); } } else if (error == GL_INVALID_ENUM) { - EXPECT_CALL(*decoder, SetGLErrorInvalidEnum(_, _, _, value, _)) + EXPECT_CALL(*error_state, SetGLErrorInvalidEnum(_, _, _, value, _)) .Times(1) .RetiresOnSaturation(); } else { - EXPECT_CALL(*decoder, SetGLErrorInvalidParam(_, _, error, _, _, _)) + EXPECT_CALL(*error_state, SetGLErrorInvalidParam(_, _, error, _, _, _)) .Times(1) .RetiresOnSaturation(); } - manager->SetParameter("", decoder, texture, pname, value); + manager->SetParameter("", error_state, texture, pname, value); } ScopedGLImplementationSetter::ScopedGLImplementationSetter( diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h index d04e9bd..41cb3aa 100644 --- a/gpu/command_buffer/service/test_helper.h +++ b/gpu/command_buffer/service/test_helper.h @@ -14,7 +14,7 @@ namespace gles2 { struct DisallowedFeatures; class Buffer; class BufferManager; -class MockGLES2Decoder; +class MockErrorState; class Texture; class TextureManager; @@ -92,12 +92,12 @@ class TestHelper { GLuint service_id); static void DoBufferData( - ::gfx::MockGLInterface* gl, MockGLES2Decoder* decoder, + ::gfx::MockGLInterface* gl, MockErrorState* error_state, BufferManager* manager, Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data, GLenum error); static void SetTexParameterWithExpectations( - ::gfx::MockGLInterface* gl, MockGLES2Decoder* decoder, + ::gfx::MockGLInterface* gl, MockErrorState* error_state, TextureManager* manager, Texture* texture, GLenum pname, GLint value, GLenum error); diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index c343af3..d64ac25 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -6,6 +6,7 @@ #include "base/bits.h" #include "base/stringprintf.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/mailbox_manager.h" @@ -1047,17 +1048,19 @@ bool TextureManager::Restore( glBindTexture(texture->target(), texture->service_id()); texture->SetImmutable(definition->immutable()); texture->SetStreamTexture(definition->stream_texture()); - SetParameter(function_name, decoder, texture, GL_TEXTURE_MIN_FILTER, + + ErrorState* error_state = decoder->GetErrorState(); + SetParameter(function_name, error_state, texture, GL_TEXTURE_MIN_FILTER, definition->min_filter()); - SetParameter(function_name, decoder, texture, GL_TEXTURE_MAG_FILTER, + SetParameter(function_name, error_state, texture, GL_TEXTURE_MAG_FILTER, definition->mag_filter()); - SetParameter(function_name, decoder, texture, GL_TEXTURE_WRAP_S, + SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_S, definition->wrap_s()); - SetParameter(function_name, decoder, texture, GL_TEXTURE_WRAP_T, + SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_T, definition->wrap_t()); if (feature_info_->validators()->texture_parameter.IsValid( GL_TEXTURE_USAGE_ANGLE)) { - SetParameter(function_name, decoder, texture, GL_TEXTURE_USAGE_ANGLE, + SetParameter(function_name, error_state, texture, GL_TEXTURE_USAGE_ANGLE, definition->usage()); } @@ -1065,9 +1068,9 @@ bool TextureManager::Restore( } void TextureManager::SetParameter( - const char* function_name, GLES2Decoder* decoder, + const char* function_name, ErrorState* error_state, Texture* texture, GLenum pname, GLint param) { - DCHECK(decoder); + DCHECK(error_state); DCHECK(texture); if (!texture->CanRender(feature_info_)) { DCHECK_NE(0, num_unrenderable_textures_); @@ -1080,11 +1083,11 @@ void TextureManager::SetParameter( GLenum result = texture->SetParameter(feature_info_, pname, param); if (result != GL_NO_ERROR) { if (result == GL_INVALID_ENUM) { - GLESDECODER_SET_GL_ERROR_INVALID_ENUM( - decoder, function_name, param, "param"); + ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( + error_state, function_name, param, "param"); } else { - GLESDECODER_SET_GL_ERROR_INVALID_PARAM( - decoder, result, function_name, pname, static_cast<GLint>(param)); + ERRORSTATE_SET_GL_ERROR_INVALID_PARAM( + error_state, result, function_name, pname, static_cast<GLint>(param)); } } else { // Texture tracking pools exist only for the command decoder, so diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 58b4c5c..51c9ba4 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -23,6 +23,7 @@ namespace gles2 { class GLES2Decoder; class Display; +class ErrorState; class FeatureInfo; class TextureDefinition; class TextureManager; @@ -477,7 +478,7 @@ class GPU_EXPORT TextureManager { // Returns GL_NO_ERROR on success. Otherwise the error to generate. // TODO(gman): Expand to SetParameteri,f,iv,fv void SetParameter( - const char* function_name, GLES2Decoder* decoder, + const char* function_name, ErrorState* error_state, Texture* texture, GLenum pname, GLint param); // Makes each of the mip levels as though they were generated. diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 2e062a4..bef870b 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -5,6 +5,7 @@ #include "gpu/command_buffer/service/texture_manager.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/memory_tracking.h" @@ -63,7 +64,7 @@ class TextureManagerTest : public testing::Test { kMaxTextureSize, kMaxCubeMapTextureSize)); TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); manager_->Initialize(); - decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); + error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); } virtual void TearDown() { @@ -76,7 +77,7 @@ class TextureManagerTest : public testing::Test { void SetParameter( Texture* texture, GLenum pname, GLint value, GLenum error) { TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), manager_.get(), + gl_.get(), error_state_.get(), manager_.get(), texture, pname, value, error); } @@ -84,7 +85,7 @@ class TextureManagerTest : public testing::Test { scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<TextureManager> manager_; - scoped_ptr<MockGLES2Decoder> decoder_; + scoped_ptr<MockErrorState> error_state_; }; // GCC requires these declarations, but MSVC requires they not be present @@ -172,7 +173,7 @@ TEST_F(TextureManagerTest, TextureUsageExt) { Texture* texture = manager.GetTexture(kClient1Id); ASSERT_TRUE(texture != NULL); TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &manager, texture, + gl_.get(), error_state_.get(), &manager, texture, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE,GL_NO_ERROR); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_ATTACHMENT_ANGLE), texture->usage()); @@ -382,6 +383,7 @@ class TextureTestBase : public testing::Test { memory_tracker, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize)); decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); + error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); manager_->CreateTexture(kClient1Id, kService1Id); texture_ = manager_->GetTexture(kClient1Id); ASSERT_TRUE(texture_.get() != NULL); @@ -410,15 +412,16 @@ class TextureTestBase : public testing::Test { void SetParameter( Texture* texture, GLenum pname, GLint value, GLenum error) { TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), manager_.get(), + gl_.get(), error_state_.get(), manager_.get(), texture, pname, value, error); } + scoped_ptr<MockGLES2Decoder> decoder_; + scoped_ptr<MockErrorState> error_state_; // Use StrictMock to make 100% sure we know how GL will be called. scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; scoped_refptr<FeatureInfo> feature_info_; scoped_ptr<TextureManager> manager_; - scoped_ptr<MockGLES2Decoder> decoder_; scoped_refptr<Texture> texture_; }; @@ -852,11 +855,11 @@ TEST_F(TextureTest, FloatNotLinear) { GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT, true); EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &manager, + gl_.get(), error_state_.get(), &manager, texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &manager, + gl_.get(), error_state_.get(), &manager, texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); manager.Destroy(false); @@ -896,11 +899,11 @@ TEST_F(TextureTest, HalfFloatNotLinear) { GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES, true); EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &manager, + gl_.get(), error_state_.get(), &manager, texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); TestHelper::SetTexParameterWithExpectations( - gl_.get(), decoder_.get(), &manager, + gl_.get(), error_state_.get(), &manager, texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); manager.Destroy(false); @@ -1293,6 +1296,9 @@ class SaveRestoreTextureTest : public TextureTest { TextureTest::SetUpBase(NULL, "GL_OES_EGL_image_external"); manager_->CreateTexture(kClient2Id, kService2Id); texture2_ = manager_->GetTexture(kClient2Id); + + EXPECT_CALL(*decoder_.get(), GetErrorState()) + .WillRepeatedly(Return(error_state_.get())); } virtual void TearDown() { diff --git a/gpu/command_buffer/service/vertex_attrib_manager.cc b/gpu/command_buffer/service/vertex_attrib_manager.cc index 9bba30d..e1ae1c0 100644 --- a/gpu/command_buffer/service/vertex_attrib_manager.cc +++ b/gpu/command_buffer/service/vertex_attrib_manager.cc @@ -15,6 +15,7 @@ #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/error_state.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" @@ -166,6 +167,7 @@ bool VertexAttribManager::ValidateBindings( Program* current_program, GLuint max_vertex_accessed, GLsizei primcount) { + ErrorState* error_state = decoder->GetErrorState(); // true if any enabled, used divisor is zero bool divisor0 = false; const GLuint kInitialBufferId = 0xFFFFFFFFU; @@ -186,8 +188,8 @@ bool VertexAttribManager::ValidateBindings( GLuint count = attrib->MaxVertexAccessed(primcount, max_vertex_accessed); // This attrib is used in the current program. if (!attrib->CanAccess(count)) { - GLESDECODER_SET_GL_ERROR( - decoder, GL_INVALID_OPERATION, function_name, + ERRORSTATE_SET_GL_ERROR( + error_state, GL_INVALID_OPERATION, function_name, (std::string( "attempt to access out of range vertices in attribute ") + base::IntToString(attrib->index())).c_str()); @@ -231,8 +233,8 @@ bool VertexAttribManager::ValidateBindings( } else { // This attrib is not used in the current program. if (!attrib->buffer()) { - GLESDECODER_SET_GL_ERROR( - decoder, GL_INVALID_OPERATION, function_name, + ERRORSTATE_SET_GL_ERROR( + error_state, GL_INVALID_OPERATION, function_name, (std::string( "attempt to render with no buffer attached to " "enabled attribute ") + @@ -253,8 +255,8 @@ bool VertexAttribManager::ValidateBindings( } if (primcount && !divisor0) { - GLESDECODER_SET_GL_ERROR( - decoder, GL_INVALID_OPERATION, function_name, + ERRORSTATE_SET_GL_ERROR( + error_state, GL_INVALID_OPERATION, function_name, "attempt instanced render with all attributes having " "non-zero divisors"); return false; diff --git a/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc b/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc index e8eb6a4..28a051c 100644 --- a/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc +++ b/gpu/command_buffer/service/vertex_attrib_manager_unittest.cc @@ -6,8 +6,8 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/buffer_manager.h" +#include "gpu/command_buffer/service/error_state_mock.h" #include "gpu/command_buffer/service/feature_info.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" @@ -142,7 +142,7 @@ TEST_F(VertexAttribManagerTest, HaveFixedAttribs) { } TEST_F(VertexAttribManagerTest, CanAccess) { - MockGLES2Decoder decoder; + MockErrorState error_state; BufferManager buffer_manager(NULL, NULL); buffer_manager.CreateBuffer(1, 2); Buffer* buffer = buffer_manager.GetBuffer(1); @@ -159,13 +159,13 @@ TEST_F(VertexAttribManagerTest, CanAccess) { EXPECT_TRUE(buffer_manager.SetTarget(buffer, GL_ARRAY_BUFFER)); TestHelper::DoBufferData( - gl_.get(), &decoder, &buffer_manager, buffer, 15, GL_STATIC_DRAW, NULL, - GL_NO_ERROR); + gl_.get(), &error_state, &buffer_manager, buffer, 15, GL_STATIC_DRAW, + NULL, GL_NO_ERROR); EXPECT_FALSE(attrib->CanAccess(0)); TestHelper::DoBufferData( - gl_.get(), &decoder, &buffer_manager, buffer, 16, GL_STATIC_DRAW, NULL, - GL_NO_ERROR); + gl_.get(), &error_state, &buffer_manager, buffer, 16, GL_STATIC_DRAW, + NULL, GL_NO_ERROR); EXPECT_TRUE(attrib->CanAccess(0)); EXPECT_FALSE(attrib->CanAccess(1)); @@ -173,8 +173,8 @@ TEST_F(VertexAttribManagerTest, CanAccess) { EXPECT_FALSE(attrib->CanAccess(0)); TestHelper::DoBufferData( - gl_.get(), &decoder, &buffer_manager, buffer, 32, GL_STATIC_DRAW, NULL, - GL_NO_ERROR); + gl_.get(), &error_state, &buffer_manager, buffer, 32, GL_STATIC_DRAW, + NULL, GL_NO_ERROR); EXPECT_TRUE(attrib->CanAccess(0)); EXPECT_FALSE(attrib->CanAccess(1)); manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index b0327ef..1f43017 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -40,6 +40,8 @@ 'command_buffer/service/context_state_autogen.h', 'command_buffer/service/context_state_impl_autogen.h', 'command_buffer/service/context_state.cc', + 'command_buffer/service/error_state.cc', + 'command_buffer/service/error_state.h', 'command_buffer/service/feature_info.h', 'command_buffer/service/feature_info.cc', 'command_buffer/service/framebuffer_manager.h', diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index aa4f1f9..540d51a 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -289,7 +289,7 @@ ], 'sources': [ 'command_buffer/service/gles2_cmd_decoder_mock.cc', - 'command_buffer/service/gles2_cmd_decoder_mock.cc', + 'command_buffer/service/error_state_mock.cc', ], }, ], |