Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / error_state.cc
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(ErrorStateClient* client, 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 SetGLErrorInvalidParami(
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   virtual void SetGLErrorInvalidParamf(
44       const char* filename,
45       int line,
46       unsigned int error,
47       const char* function_name,
48       unsigned int pname,
49       float param) OVERRIDE;
50
51   virtual unsigned int PeekGLError(
52       const char* filename, int line, const char* function_name) OVERRIDE;
53
54   virtual void CopyRealGLErrorsToWrapper(
55       const char* filename, int line, const char* function_name) OVERRIDE;
56
57   virtual void ClearRealGLErrors(
58       const char* filename, int line, const char* function_name) OVERRIDE;
59
60  private:
61   // The last error message set.
62   std::string last_error_;
63   // Current GL error bits.
64   uint32 error_bits_;
65
66   ErrorStateClient* client_;
67   Logger* logger_;
68
69   DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl);
70 };
71
72 ErrorState::ErrorState() {}
73
74 ErrorState::~ErrorState() {}
75
76 ErrorState* ErrorState::Create(ErrorStateClient* client, Logger* logger) {
77   return new ErrorStateImpl(client, logger);
78 }
79
80 ErrorStateImpl::ErrorStateImpl(ErrorStateClient* client, Logger* logger)
81     : error_bits_(0), client_(client), logger_(logger) {}
82
83 ErrorStateImpl::~ErrorStateImpl() {}
84
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);
92         break;
93       }
94     }
95   }
96
97   if (error != GL_NO_ERROR) {
98     // There was an error, clear the corresponding wrapped error.
99     error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
100   }
101   return error;
102 }
103
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, "");
109   }
110   return error;
111 }
112
113 void ErrorStateImpl::SetGLError(
114     const char* filename,
115     int line,
116     unsigned int error,
117     const char* function_name,
118     const char* msg) {
119   if (msg) {
120     last_error_ = msg;
121     logger_->LogMessage(
122         filename, line,
123         std::string("GL ERROR :") +
124         GLES2Util::GetStringEnum(error) + " : " +
125         function_name + ": " + msg);
126   }
127   error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
128   if (error == GL_OUT_OF_MEMORY)
129     client_->OnOutOfMemoryError();
130 }
131
132 void ErrorStateImpl::SetGLErrorInvalidEnum(
133     const char* filename,
134     int line,
135     const char* function_name,
136     unsigned int value,
137     const char* label) {
138   SetGLError(filename, line, GL_INVALID_ENUM, function_name,
139              (std::string(label) + " was " +
140              GLES2Util::GetStringEnum(value)).c_str());
141 }
142
143 void ErrorStateImpl::SetGLErrorInvalidParami(
144     const char* filename,
145     int line,
146     unsigned int error,
147     const char* function_name,
148     unsigned int pname, int param) {
149   if (error == GL_INVALID_ENUM) {
150     SetGLError(
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());
155   } else {
156     SetGLError(
157         filename, line, error, function_name,
158         (std::string("trying to set ") +
159          GLES2Util::GetStringEnum(pname) + " to " +
160          base::StringPrintf("%d", param)).c_str());
161   }
162 }
163
164 void ErrorStateImpl::SetGLErrorInvalidParamf(
165     const char* filename,
166     int line,
167     unsigned int error,
168     const char* function_name,
169     unsigned int pname, float param) {
170   SetGLError(
171       filename, line, error, function_name,
172       (std::string("trying to set ") +
173        GLES2Util::GetStringEnum(pname) + " to " +
174        base::StringPrintf("%G", param)).c_str());
175 }
176
177 void ErrorStateImpl::CopyRealGLErrorsToWrapper(
178     const char* filename, int line, const char* function_name) {
179   GLenum error;
180   while ((error = glGetError()) != GL_NO_ERROR) {
181     SetGLError(filename, line, error, function_name,
182                "<- error from previous GL command");
183   }
184 }
185
186 void ErrorStateImpl::ClearRealGLErrors(
187     const char* filename, int line, const char* function_name) {
188   // Clears and logs all current gl errors.
189   GLenum error;
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.
193       logger_->LogMessage(
194           filename, line,
195           std::string("GL ERROR :") +
196           GLES2Util::GetStringEnum(error) + " : " +
197           function_name + ": was unhandled");
198       NOTREACHED() << "GL error " << error << " was unhandled.";
199     }
200   }
201 }
202
203 }  // namespace gles2
204 }  // namespace gpu
205