Home | History | Annotate | Download | only in service
      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