// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/configuration.h"
#if SB_API_VERSION >= 12 || SB_HAS(GLES2)

#include <algorithm>
#include <memory>

#include "cobalt/renderer/backend/egl/graphics_context.h"

#include "base/debug/leak_annotations.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/configuration/configuration.h"
#include "cobalt/renderer/backend/egl/framebuffer_render_target.h"
#include "cobalt/renderer/backend/egl/graphics_system.h"
#include "cobalt/renderer/backend/egl/pbuffer_render_target.h"
#include "cobalt/renderer/backend/egl/render_target.h"
#include "cobalt/renderer/backend/egl/texture.h"
#include "cobalt/renderer/backend/egl/texture_data.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"

#if defined(GLES3_SUPPORTED) && SB_API_VERSION >= 12
#error "Support for gles3 features has been deprecated."
#endif

namespace cobalt {
namespace renderer {
namespace backend {

namespace {

bool HasExtension(const char* extension) {
  const char* raw_extension_string =
      reinterpret_cast<const char*>(GL_CALL_SIMPLE(glGetString(GL_EXTENSIONS)));
  DCHECK(raw_extension_string);

  return strstr(raw_extension_string, extension) != NULL;
}

}  // namespace

GraphicsContextEGL::GraphicsContextEGL(GraphicsSystem* parent_system,
                                       EGLDisplay display, EGLConfig config,
                                       ResourceContext* resource_context)
    : GraphicsContext(parent_system),
      display_(display),
      config_(config),
      is_current_(false) {
#if SB_API_VERSION < 12 && defined(GLES3_SUPPORTED)
  context_ = CreateGLES3Context(display, config, resource_context->context());
#else
  // Create an OpenGL ES 2.0 context.
  EGLint context_attrib_list[] = {
      EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE,
  };
  context_ = EGL_CALL_SIMPLE(
      eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrib_list));
  CHECK_EQ(EGL_SUCCESS, EGL_CALL_SIMPLE(eglGetError()));
#endif

  // Create a dummy EGLSurface object to be assigned as the target surface
  // when we need to make OpenGL calls that do not depend on a surface (e.g.
  // creating a texture).
  null_surface_ = new PBufferRenderTargetEGL(display, config, math::Size(0, 0));
  CHECK(!null_surface_->CreationError());

  ScopedMakeCurrent scoped_current_context(this);

  bgra_format_supported_ = HasExtension("GL_EXT_texture_format_BGRA8888");

  SetupBlitObjects();

  {
    // The current mesa egl drivers leak memory on the first call to glDraw*.
    // Get that first draw out of the way, and do something useful with it.
    ANNOTATE_SCOPED_MEMORY_LEAK;
    ComputeReadPixelsNeedVerticalFlip();
  }
}

GraphicsSystemEGL* GraphicsContextEGL::system_egl() {
  return base::polymorphic_downcast<GraphicsSystemEGL*>(system());
}

bool GraphicsContextEGL::ComputeReadPixelsNeedVerticalFlip() {
  // This computation is expensive, so it is cached the first time that it is
  // computed. Simply return the value if it is already cached.
  if (read_pixels_needs_vertical_flip_) {
    return *read_pixels_needs_vertical_flip_;
  }

  // Create a 1x2 texture with distinct values vertically so that we can test
  // them.  We will blit the texture to an offscreen render target, and then
  // read back the value of the render target's pixels to check if they are
  // flipped or not.  It is found that the results of this test can differ
  // between at least Angle and Mesa GL, so if the results of this test are not
  // taken into account, one of those platforms will read pixels out upside
  // down.
  const int kDummyTextureWidth = 1;
  const int kDummyTextureHeight = 2;

  ScopedMakeCurrent scoped_make_current(this);

  std::unique_ptr<FramebufferEGL> framebuffer(new FramebufferEGL(
      this, math::Size(kDummyTextureWidth, kDummyTextureHeight), GL_RGBA,
      GL_NONE));
  GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->gl_handle()));

  {
    // Create a 2-pixel texture and then immediately blit it to our 2-pixel
    // framebuffer render target.
    GLuint texture;
    GL_CALL(glGenTextures(1, &texture));
    GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));

    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
    GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    GL_CALL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    GL_CALL(
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

    uint8_t pixels[8];
    pixels[0] = 0;
    pixels[1] = 0;
    pixels[2] = 0;
    pixels[3] = 0;
    pixels[4] = 255;
    pixels[5] = 255;
    pixels[6] = 255;
    pixels[7] = 255;

    GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kDummyTextureWidth,
                         kDummyTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                         pixels));
    GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));

    Blit(texture, 0, 0, kDummyTextureWidth, kDummyTextureHeight);
    GL_CALL(glFinish());
    GL_CALL(glDeleteTextures(1, &texture));
  }

  // Now read back the texture data using glReadPixels().
  uint32_t out_data[kDummyTextureWidth * kDummyTextureHeight];
  GL_CALL(glReadPixels(0, 0, kDummyTextureWidth, kDummyTextureHeight, GL_RGBA,
                       GL_UNSIGNED_BYTE, out_data));

  GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

  // Ensure the data is in one of two possible states, flipped or not flipped.
  DCHECK((out_data[0] == 0x00000000 && out_data[1] == 0xFFFFFFFF) ||
         (out_data[0] == 0xFFFFFFFF && out_data[1] == 0x00000000));

  // Finally check if the data we read back was flipped or not and cache the
  // result.
  read_pixels_needs_vertical_flip_ = out_data[1] == 0x00000000;
  return *read_pixels_needs_vertical_flip_;
}

void GraphicsContextEGL::SetupBlitObjects() {
  // Setup shaders used when blitting the current texture.
  blit_program_ = GL_CALL_SIMPLE(glCreateProgram());

  blit_vertex_shader_ = GL_CALL_SIMPLE(glCreateShader(GL_VERTEX_SHADER));
  const char* blit_vertex_shader_source =
      "attribute vec2 a_position;"
      "attribute vec2 a_tex_coord;"
      "varying vec2 v_tex_coord;"
      "void main() {"
      "  gl_Position = vec4(a_position.x, a_position.y, 0, 1);"
      "  v_tex_coord = a_tex_coord;"
      "}";
  int blit_vertex_shader_source_length = strlen(blit_vertex_shader_source);
  GL_CALL(glShaderSource(blit_vertex_shader_, 1, &blit_vertex_shader_source,
                         &blit_vertex_shader_source_length));
  GL_CALL(glCompileShader(blit_vertex_shader_));
  GL_CALL(glAttachShader(blit_program_, blit_vertex_shader_));

  blit_fragment_shader_ = GL_CALL_SIMPLE(glCreateShader(GL_FRAGMENT_SHADER));
  const char* blit_fragment_shader_source =
      "precision mediump float;"
      "varying vec2 v_tex_coord;"
      "uniform sampler2D tex;"
      "void main() {"
      "  gl_FragColor = texture2D(tex, v_tex_coord);"
      "}";
  int blit_fragment_shader_source_length = strlen(blit_fragment_shader_source);
  GL_CALL(glShaderSource(blit_fragment_shader_, 1, &blit_fragment_shader_source,
                         &blit_fragment_shader_source_length));
  GL_CALL(glCompileShader(blit_fragment_shader_));
  GL_CALL(glAttachShader(blit_program_, blit_fragment_shader_));

  GL_CALL(glBindAttribLocation(
      blit_program_, kBlitPositionAttribute, "a_position"));
  GL_CALL(glBindAttribLocation(
      blit_program_, kBlitTexcoordAttribute, "a_tex_coord"));

  GL_CALL(glLinkProgram(blit_program_));

  // Setup a vertex buffer that can blit a quad with a full texture, to be used
  // by Frame::BlitToRenderTarget().
  struct QuadVertex {
    float position_x;
    float position_y;
    float tex_coord_u;
    float tex_coord_v;
  };
  const QuadVertex kBlitQuadVerts[4] = {
      {-1.0f, -1.0f, 0.0f, 1.0f},
      {-1.0f, 1.0f, 0.0f, 0.0f},
      {1.0f, -1.0f, 1.0f, 1.0f},
      {1.0f, 1.0, 1.0f, 0.0f},
  };
  GL_CALL(glGenBuffers(1, &blit_vertex_buffer_));
  GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, blit_vertex_buffer_));
  GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(kBlitQuadVerts), kBlitQuadVerts,
                       GL_STATIC_DRAW));
}

GraphicsContextEGL::~GraphicsContextEGL() {
  MakeCurrent();
  GL_CALL(glFinish());
  GL_CALL(glDeleteBuffers(1, &blit_vertex_buffer_));
  GL_CALL(glDeleteProgram(blit_program_));
  GL_CALL(glDeleteShader(blit_fragment_shader_));
  GL_CALL(glDeleteShader(blit_vertex_shader_));

  ReleaseCurrentContext();

  null_surface_ = nullptr;

  EGL_CALL(eglDestroyContext(display_, context_));
}

void GraphicsContextEGL::SafeEglMakeCurrent(RenderTargetEGL* surface) {
  // In some EGL implementations, like Angle, the first time we make current on
  // a thread can result in global allocations being made that are never freed.
  ANNOTATE_SCOPED_MEMORY_LEAK;

  EGLSurface egl_surface = surface->GetSurface();

  // This should only be used with egl surfaces (not framebuffer objects).
  DCHECK_NE(egl_surface, EGL_NO_SURFACE);
  DCHECK_EQ(surface->GetPlatformHandle(), 0);

  if (surface->is_surface_bad()) {
    // A surface may become invalid in the middle of shutdown processing. If
    // this is a known bad surface, then bind the null surface just as if this
    // is the first time it is found to be bad.
    egl_surface = null_surface_->GetSurface();
    EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
    return;
  }

  EGL_CALL_SIMPLE(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
  EGLint make_current_error = EGL_CALL_SIMPLE(eglGetError());
  if (make_current_error != EGL_SUCCESS) {
    LOG(ERROR) << "eglMakeCurrent ERROR: " << make_current_error;
    if (make_current_error == EGL_BAD_ALLOC ||
        make_current_error == EGL_BAD_NATIVE_WINDOW) {
      LOG(ERROR) << "eglMakeCurrent raised either EGL_BAD_ALLOC or "
                    "EGL_BAD_NATIVE_WINDOW, continuing with null surface "
                    "under the assumption that our window surface has become "
                    "invalid due to a suspend or shutdown being triggered.";
      surface->set_surface_bad();
      egl_surface = null_surface_->GetSurface();
      EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
    } else {
      NOTREACHED() << "Unexpected error when calling eglMakeCurrent().";
    }
  }
}

void GraphicsContextEGL::MakeCurrentWithSurface(RenderTargetEGL* surface) {
  DCHECK_NE(EGL_NO_SURFACE, surface) <<
      "Use ReleaseCurrentContext().";

  // In some EGL implementations, like Angle, the first time we make current on
  // a thread can result in global allocations being made that are never freed.
  ANNOTATE_SCOPED_MEMORY_LEAK;

  EGLSurface egl_surface = surface->GetSurface();
  if (egl_surface != EGL_NO_SURFACE) {
    SafeEglMakeCurrent(surface);

    // Minimize calls to glBindFramebuffer. Normally, nothing keeps their
    // framebuffer object bound, so 0 is normally bound at this point --
    // unless the previous MakeCurrentWithSurface bound a framebuffer object.
    if (current_surface_ && current_surface_->GetPlatformHandle() != 0) {
      GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
    }
  } else {
    // This is a framebuffer object, and it does not have an EGL surface. It
    // must be bound using glBindFramebuffer. Use the null surface's EGLSurface
    // with eglMakeCurrent to avoid polluting the previous EGLSurface target.
    DCHECK_NE(surface->GetPlatformHandle(), 0);

    // Since we don't care about what surface is backing the default
    // framebuffer, don't change draw surfaces unless we simply don't have one
    // already.
    if (!IsCurrent()) {
      egl_surface = null_surface_->GetSurface();
      EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
    }
    GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, surface->GetPlatformHandle()));
  }

  if (surface->IsWindowRenderTarget() && !surface->has_been_made_current()) {
    SecurityClear();
  }
  surface->set_has_been_made_current();

  is_current_ = true;
  current_surface_ = surface;
}

void GraphicsContextEGL::ResetCurrentSurface() {
  if (is_current_ && current_surface_) {
    if (current_surface_->GetSurface() == EGL_NO_SURFACE) {
      EGLSurface egl_surface = null_surface_->GetSurface();
      EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
    } else {
      SafeEglMakeCurrent(current_surface_.get());
    }

    GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER,
                              current_surface_->GetPlatformHandle()));
  }
}

void GraphicsContextEGL::MakeCurrent() {
  // Some GL drivers do *not* handle switching contexts in the middle of a
  // frame very well, so with this change we avoid making a new surface
  // current if we don't actually care about what surface is current.
  if (!IsCurrent()) {
    MakeCurrentWithSurface(null_surface_.get());
  }
}

void GraphicsContextEGL::ReleaseCurrentContext() {
  GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
  EGL_CALL(eglMakeCurrent(
      display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

  current_surface_ = NULL;
  is_current_ = false;
}

std::unique_ptr<TextureEGL> GraphicsContextEGL::CreateTexture(
    std::unique_ptr<TextureDataEGL> texture_data) {
  return std::unique_ptr<TextureEGL>(
      new TextureEGL(this, std::move(texture_data), bgra_format_supported_));
}

std::unique_ptr<TextureEGL> GraphicsContextEGL::CreateTextureFromRawMemory(
    const scoped_refptr<ConstRawTextureMemoryEGL>& raw_texture_memory,
    intptr_t offset, const math::Size& size, GLenum format,
    int pitch_in_bytes) {
  const RawTextureMemoryEGL* texture_memory =
      &(raw_texture_memory->raw_texture_memory());

  return std::unique_ptr<TextureEGL>(
      new TextureEGL(this, texture_memory, offset, size, format, pitch_in_bytes,
                     bgra_format_supported_));
}

scoped_refptr<RenderTarget> GraphicsContextEGL::CreateOffscreenRenderTarget(
    const math::Size& dimensions) {
  scoped_refptr<RenderTarget> render_target(new PBufferRenderTargetEGL(
      display_, config_, dimensions));

  if (render_target->CreationError()) {
    return scoped_refptr<RenderTarget>();
  } else {
    return render_target;
  }
}

scoped_refptr<RenderTarget>
GraphicsContextEGL::CreateDownloadableOffscreenRenderTarget(
    const math::Size& dimensions) {
  scoped_refptr<RenderTarget> render_target(
      new FramebufferRenderTargetEGL(this, dimensions));

  if (render_target->CreationError()) {
    return scoped_refptr<RenderTarget>();
  } else {
    return render_target;
  }
}

void GraphicsContextEGL::InitializeDebugContext() {
  ComputeReadPixelsNeedVerticalFlip();
}

namespace {
void VerticallyFlipPixels(uint8_t* pixels, int pitch_in_bytes, int height) {
  int half_height = height / 2;
  for (int row = 0; row < half_height; ++row) {
    uint8_t* top_row = pixels + row * pitch_in_bytes;
    uint8_t* bottom_row =
        pixels + (height - 1 - row) * pitch_in_bytes;
    for (int i = 0; i < pitch_in_bytes; ++i) {
      std::swap(top_row[i], bottom_row[i]);
    }
  }
}
}  // namespace

std::unique_ptr<uint8_t[]> GraphicsContextEGL::DownloadPixelDataAsRGBA(
    const scoped_refptr<RenderTarget>& render_target) {
  TRACE_EVENT0("cobalt::renderer",
               "GraphicsContextEGL::DownloadPixelDataAsRGBA()");
  ScopedMakeCurrent scoped_current_context(this);

  int pitch_in_bytes =
      render_target->GetSize().width() * BytesPerPixelForGLFormat(GL_RGBA);
  std::unique_ptr<uint8_t[]> pixels(
      new uint8_t[render_target->GetSize().height() * pitch_in_bytes]);

  if (render_target->GetPlatformHandle() == 0) {
    // Need to bind the PBufferSurface to a framebuffer object in order to
    // read its pixels.
    PBufferRenderTargetEGL* pbuffer_render_target =
        base::polymorphic_downcast<PBufferRenderTargetEGL*>(
            render_target.get());

    std::unique_ptr<TextureEGL> texture(
        new TextureEGL(this, pbuffer_render_target));
    DCHECK(texture->GetSize() == render_target->GetSize());

    // This shouldn't be strictly necessary as glReadPixels() should implicitly
    // call glFinish(), however it doesn't hurt to be safe and guard against
    // potentially different implementations.  Performance is not an issue
    // in this function, because it is only used by tests to verify rendered
    // output.
    GL_CALL(glFinish());

    GLuint texture_framebuffer;
    GL_CALL(glGenFramebuffers(1, &texture_framebuffer));
    GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, texture_framebuffer));

    GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                   GL_TEXTURE_2D, texture->gl_handle(), 0));
    DCHECK_EQ(GL_FRAMEBUFFER_COMPLETE,
              GL_CALL_SIMPLE(glCheckFramebufferStatus(GL_FRAMEBUFFER)));

    GL_CALL(glReadPixels(0, 0, texture->GetSize().width(),
                         texture->GetSize().height(), GL_RGBA, GL_UNSIGNED_BYTE,
                         pixels.get()));

    GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
    GL_CALL(glDeleteFramebuffers(1, &texture_framebuffer));
  } else {
    // The render target is a framebuffer object, so just bind it and read.
    GL_CALL(
        glBindFramebuffer(GL_FRAMEBUFFER, render_target->GetPlatformHandle()));
    GL_CALL(glReadPixels(0, 0, render_target->GetSize().width(),
                         render_target->GetSize().height(), GL_RGBA,
                         GL_UNSIGNED_BYTE, pixels.get()));
    GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
  }

  // Vertically flip the resulting pixel data before returning so that the 0th
  // pixel is at the top-left.  While computing this is not a fast procedure,
  // this entire function is only intended to be used in debug/test code. This
  // is lazily computed and cached during the first call, so that subsequent
  // calls can simply return the result.
  if (ComputeReadPixelsNeedVerticalFlip()) {
    // Some platforms, like the Mesa Gallium EGL implementation on Linux, seem
    // to return already flipped pixels.  So in that case, we flip them again
    // before returning here.
    VerticallyFlipPixels(pixels.get(), pitch_in_bytes,
                         render_target->GetSize().height());
  }

  return std::move(pixels);
}

void GraphicsContextEGL::Finish() {
  ScopedMakeCurrent scoped_current_context(this);
  GL_CALL(glFinish());
}

void GraphicsContextEGL::Blit(GLuint texture, int x, int y, int width,
                              int height) {
  // Render a texture to the specified output rectangle on the render target.
  GL_CALL(glViewport(x, y, width, height));
  GL_CALL(glScissor(x, y, width, height));

  GL_CALL(glUseProgram(blit_program_));

  GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, blit_vertex_buffer_));
  GL_CALL(glVertexAttribPointer(kBlitPositionAttribute, 2, GL_FLOAT, GL_FALSE,
                                sizeof(float) * 4, 0));
  GL_CALL(glVertexAttribPointer(kBlitTexcoordAttribute, 2, GL_FLOAT, GL_FALSE,
                                sizeof(float) * 4,
                                reinterpret_cast<GLvoid*>(sizeof(float) * 2)));
  GL_CALL(glEnableVertexAttribArray(kBlitPositionAttribute));
  GL_CALL(glEnableVertexAttribArray(kBlitTexcoordAttribute));

  GL_CALL(glActiveTexture(GL_TEXTURE0));
  GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));

  GL_CALL(glDisable(GL_BLEND));

  GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));

  GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));

  GL_CALL(glDisableVertexAttribArray(kBlitTexcoordAttribute));
  GL_CALL(glDisableVertexAttribArray(kBlitPositionAttribute));
  GL_CALL(glUseProgram(0));
}

void GraphicsContextEGL::SwapBuffers(RenderTargetEGL* surface) {
  TRACE_EVENT0("cobalt::renderer", "GraphicsContextEGL::SwapBuffers()");
  if (surface->is_surface_bad()) {
    // The surface may become invalid during shutdown.
    return;
  }

  // SwapBuffers should have no effect for offscreen render targets. The
  // current implementation of eglSwapBuffers() does nothing for PBuffers,
  // so only check for framebuffer render targets.
  if (surface->GetPlatformHandle() == 0) {
    EGL_CALL_SIMPLE(eglSwapInterval(
        display_,
        configuration::Configuration::GetInstance()->CobaltEglSwapInterval()));
    EGL_CALL_SIMPLE(eglSwapBuffers(display_, surface->GetSurface()));
    EGLint swap_err = EGL_CALL_SIMPLE(eglGetError());
    if (swap_err != EGL_SUCCESS) {
      LOG(WARNING) << "Marking surface bad after swap error " << std::hex
                   << swap_err;
      surface->set_surface_bad();
      return;
    }
  }

  surface->increment_swap_count();
  if (surface->IsWindowRenderTarget() && surface->swap_count() <= 2) {
    surface->set_cleared_on_swap(true);
    SecurityClear();
  } else {
    surface->set_cleared_on_swap(false);
  }
}

void GraphicsContextEGL::SecurityClear() {
  // Explicitly clear the screen to transparent to ensure that data from a
  // previous use of the surface is not visible.
  GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
  GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
}

}  // namespace backend
}  // namespace renderer
}  // namespace cobalt

#endif  // SB_API_VERSION >= 12 || SB_HAS(GLES2)
