/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.
 */

#define LOG_TAG "GLCompositor"

#include <sstream>
#include <string>
#include <vector>

#include <cutils/log.h>

#define EGL_EGLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>

#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>

#include <cutils/properties.h>
#include <sync/sync.h>
#include <sw_sync.h>

#include "drm_hwcomposer.h"

#include "gl_compositor.h"
#include "seperate_rects.h"

// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures
#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX
#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A
#endif

#define MAX_OVERLAPPING_LAYERS 64

namespace android {

struct GLCompositor::texture_from_handle {
  EGLImageKHR image;
  GLuint texture;
};

static const char *get_gl_error(void);
static const char *get_egl_error(void);
static bool has_extension(const char *extension, const char *extensions);

template <typename T>
int AllocResource(std::vector<T> &array) {
  for (typename std::vector<T>::iterator it = array.begin(); it != array.end();
       ++it) {
    if (!it->is_some()) {
      return std::distance(array.begin(), it);
    }
  }

  array.push_back(T());
  return array.size() - 1;
}

template <typename T>
void FreeResource(std::vector<T> &array, int index) {
  if (index == (int)array.size() - 1) {
    array.pop_back();
  } else if (index >= 0 && (unsigned)index < array.size()) {
    array[index].Reset();
  }
}

struct GLTarget {
  sp<GraphicBuffer> fb;
  EGLImageKHR egl_fb_image;
  GLuint gl_fb;
  GLuint gl_fb_tex;
  bool forgotten;
  unsigned composition_count;

  GLTarget()
      : egl_fb_image(EGL_NO_IMAGE_KHR),
        gl_fb(0),
        gl_fb_tex(0),
        forgotten(true),
        composition_count(0) {
  }

  void Reset() {
    fb.clear();
    egl_fb_image = EGL_NO_IMAGE_KHR;
    gl_fb = 0;
    gl_fb_tex = 0;
    forgotten = true;
    composition_count = 0;
  }

  bool is_some() const {
    return egl_fb_image != EGL_NO_IMAGE_KHR;
  }
};

struct GLCompositor::priv_data {
  EGLDisplay egl_display;
  EGLContext egl_ctx;

  EGLDisplay saved_egl_display;
  EGLContext saved_egl_ctx;
  EGLSurface saved_egl_read;
  EGLSurface saved_egl_draw;

  int current_target;
  std::vector<GLTarget> targets;
  std::vector<GLComposition *> compositions;

  std::vector<GLint> blend_programs;
  GLuint vertex_buffer;

  priv_data()
      : egl_display(EGL_NO_DISPLAY),
        egl_ctx(EGL_NO_CONTEXT),
        saved_egl_display(EGL_NO_DISPLAY),
        saved_egl_ctx(EGL_NO_CONTEXT),
        saved_egl_read(EGL_NO_SURFACE),
        saved_egl_draw(EGL_NO_SURFACE),
        current_target(-1) {
  }
};

class GLComposition : public Composition {
 public:
  struct LayerData {
    hwc_layer_1 layer;
    hwc_drm_bo bo;
  };

  GLComposition(GLCompositor *owner) : compositor(owner), target_handle(-1) {
  }

  virtual ~GLComposition() {
    if (compositor == NULL) {
      return;
    }

    // Removes this composition from the owning compositor automatically.
    std::vector<GLComposition *> &compositions =
        compositor->priv_->compositions;
    std::vector<GLComposition *>::iterator it =
        std::find(compositions.begin(), compositions.end(), this);
    if (it != compositions.end()) {
      compositions.erase(it);
    }

    GLTarget *target = &compositor->priv_->targets[target_handle];
    target->composition_count--;
    compositor->CheckAndDestroyTarget(target_handle);
  }

  virtual int AddLayer(int display, hwc_layer_1 *layer, hwc_drm_bo *bo) {
    (void)display;
    if (layer->compositionType != HWC_OVERLAY) {
      ALOGE("Must add layers with compositionType == HWC_OVERLAY");
      return 1;
    }

    if (layer->handle == 0) {
      ALOGE("Must add layers with valid buffer handle");
      return 1;
    }

    layer_data.push_back(LayerData());
    LayerData &layer_datum = layer_data.back();
    layer_datum.layer = *layer;
    layer_datum.bo = *bo;

    return 0;
  }

  virtual unsigned GetRemainingLayers(int display, unsigned num_needed) const {
    (void)display;
    return num_needed;
  }

  GLCompositor *compositor;
  int target_handle;
  std::vector<LayerData> layer_data;
};

struct RenderingCommand {
  struct TextureSource {
    unsigned texture_index;
    float crop_bounds[4];
    float alpha;
  };

  float bounds[4];
  unsigned texture_count;
  TextureSource textures[MAX_OVERLAPPING_LAYERS];

  RenderingCommand() : texture_count(0) {
  }
};

static void ConstructCommands(const GLComposition &composition,
                              std::vector<RenderingCommand> *commands) {
  std::vector<seperate_rects::Rect<float> > in_rects;
  std::vector<seperate_rects::RectSet<uint64_t, float> > out_rects;
  int i;

  for (unsigned rect_index = 0; rect_index < composition.layer_data.size();
       rect_index++) {
    const struct hwc_layer_1 &layer = composition.layer_data[rect_index].layer;
    seperate_rects::Rect<float> rect;
    in_rects.push_back(seperate_rects::Rect<float>(
        layer.displayFrame.left, layer.displayFrame.top,
        layer.displayFrame.right, layer.displayFrame.bottom));
  }

  seperate_frects_64(in_rects, &out_rects);

  for (unsigned rect_index = 0; rect_index < out_rects.size(); rect_index++) {
    const seperate_rects::RectSet<uint64_t, float> &out_rect =
        out_rects[rect_index];
    commands->push_back(RenderingCommand());
    RenderingCommand &cmd = commands->back();

    memcpy(cmd.bounds, out_rect.rect.bounds, sizeof(cmd.bounds));

    uint64_t tex_set = out_rect.id_set.getBits();
    for (unsigned i = composition.layer_data.size() - 1; tex_set != 0x0; i--) {
      if (tex_set & (0x1 << i)) {
        tex_set &= ~(0x1 << i);

        const struct hwc_layer_1 &layer = composition.layer_data[i].layer;

        seperate_rects::Rect<float> display_rect(
            layer.displayFrame.left, layer.displayFrame.top,
            layer.displayFrame.right, layer.displayFrame.bottom);
        float display_size[2] = {
            display_rect.bounds[2] - display_rect.bounds[0],
            display_rect.bounds[3] - display_rect.bounds[1]};

        seperate_rects::Rect<float> crop_rect(
            layer.sourceCropf.left, layer.sourceCropf.top,
            layer.sourceCropf.right, layer.sourceCropf.bottom);
        float crop_size[2] = {crop_rect.bounds[2] - crop_rect.bounds[0],
                              crop_rect.bounds[3] - crop_rect.bounds[1]};

        RenderingCommand::TextureSource &src = cmd.textures[cmd.texture_count];
        cmd.texture_count++;
        src.texture_index = i;

        for (int b = 0; b < 4; b++) {
          float bound_percent = (cmd.bounds[b] - display_rect.bounds[b % 2]) /
                                display_size[b % 2];
          src.crop_bounds[b] =
              crop_rect.bounds[b % 2] + bound_percent * crop_size[b % 2];
        }

        if (layer.blending == HWC_BLENDING_NONE) {
          src.alpha = 1.0f;
          // This layer is opaque. There is no point in using layers below this
          // one.
          break;
        }

        src.alpha = layer.planeAlpha / 255.0f;
      }
    }
  }
}

GLCompositor::GLCompositor() {
  priv_ = new priv_data;
}

GLCompositor::~GLCompositor() {
  if (BeginContext()) {
    goto destroy_ctx;
  }

  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glBindTexture(GL_TEXTURE_2D, 0);

  for (std::vector<GLTarget>::iterator it = priv_->targets.end();
       it != priv_->targets.begin(); it = priv_->targets.end()) {
    --it;
    glDeleteFramebuffers(1, &it->gl_fb);
    glDeleteTextures(1, &it->gl_fb_tex);
    eglDestroyImageKHR(priv_->egl_display, it->egl_fb_image);
    priv_->targets.erase(it);
  }

  for (std::vector<GLComposition *>::iterator it = priv_->compositions.end();
       it != priv_->compositions.begin(); it = priv_->compositions.end()) {
    --it;

    // Prevents compositor from trying to erase itself
    (*it)->compositor = NULL;
    delete *it;
    priv_->compositions.erase(it);
  }

destroy_ctx:
  eglMakeCurrent(priv_->egl_display,
                 EGL_NO_SURFACE /* No default draw surface */,
                 EGL_NO_SURFACE /* No default draw read */, EGL_NO_CONTEXT);
  eglDestroyContext(priv_->egl_display, priv_->egl_ctx);

  EndContext();
  delete priv_;
}

int GLCompositor::Init() {
  int ret = 0;
  const char *egl_extensions;
  const char *gl_extensions;
  EGLint num_configs;
  EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
  EGLConfig egl_config;

  // clang-format off
  const GLfloat verts[] = {
    0.0f,  0.0f,    0.0f, 0.0f,
    0.0f,  1.0f,    0.0f, 1.0f,
    1.0f,  0.0f,    1.0f, 0.0f,
    1.0f,  1.0f,    1.0f, 1.0f
  };
  // clang-format on

  const EGLint config_attribs[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                                   EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
                                   EGL_BLUE_SIZE, 8, EGL_NONE};

  const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};

  priv_->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  if (priv_->egl_display == EGL_NO_DISPLAY) {
    ALOGE("Failed to get egl display");
    ret = 1;
    goto out;
  }

  if (!eglInitialize(priv_->egl_display, NULL, NULL)) {
    ALOGE("Failed to initialize egl: %s", get_egl_error());
    ret = 1;
    goto out;
  }

  egl_extensions = eglQueryString(priv_->egl_display, EGL_EXTENSIONS);

  // These extensions are all technically required but not always reported due
  // to meta EGL filtering them out.
  if (!has_extension("EGL_KHR_image_base", egl_extensions))
    ALOGW("EGL_KHR_image_base extension not supported");

  if (!has_extension("EGL_ANDROID_image_native_buffer", egl_extensions))
    ALOGW("EGL_ANDROID_image_native_buffer extension not supported");

  if (!has_extension("EGL_ANDROID_native_fence_sync", egl_extensions))
    ALOGW("EGL_ANDROID_native_fence_sync extension not supported");

  if (!eglChooseConfig(priv_->egl_display, config_attribs, &egl_config, 1,
                       &num_configs)) {
    ALOGE("eglChooseConfig() failed with error: %s", get_egl_error());
    goto out;
  }

  priv_->egl_ctx =
      eglCreateContext(priv_->egl_display, egl_config,
                       EGL_NO_CONTEXT /* No shared context */, context_attribs);

  if (priv_->egl_ctx == EGL_NO_CONTEXT) {
    ALOGE("Failed to create OpenGL ES Context: %s", get_egl_error());
    ret = 1;
    goto out;
  }

  ret = BeginContext();
  if (ret)
    goto out;

  gl_extensions = (const char *)glGetString(GL_EXTENSIONS);

  if (!has_extension("GL_OES_EGL_image", gl_extensions))
    ALOGW("GL_OES_EGL_image extension not supported");

  glGenBuffers(1, &priv_->vertex_buffer);
  glBindBuffer(GL_ARRAY_BUFFER, priv_->vertex_buffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  if (GenerateShaders()) {
    ret = 1;
    goto end_ctx;
  }

end_ctx:
  EndContext();

out:
  return ret;
}

Targeting *GLCompositor::targeting() {
  return (Targeting *)this;
}

int GLCompositor::CreateTarget(sp<GraphicBuffer> &buffer) {
  int ret;

  ret = BeginContext();
  if (ret)
    return -1;

  int target_handle = AllocResource(priv_->targets);
  GLTarget *target = &priv_->targets[target_handle];

  target->fb = buffer;

  target->egl_fb_image = eglCreateImageKHR(
      priv_->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
      (EGLClientBuffer)target->fb->getNativeBuffer(), NULL /* no attribs */);

  if (target->egl_fb_image == EGL_NO_IMAGE_KHR) {
    ALOGE("Failed to make image from target buffer: %s", get_egl_error());
    ret = -1;
    goto fail_create_image;
  }

  glGenTextures(1, &target->gl_fb_tex);
  glBindTexture(GL_TEXTURE_2D, target->gl_fb_tex);
  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
                               (GLeglImageOES)target->egl_fb_image);
  glBindTexture(GL_TEXTURE_2D, 0);

  glGenFramebuffers(1, &target->gl_fb);
  glBindFramebuffer(GL_FRAMEBUFFER, target->gl_fb);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         target->gl_fb_tex, 0);

  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    ALOGE("Failed framebuffer check for created target buffer");
    ret = 1;
    goto fail_framebuffer_status;
  }

  target->forgotten = false;

  ret = target_handle;
  goto out;

fail_framebuffer_status:
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glDeleteFramebuffers(1, &target->gl_fb);
  glDeleteTextures(1, &target->gl_fb_tex);
  eglDestroyImageKHR(priv_->egl_display, target->egl_fb_image);
  target->gl_fb = 0;
  target->gl_fb_tex = 0;
  target->egl_fb_image = EGL_NO_IMAGE_KHR;

fail_create_image:
  target->fb.clear();
  FreeResource(priv_->targets, target_handle);

out:
  EndContext();
  return ret;
}

void GLCompositor::SetTarget(int target_handle) {
  if (target_handle >= 0 && (unsigned)target_handle < priv_->targets.size()) {
    GLTarget *target = &priv_->targets[target_handle];
    if (target->is_some()) {
      priv_->current_target = target_handle;
      return;
    }
  }

  priv_->current_target = -1;
}

void GLCompositor::ForgetTarget(int target_handle) {
  if (target_handle >= 0 && (unsigned)target_handle < priv_->targets.size()) {
    if (target_handle == priv_->current_target) {
      priv_->current_target = -1;
    }

    GLTarget *target = &priv_->targets[target_handle];
    if (target->is_some()) {
      target->forgotten = true;
      CheckAndDestroyTarget(target_handle);
      return;
    }
  }

  ALOGE("Failed to forget target because of invalid handle");
}

void GLCompositor::CheckAndDestroyTarget(int target_handle) {
  GLTarget *target = &priv_->targets[target_handle];
  if (target->composition_count == 0 && target->forgotten) {
    if (BeginContext() == 0) {
      glDeleteFramebuffers(1, &target->gl_fb);
      glDeleteTextures(1, &target->gl_fb_tex);
      eglDestroyImageKHR(priv_->egl_display, target->egl_fb_image);
      EndContext();
    }

    FreeResource(priv_->targets, target_handle);
  }
}

Composition *GLCompositor::CreateComposition() {
  if (priv_->current_target >= 0 &&
      (unsigned)priv_->current_target < priv_->targets.size()) {
    GLTarget *target = &priv_->targets[priv_->current_target];
    if (target->is_some()) {
      GLComposition *composition = new GLComposition(this);
      composition->target_handle = priv_->current_target;
      target->composition_count++;
      priv_->compositions.push_back(composition);
      return composition;
    }
  }

  ALOGE("Failed to create composition because of invalid target handle %d",
        priv_->current_target);

  return NULL;
}

int GLCompositor::QueueComposition(Composition *composition) {
  if (composition) {
    int ret = DoComposition(*(GLComposition *)composition);
    delete composition;
    return ret;
  }

  ALOGE("Failed to queue composition because of invalid composition handle");

  return -EINVAL;
}

int GLCompositor::Composite() {
  return 0;
}

int GLCompositor::BeginContext() {
  priv_->saved_egl_display = eglGetCurrentDisplay();
  priv_->saved_egl_ctx = eglGetCurrentContext();

  if (priv_->saved_egl_display != priv_->egl_display ||
      priv_->saved_egl_ctx != priv_->egl_ctx) {
    priv_->saved_egl_read = eglGetCurrentSurface(EGL_READ);
    priv_->saved_egl_draw = eglGetCurrentSurface(EGL_DRAW);
  } else {
    return 0;
  }

  if (!eglMakeCurrent(priv_->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                      priv_->egl_ctx)) {
    ALOGE("Failed to make the OpenGL ES Context current: %s", get_egl_error());
    return 1;
  }
  return 0;
}

int GLCompositor::EndContext() {
  if (priv_->saved_egl_display != eglGetCurrentDisplay() ||
      priv_->saved_egl_ctx != eglGetCurrentContext()) {
    if (!eglMakeCurrent(priv_->saved_egl_display, priv_->saved_egl_read,
                        priv_->saved_egl_draw, priv_->saved_egl_ctx)) {
      ALOGE("Failed to make the OpenGL ES Context current: %s",
            get_egl_error());
      return 1;
    }
  }

  return 0;
}

GLint CompileAndCheckShader(GLenum type, unsigned source_count,
                            const GLchar **sources, std::string *shader_log) {
  GLint status;
  GLint shader = glCreateShader(type);
  if (!shader) {
    *shader_log = "glCreateShader failed";
    return 0;
  }
  glShaderSource(shader, source_count, sources, NULL);
  glCompileShader(shader);
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if (!status) {
    if (shader_log) {
      GLint log_length;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
      shader_log->resize(log_length);
      glGetShaderInfoLog(shader, log_length, NULL, &(*shader_log)[0]);
    }
    glDeleteShader(shader);
    return 0;
  }

  return shader;
}

int GLCompositor::GenerateShaders() {
  // Limits: GL_MAX_VARYING_COMPONENTS, GL_MAX_TEXTURE_IMAGE_UNITS,
  // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
  // clang-format off
  const GLchar *shader_preamble = "#version 300 es\n#define LAYER_COUNT ";

  const GLchar *vertex_shader_source =
"\n"
"precision mediump int;                                                     \n"
"uniform vec4 uViewport;                                                    \n"
"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
"uniform vec4 uLayerCrop[LAYER_COUNT];                                      \n"
"in vec2 vPosition;                                                         \n"
"in vec2 vTexCoords;                                                        \n"
"out vec2 fTexCoords[LAYER_COUNT];                                          \n"
"void main() {                                                              \n"
"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
"    fTexCoords[i] = (uLayerCrop[i].xy + vTexCoords * uLayerCrop[i].zw) /   \n"
"                     vec2(textureSize(uLayerTextures[i], 0));              \n"
"  }                                                                        \n"
"  vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;           \n"
"  gl_Position = vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);    \n"
"}                                                                          \n";

  const GLchar *fragment_shader_source =
"\n"
"precision mediump float;                                                   \n"
"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
"uniform float uLayerAlpha[LAYER_COUNT];                                    \n"
"in vec2 fTexCoords[LAYER_COUNT];                                           \n"
"out vec4 oFragColor;                                                       \n"
"void main() {                                                              \n"
"  vec3 color = vec3(0.0, 0.0, 0.0);                                        \n"
"  float alphaCover = 1.0;                                                  \n"
"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
"    vec4 texSample = texture(uLayerTextures[i], fTexCoords[i]);            \n"
"    float a = texSample.a * uLayerAlpha[i];                                \n"
"    color += a * alphaCover * texSample.rgb;                               \n"
"    alphaCover *= 1.0 - a;                                                 \n"
"    if (alphaCover <= 0.5/255.0)                                           \n"
"      break;                                                               \n"
"  }                                                                        \n"
"  oFragColor = vec4(color, 1.0);                                           \n"
"}                                                                          \n";
  // clang-format on

  int i, ret = 1;
  GLint max_texture_images, vertex_shader, fragment_shader, program, status;
  std::string shader_log;

  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_images);

  for (i = 1; i <= max_texture_images; i++) {
    std::ostringstream layer_count_formatter;
    layer_count_formatter << i;
    std::string layer_count(layer_count_formatter.str());
    const GLchar *shader_sources[3] = {shader_preamble, layer_count.c_str(),
                                       NULL};

    shader_sources[2] = vertex_shader_source;
    vertex_shader = CompileAndCheckShader(GL_VERTEX_SHADER, 3, shader_sources,
                                          ret ? &shader_log : NULL);
    if (!vertex_shader) {
      if (ret) {
        ALOGE("Failed to make vertex shader:\n%s", shader_log.c_str());
      }
      break;
    }

    shader_sources[2] = fragment_shader_source;
    fragment_shader = CompileAndCheckShader(
        GL_FRAGMENT_SHADER, 3, shader_sources, ret ? &shader_log : NULL);
    if (!fragment_shader) {
      if (ret) {
        ALOGE("Failed to make fragment shader:\n%s", shader_log.c_str());
      }
      goto delete_vs;
    }

    program = glCreateProgram();
    if (!program) {
      if (ret)
        ALOGE("Failed to create program %s", get_gl_error());
      goto delete_fs;
    }

    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glBindAttribLocation(program, 0, "vPosition");
    glBindAttribLocation(program, 1, "vTexCoords");
    glLinkProgram(program);
    glDetachShader(program, vertex_shader);
    glDeleteShader(vertex_shader);
    glDetachShader(program, fragment_shader);
    glDeleteShader(fragment_shader);

    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (!status) {
      if (ret) {
        GLint log_length;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
        std::string program_log(log_length, ' ');
        glGetProgramInfoLog(program, log_length, NULL, &program_log[0]);
        ALOGE("Failed to link program: \n%s", program_log.c_str());
      }
      glDeleteProgram(program);
      break;
    }

    ret = 0;
    priv_->blend_programs.push_back(program);

    continue;

  delete_fs:
    glDeleteShader(fragment_shader);

  delete_vs:
    glDeleteShader(vertex_shader);

    if (ret)
      break;
  }

  return ret;
}

int GLCompositor::DoComposition(const GLComposition &composition) {
  int ret = 0;
  size_t i;
  std::vector<struct texture_from_handle> layer_textures;
  std::vector<RenderingCommand> commands;

  if (composition.layer_data.size() == 0) {
    return -EALREADY;
  }

  if (BeginContext()) {
    return -EINVAL;
  }

  GLTarget *target = &priv_->targets[composition.target_handle];
  GLint frame_width = target->fb->getWidth();
  GLint frame_height = target->fb->getHeight();
  EGLSyncKHR finished_sync;

  for (i = 0; i < composition.layer_data.size(); i++) {
    const struct hwc_layer_1 *layer = &composition.layer_data[i].layer;

    if (ret) {
      if (layer->acquireFenceFd >= 0)
        close(layer->acquireFenceFd);
      continue;
    }

    layer_textures.push_back(texture_from_handle());
    ret = CreateTextureFromHandle(layer->handle, &layer_textures.back());
    if (!ret) {
      ret = DoFenceWait(layer->acquireFenceFd);
    }
    if (ret) {
      layer_textures.pop_back();
      ret = -EINVAL;
    }
  }

  if (ret) {
    goto destroy_textures;
  }

  ConstructCommands(composition, &commands);

  glBindFramebuffer(GL_FRAMEBUFFER, target->gl_fb);

  glViewport(0, 0, frame_width, frame_height);

  glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT);

  glBindBuffer(GL_ARRAY_BUFFER, priv_->vertex_buffer);
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4,
                        (void *)(sizeof(float) * 2));
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);

  for (std::vector<RenderingCommand>::iterator it = commands.begin();
       it != commands.end(); ++it) {
    const RenderingCommand &cmd = *it;

    if (cmd.texture_count <= 0) {
      continue;
    }

    // TODO(zachr): handle the case of too many overlapping textures for one
    // area by falling back to rendering as many layers as possible using
    // multiple blending passes.
    if (cmd.texture_count > priv_->blend_programs.size()) {
      ALOGE("Too many layers to render in one area");
      continue;
    }

    GLint program = priv_->blend_programs[cmd.texture_count - 1];
    glUseProgram(program);
    GLint gl_viewport_loc = glGetUniformLocation(program, "uViewport");
    GLint gl_tex_loc = glGetUniformLocation(program, "uLayerTextures");
    GLint gl_crop_loc = glGetUniformLocation(program, "uLayerCrop");
    GLint gl_alpha_loc = glGetUniformLocation(program, "uLayerAlpha");
    glUniform4f(gl_viewport_loc, cmd.bounds[0] / (float)frame_width,
                cmd.bounds[1] / (float)frame_height,
                (cmd.bounds[2] - cmd.bounds[0]) / (float)frame_width,
                (cmd.bounds[3] - cmd.bounds[1]) / (float)frame_height);

    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
      const RenderingCommand::TextureSource &src = cmd.textures[src_index];
      glUniform1f(gl_alpha_loc + src_index, src.alpha);
      glUniform4f(gl_crop_loc + src_index, src.crop_bounds[0],
                  src.crop_bounds[1], src.crop_bounds[2] - src.crop_bounds[0],
                  src.crop_bounds[3] - src.crop_bounds[1]);

      glUniform1i(gl_tex_loc + src_index, src_index);
      glActiveTexture(GL_TEXTURE0 + src_index);
      glBindTexture(GL_TEXTURE_2D, layer_textures[src.texture_index].texture);
    }

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
      glActiveTexture(GL_TEXTURE0 + src_index);
      glBindTexture(GL_TEXTURE_2D, 0);
    }
  }

  glActiveTexture(GL_TEXTURE0);
  glDisableVertexAttribArray(0);
  glDisableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glUseProgram(0);

  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  finished_sync =
      eglCreateSyncKHR(priv_->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
  if (finished_sync != EGL_NO_SYNC_KHR) {
    glFlush();  // Creates the syncpoint
    ret = eglDupNativeFenceFDANDROID(priv_->egl_display, finished_sync);
    eglDestroySyncKHR(priv_->egl_display, finished_sync);
    if (ret != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
      goto destroy_textures;
    }
  }

  // Used as a fallback if the native sync fence fails.
  ret = -EALREADY;
  glFinish();

destroy_textures:
  for (i = 0; i < layer_textures.size(); i++)
    DestroyTextureFromHandle(layer_textures[i]);

  EndContext();

  return ret;
}

int GLCompositor::DoFenceWait(int acquireFenceFd) {
  int ret = 0;

  EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, acquireFenceFd,
                      EGL_NONE};
  EGLSyncKHR egl_sync = eglCreateSyncKHR(
      priv_->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
  if (egl_sync == EGL_NO_SYNC_KHR) {
    ALOGE("Failed to make EGLSyncKHR from acquireFenceFd: %s", get_egl_error());
    close(acquireFenceFd);
    return 1;
  }

  EGLint success = eglWaitSyncKHR(priv_->egl_display, egl_sync, 0);
  if (success == EGL_FALSE) {
    ALOGE("Failed to wait for acquire: %s", get_egl_error());
    ret = 1;
  }
  eglDestroySyncKHR(priv_->egl_display, egl_sync);

  return ret;
}

int GLCompositor::CreateTextureFromHandle(buffer_handle_t handle,
                                          struct texture_from_handle *tex) {
  EGLImageKHR image = eglCreateImageKHR(
      priv_->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX,
      (EGLClientBuffer)handle, NULL /* no attribs */);

  if (image == EGL_NO_IMAGE_KHR) {
    ALOGE("Failed to make image %s %p", get_egl_error(), handle);
    return 1;
  }

  glGenTextures(1, &tex->texture);
  glBindTexture(GL_TEXTURE_2D, tex->texture);
  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  tex->image = image;

  return 0;
}

void GLCompositor::DestroyTextureFromHandle(
    const struct texture_from_handle &tex) {
  glDeleteTextures(1, &tex.texture);
  eglDestroyImageKHR(priv_->egl_display, tex.image);
}

static const char *get_gl_error(void) {
  switch (glGetError()) {
    case GL_NO_ERROR:
      return "GL_NO_ERROR";
    case GL_INVALID_ENUM:
      return "GL_INVALID_ENUM";
    case GL_INVALID_VALUE:
      return "GL_INVALID_VALUE";
    case GL_INVALID_OPERATION:
      return "GL_INVALID_OPERATION";
    case GL_INVALID_FRAMEBUFFER_OPERATION:
      return "GL_INVALID_FRAMEBUFFER_OPERATION";
    case GL_OUT_OF_MEMORY:
      return "GL_OUT_OF_MEMORY";
    default:
      return "Unknown error";
  }
}

static const char *get_egl_error(void) {
  switch (eglGetError()) {
    case EGL_SUCCESS:
      return "EGL_SUCCESS";
    case EGL_NOT_INITIALIZED:
      return "EGL_NOT_INITIALIZED";
    case EGL_BAD_ACCESS:
      return "EGL_BAD_ACCESS";
    case EGL_BAD_ALLOC:
      return "EGL_BAD_ALLOC";
    case EGL_BAD_ATTRIBUTE:
      return "EGL_BAD_ATTRIBUTE";
    case EGL_BAD_CONTEXT:
      return "EGL_BAD_CONTEXT";
    case EGL_BAD_CONFIG:
      return "EGL_BAD_CONFIG";
    case EGL_BAD_CURRENT_SURFACE:
      return "EGL_BAD_CURRENT_SURFACE";
    case EGL_BAD_DISPLAY:
      return "EGL_BAD_DISPLAY";
    case EGL_BAD_SURFACE:
      return "EGL_BAD_SURFACE";
    case EGL_BAD_MATCH:
      return "EGL_BAD_MATCH";
    case EGL_BAD_PARAMETER:
      return "EGL_BAD_PARAMETER";
    case EGL_BAD_NATIVE_PIXMAP:
      return "EGL_BAD_NATIVE_PIXMAP";
    case EGL_BAD_NATIVE_WINDOW:
      return "EGL_BAD_NATIVE_WINDOW";
    case EGL_CONTEXT_LOST:
      return "EGL_CONTEXT_LOST";
    default:
      return "Unknown error";
  }
}

static bool has_extension(const char *extension, const char *extensions) {
  const char *start, *where, *terminator;
  start = extensions;
  for (;;) {
    where = (char *)strstr((const char *)start, extension);
    if (!where)
      break;
    terminator = where + strlen(extension);
    if (where == start || *(where - 1) == ' ')
      if (*terminator == ' ' || *terminator == '\0')
        return true;
    start = terminator;
  }
  return false;
}

}  // namespace android
