// 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 <algorithm>
#include <memory>
#include <utility>

#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"
#include "starboard/configuration.h"

#if defined(GLES3_SUPPORTED)
#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) {
  // 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()));

  // 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());
}

const GraphicsSystemEGL* GraphicsContextEGL::system_egl() const {
  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());
}

math::Size GraphicsContextEGL::GetWindowSize() const {
  return system_egl()->GetWindowSize();
}

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
