/*
 * # Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

#include <gst/allocators/gstdmabuf.h>
#include <gst/gl/gstglfuncs.h>

#include "gstglmemorydma.h"

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY_DMA);
#define GST_CAT_DEFAULT GST_CAT_GL_MEMORY_DMA

#define parent_class gst_gl_memory_dma_allocator_parent_class
G_DEFINE_TYPE (GstGLMemoryDmaAllocator, gst_gl_memory_dma_allocator,
    GST_TYPE_GL_MEMORY_ALLOCATOR);

static void gst_gl_memory_dma_allocator_finalize (GObject * object);
static GstGLBaseMemory *  _gl_mem_dma_alloc
    (GstGLBaseMemoryAllocator * allocator, GstGLAllocationParams * params);
static gboolean _gl_mem_dma_create (GstGLBaseMemory * glmem, GError ** error);
static void _gl_mem_dma_destroy (GstGLBaseMemory * glmem);
static GstMemory * _mem_alloc (GstAllocator * allocator, gsize size,
    GstAllocationParams * params);


static void
gst_gl_memory_dma_allocator_class_init (GstGLMemoryDmaAllocatorClass * klass)
{
  GST_ALLOCATOR_CLASS (klass)->alloc = _mem_alloc;

  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (klass)->alloc = _gl_mem_dma_alloc;
  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (klass)->create = _gl_mem_dma_create;
  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (klass)->destroy = _gl_mem_dma_destroy;

  G_OBJECT_CLASS (klass)->finalize = gst_gl_memory_dma_allocator_finalize;

  GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_MEMORY_DMA, "glmemorydma", 0,
    "OpenGL DMA memory");
}

static void
gst_gl_memory_dma_allocator_init (GstGLMemoryDmaAllocator * alloc)
{
  GST_DEBUG_OBJECT (alloc, "init");
  GST_ALLOCATOR (alloc)->mem_type = GST_GL_MEMORY_DMA_ALLOCATOR_NAME;
  GST_OBJECT_FLAG_SET (GST_OBJECT (alloc), GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);

  /* ION allocator is in the "coral" plugin, load it. */
  alloc->plugin = gst_plugin_load_by_name ("coral");
  if (!alloc->plugin) {
    GST_ERROR_OBJECT (alloc, "coral plugin not found");
    return;
  }

  alloc->ion_allocator = gst_allocator_find ("ion");
  if (!alloc->ion_allocator) {
    GST_ERROR_OBJECT (alloc, "ION allocator not found");
    return;
  }

  GST_INFO_OBJECT (alloc, "ION allocator loaded");
}

static void
gst_gl_memory_dma_allocator_finalize (GObject * object)
{
  GstGLMemoryDmaAllocator *alloc = GST_GL_MEMORY_DMA_ALLOCATOR (object);

  GST_DEBUG_OBJECT (alloc, "finalize");

  if (alloc->ion_allocator) {
    gst_object_unref (alloc->ion_allocator);
    alloc->ion_allocator = NULL;
  }

  if (alloc->plugin) {
    gst_object_unref (alloc->plugin);
    alloc->plugin = NULL;
  }

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

static GstGLBaseMemory *
 _gl_mem_dma_alloc (GstGLBaseMemoryAllocator * allocator,
    GstGLAllocationParams * alloc_params)
{
  GstGLMemoryDmaAllocator *alloc;
  GstGLMemoryDMA *dmamem;
  GstGLVideoAllocationParams *params;
  gsize size;

  alloc = GST_GL_MEMORY_DMA_ALLOCATOR (allocator);
  params = (GstGLVideoAllocationParams *) alloc_params;

  g_return_val_if_fail (params->parent.alloc_flags &
      GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO, NULL);

  dmamem = g_new0 (GstGLMemoryDMA, 1);
  dmamem->params = params->parent.alloc_params;

  /* GstVideoInfo defaults to 4 b stride align for RGB/BGR but we want to
   * pack the buffer as tightly as possible (i.e. stride == width * bpp).
   */
  switch (params->v_info->finfo->format) {
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
      params->v_info->stride[0] = params->v_info->width * 3;
      params->v_info->size = params->v_info->stride[0] * params->v_info->height;
      break;
    default:
      break;
  }

  size = gst_gl_get_plane_data_size (params->v_info, params->valign,
      params->plane);
  dmamem->dma = gst_allocator_alloc (alloc->ion_allocator, size,
      dmamem->params);

  if (!dmamem->dma) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY_DMA, "ION alloc of %zu b failed", size);
    g_free (dmamem);
    return NULL;
  }

  GST_CAT_DEBUG (GST_CAT_GL_MEMORY_DMA, "ION alloc %zu b", size);

  gst_gl_memory_init (GST_GL_MEMORY_CAST (dmamem), GST_ALLOCATOR_CAST (alloc),
      NULL, params->parent.context, params->target, params->tex_format,
      params->parent.alloc_params, params->v_info, params->plane,
      params->valign, params->parent.user_data, params->parent.notify);

  return GST_GL_BASE_MEMORY_CAST (dmamem);
}

static gboolean
_gl_mem_dma_create (GstGLBaseMemory * glmem, GError ** error)
{
  GstGLMemoryDMA *dmamem;
  const GstGLFuncs *gl;
  gint fd;
  guint tex_id;

  g_return_val_if_fail (glmem, FALSE);
  g_return_val_if_fail (glmem->context, FALSE);
  gl = glmem->context->gl_vtable;

  if (!GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->create (glmem,
      error)) {
    return FALSE;
  }

  dmamem = GST_GL_MEMORY_DMA_CAST (glmem);
  fd = gst_dmabuf_memory_get_fd (dmamem->dma);
  tex_id = GST_GL_MEMORY_CAST (&glmem->mem)->tex_id;

  dmamem->image = gst_egl_image_from_dmabuf (glmem->context, fd,
      &GST_GL_MEMORY_CAST (glmem)->info, 0, 0);
  if (!dmamem->image) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY_DMA, "gst_egl_image_from_dmabuf failed");
    return FALSE;
  }

  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, tex_id);
  gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, gst_egl_image_get_image (
      dmamem->image));

  GST_CAT_DEBUG (GST_CAT_GL_MEMORY_DMA, "created dma mem %p fd %d tex_id %u",
      glmem, fd, tex_id);

  return TRUE;
}

static void
_gl_mem_dma_destroy (GstGLBaseMemory * glmem)
{
  GstGLMemoryDMA *dmamem;

  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->destroy (glmem);

  dmamem = GST_GL_MEMORY_DMA_CAST (glmem);

  if (dmamem->image) {
    gst_egl_image_unref (dmamem->image);
    dmamem->image = NULL;
  }

  if (dmamem->dma) {
    gst_memory_unref (dmamem->dma);
    dmamem->dma = NULL;
  }

  /* Base class frees dmamem. */
  GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->destroy (glmem);
  GST_CAT_DEBUG (GST_CAT_GL_MEMORY_DMA, "destroyed dma mem %p", dmamem);
}

static GstMemory *
_mem_alloc (GstAllocator * allocator, gsize size,
    GstAllocationParams * params)
{
  /* Only used as an init check, does not support actual GL alloc. */

  GstGLMemoryDmaAllocator *alloc;

  alloc = GST_GL_MEMORY_DMA_ALLOCATOR (allocator);

  g_return_val_if_fail (alloc->ion_allocator, NULL);

  return gst_allocator_alloc (alloc->ion_allocator, size, params);
}

static EGLDisplay
_get_egl_display (GstGLContext * context)
{
  EGLDisplay egl_display;
  GstGLDisplayEGL *display_egl;
  if (!context->display) {
    return EGL_NO_DISPLAY;
  }
  display_egl = gst_gl_display_egl_from_gl_display (context->display);
  egl_display =
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
  gst_object_unref (display_egl);
  return egl_display;
}

static EGLSyncKHR
_eglCreateSyncKHR (GstGLContext * context)
{
  GstClockTime ts;
  EGLSyncKHR sync;
  EGLSyncKHR (*gst_eglCreateSyncKHR) (EGLDisplay dpy, EGLenum type,
      const EGLAttrib * attrib_list);
  EGLDisplay dpy = _get_egl_display (context);
  g_assert (dpy != EGL_NO_DISPLAY);

  ts = gst_util_get_timestamp ();
  gst_eglCreateSyncKHR = gst_gl_context_get_proc_address (context,
        "eglCreateSyncKHR");
  sync = gst_eglCreateSyncKHR (dpy, EGL_SYNC_FENCE_KHR, NULL);
  GST_CAT_LOG (GST_CAT_GL_MEMORY_DMA, "created egl sync object %p", sync);
  ts = gst_util_get_timestamp () - ts;
  GST_CAT_LOG (GST_CAT_GL_MEMORY_DMA, "create %.2g ms",(double) ts / GST_MSECOND);
  return sync;
}

static EGLBoolean
_eglClientWaitSyncKHR (GstGLContext * context, EGLSyncKHR sync)
{
  EGLint (*gst_eglClientWaitSyncKHR) (EGLDisplay dpy, EGLSyncKHR sync,
        EGLint flags, EGLTimeKHR timeout);
  EGLDisplay dpy = _get_egl_display (context);
  g_assert (dpy != EGL_NO_DISPLAY);

  GST_CAT_LOG (GST_CAT_GL_MEMORY_DMA, "waiting on egl sync object %p", sync);
  gst_eglClientWaitSyncKHR = gst_gl_context_get_proc_address (context,
        "eglClientWaitSyncKHR");
  return gst_eglClientWaitSyncKHR (dpy, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
      1000000000 /* 1s */ ) == EGL_CONDITION_SATISFIED_KHR;
}

static EGLBoolean
_eglDestroySyncKHR (GstGLContext * context, EGLSyncKHR sync)
{
  EGLBoolean (*gst_eglDestroySyncKHR) (EGLDisplay dpy, EGLSyncKHR sync);
  EGLDisplay dpy = _get_egl_display (context);
  if (dpy == EGL_NO_DISPLAY) {
    return EGL_FALSE;
  }

  gst_eglDestroySyncKHR = gst_gl_context_get_proc_address (context,
        "eglDestroySyncKHR");
  GST_CAT_LOG (GST_CAT_GL_MEMORY_DMA, "deleting egl sync object %p", sync);
  return gst_eglDestroySyncKHR (dpy, sync);
}

static void
_create_sync_gl (GstGLContext * context, gpointer data)
{
  EGLSyncKHR *sync = (EGLSyncKHR *) data;
  *sync = _eglCreateSyncKHR (context);
}

GstBuffer *
gst_gl_memory_dma_sync_buffer (GstBuffer * glbuf)
{
  GstBuffer *buf;
  GstVideoInfo *info;
  GstMemory *mem;
  GstGLBaseMemory *glmem;
  GstGLMemoryDMA *dmamem;
  GstGLSyncMeta *sync_meta;
  EGLSyncKHR sync;
  EGLBoolean res;
  GstClockTime ts;

  mem = gst_buffer_peek_memory (glbuf, 0);
  g_assert (gst_is_gl_memory_dma (mem));

  glmem = GST_GL_BASE_MEMORY_CAST (mem);
  dmamem = GST_GL_MEMORY_DMA_CAST (mem);
  sync_meta = gst_buffer_get_gl_sync_meta (glbuf);

  if (sync_meta) {
    ts = gst_util_get_timestamp ();
    gst_gl_sync_meta_wait_cpu (sync_meta, glmem->context);
    ts = gst_util_get_timestamp () - ts;
    GST_CAT_DEBUG (GST_CAT_GL_MEMORY_DMA, "wait_cpu %.2g ms",
        (double) ts / GST_MSECOND);
  } else {
    ts = gst_util_get_timestamp ();
    gst_gl_context_thread_add (glmem->context, _create_sync_gl, &sync);
    g_assert (sync != EGL_NO_SYNC_KHR);

    do {
      res = _eglClientWaitSyncKHR (glmem->context, sync);
    } while (res == EGL_FALSE);
    ts = gst_util_get_timestamp () - ts;

    res = _eglDestroySyncKHR (glmem->context, sync);
    g_assert (res == EGL_TRUE);
    ts = gst_util_get_timestamp () - ts;
    GST_CAT_DEBUG (GST_CAT_GL_MEMORY_DMA, "egl_sync %.2g ms",
        (double) ts / GST_MSECOND);
  }

  info = &dmamem->mem.info;
  buf = gst_buffer_new ();
  gst_buffer_add_parent_buffer_meta (buf, glbuf);
  gst_buffer_append_memory (buf, gst_memory_ref (dmamem->dma));
  gst_buffer_add_video_meta_full (buf, 0,
      GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
      GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride);

  return buf;
}

gboolean
gst_is_gl_memory_dma (GstMemory * mem)
{
  return mem && mem->allocator && g_type_is_a (G_OBJECT_TYPE (mem->allocator),
      GST_TYPE_GL_MEMORY_DMA_ALLOCATOR);
}

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

  if (g_once_init_enter (&_init)) {
    GstAllocator *alloc = g_object_new (GST_TYPE_GL_MEMORY_DMA_ALLOCATOR, NULL);
    gst_object_ref_sink (alloc);
    gst_allocator_register (GST_GL_MEMORY_DMA_ALLOCATOR_NAME, alloc);
    g_once_init_leave (&_init, 1);
  }
}
