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. 4 5 #include "gpu/command_buffer/service/error_state.h" 6 7 #include <string> 8 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" 13 14 namespace gpu { 15 namespace gles2 { 16 17 class ErrorStateImpl : public ErrorState { 18 public: 19 explicit ErrorStateImpl(Logger* logger); 20 virtual ~ErrorStateImpl(); 21 22 virtual uint32 GetGLError() OVERRIDE; 23 24 virtual void SetGLError( 25 const char* filename, 26 int line, 27 unsigned int error, 28 const char* function_name, 29 const char* msg) OVERRIDE; 30 virtual void SetGLErrorInvalidEnum( 31 const char* filename, 32 int line, 33 const char* function_name, 34 unsigned int value, 35 const char* label) OVERRIDE; 36 virtual void SetGLErrorInvalidParam( 37 const char* filename, 38 int line, 39 unsigned int error, 40 const char* function_name, 41 unsigned int pname, 42 int param) OVERRIDE; 43 44 virtual unsigned int PeekGLError( 45 const char* filename, int line, const char* function_name) OVERRIDE; 46 47 virtual void CopyRealGLErrorsToWrapper( 48 const char* filename, int line, const char* function_name) OVERRIDE; 49 50 virtual void ClearRealGLErrors( 51 const char* filename, int line, const char* function_name) OVERRIDE; 52 53 private: 54 // The last error message set. 55 std::string last_error_; 56 // Current GL error bits. 57 uint32 error_bits_; 58 59 Logger* logger_; 60 61 DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl); 62 }; 63 64 ErrorState::ErrorState() {} 65 66 ErrorState::~ErrorState() {} 67 68 ErrorState* ErrorState::Create(Logger* logger) { 69 return new ErrorStateImpl(logger); 70 } 71 72 ErrorStateImpl::ErrorStateImpl(Logger* logger) 73 : error_bits_(0), 74 logger_(logger) {} 75 76 ErrorStateImpl::~ErrorStateImpl() {} 77 78 uint32 ErrorStateImpl::GetGLError() { 79 // Check the GL error first, then our wrapped error. 80 GLenum error = glGetError(); 81 if (error == GL_NO_ERROR && error_bits_ != 0) { 82 for (uint32 mask = 1; mask != 0; mask = mask << 1) { 83 if ((error_bits_ & mask) != 0) { 84 error = GLES2Util::GLErrorBitToGLError(mask); 85 break; 86 } 87 } 88 } 89 90 if (error != GL_NO_ERROR) { 91 // There was an error, clear the corresponding wrapped error. 92 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error); 93 } 94 return error; 95 } 96 97 unsigned int ErrorStateImpl::PeekGLError( 98 const char* filename, int line, const char* function_name) { 99 GLenum error = glGetError(); 100 if (error != GL_NO_ERROR) { 101 SetGLError(filename, line, error, function_name, ""); 102 } 103 return error; 104 } 105 106 void ErrorStateImpl::SetGLError( 107 const char* filename, 108 int line, 109 unsigned int error, 110 const char* function_name, 111 const char* msg) { 112 if (msg) { 113 last_error_ = msg; 114 logger_->LogMessage( 115 filename, line, 116 std::string("GL ERROR :") + 117 GLES2Util::GetStringEnum(error) + " : " + 118 function_name + ": " + msg); 119 } 120 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); 121 } 122 123 void ErrorStateImpl::SetGLErrorInvalidEnum( 124 const char* filename, 125 int line, 126 const char* function_name, 127 unsigned int value, 128 const char* label) { 129 SetGLError(filename, line, GL_INVALID_ENUM, function_name, 130 (std::string(label) + " was " + 131 GLES2Util::GetStringEnum(value)).c_str()); 132 } 133 134 void ErrorStateImpl::SetGLErrorInvalidParam( 135 const char* filename, 136 int line, 137 unsigned int error, 138 const char* function_name, 139 unsigned int pname, int param) { 140 if (error == GL_INVALID_ENUM) { 141 SetGLError( 142 filename, line, GL_INVALID_ENUM, function_name, 143 (std::string("trying to set ") + 144 GLES2Util::GetStringEnum(pname) + " to " + 145 GLES2Util::GetStringEnum(param)).c_str()); 146 } else { 147 SetGLError( 148 filename, line, error, function_name, 149 (std::string("trying to set ") + 150 GLES2Util::GetStringEnum(pname) + " to " + 151 base::StringPrintf("%d", param)).c_str()); 152 } 153 } 154 155 void ErrorStateImpl::CopyRealGLErrorsToWrapper( 156 const char* filename, int line, const char* function_name) { 157 GLenum error; 158 while ((error = glGetError()) != GL_NO_ERROR) { 159 SetGLError(filename, line, error, function_name, 160 "<- error from previous GL command"); 161 } 162 } 163 164 void ErrorStateImpl::ClearRealGLErrors( 165 const char* filename, int line, const char* function_name) { 166 // Clears and logs all current gl errors. 167 GLenum error; 168 while ((error = glGetError()) != GL_NO_ERROR) { 169 if (error != GL_OUT_OF_MEMORY) { 170 // GL_OUT_OF_MEMORY can legally happen on lost device. 171 logger_->LogMessage( 172 filename, line, 173 std::string("GL ERROR :") + 174 GLES2Util::GetStringEnum(error) + " : " + 175 function_name + ": was unhandled"); 176 NOTREACHED() << "GL error " << error << " was unhandled."; 177 } 178 } 179 } 180 181 } // namespace gles2 182 } // namespace gpu 183 184