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 ~ErrorStateImpl() override
;
22 uint32
GetGLError() override
;
24 void SetGLError(const char* filename
,
27 const char* function_name
,
28 const char* msg
) override
;
29 void SetGLErrorInvalidEnum(const char* filename
,
31 const char* function_name
,
33 const char* label
) override
;
34 void SetGLErrorInvalidParami(const char* filename
,
37 const char* function_name
,
40 void SetGLErrorInvalidParamf(const char* filename
,
43 const char* function_name
,
45 float param
) override
;
47 unsigned int PeekGLError(const char* filename
,
49 const char* function_name
) override
;
51 void CopyRealGLErrorsToWrapper(const char* filename
,
53 const char* function_name
) override
;
55 void ClearRealGLErrors(const char* filename
,
57 const char* function_name
) override
;
60 GLenum
GetErrorHandleContextLoss();
62 // The last error message set.
63 std::string last_error_
;
64 // Current GL error bits.
67 ErrorStateClient
* client_
;
70 DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl
);
73 ErrorState::ErrorState() {}
75 ErrorState::~ErrorState() {}
77 ErrorState
* ErrorState::Create(ErrorStateClient
* client
, Logger
* logger
) {
78 return new ErrorStateImpl(client
, logger
);
81 ErrorStateImpl::ErrorStateImpl(ErrorStateClient
* client
, Logger
* logger
)
82 : error_bits_(0), client_(client
), logger_(logger
) {}
84 ErrorStateImpl::~ErrorStateImpl() {}
86 uint32
ErrorStateImpl::GetGLError() {
87 // Check the GL error first, then our wrapped error.
88 GLenum error
= GetErrorHandleContextLoss();
89 if (error
== GL_NO_ERROR
&& error_bits_
!= 0) {
90 for (uint32 mask
= 1; mask
!= 0; mask
= mask
<< 1) {
91 if ((error_bits_
& mask
) != 0) {
92 error
= GLES2Util::GLErrorBitToGLError(mask
);
98 if (error
!= GL_NO_ERROR
) {
99 // There was an error, clear the corresponding wrapped error.
100 error_bits_
&= ~GLES2Util::GLErrorToErrorBit(error
);
105 GLenum
ErrorStateImpl::GetErrorHandleContextLoss() {
106 GLenum error
= glGetError();
107 if (error
== GL_CONTEXT_LOST_KHR
) {
108 client_
->OnContextLostError();
109 // Do not expose GL_CONTEXT_LOST_KHR, as the version of the robustness
110 // extension that introduces the error is not exposed by the command
117 unsigned int ErrorStateImpl::PeekGLError(
118 const char* filename
, int line
, const char* function_name
) {
119 GLenum error
= GetErrorHandleContextLoss();
120 if (error
!= GL_NO_ERROR
) {
121 SetGLError(filename
, line
, error
, function_name
, "");
126 void ErrorStateImpl::SetGLError(
127 const char* filename
,
130 const char* function_name
,
136 std::string("GL ERROR :") +
137 GLES2Util::GetStringEnum(error
) + " : " +
138 function_name
+ ": " + msg
);
140 error_bits_
|= GLES2Util::GLErrorToErrorBit(error
);
141 if (error
== GL_OUT_OF_MEMORY
)
142 client_
->OnOutOfMemoryError();
145 void ErrorStateImpl::SetGLErrorInvalidEnum(
146 const char* filename
,
148 const char* function_name
,
151 SetGLError(filename
, line
, GL_INVALID_ENUM
, function_name
,
152 (std::string(label
) + " was " +
153 GLES2Util::GetStringEnum(value
)).c_str());
156 void ErrorStateImpl::SetGLErrorInvalidParami(
157 const char* filename
,
160 const char* function_name
,
161 unsigned int pname
, int param
) {
162 if (error
== GL_INVALID_ENUM
) {
164 filename
, line
, GL_INVALID_ENUM
, function_name
,
165 (std::string("trying to set ") +
166 GLES2Util::GetStringEnum(pname
) + " to " +
167 GLES2Util::GetStringEnum(param
)).c_str());
170 filename
, line
, error
, function_name
,
171 (std::string("trying to set ") +
172 GLES2Util::GetStringEnum(pname
) + " to " +
173 base::StringPrintf("%d", param
)).c_str());
177 void ErrorStateImpl::SetGLErrorInvalidParamf(
178 const char* filename
,
181 const char* function_name
,
182 unsigned int pname
, float param
) {
184 filename
, line
, error
, function_name
,
185 (std::string("trying to set ") +
186 GLES2Util::GetStringEnum(pname
) + " to " +
187 base::StringPrintf("%G", param
)).c_str());
190 void ErrorStateImpl::CopyRealGLErrorsToWrapper(
191 const char* filename
, int line
, const char* function_name
) {
193 while ((error
= GetErrorHandleContextLoss()) != GL_NO_ERROR
) {
194 SetGLError(filename
, line
, error
, function_name
,
195 "<- error from previous GL command");
199 void ErrorStateImpl::ClearRealGLErrors(
200 const char* filename
, int line
, const char* function_name
) {
201 // Clears and logs all current gl errors.
203 while ((error
= glGetError()) != GL_NO_ERROR
) {
204 if (error
!= GL_CONTEXT_LOST_KHR
&& error
!= GL_OUT_OF_MEMORY
) {
205 // GL_OUT_OF_MEMORY can legally happen on lost device.
208 std::string("GL ERROR :") +
209 GLES2Util::GetStringEnum(error
) + " : " +
210 function_name
+ ": was unhandled");
211 NOTREACHED() << "GL error " << error
<< " was unhandled.";