/*
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstgldisplay_gbm.h"
#include "gstgl_gbm_utils.h"

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

GST_DEBUG_CATEGORY (gst_gl_gbm_debug);

GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug


#define INVALID_CRTC ((guint32)0)


G_DEFINE_TYPE (GstGLDisplayGBM, gst_gl_display_gbm, GST_TYPE_GL_DISPLAY);


static void gst_gl_display_gbm_finalize (GObject * object);
static guintptr gst_gl_display_gbm_get_handle (GstGLDisplay * display);

static guint32 gst_gl_gbm_find_crtc_id_for_encoder (GstGLDisplayGBM *
    display_gbm, drmModeEncoder const *encoder);
static guint32 gst_gl_gbm_find_crtc_id_for_connector (GstGLDisplayGBM *
    display_gbm);

static gboolean gst_gl_display_gbm_setup_drm (GstGLDisplayGBM * display_gbm);
static void gst_gl_display_gbm_shutdown_drm (GstGLDisplayGBM * display_gbm);

static gboolean gst_gl_display_gbm_setup_gbm (GstGLDisplayGBM * display_gbm);
static void gst_gl_display_gbm_shutdown_gbm (GstGLDisplayGBM * display_gbm);


static void
gst_gl_display_gbm_class_init (GstGLDisplayGBMClass * klass)
{
  GST_GL_DISPLAY_CLASS (klass)->get_handle =
      GST_DEBUG_FUNCPTR (gst_gl_display_gbm_get_handle);

  G_OBJECT_CLASS (klass)->finalize = gst_gl_display_gbm_finalize;
}

static void
gst_gl_display_gbm_init (GstGLDisplayGBM * display_gbm)
{
  GstGLDisplay *display = (GstGLDisplay *) display_gbm;
  display->type = GST_GL_DISPLAY_TYPE_GBM;

  display_gbm->drm_fd = -1;
}

static void
gst_gl_display_gbm_finalize (GObject * object)
{
  GstGLDisplayGBM *display_gbm = GST_GL_DISPLAY_GBM (object);

  gst_gl_display_gbm_shutdown_gbm (display_gbm);
  gst_gl_display_gbm_shutdown_drm (display_gbm);

  G_OBJECT_CLASS (gst_gl_display_gbm_parent_class)->finalize (object);
}

static guintptr
gst_gl_display_gbm_get_handle (GstGLDisplay * display)
{
  return (guintptr) GST_GL_DISPLAY_GBM (display)->gbm_dev;
}


static guint32
gst_gl_gbm_find_crtc_id_for_encoder (GstGLDisplayGBM * display_gbm,
    drmModeEncoder const *encoder)
{
  int i;
  for (i = 0; i < display_gbm->drm_mode_resources->count_crtcs; ++i) {
    /* possible_crtcs is a bitmask as described here:
     * https://dvdhrm.wordpress.com/2012/09/13/linux-drm-mode-setting-api */
    guint32 const crtc_mask = 1 << i;
    guint32 const crtc_id = display_gbm->drm_mode_resources->crtcs[i];

    if (encoder->possible_crtcs & crtc_mask)
      return crtc_id;
  }

  /* No match found */
  return INVALID_CRTC;
}


static guint32
gst_gl_gbm_find_crtc_id_for_connector (GstGLDisplayGBM * display_gbm)
{
  int i;
  for (i = 0; i < display_gbm->drm_mode_connector->count_encoders; ++i) {
    guint32 encoder_id = display_gbm->drm_mode_connector->encoders[i];
    drmModeEncoder *encoder =
        drmModeGetEncoder (display_gbm->drm_fd, encoder_id);

    if (encoder != NULL) {
      guint32 crtc_id =
          gst_gl_gbm_find_crtc_id_for_encoder (display_gbm, encoder);
      drmModeFreeEncoder (encoder);

      if (crtc_id != INVALID_CRTC)
        return crtc_id;
    }
  }

  /* No match found */
  return INVALID_CRTC;
}


static gboolean
gst_gl_display_gbm_setup_drm (GstGLDisplayGBM * display_gbm)
{
  int i;

  g_assert (display_gbm != NULL);
  g_assert (display_gbm->drm_fd >= 0);

  /* Get the DRM mode resources */
  display_gbm->drm_mode_resources = drmModeGetResources (display_gbm->drm_fd);
  if (display_gbm->drm_mode_resources == NULL) {
    GST_ERROR ("Could not get DRM resources: %s (%d)", g_strerror (errno),
        errno);
    goto cleanup;
  }
  GST_DEBUG ("Got DRM resources");

  /* Find a connected connector. The connector is where the pixel data is
   * finally sent to, and typically connects to some form of display, like an
   * HDMI TV, an LVDS panel etc. */
  {
    drmModeConnector *connector = NULL;

    GST_DEBUG ("Checking %d DRM connector(s)",
        display_gbm->drm_mode_resources->count_connectors);
    for (i = 0; i < display_gbm->drm_mode_resources->count_connectors; ++i) {
      connector = drmModeGetConnector (display_gbm->drm_fd,
          display_gbm->drm_mode_resources->connectors[i]);
      GST_DEBUG ("Found DRM connector #%d \"%s\" with ID %" G_GUINT32_FORMAT, i,
          gst_gl_gbm_get_name_for_drm_connector (connector),
          connector->connector_id);

      if (connector->connection == DRM_MODE_CONNECTED) {
        GST_DEBUG ("DRM connector #%d is connected", i);
        break;
      }

      drmModeFreeConnector (connector);
      connector = NULL;
    }

    if (connector == NULL) {
      GST_ERROR ("No connected DRM connector found");
      goto cleanup;
    }

    display_gbm->drm_mode_connector = connector;
  }

  /* Check out what modes are supported by the chosen connector,
   * and pick either the "preferred" mode or the one with the largest
   * pixel area. */
  {
    int selected_mode_index = -1;
    int selected_mode_area = -1;

    GST_DEBUG ("Checking %d DRM mode(s) from selected connector",
        display_gbm->drm_mode_connector->count_modes);
    for (i = 0; i < display_gbm->drm_mode_connector->count_modes; ++i) {
      drmModeModeInfo *current_mode =
          &(display_gbm->drm_mode_connector->modes[i]);
      int current_mode_area = current_mode->hdisplay * current_mode->vdisplay;

      GST_DEBUG ("Found DRM mode #%d width/height %" G_GUINT16_FORMAT "/%"
          G_GUINT16_FORMAT " hsync/vsync start %" G_GUINT16_FORMAT "/%"
          G_GUINT16_FORMAT " hsync/vsync end %" G_GUINT16_FORMAT "/%"
          G_GUINT16_FORMAT " htotal/vtotal %" G_GUINT16_FORMAT "/%"
          G_GUINT16_FORMAT " hskew %" G_GUINT16_FORMAT " vscan %"
          G_GUINT16_FORMAT " vrefresh %" G_GUINT32_FORMAT " preferred %d", i,
          current_mode->hdisplay, current_mode->vdisplay,
          current_mode->hsync_start, current_mode->vsync_start,
          current_mode->hsync_end, current_mode->vsync_end,
          current_mode->htotal, current_mode->vtotal, current_mode->hskew,
          current_mode->vscan, current_mode->vrefresh,
          (current_mode->type & DRM_MODE_TYPE_PREFERRED) ? TRUE : FALSE);

      if ((current_mode->type & DRM_MODE_TYPE_PREFERRED) ||
          (current_mode_area > selected_mode_area)) {
        display_gbm->drm_mode_info = current_mode;
        selected_mode_area = current_mode_area;
        selected_mode_index = i;

        if (current_mode->type & DRM_MODE_TYPE_PREFERRED)
          break;
      }
    }

    if (display_gbm->drm_mode_info == NULL) {
      GST_ERROR ("No usable DRM mode found");
      goto cleanup;
    }

    GST_DEBUG ("Selected DRM mode #%d", selected_mode_index);
  }

  /* Find an encoder that is attached to the chosen connector. Also find the
   * index/id of the CRTC associated with this encoder. The encoder takes pixel
   * data from the CRTC and transmits it to the connector. The CRTC roughly
   * represents the scanout framebuffer.
   *
   * Ultimately, we only care about the CRTC index & ID, so the encoder
   * reference is discarded here once these are found. The CRTC index is the
   * index in the m_drm_mode_resources' CRTC array, while the ID is an identifier
   * used by the DRM to refer to the CRTC universally. (We need the CRTC
   * information for page flipping and DRM scanout framebuffer configuration.) */
  {
    drmModeEncoder *encoder = NULL;

    GST_DEBUG ("Checking %d DRM encoder(s)",
        display_gbm->drm_mode_resources->count_encoders);
    for (i = 0; i < display_gbm->drm_mode_resources->count_encoders; ++i) {
      encoder = drmModeGetEncoder (display_gbm->drm_fd,
          display_gbm->drm_mode_resources->encoders[i]);

      GST_DEBUG ("Found DRM encoder #%d \"%s\"", i,
          gst_gl_gbm_get_name_for_drm_encoder (encoder));

      if (encoder->encoder_id == display_gbm->drm_mode_connector->encoder_id) {
        GST_DEBUG ("DRM encoder #%d corresponds to selected DRM connector "
            "-> selected", i);
        break;
      }
      drmModeFreeEncoder (encoder);
      encoder = NULL;
    }

    if (encoder == NULL) {
      GST_DEBUG ("No encoder found; searching for CRTC ID in the connector");
      display_gbm->crtc_id =
          gst_gl_gbm_find_crtc_id_for_connector (display_gbm);
    } else {
      GST_DEBUG ("Using CRTC ID from selected encoder");
      display_gbm->crtc_id = encoder->crtc_id;
      drmModeFreeEncoder (encoder);
    }

    if (display_gbm->crtc_id == INVALID_CRTC) {
      GST_ERROR ("No CRTC found");
      goto cleanup;
    }

    GST_DEBUG ("CRTC with ID %" G_GUINT32_FORMAT " found; now locating it in "
        "the DRM mode resources CRTC array", display_gbm->crtc_id);

    for (i = 0; i < display_gbm->drm_mode_resources->count_crtcs; ++i) {
      if (display_gbm->drm_mode_resources->crtcs[i] == display_gbm->crtc_id) {
        display_gbm->crtc_index = i;
        break;
      }
    }

    if (display_gbm->crtc_index < 0) {
      GST_ERROR ("No matching CRTC entry in DRM resources found");
      goto cleanup;
    }

    GST_DEBUG ("CRTC with ID %" G_GUINT32_FORMAT " can be found at index #%d "
        "in the DRM mode resources CRTC array", display_gbm->crtc_id,
        display_gbm->crtc_index);
  }

  GST_DEBUG ("DRM structures initialized");
  return TRUE;

cleanup:
  gst_gl_display_gbm_shutdown_drm (display_gbm);
  return FALSE;
}


static void
gst_gl_display_gbm_shutdown_drm (GstGLDisplayGBM * display_gbm)
{
  g_assert (display_gbm != NULL);

  display_gbm->drm_mode_info = NULL;

  display_gbm->crtc_index = -1;
  display_gbm->crtc_id = INVALID_CRTC;

  if (display_gbm->drm_mode_connector != NULL) {
    drmModeFreeConnector (display_gbm->drm_mode_connector);
    display_gbm->drm_mode_connector = NULL;
  }

  if (display_gbm->drm_mode_resources != NULL) {
    drmModeFreeResources (display_gbm->drm_mode_resources);
    display_gbm->drm_mode_resources = NULL;
  }
}


static gboolean
gst_gl_display_gbm_setup_gbm (GstGLDisplayGBM * display_gbm)
{
  display_gbm->gbm_dev = gbm_create_device (display_gbm->drm_fd);
  if (display_gbm->gbm_dev == NULL) {
    GST_ERROR ("Creating GBM device failed");
    return FALSE;
  }

  GST_DEBUG ("GBM structures initialized");
  return TRUE;
}


static void
gst_gl_display_gbm_shutdown_gbm (GstGLDisplayGBM * display_gbm)
{
  if (display_gbm->gbm_dev != NULL) {
    gbm_device_destroy (display_gbm->gbm_dev);
    display_gbm->gbm_dev = NULL;
  }
}


static void
_init_debug (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
    GST_DEBUG_CATEGORY_INIT (gst_gl_gbm_debug, "gleglgbm", 0,
        "Mesa3D EGL GBM debugging");
    g_once_init_leave (&_init, 1);
  }
}


GstGLDisplayGBM *
gst_gl_display_gbm_new (void)
{
  int drm_fd = -1;
  GstGLDisplayGBM *display;
  const gchar *drm_node_name;

  _init_debug ();

  drm_node_name = g_getenv ("GST_GL_GBM_DRM_DEVICE");

  if (drm_node_name != NULL) {
    GST_DEBUG ("attempting to open device %s (specified by the "
        "GST_GL_GBM_DRM_DEVICE environment variable)", drm_node_name);
    drm_fd = open (drm_node_name, O_RDWR | O_CLOEXEC);
    if (drm_fd < 0) {
      GST_ERROR ("could not open DRM device %s: %s (%d)", drm_node_name,
          g_strerror (errno), errno);
      return NULL;
    }
  } else {
    GST_DEBUG ("GST_GL_GBM_DRM_DEVICE environment variable is not "
        "set - trying to autodetect device");
    drm_fd = gst_gl_gbm_find_and_open_drm_node ();
    if (drm_fd < 0) {
      GST_ERROR ("could not find or open DRM device");
      return NULL;
    }
  }

  display = g_object_new (GST_TYPE_GL_DISPLAY_GBM, NULL);
  display->drm_fd = drm_fd;

  if (!gst_gl_display_gbm_setup_drm (display)) {
    GST_ERROR ("Failed to initialize DRM");
    goto cleanup;
  }

  if (!gst_gl_display_gbm_setup_gbm (display)) {
    GST_ERROR ("Failed to initialize GBM");
    goto cleanup;
  }

  GST_DEBUG ("Created GBM EGL display %p", (gpointer) display);

  return display;

cleanup:
  gst_gl_display_gbm_shutdown_gbm (display);
  gst_gl_display_gbm_shutdown_drm (display);
  gst_object_unref (G_OBJECT (display));
  if (drm_fd >= 0)
    close (drm_fd);
  return NULL;
}
