Update To 11.40.268.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   ~ErrorStateImpl() override;
21
22   uint32 GetGLError() override;
23
24   void SetGLError(const char* filename,
25                   int line,
26                   unsigned int error,
27                   const char* function_name,
28                   const char* msg) override;
29   void SetGLErrorInvalidEnum(const char* filename,
30                              int line,
31                              const char* function_name,
32                              unsigned int value,
33                              const char* label) override;
34   void SetGLErrorInvalidParami(const char* filename,
35                                int line,
36                                unsigned int error,
37                                const char* function_name,
38                                unsigned int pname,
39                                int param) override;
40   void SetGLErrorInvalidParamf(const char* filename,
41                                int line,
42                                unsigned int error,
43                                const char* function_name,
44                                unsigned int pname,
45                                float param) override;
46
47   unsigned int PeekGLError(const char* filename,
48                            int line,
49                            const char* function_name) override;
50
51   void CopyRealGLErrorsToWrapper(const char* filename,
52                                  int line,
53                                  const char* function_name) override;
54
55   void ClearRealGLErrors(const char* filename,
56                          int line,
57                          const char* function_name) override;
58
59  private:
60   GLenum GetErrorHandleContextLoss();
61
62   // The last error message set.
63   std::string last_error_;
64   // Current GL error bits.
65   uint32 error_bits_;
66
67   ErrorStateClient* client_;
68   Logger* logger_;
69
70   DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl);
71 };
72
73 ErrorState::ErrorState() {}
74
75 ErrorState::~ErrorState() {}
76
77 ErrorState* ErrorState::Create(ErrorStateClient* client, Logger* logger) {
78   return new ErrorStateImpl(client, logger);
79 }
80
81 ErrorStateImpl::ErrorStateImpl(ErrorStateClient* client, Logger* logger)
82     : error_bits_(0), client_(client), logger_(logger) {}
83
84 ErrorStateImpl::~ErrorStateImpl() {}
85
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);
93         break;
94       }
95     }
96   }
97
98   if (error != GL_NO_ERROR) {
99     // There was an error, clear the corresponding wrapped error.
100     error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
101   }
102   return error;
103 }
104
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
111     // buffer.
112     error = GL_NO_ERROR;
113   }
114   return error;
115 }
116
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, "");
122   }
123   return error;
124 }
125
126 void ErrorStateImpl::SetGLError(
127     const char* filename,
128     int line,
129     unsigned int error,
130     const char* function_name,
131     const char* msg) {
132   if (msg) {
133     last_error_ = msg;
134     logger_->LogMessage(
135         filename, line,
136         std::string("GL ERROR :") +
137         GLES2Util::GetStringEnum(error) + " : " +
138         function_name + ": " + msg);
139   }
140   error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
141   if (error == GL_OUT_OF_MEMORY)
142     client_->OnOutOfMemoryError();
143 }
144
145 void ErrorStateImpl::SetGLErrorInvalidEnum(
146     const char* filename,
147     int line,
148     const char* function_name,
149     unsigned int value,
150     const char* label) {
151   SetGLError(filename, line, GL_INVALID_ENUM, function_name,
152              (std::string(label) + " was " +
153              GLES2Util::GetStringEnum(value)).c_str());
154 }
155
156 void ErrorStateImpl::SetGLErrorInvalidParami(
157     const char* filename,
158     int line,
159     unsigned int error,
160     const char* function_name,
161     unsigned int pname, int param) {
162   if (error == GL_INVALID_ENUM) {
163     SetGLError(
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());
168   } else {
169     SetGLError(
170         filename, line, error, function_name,
171         (std::string("trying to set ") +
172          GLES2Util::GetStringEnum(pname) + " to " +
173          base::StringPrintf("%d", param)).c_str());
174   }
175 }
176
177 void ErrorStateImpl::SetGLErrorInvalidParamf(
178     const char* filename,
179     int line,
180     unsigned int error,
181     const char* function_name,
182     unsigned int pname, float param) {
183   SetGLError(
184       filename, line, error, function_name,
185       (std::string("trying to set ") +
186        GLES2Util::GetStringEnum(pname) + " to " +
187        base::StringPrintf("%G", param)).c_str());
188 }
189
190 void ErrorStateImpl::CopyRealGLErrorsToWrapper(
191     const char* filename, int line, const char* function_name) {
192   GLenum error;
193   while ((error = GetErrorHandleContextLoss()) != GL_NO_ERROR) {
194     SetGLError(filename, line, error, function_name,
195                "<- error from previous GL command");
196   }
197 }
198
199 void ErrorStateImpl::ClearRealGLErrors(
200     const char* filename, int line, const char* function_name) {
201   // Clears and logs all current gl errors.
202   GLenum error;
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.
206       logger_->LogMessage(
207           filename, line,
208           std::string("GL ERROR :") +
209           GLES2Util::GetStringEnum(error) + " : " +
210           function_name + ": was unhandled");
211       NOTREACHED() << "GL error " << error << " was unhandled.";
212     }
213   }
214 }
215
216 }  // namespace gles2
217 }  // namespace gpu
218