// 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 <GLES2/gl2.h>
#include <algorithm>

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

#include "base/debug/leak_annotations.h"
#include "base/debug/trace_event.h"
#include "cobalt/base/polymorphic_downcast.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"

namespace cobalt {
namespace renderer {
namespace backend {

namespace {

bool HasExtension(const char* extension) {
  const char* raw_extension_string =
      reinterpret_cast<const char*>(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 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_ =
      eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrib_list);
  CHECK_EQ(EGL_SUCCESS, 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);

  scoped_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_ = glCreateProgram();

  blit_vertex_shader_ = 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_ = 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_ = NULL;

  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;
  }

  eglMakeCurrent(display_, egl_surface, egl_surface, context_);
  EGLint make_current_error = 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_);
    }

    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_);
  }
}

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;
}

scoped_ptr<TextureEGL> GraphicsContextEGL::CreateTexture(
    scoped_ptr<TextureDataEGL> texture_data) {
  return make_scoped_ptr(
      new TextureEGL(this, texture_data.Pass(), bgra_format_supported_));
}

scoped_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 make_scoped_ptr(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

scoped_array<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);
  scoped_array<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());

    scoped_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,
              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 pixels.Pass();
}

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) {
    eglSwapInterval(display_, COBALT_EGL_SWAP_INTERVAL);
    eglSwapBuffers(display_, surface->GetSurface());
    EGLint swap_err = 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
