/*
 * GTK UI -- egl opengl code.
 *
 * Note that gtk 3.16+ (released 2015-03-23) has a GtkGLArea widget,
 * which is GtkDrawingArea like widget with opengl rendering support.
 *
 * This code handles opengl support on older gtk versions, using egl
 * to get a opengl context for the X11 window.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"

#include "trace.h"

#include "ui/console.h"
#include "ui/gtk.h"
#include "ui/egl-helpers.h"
#include "ui/shader.h"

#include "system/system.h"

static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
{
    if (vc->gfx.scanout_mode == scanout) {
        return;
    }

    vc->gfx.scanout_mode = scanout;
    if (!vc->gfx.scanout_mode) {
        eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                       vc->gfx.esurface, vc->gfx.ectx);
        egl_fb_destroy(&vc->gfx.guest_fb);
        if (vc->gfx.surface) {
            surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
        }
    }
}

/** DisplayState Callbacks (opengl version) **/

void gd_egl_init(VirtualConsole *vc)
{
    GdkWindow *gdk_window = gtk_widget_get_window(vc->gfx.drawing_area);
    if (!gdk_window) {
        return;
    }

    Window x11_window = gdk_x11_window_get_xid(gdk_window);
    if (!x11_window) {
        return;
    }

    vc->gfx.ectx = qemu_egl_init_ctx();
    vc->gfx.esurface = qemu_egl_init_surface_x11
        (vc->gfx.ectx, (EGLNativeWindowType)x11_window);

    assert(vc->gfx.esurface);
}

void gd_egl_draw(VirtualConsole *vc)
{
    GdkWindow *window;
#ifdef CONFIG_GBM
    QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
    int fence_fd;
#endif
    int ww, wh, pw, ph, gs;

    if (!vc->gfx.gls || !vc->gfx.ds) {
        return;
    }

    window = gtk_widget_get_window(vc->gfx.drawing_area);
    gs = gdk_window_get_scale_factor(window);
    ww = gdk_window_get_width(window);
    wh = gdk_window_get_height(window);
    pw = ww * gs;
    ph = wh * gs;

    if (vc->gfx.scanout_mode) {
#ifdef CONFIG_GBM
        if (dmabuf) {
            if (!qemu_dmabuf_get_draw_submitted(dmabuf)) {
                return;
            } else {
                qemu_dmabuf_set_draw_submitted(dmabuf, false);
            }
        }
#endif
        gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);

        gd_update_scale(vc, ww, wh,
                        surface_width(vc->gfx.ds),
                        surface_height(vc->gfx.ds));

        glFlush();
#ifdef CONFIG_GBM
        if (dmabuf) {
            egl_dmabuf_create_fence(dmabuf);
            fence_fd = qemu_dmabuf_get_fence_fd(dmabuf);
            if (fence_fd >= 0) {
                qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc);
                return;
            }
            qemu_console_hw_gl_block(vc->gfx.dcl.con, false);
        }
#endif
    } else {
        eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                       vc->gfx.esurface, vc->gfx.ectx);

        surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, pw, ph);
        surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);

        eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);

        gd_update_scale(vc, ww, wh,
                        surface_width(vc->gfx.ds),
                        surface_height(vc->gfx.ds));

        glFlush();
    }
}

void gd_egl_update(DisplayChangeListener *dcl,
                   int x, int y, int w, int h)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

    if (!vc->gfx.gls || !vc->gfx.ds) {
        return;
    }

    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                   vc->gfx.esurface, vc->gfx.ectx);
    surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
    vc->gfx.glupdates++;
    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE,
                   EGL_NO_SURFACE, EGL_NO_CONTEXT);
}

void gd_egl_refresh(DisplayChangeListener *dcl)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

    gd_update_monitor_refresh_rate(
            vc, vc->window ? vc->window : vc->gfx.drawing_area);

    if (!vc->gfx.esurface) {
        gd_egl_init(vc);
        if (!vc->gfx.esurface) {
            return;
        }
        vc->gfx.gls = qemu_gl_init_shader();
        if (vc->gfx.ds) {
            surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
            surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
        }
#ifdef CONFIG_GBM
        if (vc->gfx.guest_fb.dmabuf) {
            egl_dmabuf_release_texture(vc->gfx.guest_fb.dmabuf);
            gd_egl_scanout_dmabuf(dcl, vc->gfx.guest_fb.dmabuf);
        }
#endif
    }

    if (vc->gfx.guest_fb.dmabuf &&
        qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
        gd_egl_draw(vc);
        return;
    }

    qemu_console_hw_update(dcl->con);

    if (vc->gfx.glupdates) {
        vc->gfx.glupdates = 0;
        gd_egl_draw(vc);
    }
}

void gd_egl_switch(DisplayChangeListener *dcl,
                   DisplaySurface *surface)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
    bool resized = true;

    trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));

    if (vc->gfx.ds &&
        surface_width(vc->gfx.ds) == surface_width(surface) &&
        surface_height(vc->gfx.ds) == surface_height(surface)) {
        resized = false;
    }
    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                   vc->gfx.esurface, vc->gfx.ectx);

    surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
    vc->gfx.ds = surface;
    if (vc->gfx.gls) {
        surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
    }

    if (resized) {
        gd_update_windowsize(vc);
    }

    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                   EGL_NO_CONTEXT);
}

QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,
                                    QEMUGLParams *params)
{
    VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);

    return qemu_egl_create_context(dgc, params, vc->gfx.ectx);
}

void gd_egl_scanout_disable(DisplayChangeListener *dcl)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

    vc->gfx.w = 0;
    vc->gfx.h = 0;
    gtk_egl_set_scanout_mode(vc, false);
}

void gd_egl_scanout_texture(DisplayChangeListener *dcl,
                            uint32_t backing_id, bool backing_y_0_top,
                            uint32_t backing_width, uint32_t backing_height,
                            uint32_t x, uint32_t y,
                            uint32_t w, uint32_t h,
                            void *d3d_tex2d)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

    vc->gfx.x = x;
    vc->gfx.y = y;
    vc->gfx.w = w;
    vc->gfx.h = h;
    vc->gfx.y0_top = backing_y_0_top;

    if (!vc->gfx.esurface) {
        gd_egl_init(vc);
        if (!vc->gfx.esurface) {
            return;
        }
    }

    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                   vc->gfx.esurface, vc->gfx.ectx);

    gtk_egl_set_scanout_mode(vc, true);
    egl_fb_setup_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
                         backing_id, false);
}

void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
                           QemuDmaBuf *dmabuf)
{
#ifdef CONFIG_GBM
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
    uint32_t x, y, width, height, backing_width, backing_height, texture;
    bool y0_top;

    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                   vc->gfx.esurface, vc->gfx.ectx);

    egl_dmabuf_import_texture(dmabuf);
    texture = qemu_dmabuf_get_texture(dmabuf);
    if (!texture) {
        return;
    }

    x = qemu_dmabuf_get_x(dmabuf);
    y = qemu_dmabuf_get_y(dmabuf);
    width = qemu_dmabuf_get_width(dmabuf);
    height = qemu_dmabuf_get_height(dmabuf);
    backing_width = qemu_dmabuf_get_backing_width(dmabuf);
    backing_height = qemu_dmabuf_get_backing_height(dmabuf);
    y0_top = qemu_dmabuf_get_y0_top(dmabuf);

    gd_egl_scanout_texture(dcl, texture, y0_top, backing_width, backing_height,
                           x, y, width, height, NULL);

    if (qemu_dmabuf_get_allow_fences(dmabuf)) {
        vc->gfx.guest_fb.dmabuf = dmabuf;
    }
#endif
}

void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl,
                          QemuDmaBuf *dmabuf, bool have_hot,
                          uint32_t hot_x, uint32_t hot_y)
{
#ifdef CONFIG_GBM
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
    uint32_t backing_width, backing_height, texture;

    if (dmabuf) {
        egl_dmabuf_import_texture(dmabuf);
        texture = qemu_dmabuf_get_texture(dmabuf);
        if (!texture) {
            return;
        }

        backing_width = qemu_dmabuf_get_backing_width(dmabuf);
        backing_height = qemu_dmabuf_get_backing_height(dmabuf);
        egl_fb_setup_for_tex(&vc->gfx.cursor_fb, backing_width, backing_height,
                             texture, false);
    } else {
        egl_fb_destroy(&vc->gfx.cursor_fb);
    }
#endif
}

void gd_egl_cursor_position(DisplayChangeListener *dcl,
                            uint32_t pos_x, uint32_t pos_y)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

    vc->gfx.cursor_x = pos_x * vc->gfx.scale_x;
    vc->gfx.cursor_y = pos_y * vc->gfx.scale_y;
}

void gd_egl_scanout_flush(DisplayChangeListener *dcl,
                          uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
    GdkWindow *window;
    int px_offset, py_offset;
    int gs;
    int pw_widget, ph_widget, pw_surface, ph_surface;
    int ww_widget, wh_widget, ww_surface, wh_surface;
    int fbw, fbh;

    if (!vc->gfx.scanout_mode) {
        return;
    }
    if (!vc->gfx.guest_fb.framebuffer) {
        return;
    }

    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                   vc->gfx.esurface, vc->gfx.ectx);

    window = gtk_widget_get_window(vc->gfx.drawing_area);
    gs = gdk_window_get_scale_factor(window);
    ww_widget = gdk_window_get_width(window);
    wh_widget = gdk_window_get_height(window);
    fbw = surface_width(vc->gfx.ds);
    fbh = surface_height(vc->gfx.ds);

    gd_update_scale(vc, ww_widget, wh_widget, fbw, fbh);

    ww_surface = fbw * vc->gfx.scale_x;
    wh_surface = fbh * vc->gfx.scale_y;
    pw_widget = ww_widget * gs;
    ph_widget = wh_widget * gs;
    pw_surface = ww_surface * gs;
    ph_surface = wh_surface * gs;

    px_offset = 0;
    py_offset = 0;
    if (pw_widget > pw_surface) {
        px_offset = (pw_widget - pw_surface) / 2;
    }
    if (ph_widget > ph_surface) {
        py_offset = (ph_widget - ph_surface) / 2;
    }

    egl_fb_setup_default(&vc->gfx.win_fb, pw_surface, ph_surface,
                         px_offset, py_offset);
    if (vc->gfx.cursor_fb.texture) {
        egl_texture_blit(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.guest_fb,
                         vc->gfx.y0_top);
        egl_texture_blend(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.cursor_fb,
                          vc->gfx.y0_top,
                          vc->gfx.cursor_x, vc->gfx.cursor_y,
                          vc->gfx.scale_x, vc->gfx.scale_y);
    } else {
        egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
    }

#ifdef CONFIG_GBM
    if (vc->gfx.guest_fb.dmabuf) {
        egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
    }
#endif

    eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
}

void gd_egl_flush(DisplayChangeListener *dcl,
                  uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
    GtkWidget *area = vc->gfx.drawing_area;

    if (vc->gfx.guest_fb.dmabuf &&
        !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
        qemu_console_hw_gl_block(vc->gfx.dcl.con, true);
        qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true);
        gtk_egl_set_scanout_mode(vc, true);
        gtk_widget_queue_draw_area(area, x, y, w, h);
        return;
    }

    gd_egl_scanout_flush(&vc->gfx.dcl, x, y, w, h);
}

void gtk_egl_init(DisplayGLMode mode)
{
    GdkDisplay *gdk_display = gdk_display_get_default();
    Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);

    if (qemu_egl_init_dpy_x11(x11_display, mode) < 0) {
        return;
    }

    display_opengl = 1;
}

int gd_egl_make_current(DisplayGLCtx *dgc,
                        QEMUGLContext ctx)
{
    VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);

    if (!eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
                        vc->gfx.esurface, ctx)) {
        error_report("egl: eglMakeCurrent failed: %s", qemu_egl_get_error_string());
        return -1;
    }

    return 0;
}
