/*
 * Copyright © 2010-2012 Linaro Limited
 *
 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
 *
 * glmark2 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * glmark2.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Alexandros Frantzis (glmark2)
 *  Jesse Barker
 *  Simon Que
 */
#include "canvas-drm.h"
#include "log.h"
#include "options.h"
#include "util.h"

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <time.h>

#include <fstream>
#include <sstream>
#include <list>

/******************
 * Public methods *
 ******************/

bool
CanvasDRM::reset()
{
    if (!reset_context())
        return false;

    if (!make_current())
        return false;

    if (!supports_gl2()) {
        Log::error("Glmark2 needs OpenGL(ES) version >= 2.0 to run"
                   " (but version string is: '%s')!\n",
                   glGetString(GL_VERSION));
        return false;
    }

    glViewport(0, 0, width_, height_);

    clear();
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    return true;
}

bool
CanvasDRM::init()
{
    EGLint major, minor;
    const char *ver, *extensions;
    uint32_t handle, stride;
    int i, retval;
    const char device_name[] = "/dev/dri/card0";

    num_buffers_ = Options::num_buffers;
    current_front_buffer_index_ = -1;

    signal(SIGINT, &CanvasDRM::quit_handler);

    fd_ = open(device_name, O_RDWR);
    if (fd_ < 0) {
        // Probably permissions error
        fprintf(stderr, "Couldn't open %s, skipping.\n", device_name);
        return false;
    }

    gbm_ = gbm_create_device(fd_);
    if (gbm_ == NULL) {
        fprintf(stderr, "Couldn't create GBM device.\n");
        goto close_fd;
    }

    egl_display_ = eglGetDisplay(gbm_);
    if (egl_display_ == EGL_NO_DISPLAY) {
        fprintf(stderr, "eglGetDisplay() failed.\n");
        goto destroy_gbm_device;
    }

    if (!eglInitialize(egl_display_, &major, &minor)) {
        fprintf(stderr, "eglInitialize() failed.\n");
        goto egl_terminate;
    }

    ver = eglQueryString(egl_display_, EGL_VERSION);
    printf("EGL_VERSION = %s\n", ver);

    extensions = eglQueryString(egl_display_, EGL_EXTENSIONS);
    printf("EGL_EXTENSIONS: %s\n", extensions);

    if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) {
        printf("No support for EGL_KHR_surfaceless_opengl.\n");
        goto egl_terminate;
    }

    if (!setup_kms(fd_, &kms_))
         goto egl_terminate;

    eglBindAPI(EGL_OPENGL_API);
    egl_context_ = eglCreateContext(egl_display_, NULL, EGL_NO_CONTEXT, NULL);
    if (egl_context_ == NULL) {
        fprintf(stderr, "Failed to create context.\n");
        goto egl_terminate;
    }

    if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
                        egl_context_)) {
        fprintf(stderr, "Failed to make context current.\n");
        goto destroy_context;
    }

    if (GLExtensions::MapBuffer == NULL && GLExtensions::UnmapBuffer == NULL)
        init_gl_extensions();

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

    render_buffers_.resize(num_buffers_);
    buffer_objs_.resize(num_buffers_);
    kms_.fb_ids.resize(num_buffers_);
    images_.resize(num_buffers_);

    for (i = 0; i < num_buffers_; i++) {
        glGenRenderbuffers(1, &render_buffers_[i]);
        glBindRenderbuffer(GL_RENDERBUFFER, render_buffers_[i]);

        buffer_objs_[i] =
            gbm_bo_create(gbm_, kms_.mode.hdisplay, kms_.mode.vdisplay,
                          GBM_BO_FORMAT_XRGB8888,
                          GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
        if (buffer_objs_[i] == NULL) {
            fprintf(stderr, "Failed to create GBM buffer objects.\n");
            goto unmake_current;
        }
        handle = gbm_bo_get_handle(buffer_objs_[i]).u32;
        stride = gbm_bo_get_pitch(buffer_objs_[i]);

        images_[i] = eglCreateImageKHR(egl_display_, NULL,
                                       EGL_NATIVE_PIXMAP_KHR,
                                       buffer_objs_[i], NULL);
        if (images_[i] == EGL_NO_IMAGE_KHR) {
            fprintf(stderr, "Failed to create EGL image.\n");
            goto destroy_gbm_bo;
        }

#ifdef GL_OES_EGL_image
        glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, images_[i]);
#else
        fprintf(stderr, "GL_OES_EGL_image was not found at compile time.\n");
#endif

        glGenRenderbuffers(1, &depth_rb_);
        glBindRenderbuffer(GL_RENDERBUFFER, depth_rb_);
        glRenderbufferStorage(GL_RENDERBUFFER,
                              GL_DEPTH_COMPONENT,
                              kms_.mode.hdisplay, kms_.mode.vdisplay);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                  GL_RENDERBUFFER,
                                  depth_rb_);

        retval = drmModeAddFB(fd_, kms_.mode.hdisplay, kms_.mode.vdisplay,
                              24, 32, stride, handle, &kms_.fb_ids[i]);
        if (retval) {
            fprintf(stderr, "Failed to create framebuffer.\n");
            goto rm_rb;
        }
        available_buffers_.push(i);
    }

    current_back_buffer_index_ = available_buffers_.front();
    available_buffers_.pop();
    saved_crtc_ = drmModeGetCrtc(fd_, kms_.encoder->crtc_id);
    if (saved_crtc_ == NULL)
        goto rm_fb;

    if (!reset())
    {
        fprintf(stderr, "failed to reset canvas!\n");
        goto drm_mode_free_crtc;
    }

    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER,
                              render_buffers_[current_back_buffer_index_]);
    if ((retval = glCheckFramebufferStatus(GL_FRAMEBUFFER)) !=
        GL_FRAMEBUFFER_COMPLETE) {
        fprintf(stderr, "framebuffer not complete: %x\n", retval);
        goto drm_mode_free_crtc;
    }
    resize_no_viewport(width_, height_);
    return true;

drm_mode_free_crtc:
    drmModeFreeCrtc(saved_crtc_);
rm_rb:
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    for (i = 0; i < num_buffers_; i++)
      glDeleteRenderbuffers(1, &render_buffers_[i]);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, 0);
    glDeleteRenderbuffers(1, &depth_rb_);
rm_fb:
    for (i = 0; i < num_buffers_; i++) {
        drmModeRmFB(fd_, kms_.fb_ids[i]);
        eglDestroyImageKHR(egl_display_, images_[i]);
    }
destroy_gbm_bo:
    for (i = 0; i < num_buffers_; i++)
        gbm_bo_destroy(buffer_objs_[i]);
unmake_current:
    eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
                   EGL_NO_CONTEXT);
destroy_context:
    eglDestroyContext(egl_display_, egl_context_);
egl_terminate:
    eglTerminate(egl_display_);
destroy_gbm_device:
    gbm_device_destroy(gbm_);
close_fd:
    close(fd_);

    return false;
}


CanvasDRM::~CanvasDRM() {
    int i, ret;
    ret = drmModeSetCrtc(fd_, saved_crtc_->crtc_id, saved_crtc_->buffer_id,
                         saved_crtc_->x, saved_crtc_->y,
                         &kms_.connector->connector_id, 1, &saved_crtc_->mode);
    if (ret) {
        fprintf(stderr, "Failed to restore crtc: %d\n", ret);
    }

    drmModeFreeCrtc(saved_crtc_);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    for (i = 0; i < num_buffers_; i++)
        glDeleteRenderbuffers(1, &render_buffers_[i]);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, 0);
    glDeleteRenderbuffers(1, &depth_rb_);

    for (i = 0; i < num_buffers_; i++) {
        drmModeRmFB(fd_, kms_.fb_ids[i]);
        eglDestroyImageKHR(egl_display_, images_[i]);
    }
    for (i = 0; i < num_buffers_; i++)
        gbm_bo_destroy(buffer_objs_[i]);
    eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
                   EGL_NO_CONTEXT);
    eglDestroyContext(egl_display_, egl_context_);
    eglTerminate(egl_display_);
    gbm_device_destroy(gbm_);
    close(fd_);
}

void
CanvasDRM::visible(bool /* visible */)
{

}

void CanvasDRM::clear()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
#if USE_GL
    glClearDepth(1.0f);
#elif USE_GLESv2
    glClearDepthf(1.0f);
#endif
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void CanvasDRM::update()
{
    if (Options::swap_buffers)
        swap_buffers();
    else
        glFinish();
}

void CanvasDRM::print_info()
{
    make_current();

    std::stringstream ss;
    ss << "    OpenGL Information" << std::endl;
    ss << "    GL_VENDOR:     " << glGetString(GL_VENDOR) << std::endl;
    ss << "    GL_RENDERER:   " << glGetString(GL_RENDERER) << std::endl;
    ss << "    GL_VERSION:    " << glGetString(GL_VERSION) << std::endl;
    Log::info("%s", ss.str().c_str());
}

Canvas::Pixel CanvasDRM::read_pixel(int x, int y)
{
    uint8_t pixel[4];
    glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
    return Canvas::Pixel(pixel[0], pixel[1], pixel[2], pixel[3]);
}

void CanvasDRM::write_to_file(std::string &filename)
{
    char *pixels = new char[width_ * height_ * 4];

    for (int i = 0; i < height_; i++) {
        glReadPixels(0, i, width_, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                     &pixels[(height_ - i - 1) * width_ * 4]);
    }

    std::ofstream output (filename.c_str(), std::ios::out | std::ios::binary);
    output.write(pixels, 4 * width_ * height_);

    delete [] pixels;
}

bool
CanvasDRM::should_quit()
{
    return should_quit_;
}

void
CanvasDRM::resize(int width, int height)
{
    resize_no_viewport(width, height);
    glViewport(0, 0, width_, height_);
}

int
CanvasDRM::get_frame_buffer() {
    return fb_;
}

/*********************
 * Protected methods *
 *********************/

bool CanvasDRM::supports_gl2()
{
    std::string gl_version_str(
        reinterpret_cast<const char*>(glGetString(GL_VERSION)));
    int gl_major = 0;

    size_t point_pos(gl_version_str.find('.'));

    if (point_pos != std::string::npos) {
        point_pos--;

        size_t start_pos(gl_version_str.rfind(' ', point_pos));
        if (start_pos == std::string::npos)
            start_pos = 0;
        else
            start_pos++;

        gl_major = Util::fromString<int>(
                gl_version_str.substr(start_pos, point_pos - start_pos + 1)
                );
    }

    return gl_major >= 2;
}

bool CanvasDRM::make_current()
{
    if (!ensure_egl_surface())
        return false;

    if (!ensure_egl_context())
        return false;

    if (egl_context_ == eglGetCurrentContext())
        return true;

    if (!eglMakeCurrent(egl_display_, egl_surface_, egl_surface_,
        egl_context_)) {
        Log::error("Error: eglMakeCurrent failed with error %d\n",
                   eglGetError());
        return false;
    }

    if (!eglSwapInterval(egl_display_, 0))
        Log::info("** Failed to set swap interval. Results may be bounded above"
                  " by refresh rate.\n");
    init_gl_extensions();
    return true;
}
bool CanvasDRM::reset_context()
{
    if (!ensure_egl_display())
        return false;

    if (!egl_context_)
        return true;

    if (eglDestroyContext(egl_display_, egl_context_) == EGL_FALSE) {
        Log::debug("eglDestroyContext() failed with error: 0x%x\n",
                   eglGetError());
    }

    egl_context_ = 0;
    return true;
}
extern unsigned int *nitrous_timestamps;

void CanvasDRM::swap_buffers()
{
    int ret;

    rendered_buffers_.push(current_back_buffer_index_);

    pollfd poll_data;
    poll_data.fd = fd_;
    poll_data.events = POLLIN;

    // Check the display controller to see if it has data to be read back.
    ret = poll(&poll_data, 1, 0);
    // If there is display controller data available, or there are no more
    // free buffers, handle the display controller data.
    if (ret > 0 || available_buffers_.empty()) {
        // Make sure there is data available.
        if (ret <= 0)
            while (poll(&poll_data, 1, -1) <= 0);

        // Handle the display controller page flip event(s).
        drmEventContext event_context;
        memset(&event_context, 0, sizeof event_context);
        event_context.version = DRM_EVENT_CONTEXT_VERSION;
        event_context.page_flip_handler = CanvasDRM::page_flip_handler;
        drmHandleEvent(fd_, &event_context);
    }
    // Get the next buffer for rendering.
    current_back_buffer_index_ = available_buffers_.front();
    available_buffers_.pop();
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER,
                              render_buffers_[current_back_buffer_index_]);
    if ((ret = glCheckFramebufferStatus(GL_FRAMEBUFFER)) !=
        GL_FRAMEBUFFER_COMPLETE) {
        fprintf(stderr, "framebuffer not complete: %x\n", ret);
        return;
    }

    // Attempt to flip to the first rendered buffer in the queue.
    if (current_front_buffer_index_ < 0) {
        ret = drmModePageFlip(fd_, kms_.encoder->crtc_id,
                              kms_.fb_ids[rendered_buffers_.front()],
                              DRM_MODE_PAGE_FLIP_EVENT, this);
        if (!ret) {
            // If flip was successful, take it out of the queue.
            current_front_buffer_index_ = rendered_buffers_.front();
            rendered_buffers_.pop();
        }
    }
}

bool
CanvasDRM::ensure_egl_display()
{
    if (egl_display_)
        return true;

    egl_display_ = eglGetDisplay((EGLNativeDisplayType) egl_display_);
    if (!egl_display_) {
        Log::error("eglGetDisplay() failed with error: %d\n",
                   eglGetError());
        return false;
    }

    if (!eglInitialize(egl_display_, NULL, NULL)) {
        Log::error("eglInitialize() failed with error: %d\n",
                   eglGetError());
        return false;
        egl_display_ = 0;
    }

    return true;
}

bool
CanvasDRM::ensure_egl_config()
{
    static const EGLint attribs[] = {
        EGL_RED_SIZE, 1,
        EGL_GREEN_SIZE, 1,
        EGL_BLUE_SIZE, 1,
        EGL_ALPHA_SIZE, 1,
        EGL_DEPTH_SIZE, 1,
#if USE_GLESv2
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#elif USE_GL
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
#endif
        EGL_NONE
    };
    EGLint num_configs;
    EGLint vid;

    if (egl_config_)
        return true;

    if (!ensure_egl_display())
        return false;

    if (!eglChooseConfig(egl_display_, attribs, &egl_config_, 1,
                         &num_configs)) {
        Log::error("eglChooseConfig() failed with error: %d\n", eglGetError());
        return false;
    }

    if (!eglGetConfigAttrib(egl_display_, egl_config_,
                            EGL_NATIVE_VISUAL_ID, &vid)) {
        Log::error("eglGetConfigAttrib() failed with error: %d\n",
                   eglGetError());
        return false;
    }

    if (Options::show_debug) {
        int buf, red, green, blue, alpha, depth, id, native_id;
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_CONFIG_ID, &id);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_NATIVE_VISUAL_ID,
                           &native_id);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_BUFFER_SIZE, &buf);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_RED_SIZE, &red);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_GREEN_SIZE, &green);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_BLUE_SIZE, &blue);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_ALPHA_SIZE, &alpha);
        eglGetConfigAttrib(egl_display_, egl_config_, EGL_DEPTH_SIZE, &depth);
        Log::debug("EGL chosen config ID: 0x%x Native Visual ID: 0x%x\n"
                   "  Buffer: %d bits\n"
                   "     Red: %d bits\n"
                   "   Green: %d bits\n"
                   "    Blue: %d bits\n"
                   "   Alpha: %d bits\n"
                   "   Depth: %d bits\n",
                   id, native_id,
                   buf, red, green, blue, alpha, depth);
    }

    return true;
}

bool
CanvasDRM::ensure_egl_context()
{
    return true;
}

bool
CanvasDRM::ensure_egl_surface()
{
    return true;
}

void
CanvasDRM::init_gl_extensions()
{
#if USE_GLESv2
    /*
     * Parse the extensions we care about from the extension string.
     * Don't even bother to get function pointers until we know the
     * extension is present.
     */
    std::string extString;
    const char* exts =
        reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
    if (exts)
        extString = exts;

    if (extString.find("GL_OES_mapbuffer") != std::string::npos) {
        GLExtensions::MapBuffer = reinterpret_cast<PFNGLMAPBUFFEROESPROC>(
            eglGetProcAddress("glMapBufferOES"));
        GLExtensions::UnmapBuffer = reinterpret_cast<PFNGLUNMAPBUFFEROESPROC>(
            eglGetProcAddress("glUnmapBufferOES"));
    }
#elif USE_GL
    GLExtensions::MapBuffer = glMapBuffer;
    GLExtensions::UnmapBuffer = glUnmapBuffer;
#endif
}


/*******************
 * Private methods *
 *******************/

void
CanvasDRM::resize_no_viewport(int width, int height)
{
    width_ = width;
    height_ = height;

    projection_ =
        LibMatrix::Mat4::perspective(60.0, width_ / static_cast<float>(height_),
                                     1.0, 1024.0);
}

EGLBoolean CanvasDRM::setup_kms(int fd_, struct CanvasDRM::kms *kms_)
{
    drmModeRes *resources = NULL;
    drmModeConnector *connector = NULL;
    drmModeEncoder *encoder = NULL;
    int i;

    resources = drmModeGetResources(fd_);
    if (!resources) {
        fprintf(stderr, "drmModeGetResources failed\n");
        return EGL_FALSE;
    }

    for (i = 0; i < resources->count_connectors; i++) {
        connector = drmModeGetConnector(fd_, resources->connectors[i]);
        if (connector == NULL)
            continue;

        if (connector->connection == DRM_MODE_CONNECTED &&
        connector->count_modes > 0)
            break;

        drmModeFreeConnector(connector);
    }

    if (i == resources->count_connectors) {
        fprintf(stderr, "No currently active connector found.\n");
        return EGL_FALSE;
    }

    for (i = 0; i < resources->count_encoders; i++) {
        encoder = drmModeGetEncoder(fd_, resources->encoders[i]);

    if (encoder == NULL)
        continue;

    if (encoder->encoder_id == connector->encoder_id)
        break;

        drmModeFreeEncoder(encoder);
    }

    kms_->connector = connector;
    kms_->encoder = encoder;
    kms_->mode = connector->modes[0];

    return EGL_TRUE;
}


void CanvasDRM::page_flip_handler(int /* fd */, unsigned int /* frame */,
    unsigned int /* sec */, unsigned int /* usec */, void* data)
{
    CanvasDRM* canvas = reinterpret_cast<CanvasDRM*> (data);
    canvas->available_buffers_.push(canvas->current_front_buffer_index_);
    canvas->current_front_buffer_index_ = -1;
}

bool CanvasDRM::should_quit_ = false;

void CanvasDRM::quit_handler(int /* signum */)
{
    should_quit_ = true;
}
