/*
 * GStreamer
 * Copyright (C) 2018 Carlos Rafael Giani <dv@pseudoterminal.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <poll.h>

#include "../gstgl_fwd.h"
#include <gst/gl/gstglcontext.h>
#include <gst/gl/egl/gstglcontext_egl.h>

#include "gstgldisplay_gbm.h"
#include "gstglwindow_gbm_egl.h"
#include "gstgl_gbm_utils.h"
#include "../gstglwindow_private.h"

#define GST_CAT_DEFAULT gst_gl_window_debug


#define GST_GL_WINDOW_GBM_EGL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
    GST_TYPE_GL_WINDOW_GBM_EGL, GstGLWindowGBMEGLPrivate))


G_DEFINE_TYPE (GstGLWindowGBMEGL, gst_gl_window_gbm_egl, GST_TYPE_GL_WINDOW);


static guintptr gst_gl_window_gbm_egl_get_window_handle (GstGLWindow * window);
static guintptr gst_gl_window_gbm_egl_get_display (GstGLWindow * window);
static void gst_gl_window_gbm_egl_set_window_handle (GstGLWindow * window,
    guintptr handle);
static void gst_gl_window_gbm_egl_close (GstGLWindow * window);
static void gst_gl_window_gbm_egl_draw (GstGLWindow * window);

static gboolean gst_gl_window_gbm_init_surface (GstGLWindowGBMEGL * window_egl);
static void gst_gl_window_gbm_egl_cleanup (GstGLWindowGBMEGL * window_egl);



static void
gst_gl_window_gbm_egl_class_init (GstGLWindowGBMEGLClass * klass)
{
  GstGLWindowClass *window_class = (GstGLWindowClass *) klass;

  window_class->get_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_gbm_egl_get_window_handle);
  window_class->get_display =
      GST_DEBUG_FUNCPTR (gst_gl_window_gbm_egl_get_display);
  window_class->set_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_gbm_egl_set_window_handle);
  window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_gbm_egl_close);
  window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_gbm_egl_draw);

  /* TODO: add support for set_render_rectangle (assuming this functionality
   * is possible with libdrm/gbm) */
}


static void
gst_gl_window_gbm_egl_init (GstGLWindowGBMEGL * window_gbm)
{
  window_gbm->gbm_surf = NULL;
  window_gbm->current_bo = NULL;
  window_gbm->prev_bo = NULL;
  window_gbm->waiting_for_flip = 0;
}


static guintptr
gst_gl_window_gbm_egl_get_window_handle (GstGLWindow * window)
{
  GstGLWindowGBMEGL *window_egl = GST_GL_WINDOW_GBM_EGL (window);

  /* This function is called in here, and not in the open()
   * vmethod. The reason for this is explained inside the
   * gst_gl_window_gbm_init_surface() function. */
  if (window_egl->gbm_surf == NULL) {
    if (!gst_gl_window_gbm_init_surface (window_egl))
      return 0;
  }

  return (guintptr) GST_GL_WINDOW_GBM_EGL (window)->gbm_surf;
}


static guintptr
gst_gl_window_gbm_egl_get_display (GstGLWindow * window)
{
  return gst_gl_display_get_handle (window->display);
}


static void
gst_gl_window_gbm_egl_set_window_handle (G_GNUC_UNUSED GstGLWindow * window,
    G_GNUC_UNUSED guintptr handle)
{
  /* TODO: Currently, it is unclear how to use external GBM buffer objects,
   * since it is not defined how this would work together with DRM page flips
   */
}


static void
gst_gl_window_gbm_egl_close (GstGLWindow * window)
{
  GstGLWindowGBMEGL *window_egl = GST_GL_WINDOW_GBM_EGL (window);

  gst_gl_window_gbm_egl_cleanup (window_egl);

  GST_GL_WINDOW_CLASS (gst_gl_window_gbm_egl_parent_class)->close (window);
}


static void
_page_flip_handler (G_GNUC_UNUSED int fd, G_GNUC_UNUSED unsigned int frame,
    G_GNUC_UNUSED unsigned int sec, G_GNUC_UNUSED unsigned int usec, void *data)
{
  /* If we reach this point, it means the page flip has been completed.
   * Signal this by clearing the flag so the poll() loop in draw_cb()
   * can exit. */
  int *waiting_for_flip = data;
  *waiting_for_flip = 0;
}

static void
draw_cb (gpointer data)
{
  GstGLWindowGBMEGL *window_egl = data;
  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
  GstGLDisplayGBM *display = (GstGLDisplayGBM *) window->display;
  struct gbm_bo *next_bo;
  GstGLDRMFramebuffer *framebuf;
  int ret;

  drmEventContext evctx = {
    .version = DRM_EVENT_CONTEXT_VERSION,
    .page_flip_handler = _page_flip_handler,
  };

  struct pollfd pfd = {
    .fd = display->drm_fd,
    .events = POLLIN,
    .revents = 0,
  };

  /* Rendering, page flipping etc. are connect this way:
   *
   * The frames are stored in buffer objects (BOs). Inside the eglSwapBuffers()
   * call, GBM creates new BOs if necessary. BOs can be "locked" for rendering,
   * meaning that EGL cannot use them as a render target. If all available
   * BOs are locked, the GBM code inside eglSwapBuffers() creates a new,
   * unlocked one. We make use of this to implement triple buffering.
   *
   * There are 3 BOs in play:
   *
   * * next_bo: The BO we just rendered into.
   * * current_bo: The currently displayed BO.
   * * prev_bo: The previously displayed BO.
   *
   * current_bo and prev_bo are involed in page flipping. next_bo is not.
   *
   * Once rendering is done, the next_bo is retrieved and locked. Then, we 
   * wait until any ongoing page flipping finishes. Once it does, the
   * current_bo is displayed on screen, and the prev_bo isn't anymore. At
   * this point, it is safe to release the prev_bo, which unlocks it and
   * makes it available again as a render target. Then we initiate the
   * next page flipping; this time, we flip to next_bo. At that point,
   * next_bo becomes current_bo, and current_bo becomes prev_bo.
   */

  /*
   * There is a special case at the beginning. There is no currently
   * displayed BO at first, so we create an empty one to get the page
   * flipping cycle going. Also, we use this first BO for setting up
   * the CRTC.
   */
  if (window_egl->current_bo == NULL) {
    /* Call eglSwapBuffers() to create a BO. */
    context_class->swap_buffers (context);

    /* Lock the BO so we get our first current_bo. */
    window_egl->current_bo =
        gbm_surface_lock_front_buffer (window_egl->gbm_surf);
    framebuf = gst_gl_gbm_drm_fb_get_from_bo (window_egl->current_bo);

    /* Configure CRTC to show this first BO. */
    ret = drmModeSetCrtc (display->drm_fd, display->crtc_id, framebuf->fb_id,
        0, 0, &(display->drm_mode_connector->connector_id), 1,
        display->drm_mode_info);

    if (ret != 0) {
      GST_ERROR ("Could not set DRM CRTC: %s (%d)", g_strerror (errno), errno);
      /* XXX: it is not possible to communicate the error to the pipeline */
      return;
    }
  }

  /* Do the actual drawing */
  if (window->draw)
    window->draw (window->draw_data);

  /* Let the context class call eglSwapBuffers(). As mentioned above,
   * if necessary, this function creates a new unlocked framebuffer
   * that can be used as render target. */
  context_class->swap_buffers (context);
  gst_object_unref (context);

  next_bo = gbm_surface_lock_front_buffer (window_egl->gbm_surf);
  framebuf = gst_gl_gbm_drm_fb_get_from_bo (next_bo);
  GST_LOG ("rendered new frame into bo %p", (gpointer) next_bo);

  /* Wait until any ongoing page flipping is done. After this is done,
   * prev_bo is no longer involved in any page flipping, and can be
   * safely released. */
  while (window_egl->waiting_for_flip) {
    ret = poll (&pfd, 1, -1);
    if (ret < 0) {
      if (errno == EINTR)
        GST_DEBUG ("Signal caught during poll() call");
      else
        GST_ERROR ("poll() failed: %s (%d)", g_strerror (errno), errno);
      /* XXX: it is not possible to communicate errors and interruptions
       * to the pipeline */
      return;
    }

    drmHandleEvent (display->drm_fd, &evctx);
  }
  GST_LOG ("now showing bo %p", (gpointer) (window_egl->current_bo));

  /* Release prev_bo, since it is no longer shown on screen. */
  if (G_LIKELY (window_egl->prev_bo != NULL)) {
    gbm_surface_release_buffer (window_egl->gbm_surf, window_egl->prev_bo);
    GST_LOG ("releasing bo %p", (gpointer) (window_egl->prev_bo));
  }

  /* Presently, current_bo is shown on screen. Schedule the next page
   * flip, this time flip to next_bo. The flip happens asynchronously, so
   * we can continue and render etc. in the meantime. */
  window_egl->waiting_for_flip = 1;
  ret = drmModePageFlip (display->drm_fd, display->crtc_id, framebuf->fb_id,
      DRM_MODE_PAGE_FLIP_EVENT, &(window_egl->waiting_for_flip));
  if (ret != 0) {
    /* NOTE: According to libdrm sources, the page is _not_
     * considered flipped if drmModePageFlip() reports an error,
     * so we do not update the priv->current_bo pointer here */
    GST_ERROR ("Could not initialize GBM surface");
    /* XXX: it is not possible to communicate the error to the pipeline */
    return;
  }

  /* At this point, we relabel the current_bo as the prev_bo.
   * This may not actually be the case yet, but it will be soon - latest
   * when the wait loop above finishes.
   * Also, next_bo becomes current_bo. */
  window_egl->prev_bo = window_egl->current_bo;
  window_egl->current_bo = next_bo;
}


static void
gst_gl_window_gbm_egl_draw (GstGLWindow * window)
{
  gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window);
}


static gboolean
gst_gl_window_gbm_init_surface (GstGLWindowGBMEGL * window_egl)
{
  /* NOTE: This function cannot be called in the open() vmethod
   * since context_egl->egl_display and context_egl->egl_config
   * must have been set to valid values at this point, and open()
   * is called _before_ these are set.
   * Also, eglInitialize() is called _after_ the open() vmethod,
   * which means that the return value of gbm_surface_create()
   * contains some function pointers that are set to NULL and
   * shouldn't be. This is because Mesa's eglInitialize() loads
   * the DRI2 driver and the relevant functions aren't available
   * until then. */

  GstGLWindow *window = GST_GL_WINDOW (window_egl);
  GstGLDisplayGBM *display = (GstGLDisplayGBM *) window->display;
  drmModeModeInfo *drm_mode_info = display->drm_mode_info;
  GstGLContext *context = gst_gl_window_get_context (window);
  GstGLContextEGL *context_egl = GST_GL_CONTEXT_EGL (context);
  EGLint gbm_format;

  /* With GBM-based EGL displays and configs, the native visual ID
   * is a GBM pixel format. */
  if (!eglGetConfigAttrib (context_egl->egl_display, context_egl->egl_config,
          EGL_NATIVE_VISUAL_ID, &gbm_format)) {
    GST_ERROR ("eglGetConfigAttrib failed: %s",
        gst_egl_get_error_string (eglGetError ()));
    return FALSE;
  }

  /* Create a GBM surface that shall contain the BOs we are
   * going to render into. */
  window_egl->gbm_surf = gbm_surface_create (display->gbm_dev,
      drm_mode_info->hdisplay, drm_mode_info->vdisplay, gbm_format,
      GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

  gst_gl_window_resize (window, drm_mode_info->hdisplay,
      drm_mode_info->vdisplay);

  GST_DEBUG ("Successfully created GBM surface");

  return TRUE;
}


static void
gst_gl_window_gbm_egl_cleanup (GstGLWindowGBMEGL * window_egl)
{
  if (window_egl->gbm_surf != NULL) {
    if (window_egl->current_bo != NULL) {
      gbm_surface_release_buffer (window_egl->gbm_surf, window_egl->current_bo);
      window_egl->current_bo = NULL;
    }

    gbm_surface_destroy (window_egl->gbm_surf);
    window_egl->gbm_surf = NULL;
  }
}


/* Must be called in the gl thread */
GstGLWindowGBMEGL *
gst_gl_window_gbm_egl_new (GstGLDisplay * display)
{
  GstGLWindowGBMEGL *window_egl;

  if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_GBM) == 0)
    /* we require a GBM display to create windows */
    return NULL;

  window_egl = g_object_new (GST_TYPE_GL_WINDOW_GBM_EGL, NULL);

  return window_egl;
}
