1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/error_state.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/logger.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gl/gl_bindings.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace gpu {
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace gles2 {
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ErrorStateImpl : public ErrorState {
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  explicit ErrorStateImpl(ErrorStateClient* client, Logger* logger);
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~ErrorStateImpl();
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual uint32 GetGLError() OVERRIDE;
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetGLError(
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename,
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int line,
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      unsigned int error,
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* function_name,
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* msg) OVERRIDE;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetGLErrorInvalidEnum(
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename,
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int line,
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* function_name,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      unsigned int value,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* label) OVERRIDE;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetGLErrorInvalidParami(
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int line,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      unsigned int error,
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* function_name,
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      unsigned int pname,
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int param) OVERRIDE;
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void SetGLErrorInvalidParamf(
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const char* filename,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      int line,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unsigned int error,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const char* function_name,
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unsigned int pname,
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      float param) OVERRIDE;
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual unsigned int PeekGLError(
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename, int line, const char* function_name) OVERRIDE;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void CopyRealGLErrorsToWrapper(
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename, int line, const char* function_name) OVERRIDE;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ClearRealGLErrors(
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const char* filename, int line, const char* function_name) OVERRIDE;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The last error message set.
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string last_error_;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Current GL error bits.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 error_bits_;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  ErrorStateClient* client_;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Logger* logger_;
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ErrorStateImpl);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ErrorState::ErrorState() {}
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ErrorState::~ErrorState() {}
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochErrorState* ErrorState::Create(ErrorStateClient* client, Logger* logger) {
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return new ErrorStateImpl(client, logger);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochErrorStateImpl::ErrorStateImpl(ErrorStateClient* client, Logger* logger)
81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : error_bits_(0), client_(client), logger_(logger) {}
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ErrorStateImpl::~ErrorStateImpl() {}
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)uint32 ErrorStateImpl::GetGLError() {
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the GL error first, then our wrapped error.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GLenum error = glGetError();
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error == GL_NO_ERROR && error_bits_ != 0) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (uint32 mask = 1; mask != 0; mask = mask << 1) {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if ((error_bits_ & mask) != 0) {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        error = GLES2Util::GLErrorBitToGLError(mask);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != GL_NO_ERROR) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // There was an error, clear the corresponding wrapped error.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)unsigned int ErrorStateImpl::PeekGLError(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename, int line, const char* function_name) {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GLenum error = glGetError();
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != GL_NO_ERROR) {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetGLError(filename, line, error, function_name, "");
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ErrorStateImpl::SetGLError(
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int line,
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int error,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* function_name,
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* msg) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (msg) {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_error_ = msg;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    logger_->LogMessage(
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        filename, line,
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        std::string("GL ERROR :") +
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GLES2Util::GetStringEnum(error) + " : " +
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function_name + ": " + msg);
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (error == GL_OUT_OF_MEMORY)
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    client_->OnOutOfMemoryError();
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ErrorStateImpl::SetGLErrorInvalidEnum(
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename,
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int line,
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* function_name,
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int value,
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* label) {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetGLError(filename, line, GL_INVALID_ENUM, function_name,
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             (std::string(label) + " was " +
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             GLES2Util::GetStringEnum(value)).c_str());
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ErrorStateImpl::SetGLErrorInvalidParami(
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int line,
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int error,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* function_name,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int pname, int param) {
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error == GL_INVALID_ENUM) {
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetGLError(
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        filename, line, GL_INVALID_ENUM, function_name,
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (std::string("trying to set ") +
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         GLES2Util::GetStringEnum(pname) + " to " +
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         GLES2Util::GetStringEnum(param)).c_str());
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetGLError(
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        filename, line, error, function_name,
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (std::string("trying to set ") +
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         GLES2Util::GetStringEnum(pname) + " to " +
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         base::StringPrintf("%d", param)).c_str());
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ErrorStateImpl::SetGLErrorInvalidParamf(
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char* filename,
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int line,
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    unsigned int error,
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char* function_name,
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    unsigned int pname, float param) {
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetGLError(
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      filename, line, error, function_name,
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (std::string("trying to set ") +
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       GLES2Util::GetStringEnum(pname) + " to " +
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       base::StringPrintf("%G", param)).c_str());
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ErrorStateImpl::CopyRealGLErrorsToWrapper(
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename, int line, const char* function_name) {
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GLenum error;
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while ((error = glGetError()) != GL_NO_ERROR) {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetGLError(filename, line, error, function_name,
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               "<- error from previous GL command");
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ErrorStateImpl::ClearRealGLErrors(
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* filename, int line, const char* function_name) {
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clears and logs all current gl errors.
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GLenum error;
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while ((error = glGetError()) != GL_NO_ERROR) {
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (error != GL_OUT_OF_MEMORY) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // GL_OUT_OF_MEMORY can legally happen on lost device.
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      logger_->LogMessage(
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          filename, line,
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          std::string("GL ERROR :") +
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GLES2Util::GetStringEnum(error) + " : " +
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          function_name + ": was unhandled");
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED() << "GL error " << error << " was unhandled.";
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace gles2
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace gpu
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206