1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/error_state.h"
9 #include "base/strings/stringprintf.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 #include "gpu/command_buffer/service/logger.h"
12 #include "ui/gl/gl_bindings.h"
17 class ErrorStateImpl
: public ErrorState
{
19 explicit ErrorStateImpl(ErrorStateClient
* client
, Logger
* logger
);
20 virtual ~ErrorStateImpl();
22 virtual uint32
GetGLError() OVERRIDE
;
24 virtual void SetGLError(
28 const char* function_name
,
29 const char* msg
) OVERRIDE
;
30 virtual void SetGLErrorInvalidEnum(
33 const char* function_name
,
35 const char* label
) OVERRIDE
;
36 virtual void SetGLErrorInvalidParami(
40 const char* function_name
,
43 virtual void SetGLErrorInvalidParamf(
47 const char* function_name
,
49 float param
) OVERRIDE
;
51 virtual unsigned int PeekGLError(
52 const char* filename
, int line
, const char* function_name
) OVERRIDE
;
54 virtual void CopyRealGLErrorsToWrapper(
55 const char* filename
, int line
, const char* function_name
) OVERRIDE
;
57 virtual void ClearRealGLErrors(
58 const char* filename
, int line
, const char* function_name
) OVERRIDE
;
61 // The last error message set.
62 std::string last_error_
;
63 // Current GL error bits.
66 ErrorStateClient
* client_
;
69 DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl
);
72 ErrorState::ErrorState() {}
74 ErrorState::~ErrorState() {}
76 ErrorState
* ErrorState::Create(ErrorStateClient
* client
, Logger
* logger
) {
77 return new ErrorStateImpl(client
, logger
);
80 ErrorStateImpl::ErrorStateImpl(ErrorStateClient
* client
, Logger
* logger
)
81 : error_bits_(0), client_(client
), logger_(logger
) {}
83 ErrorStateImpl::~ErrorStateImpl() {}
85 uint32
ErrorStateImpl::GetGLError() {
86 // Check the GL error first, then our wrapped error.
87 GLenum error
= glGetError();
88 if (error
== GL_NO_ERROR
&& error_bits_
!= 0) {
89 for (uint32 mask
= 1; mask
!= 0; mask
= mask
<< 1) {
90 if ((error_bits_
& mask
) != 0) {
91 error
= GLES2Util::GLErrorBitToGLError(mask
);
97 if (error
!= GL_NO_ERROR
) {
98 // There was an error, clear the corresponding wrapped error.
99 error_bits_
&= ~GLES2Util::GLErrorToErrorBit(error
);
104 unsigned int ErrorStateImpl::PeekGLError(
105 const char* filename
, int line
, const char* function_name
) {
106 GLenum error
= glGetError();
107 if (error
!= GL_NO_ERROR
) {
108 SetGLError(filename
, line
, error
, function_name
, "");
113 void ErrorStateImpl::SetGLError(
114 const char* filename
,
117 const char* function_name
,
123 std::string("GL ERROR :") +
124 GLES2Util::GetStringEnum(error
) + " : " +
125 function_name
+ ": " + msg
);
127 error_bits_
|= GLES2Util::GLErrorToErrorBit(error
);
128 if (error
== GL_OUT_OF_MEMORY
)
129 client_
->OnOutOfMemoryError();
132 void ErrorStateImpl::SetGLErrorInvalidEnum(
133 const char* filename
,
135 const char* function_name
,
138 SetGLError(filename
, line
, GL_INVALID_ENUM
, function_name
,
139 (std::string(label
) + " was " +
140 GLES2Util::GetStringEnum(value
)).c_str());
143 void ErrorStateImpl::SetGLErrorInvalidParami(
144 const char* filename
,
147 const char* function_name
,
148 unsigned int pname
, int param
) {
149 if (error
== GL_INVALID_ENUM
) {
151 filename
, line
, GL_INVALID_ENUM
, function_name
,
152 (std::string("trying to set ") +
153 GLES2Util::GetStringEnum(pname
) + " to " +
154 GLES2Util::GetStringEnum(param
)).c_str());
157 filename
, line
, error
, function_name
,
158 (std::string("trying to set ") +
159 GLES2Util::GetStringEnum(pname
) + " to " +
160 base::StringPrintf("%d", param
)).c_str());
164 void ErrorStateImpl::SetGLErrorInvalidParamf(
165 const char* filename
,
168 const char* function_name
,
169 unsigned int pname
, float param
) {
171 filename
, line
, error
, function_name
,
172 (std::string("trying to set ") +
173 GLES2Util::GetStringEnum(pname
) + " to " +
174 base::StringPrintf("%G", param
)).c_str());
177 void ErrorStateImpl::CopyRealGLErrorsToWrapper(
178 const char* filename
, int line
, const char* function_name
) {
180 while ((error
= glGetError()) != GL_NO_ERROR
) {
181 SetGLError(filename
, line
, error
, function_name
,
182 "<- error from previous GL command");
186 void ErrorStateImpl::ClearRealGLErrors(
187 const char* filename
, int line
, const char* function_name
) {
188 // Clears and logs all current gl errors.
190 while ((error
= glGetError()) != GL_NO_ERROR
) {
191 if (error
!= GL_OUT_OF_MEMORY
) {
192 // GL_OUT_OF_MEMORY can legally happen on lost device.
195 std::string("GL ERROR :") +
196 GLES2Util::GetStringEnum(error
) + " : " +
197 function_name
+ ": was unhandled");
198 NOTREACHED() << "GL error " << error
<< " was unhandled.";