// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/service/error_state.h"

#include <stdint.h>

#include <string>

#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/logger.h"
#include "ui/gl/gl_bindings.h"

namespace gpu {
namespace gles2 {
namespace {
GLenum GetErrorHelper() {
  // Skip calling glGetError if no context is bound - this should only happen
  // when GL is not used e.g. with Graphite.
  if (gl::g_current_gl_driver) {
    gl::GLApi* const api = gl::g_current_gl_context;
    return api->glGetErrorFn();
  }
  return GL_NO_ERROR;
}
}  // namespace

class ErrorStateImpl : public ErrorState {
 public:
  explicit ErrorStateImpl(ErrorStateClient* client, Logger* logger);

  ErrorStateImpl(const ErrorStateImpl&) = delete;
  ErrorStateImpl& operator=(const ErrorStateImpl&) = delete;

  ~ErrorStateImpl() override;

  uint32_t GetGLError() override;

  void SetGLError(const char* filename,
                  int line,
                  unsigned int error,
                  const char* function_name,
                  const char* msg) override;
  void SetGLErrorInvalidEnum(const char* filename,
                             int line,
                             const char* function_name,
                             unsigned int value,
                             const char* label) override;
  void SetGLErrorInvalidParami(const char* filename,
                               int line,
                               unsigned int error,
                               const char* function_name,
                               unsigned int pname,
                               int param) override;
  void SetGLErrorInvalidParamf(const char* filename,
                               int line,
                               unsigned int error,
                               const char* function_name,
                               unsigned int pname,
                               float param) override;

  unsigned int PeekGLError(const char* filename,
                           int line,
                           const char* function_name) override;

  void CopyRealGLErrorsToWrapper(const char* filename,
                                 int line,
                                 const char* function_name) override;

  void ClearRealGLErrors(const char* filename,
                         int line,
                         const char* function_name) override;

 private:
  GLenum GetErrorHandleContextLoss();

  // The last error message set.
  std::string last_error_;
  // Current GL error bits.
  uint32_t error_bits_;

  raw_ptr<ErrorStateClient> client_;
  raw_ptr<Logger> logger_;
};

ErrorState::ErrorState() = default;

ErrorState::~ErrorState() = default;

ErrorState* ErrorState::Create(ErrorStateClient* client, Logger* logger) {
  return new ErrorStateImpl(client, logger);
}

ErrorStateImpl::ErrorStateImpl(ErrorStateClient* client, Logger* logger)
    : error_bits_(0), client_(client), logger_(logger) {}

ErrorStateImpl::~ErrorStateImpl() = default;

uint32_t ErrorStateImpl::GetGLError() {
  // Check the GL error first, then our wrapped error.
  GLenum error = GetErrorHandleContextLoss();
  if (error == GL_NO_ERROR && error_bits_ != 0) {
    for (uint32_t mask = 1; mask != 0; mask = mask << 1) {
      if ((error_bits_ & mask) != 0) {
        error = GLES2Util::GLErrorBitToGLError(mask);
        break;
      }
    }
  }

  if (error != GL_NO_ERROR) {
    // There was an error, clear the corresponding wrapped error.
    error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
  }
  return error;
}

GLenum ErrorStateImpl::GetErrorHandleContextLoss() {
  GLenum error = GetErrorHelper();
  if (error == GL_CONTEXT_LOST_KHR) {
    client_->OnContextLostError();
    // Do not expose GL_CONTEXT_LOST_KHR, as the version of the robustness
    // extension that introduces the error is not exposed by the command
    // buffer.
    error = GL_NO_ERROR;
  }
  return error;
}

unsigned int ErrorStateImpl::PeekGLError(
    const char* filename, int line, const char* function_name) {
  GLenum error = GetErrorHandleContextLoss();
  if (error != GL_NO_ERROR) {
    SetGLError(filename, line, error, function_name, "");
  }
  return error;
}

void ErrorStateImpl::SetGLError(
    const char* filename,
    int line,
    unsigned int error,
    const char* function_name,
    const char* msg) {
  if (msg) {
    last_error_ = msg;
    logger_->LogMessage(
        filename, line,
        std::string("GL ERROR :") +
        GLES2Util::GetStringEnum(error) + " : " +
        function_name + ": " + msg);
  }
  error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
  if (error == GL_OUT_OF_MEMORY)
    client_->OnOutOfMemoryError();
}

void ErrorStateImpl::SetGLErrorInvalidEnum(
    const char* filename,
    int line,
    const char* function_name,
    unsigned int value,
    const char* label) {
  SetGLError(filename, line, GL_INVALID_ENUM, function_name,
             (std::string(label) + " was " +
             GLES2Util::GetStringEnum(value)).c_str());
}

void ErrorStateImpl::SetGLErrorInvalidParami(
    const char* filename,
    int line,
    unsigned int error,
    const char* function_name,
    unsigned int pname, int param) {
  if (error == GL_INVALID_ENUM) {
    SetGLError(
        filename, line, GL_INVALID_ENUM, function_name,
        (std::string("trying to set ") +
         GLES2Util::GetStringEnum(pname) + " to " +
         GLES2Util::GetStringEnum(param)).c_str());
  } else {
    SetGLError(
        filename, line, error, function_name,
        (std::string("trying to set ") + GLES2Util::GetStringEnum(pname) +
         " to " + base::NumberToString(param))
            .c_str());
  }
}

void ErrorStateImpl::SetGLErrorInvalidParamf(
    const char* filename,
    int line,
    unsigned int error,
    const char* function_name,
    unsigned int pname, float param) {
  SetGLError(
      filename, line, error, function_name,
      (std::string("trying to set ") +
       GLES2Util::GetStringEnum(pname) + " to " +
       base::StringPrintf("%G", param)).c_str());
}

void ErrorStateImpl::CopyRealGLErrorsToWrapper(
    const char* filename, int line, const char* function_name) {
  GLenum error;
  while ((error = GetErrorHandleContextLoss()) != GL_NO_ERROR) {
    SetGLError(filename, line, error, function_name,
               "<- error from previous GL command");
  }
}

void ErrorStateImpl::ClearRealGLErrors(
    const char* filename, int line, const char* function_name) {
  // Clears and logs all current gl errors.
  GLenum error;
  while ((error = GetErrorHelper()) != GL_NO_ERROR) {
    if (error != GL_CONTEXT_LOST_KHR && error != GL_OUT_OF_MEMORY) {
      // GL_OUT_OF_MEMORY can legally happen on lost device.
      logger_->LogMessage(
          filename, line,
          std::string("GL ERROR :") +
          GLES2Util::GetStringEnum(error) + " : " +
          function_name + ": was unhandled");
      NOTREACHED() << "GL error " << error << " was unhandled.";
    }
  }
}

}  // namespace gles2
}  // namespace gpu
