// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "screen-capture-utils/egl_capture.h"

#include <sys/mman.h>

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

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <xf86drm.h>
#include <xf86drmMode.h>

#include <string>
#include <utility>
#include <vector>

#include "base/strings/string_split.h"
#include "screen-capture-utils/crtc.h"

namespace screenshot {
namespace {

constexpr int kBytesPerPixel = 4;

GLuint LoadShader(const GLenum type, const char* const src) {
  GLuint shader = 0;
  shader = glCreateShader(type);
  CHECK(shader) << "Failed to to create shader";

  glShaderSource(shader, 1, &src, 0);
  glCompileShader(shader);

  GLint compiled = 0;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  if (compiled != GL_TRUE) {
    GLint log_length;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
    std::vector<char> shader_log(log_length);
    glGetShaderInfoLog(shader, log_length, nullptr, shader_log.data());
    CHECK(false) << "Shader failed to compile: " << shader_log.data()
                 << ": program: " << src;
  }

  return shader;
}

GLuint LoadProgram(const GLchar* vert, const GLchar* frag) {
  GLint program = glCreateProgram();
  GLuint vertex_shader = LoadShader(GL_VERTEX_SHADER, vert);
  GLuint frag_shader = LoadShader(GL_FRAGMENT_SHADER, frag);
  glAttachShader(program, vertex_shader);
  glAttachShader(program, frag_shader);
  glLinkProgram(program);

  GLint linked = -1;
  glGetProgramiv(program, GL_LINK_STATUS, &linked);
  if (linked != GL_TRUE) {
    GLint log_length = 0;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
    std::vector<char> program_log(log_length);
    glGetProgramInfoLog(program, log_length, nullptr, program_log.data());
    CHECK(false) << "GL program failed to link: " << program_log.data();
  }
  glUseProgram(program);
  glUniform1i(glGetUniformLocation(program, "tex"), 0);

  glDeleteProgram(program);
  glDeleteShader(vertex_shader);
  glDeleteShader(frag_shader);
  return program;
}

bool DoesExtensionExist(const char* extension_string, const char* name) {
  std::vector<std::string> extensions = base::SplitString(
      extension_string, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  return std::find(extensions.begin(), extensions.end(), std::string(name)) !=
         extensions.end();
}

EGLImageKHR CreateImage(PFNEGLCREATEIMAGEKHRPROC CreateImageKHR,
                        bool import_modifiers_exist,
                        int drm_fd,
                        EGLDisplay display,
                        const drmModeFB2Ptr fb) {
  int num_planes = 0;
  // CreateImageKHR takes its own references to the dma-bufs, so closing the fds
  // at the end of the function is necessary and won't break the returned image.
  base::ScopedFD fds[GBM_MAX_PLANES] = {};
  for (size_t plane = 0; plane < GBM_MAX_PLANES; plane++) {
    // getfb2() doesn't return the number of planes so get handles
    // and count planes until we find a handle that isn't set
    if (fb->handles[plane] == 0)
      break;

    int fd;
    int ret = drmPrimeHandleToFD(drm_fd, fb->handles[plane], 0, &fd);
    CHECK_EQ(ret, 0) << "drmPrimeHandleToFD failed";
    fds[plane].reset(fd);
    num_planes++;
  }

  CHECK_GT(num_planes, 0);

  EGLint attr_list[46] = {
      EGL_WIDTH,
      static_cast<EGLint>(fb->width),
      EGL_HEIGHT,
      static_cast<EGLint>(fb->height),
      EGL_LINUX_DRM_FOURCC_EXT,
      static_cast<EGLint>(fb->pixel_format),
  };

  size_t attrs_index = 6;

  for (size_t plane = 0; plane < num_planes; plane++) {
    attr_list[attrs_index++] = EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3;
    attr_list[attrs_index++] = fds[plane].get();
    attr_list[attrs_index++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3;
    attr_list[attrs_index++] = fb->offsets[plane];
    attr_list[attrs_index++] = EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3;
    attr_list[attrs_index++] = fb->pitches[plane];

    // If DRM_MODE_FB_MODIFIERS is not set, it means the modifiers are
    // determined implicitly in a driver-specific manner. As such we only
    // set the modifier if we got a framebuffer with explicit modifier and
    // an EGL driver that supports explicit modifiers.
    if (import_modifiers_exist && (fb->flags & DRM_MODE_FB_MODIFIERS)) {
      attr_list[attrs_index++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT + plane * 2;
      attr_list[attrs_index++] = fb->modifier & 0xfffffffful;
      attr_list[attrs_index++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT + plane * 2;
      attr_list[attrs_index++] = fb->modifier >> 32;
    }
  }

  attr_list[attrs_index] = EGL_NONE;

  EGLImageKHR image = CreateImageKHR(display, EGL_NO_CONTEXT,
                                     EGL_LINUX_DMA_BUF_EXT, 0, attr_list);
  CHECK(image != EGL_NO_IMAGE_KHR) << "Failed to create image";

  return image;
}

void WaitVBlank(int fd) {
  drmVBlank vbl;
  memset(&vbl, 0, sizeof vbl);
  vbl.request.type = DRM_VBLANK_RELATIVE;
  vbl.request.sequence = 1;
  drmWaitVBlank(fd, &vbl);
}

}  // namespace

EglDisplayBuffer::EglDisplayBuffer(
    const Crtc* crtc, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
    : crtc_(*crtc),
      x_(x),
      y_(y),
      width_(width),
      height_(height),
      device_(gbm_create_device(crtc_.file().GetPlatformFile())),
      display_(eglGetDisplay(EGL_DEFAULT_DISPLAY)),
      buffer_(width_ * height_ * kBytesPerPixel) {
  CHECK(device_) << "gbm_create_device failed";

  CHECK(display_ != EGL_NO_DISPLAY) << "Could not get EGLDisplay";

  EGLBoolean egl_ret = eglInitialize(display_, NULL, NULL);
  CHECK(egl_ret) << "Could not initialize EGLDisplay";

  const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_DONT_CARE,
                                   EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                                   EGL_NONE};

  const EGLint GLES2[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};

  EGLint num_configs;
  EGLConfig config;

  egl_ret = eglChooseConfig(display_, config_attribs, &config, 1, &num_configs);
  CHECK(egl_ret) << "Could not choose EGLConfig";
  CHECK(num_configs != 0) << "Could not choose an EGL configuration";

  ctx_ = eglCreateContext(display_, config, EGL_NO_CONTEXT, GLES2);
  CHECK(ctx_ != EGL_NO_CONTEXT) << "Could not create EGLContext";

  egl_ret = eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx_);
  CHECK(egl_ret) << "Could not bind context";

  std::string egl_extensions = eglQueryString(display_, EGL_EXTENSIONS);
  CHECK(egl_extensions.find("EGL_KHR_image_base") != std::string::npos)
      << "Missing EGL extension: EGL_KHR_image_base";
  CHECK(egl_extensions.find("EGL_EXT_image_dma_buf_import") !=
        std::string::npos)
      << "Missing EGL extension: EGL_EXT_image_dma_buf_import";

  std::string gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
  CHECK(gl_extensions.find("GL_OES_EGL_image") != std::string::npos)
      << "Missing GL extension: GL_OES_EGL_image";
  CHECK(gl_extensions.find("GL_OES_EGL_image_external") != std::string::npos)
      << "Missing GL extension: GL_OES_EGL_image_external";
  createImageKHR_ =
      (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
  CHECK(createImageKHR_) << "CreateImageKHR not supported";
  destroyImageKHR_ =
      (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
  CHECK(destroyImageKHR_) << "DestroyImageKHR not supported";

  const char* extensions = eglQueryString(display_, EGL_EXTENSIONS);
  CHECK(extensions) << "eglQueryString() failed to get egl extensions";
  import_modifiers_exist_ =
      DoesExtensionExist(extensions, "EGL_EXT_image_dma_buf_import_modifiers");

  glGenTextures(1, &output_texture_);
  glBindTexture(GL_TEXTURE_2D, output_texture_);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA,
               GL_UNSIGNED_BYTE, NULL);

  glGenTextures(1, &input_texture_);
  glBindTexture(GL_TEXTURE_EXTERNAL_OES, input_texture_);

  glEGLImageTargetTexture2DOES_ =
      (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress(
          "glEGLImageTargetTexture2DOES");
  CHECK(glEGLImageTargetTexture2DOES_)
      << "glEGLImageTargetTexture2DOES not supported";

  glGenFramebuffers(1, &fbo_);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo_);

  const GLchar* vert = R"(#version 300 es
out vec2 tex_pos;
uniform vec2 uvs[4];
void main() {
  vec2 pos[4];
  pos[0] = vec2(-1.0, -1.0);
  pos[1] = vec2(1.0, -1.0);
  pos[2] = vec2(-1.0, 1.0);
  pos[3] = vec2(1.0, 1.0);
  gl_Position.xy = pos[gl_VertexID];
  gl_Position.zw = vec2(0.0, 1.0);
  tex_pos = uvs[gl_VertexID];
}
)";

  const GLchar* frag = R"(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;
uniform samplerExternalOES tex;
in vec2 tex_pos;
out vec4 fragColor;
void main() {
  fragColor = texture(tex, tex_pos);
}
)";

  GLuint program = LoadProgram(vert, frag);
  uvs_uniform_location_ = glGetUniformLocation(program, "uvs");

  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                         output_texture_, 0);

  GLenum fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << "fb did not complete";

  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

EglDisplayBuffer::~EglDisplayBuffer() {
  eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  glDeleteTextures(1, &input_texture_);
  glDeleteTextures(1, &output_texture_);
  glDeleteFramebuffers(1, &fbo_);
  eglDestroyContext(display_, ctx_);
  eglTerminate(display_);
}

DisplayBuffer::Result EglDisplayBuffer::Capture() {
  WaitVBlank(crtc_.file().GetPlatformFile());

  auto connected_planes = crtc_.GetConnectedPlanes();
  if (connected_planes.empty()) {
    EGLImageKHR image =
        CreateImage(createImageKHR_, import_modifiers_exist_,
                    crtc_.file().GetPlatformFile(), display_, crtc_.fb2());
    CHECK(image != EGL_NO_IMAGE_KHR) << "Failed to create image";

    SetUVRect(/*crop_x=*/0, /*crop_y=*/0, /*crop_width=*/crtc_.fb2()->width,
              /*crop_height=*/crtc_.fb2()->height,
              /*src_width=*/crtc_.fb2()->width,
              /*src_height=*/crtc_.fb2()->height);
    glViewport(0, 0, width_, height_);
    glEGLImageTargetTexture2DOES_(GL_TEXTURE_EXTERNAL_OES, image);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    destroyImageKHR_(display_, image);
  } else {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    for (auto& plane : connected_planes) {
      EGLImageKHR image = CreateImage(createImageKHR_, import_modifiers_exist_,
                                      crtc_.file().GetPlatformFile(), display_,
                                      plane.first.get());
      CHECK(image != EGL_NO_IMAGE_KHR) << "Failed to create image";

      // Handle the plane's crop rectangle.
      SetUVRect(plane.second.crop_x, plane.second.crop_y, plane.second.crop_w,
                plane.second.crop_h, /*src_width=*/plane.first->width,
                /*src_height=*/plane.first->height);

      // TODO(andrescj): Handle rotation.
      glViewport(plane.second.x, plane.second.y, plane.second.w,
                 plane.second.h);

      glEGLImageTargetTexture2DOES_(GL_TEXTURE_EXTERNAL_OES, image);

      glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

      destroyImageKHR_(display_, image);
    }
  }

  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  // TODO(uekawa): potentially improve speed by creating a bo and writing to
  // it instead of reading out.
  glReadPixels(x_, y_, width_, height_, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
               buffer_.data());

  return {
      width_, height_,
      width_ * kBytesPerPixel,            // stride
      static_cast<void*>(buffer_.data())  // buffer
  };
}

void EglDisplayBuffer::SetUVRect(float crop_x,
                                 float crop_y,
                                 float crop_width,
                                 float crop_height,
                                 uint32_t src_width,
                                 uint32_t src_height) {
  const float uv_left = crop_x / src_width;
  const float uv_right = (crop_x + crop_width) / src_width;
  const float uv_top = crop_y / src_height;
  const float uv_bottom = (crop_y + crop_height) / src_height;
  // |uvs| is an array of 4 vec2s: each pair of elements represents X and Y
  // coordinates.
  GLfloat uvs[] = {
      // clang-format off
      uv_left,  uv_top,
      uv_right, uv_top,
      uv_left,  uv_bottom,
      uv_right, uv_bottom
      // clang-format on
  };
  glUniform2fv(uvs_uniform_location_, 4, uvs);
}

}  // namespace screenshot
