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/string_number_conversions.h"
10 #include "base/strings/stringprintf.h"
11 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
12 #include "gpu/command_buffer/service/logger.h"
13 #include "ui/gl/gl_bindings.h"
18 class ErrorStateImpl
: public ErrorState
{
20 explicit ErrorStateImpl(ErrorStateClient
* client
, Logger
* logger
);
21 ~ErrorStateImpl() override
;
23 uint32
GetGLError() override
;
25 void SetGLError(const char* filename
,
28 const char* function_name
,
29 const char* msg
) override
;
30 void SetGLErrorInvalidEnum(const char* filename
,
32 const char* function_name
,
34 const char* label
) override
;
35 void SetGLErrorInvalidParami(const char* filename
,
38 const char* function_name
,
41 void SetGLErrorInvalidParamf(const char* filename
,
44 const char* function_name
,
46 float param
) override
;
48 unsigned int PeekGLError(const char* filename
,
50 const char* function_name
) override
;
52 void CopyRealGLErrorsToWrapper(const char* filename
,
54 const char* function_name
) override
;
56 void ClearRealGLErrors(const char* filename
,
58 const char* function_name
) override
;
61 GLenum
GetErrorHandleContextLoss();
63 // The last error message set.
64 std::string last_error_
;
65 // Current GL error bits.
68 ErrorStateClient
* client_
;
71 DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl
);
74 ErrorState::ErrorState() {}
76 ErrorState::~ErrorState() {}
78 ErrorState
* ErrorState::Create(ErrorStateClient
* client
, Logger
* logger
) {
79 return new ErrorStateImpl(client
, logger
);
82 ErrorStateImpl::ErrorStateImpl(ErrorStateClient
* client
, Logger
* logger
)
83 : error_bits_(0), client_(client
), logger_(logger
) {}
85 ErrorStateImpl::~ErrorStateImpl() {}
87 uint32
ErrorStateImpl::GetGLError() {
88 // Check the GL error first, then our wrapped error.
89 GLenum error
= GetErrorHandleContextLoss();
90 if (error
== GL_NO_ERROR
&& error_bits_
!= 0) {
91 for (uint32 mask
= 1; mask
!= 0; mask
= mask
<< 1) {
92 if ((error_bits_
& mask
) != 0) {
93 error
= GLES2Util::GLErrorBitToGLError(mask
);
99 if (error
!= GL_NO_ERROR
) {
100 // There was an error, clear the corresponding wrapped error.
101 error_bits_
&= ~GLES2Util::GLErrorToErrorBit(error
);
106 GLenum
ErrorStateImpl::GetErrorHandleContextLoss() {
107 GLenum error
= glGetError();
108 if (error
== GL_CONTEXT_LOST_KHR
) {
109 client_
->OnContextLostError();
110 // Do not expose GL_CONTEXT_LOST_KHR, as the version of the robustness
111 // extension that introduces the error is not exposed by the command
118 unsigned int ErrorStateImpl::PeekGLError(
119 const char* filename
, int line
, const char* function_name
) {
120 GLenum error
= GetErrorHandleContextLoss();
121 if (error
!= GL_NO_ERROR
) {
122 SetGLError(filename
, line
, error
, function_name
, "");
127 void ErrorStateImpl::SetGLError(
128 const char* filename
,
131 const char* function_name
,
137 std::string("GL ERROR :") +
138 GLES2Util::GetStringEnum(error
) + " : " +
139 function_name
+ ": " + msg
);
141 error_bits_
|= GLES2Util::GLErrorToErrorBit(error
);
142 if (error
== GL_OUT_OF_MEMORY
)
143 client_
->OnOutOfMemoryError();
146 void ErrorStateImpl::SetGLErrorInvalidEnum(
147 const char* filename
,
149 const char* function_name
,
152 SetGLError(filename
, line
, GL_INVALID_ENUM
, function_name
,
153 (std::string(label
) + " was " +
154 GLES2Util::GetStringEnum(value
)).c_str());
157 void ErrorStateImpl::SetGLErrorInvalidParami(
158 const char* filename
,
161 const char* function_name
,
162 unsigned int pname
, int param
) {
163 if (error
== GL_INVALID_ENUM
) {
165 filename
, line
, GL_INVALID_ENUM
, function_name
,
166 (std::string("trying to set ") +
167 GLES2Util::GetStringEnum(pname
) + " to " +
168 GLES2Util::GetStringEnum(param
)).c_str());
171 filename
, line
, error
, function_name
,
172 (std::string("trying to set ") +
173 GLES2Util::GetStringEnum(pname
) + " to " +
174 base::IntToString(param
)).c_str());
178 void ErrorStateImpl::SetGLErrorInvalidParamf(
179 const char* filename
,
182 const char* function_name
,
183 unsigned int pname
, float param
) {
185 filename
, line
, error
, function_name
,
186 (std::string("trying to set ") +
187 GLES2Util::GetStringEnum(pname
) + " to " +
188 base::StringPrintf("%G", param
)).c_str());
191 void ErrorStateImpl::CopyRealGLErrorsToWrapper(
192 const char* filename
, int line
, const char* function_name
) {
194 while ((error
= GetErrorHandleContextLoss()) != GL_NO_ERROR
) {
195 SetGLError(filename
, line
, error
, function_name
,
196 "<- error from previous GL command");
200 void ErrorStateImpl::ClearRealGLErrors(
201 const char* filename
, int line
, const char* function_name
) {
202 // Clears and logs all current gl errors.
204 while ((error
= glGetError()) != GL_NO_ERROR
) {
205 if (error
!= GL_CONTEXT_LOST_KHR
&& error
!= GL_OUT_OF_MEMORY
) {
206 // GL_OUT_OF_MEMORY can legally happen on lost device.
209 std::string("GL ERROR :") +
210 GLES2Util::GetStringEnum(error
) + " : " +
211 function_name
+ ": was unhandled");
212 NOTREACHED() << "GL error " << error
<< " was unhandled.";