// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file is auto-generated from
// ui/gl/generate_bindings.py
// It's formatted by clang-format using chromium coding style:
//    clang-format -i -style=chromium filename
// DO NOT EDIT!

#include <string>

#include "base/trace_event/trace_event.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_enums.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_version_info.h"

namespace gl {

static bool g_debugBindingsInitialized;
DriverOSMESA g_driver_osmesa;

void DriverOSMESA::InitializeStaticBindings() {
  fn.OSMesaColorClampFn = reinterpret_cast<OSMesaColorClampProc>(
      GetGLProcAddress("OSMesaColorClamp"));
  fn.OSMesaCreateContextFn = reinterpret_cast<OSMesaCreateContextProc>(
      GetGLProcAddress("OSMesaCreateContext"));
  fn.OSMesaCreateContextExtFn = reinterpret_cast<OSMesaCreateContextExtProc>(
      GetGLProcAddress("OSMesaCreateContextExt"));
  fn.OSMesaDestroyContextFn = reinterpret_cast<OSMesaDestroyContextProc>(
      GetGLProcAddress("OSMesaDestroyContext"));
  fn.OSMesaGetColorBufferFn = reinterpret_cast<OSMesaGetColorBufferProc>(
      GetGLProcAddress("OSMesaGetColorBuffer"));
  fn.OSMesaGetCurrentContextFn = reinterpret_cast<OSMesaGetCurrentContextProc>(
      GetGLProcAddress("OSMesaGetCurrentContext"));
  fn.OSMesaGetDepthBufferFn = reinterpret_cast<OSMesaGetDepthBufferProc>(
      GetGLProcAddress("OSMesaGetDepthBuffer"));
  fn.OSMesaGetIntegervFn = reinterpret_cast<OSMesaGetIntegervProc>(
      GetGLProcAddress("OSMesaGetIntegerv"));
  fn.OSMesaGetProcAddressFn = reinterpret_cast<OSMesaGetProcAddressProc>(
      GetGLProcAddress("OSMesaGetProcAddress"));
  fn.OSMesaMakeCurrentFn = reinterpret_cast<OSMesaMakeCurrentProc>(
      GetGLProcAddress("OSMesaMakeCurrent"));
  fn.OSMesaPixelStoreFn = reinterpret_cast<OSMesaPixelStoreProc>(
      GetGLProcAddress("OSMesaPixelStore"));
}

void DriverOSMESA::InitializeExtensionBindings() {
  std::string extensions(GetPlatformExtensions());
  extensions += " ";
  ALLOW_UNUSED_LOCAL(extensions);

  if (g_debugBindingsInitialized)
    InitializeDebugBindings();
}

extern "C" {

static void GL_BINDING_CALL Debug_OSMesaColorClamp(GLboolean enable) {
  GL_SERVICE_LOG("OSMesaColorClamp"
                 << "(" << GLEnums::GetStringBool(enable) << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaColorClampFn != nullptr);
  g_driver_osmesa.debug_fn.OSMesaColorClampFn(enable);
}

static OSMesaContext GL_BINDING_CALL
Debug_OSMesaCreateContext(GLenum format, OSMesaContext sharelist) {
  GL_SERVICE_LOG("OSMesaCreateContext"
                 << "(" << GLEnums::GetStringEnum(format) << ", " << sharelist
                 << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaCreateContextFn != nullptr);
  OSMesaContext result =
      g_driver_osmesa.debug_fn.OSMesaCreateContextFn(format, sharelist);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static OSMesaContext GL_BINDING_CALL
Debug_OSMesaCreateContextExt(GLenum format,
                             GLint depthBits,
                             GLint stencilBits,
                             GLint accumBits,
                             OSMesaContext sharelist) {
  GL_SERVICE_LOG("OSMesaCreateContextExt"
                 << "(" << GLEnums::GetStringEnum(format) << ", " << depthBits
                 << ", " << stencilBits << ", " << accumBits << ", "
                 << sharelist << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaCreateContextExtFn != nullptr);
  OSMesaContext result = g_driver_osmesa.debug_fn.OSMesaCreateContextExtFn(
      format, depthBits, stencilBits, accumBits, sharelist);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static void GL_BINDING_CALL Debug_OSMesaDestroyContext(OSMesaContext ctx) {
  GL_SERVICE_LOG("OSMesaDestroyContext"
                 << "(" << ctx << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaDestroyContextFn != nullptr);
  g_driver_osmesa.debug_fn.OSMesaDestroyContextFn(ctx);
}

static GLboolean GL_BINDING_CALL Debug_OSMesaGetColorBuffer(OSMesaContext c,
                                                            GLint* width,
                                                            GLint* height,
                                                            GLint* format,
                                                            void** buffer) {
  GL_SERVICE_LOG("OSMesaGetColorBuffer"
                 << "(" << c << ", " << static_cast<const void*>(width) << ", "
                 << static_cast<const void*>(height) << ", "
                 << static_cast<const void*>(format) << ", " << buffer << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaGetColorBufferFn != nullptr);
  GLboolean result = g_driver_osmesa.debug_fn.OSMesaGetColorBufferFn(
      c, width, height, format, buffer);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static OSMesaContext GL_BINDING_CALL Debug_OSMesaGetCurrentContext(void) {
  GL_SERVICE_LOG("OSMesaGetCurrentContext"
                 << "("
                 << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaGetCurrentContextFn != nullptr);
  OSMesaContext result = g_driver_osmesa.debug_fn.OSMesaGetCurrentContextFn();
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static GLboolean GL_BINDING_CALL
Debug_OSMesaGetDepthBuffer(OSMesaContext c,
                           GLint* width,
                           GLint* height,
                           GLint* bytesPerValue,
                           void** buffer) {
  GL_SERVICE_LOG("OSMesaGetDepthBuffer"
                 << "(" << c << ", " << static_cast<const void*>(width) << ", "
                 << static_cast<const void*>(height) << ", "
                 << static_cast<const void*>(bytesPerValue) << ", " << buffer
                 << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaGetDepthBufferFn != nullptr);
  GLboolean result = g_driver_osmesa.debug_fn.OSMesaGetDepthBufferFn(
      c, width, height, bytesPerValue, buffer);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static void GL_BINDING_CALL Debug_OSMesaGetIntegerv(GLint pname, GLint* value) {
  GL_SERVICE_LOG("OSMesaGetIntegerv"
                 << "(" << pname << ", " << static_cast<const void*>(value)
                 << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaGetIntegervFn != nullptr);
  g_driver_osmesa.debug_fn.OSMesaGetIntegervFn(pname, value);
}

static OSMESAproc GL_BINDING_CALL
Debug_OSMesaGetProcAddress(const char* funcName) {
  GL_SERVICE_LOG("OSMesaGetProcAddress"
                 << "(" << funcName << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaGetProcAddressFn != nullptr);
  OSMESAproc result = g_driver_osmesa.debug_fn.OSMesaGetProcAddressFn(funcName);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static GLboolean GL_BINDING_CALL Debug_OSMesaMakeCurrent(OSMesaContext ctx,
                                                         void* buffer,
                                                         GLenum type,
                                                         GLsizei width,
                                                         GLsizei height) {
  GL_SERVICE_LOG("OSMesaMakeCurrent"
                 << "(" << ctx << ", " << static_cast<const void*>(buffer)
                 << ", " << GLEnums::GetStringEnum(type) << ", " << width
                 << ", " << height << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaMakeCurrentFn != nullptr);
  GLboolean result = g_driver_osmesa.debug_fn.OSMesaMakeCurrentFn(
      ctx, buffer, type, width, height);
  GL_SERVICE_LOG("GL_RESULT: " << result);
  return result;
}

static void GL_BINDING_CALL Debug_OSMesaPixelStore(GLint pname, GLint value) {
  GL_SERVICE_LOG("OSMesaPixelStore"
                 << "(" << pname << ", " << value << ")");
  DCHECK(g_driver_osmesa.debug_fn.OSMesaPixelStoreFn != nullptr);
  g_driver_osmesa.debug_fn.OSMesaPixelStoreFn(pname, value);
}
}  // extern "C"

void DriverOSMESA::InitializeDebugBindings() {
  if (!debug_fn.OSMesaColorClampFn) {
    debug_fn.OSMesaColorClampFn = fn.OSMesaColorClampFn;
    fn.OSMesaColorClampFn = Debug_OSMesaColorClamp;
  }
  if (!debug_fn.OSMesaCreateContextFn) {
    debug_fn.OSMesaCreateContextFn = fn.OSMesaCreateContextFn;
    fn.OSMesaCreateContextFn = Debug_OSMesaCreateContext;
  }
  if (!debug_fn.OSMesaCreateContextExtFn) {
    debug_fn.OSMesaCreateContextExtFn = fn.OSMesaCreateContextExtFn;
    fn.OSMesaCreateContextExtFn = Debug_OSMesaCreateContextExt;
  }
  if (!debug_fn.OSMesaDestroyContextFn) {
    debug_fn.OSMesaDestroyContextFn = fn.OSMesaDestroyContextFn;
    fn.OSMesaDestroyContextFn = Debug_OSMesaDestroyContext;
  }
  if (!debug_fn.OSMesaGetColorBufferFn) {
    debug_fn.OSMesaGetColorBufferFn = fn.OSMesaGetColorBufferFn;
    fn.OSMesaGetColorBufferFn = Debug_OSMesaGetColorBuffer;
  }
  if (!debug_fn.OSMesaGetCurrentContextFn) {
    debug_fn.OSMesaGetCurrentContextFn = fn.OSMesaGetCurrentContextFn;
    fn.OSMesaGetCurrentContextFn = Debug_OSMesaGetCurrentContext;
  }
  if (!debug_fn.OSMesaGetDepthBufferFn) {
    debug_fn.OSMesaGetDepthBufferFn = fn.OSMesaGetDepthBufferFn;
    fn.OSMesaGetDepthBufferFn = Debug_OSMesaGetDepthBuffer;
  }
  if (!debug_fn.OSMesaGetIntegervFn) {
    debug_fn.OSMesaGetIntegervFn = fn.OSMesaGetIntegervFn;
    fn.OSMesaGetIntegervFn = Debug_OSMesaGetIntegerv;
  }
  if (!debug_fn.OSMesaGetProcAddressFn) {
    debug_fn.OSMesaGetProcAddressFn = fn.OSMesaGetProcAddressFn;
    fn.OSMesaGetProcAddressFn = Debug_OSMesaGetProcAddress;
  }
  if (!debug_fn.OSMesaMakeCurrentFn) {
    debug_fn.OSMesaMakeCurrentFn = fn.OSMesaMakeCurrentFn;
    fn.OSMesaMakeCurrentFn = Debug_OSMesaMakeCurrent;
  }
  if (!debug_fn.OSMesaPixelStoreFn) {
    debug_fn.OSMesaPixelStoreFn = fn.OSMesaPixelStoreFn;
    fn.OSMesaPixelStoreFn = Debug_OSMesaPixelStore;
  }
  g_debugBindingsInitialized = true;
}

void DriverOSMESA::ClearBindings() {
  memset(this, 0, sizeof(*this));
}

void OSMESAApiBase::OSMesaColorClampFn(GLboolean enable) {
  driver_->fn.OSMesaColorClampFn(enable);
}

OSMesaContext OSMESAApiBase::OSMesaCreateContextFn(GLenum format,
                                                   OSMesaContext sharelist) {
  return driver_->fn.OSMesaCreateContextFn(format, sharelist);
}

OSMesaContext OSMESAApiBase::OSMesaCreateContextExtFn(GLenum format,
                                                      GLint depthBits,
                                                      GLint stencilBits,
                                                      GLint accumBits,
                                                      OSMesaContext sharelist) {
  return driver_->fn.OSMesaCreateContextExtFn(format, depthBits, stencilBits,
                                              accumBits, sharelist);
}

void OSMESAApiBase::OSMesaDestroyContextFn(OSMesaContext ctx) {
  driver_->fn.OSMesaDestroyContextFn(ctx);
}

GLboolean OSMESAApiBase::OSMesaGetColorBufferFn(OSMesaContext c,
                                                GLint* width,
                                                GLint* height,
                                                GLint* format,
                                                void** buffer) {
  return driver_->fn.OSMesaGetColorBufferFn(c, width, height, format, buffer);
}

OSMesaContext OSMESAApiBase::OSMesaGetCurrentContextFn(void) {
  return driver_->fn.OSMesaGetCurrentContextFn();
}

GLboolean OSMESAApiBase::OSMesaGetDepthBufferFn(OSMesaContext c,
                                                GLint* width,
                                                GLint* height,
                                                GLint* bytesPerValue,
                                                void** buffer) {
  return driver_->fn.OSMesaGetDepthBufferFn(c, width, height, bytesPerValue,
                                            buffer);
}

void OSMESAApiBase::OSMesaGetIntegervFn(GLint pname, GLint* value) {
  driver_->fn.OSMesaGetIntegervFn(pname, value);
}

OSMESAproc OSMESAApiBase::OSMesaGetProcAddressFn(const char* funcName) {
  return driver_->fn.OSMesaGetProcAddressFn(funcName);
}

GLboolean OSMESAApiBase::OSMesaMakeCurrentFn(OSMesaContext ctx,
                                             void* buffer,
                                             GLenum type,
                                             GLsizei width,
                                             GLsizei height) {
  return driver_->fn.OSMesaMakeCurrentFn(ctx, buffer, type, width, height);
}

void OSMESAApiBase::OSMesaPixelStoreFn(GLint pname, GLint value) {
  driver_->fn.OSMesaPixelStoreFn(pname, value);
}

void TraceOSMESAApi::OSMesaColorClampFn(GLboolean enable) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaColorClamp")
  osmesa_api_->OSMesaColorClampFn(enable);
}

OSMesaContext TraceOSMESAApi::OSMesaCreateContextFn(GLenum format,
                                                    OSMesaContext sharelist) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaCreateContext")
  return osmesa_api_->OSMesaCreateContextFn(format, sharelist);
}

OSMesaContext TraceOSMESAApi::OSMesaCreateContextExtFn(
    GLenum format,
    GLint depthBits,
    GLint stencilBits,
    GLint accumBits,
    OSMesaContext sharelist) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaCreateContextExt")
  return osmesa_api_->OSMesaCreateContextExtFn(format, depthBits, stencilBits,
                                               accumBits, sharelist);
}

void TraceOSMESAApi::OSMesaDestroyContextFn(OSMesaContext ctx) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaDestroyContext")
  osmesa_api_->OSMesaDestroyContextFn(ctx);
}

GLboolean TraceOSMESAApi::OSMesaGetColorBufferFn(OSMesaContext c,
                                                 GLint* width,
                                                 GLint* height,
                                                 GLint* format,
                                                 void** buffer) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaGetColorBuffer")
  return osmesa_api_->OSMesaGetColorBufferFn(c, width, height, format, buffer);
}

OSMesaContext TraceOSMESAApi::OSMesaGetCurrentContextFn(void) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaGetCurrentContext")
  return osmesa_api_->OSMesaGetCurrentContextFn();
}

GLboolean TraceOSMESAApi::OSMesaGetDepthBufferFn(OSMesaContext c,
                                                 GLint* width,
                                                 GLint* height,
                                                 GLint* bytesPerValue,
                                                 void** buffer) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaGetDepthBuffer")
  return osmesa_api_->OSMesaGetDepthBufferFn(c, width, height, bytesPerValue,
                                             buffer);
}

void TraceOSMESAApi::OSMesaGetIntegervFn(GLint pname, GLint* value) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaGetIntegerv")
  osmesa_api_->OSMesaGetIntegervFn(pname, value);
}

OSMESAproc TraceOSMESAApi::OSMesaGetProcAddressFn(const char* funcName) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaGetProcAddress")
  return osmesa_api_->OSMesaGetProcAddressFn(funcName);
}

GLboolean TraceOSMESAApi::OSMesaMakeCurrentFn(OSMesaContext ctx,
                                              void* buffer,
                                              GLenum type,
                                              GLsizei width,
                                              GLsizei height) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaMakeCurrent")
  return osmesa_api_->OSMesaMakeCurrentFn(ctx, buffer, type, width, height);
}

void TraceOSMESAApi::OSMesaPixelStoreFn(GLint pname, GLint value) {
  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::OSMesaPixelStore")
  osmesa_api_->OSMesaPixelStoreFn(pname, value);
}

}  // namespace gl
