/*
 * # 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 <cairo.h>
#include <libdrm/drm_fourcc.h>
#include <librsvg/rsvg.h>

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

#include "gstglsvgoverlay.h"

#define GST_CAT_DEFAULT gst_gl_svg_overlay_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_svg_overlay_debug, \
  "glsvgoverlay", 0, "glsvgoverlay element");
#define gst_gl_svg_overlay_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLSvgOverlay, gst_gl_svg_overlay,
    GST_TYPE_GL_FILTER, DEBUG_INIT);

#define USING_OPENGL3(context) (gst_gl_context_check_gl_version(context, \
    GST_GL_API_OPENGL3, 3, 1))
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, \
    GST_GL_API_GLES2, 2, 0))
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, \
  GST_GL_API_GLES2, 3, 0))

enum
{
  PROP_0,
  PROP_DATA,
  PROP_SVG,
  PROP_SYNC,
  PROP_ION,
};

#define DEFAULT_PROP_SYNC TRUE
#define DEFAULT_PROP_ION TRUE

#define QNAME "GstGLSvgOverlayImage"

static void gst_gl_svg_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_svg_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstStateChangeReturn gst_gl_svg_overlay_change_state (
    GstElement * element, GstStateChange transition);
static gboolean gst_gl_svg_overlay_gl_start (GstGLBaseFilter * base_filter);
static void gst_gl_svg_overlay_gl_stop (GstGLBaseFilter * base_filter);
static gboolean gst_gl_svg_overlay_gl_set_caps (GstGLBaseFilter * base_filter,
    GstCaps * incaps, GstCaps * outcaps);
static GstFlowReturn gst_gl_svg_overlay_transform (GstBaseTransform * bt,
    GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_svg_overlay_filter_texture (GstGLFilter * filter,
    GstGLMemory * in_tex, GstGLMemory * out_tex);
static gboolean gst_gl_svg_overlay_set_svg (GstGLSvgOverlay * overlay,
    const gchar * svg, GstClockTime pts);
static void gst_gl_svg_overlay_finalize (GObject * object);
static void gst_gl_svg_overlay_task (gpointer data, gpointer user_data);
static void gst_gl_svg_overlay_task ();

enum
{
  SIGNAL_SET_SVG,
  LAST_SIGNAL
};

static guint gst_gl_svg_overlay_signals[LAST_SIGNAL] = { 0 };

static void
gst_gl_svg_overlay_class_init (GstGLSvgOverlayClass * klass)
{
  gst_gl_filter_add_rgba_pad_templates (GST_GL_FILTER_CLASS (klass));

  G_OBJECT_CLASS (klass)->set_property = gst_gl_svg_overlay_set_property;
  G_OBJECT_CLASS (klass)->get_property = gst_gl_svg_overlay_get_property;
  G_OBJECT_CLASS (klass)->finalize = gst_gl_svg_overlay_finalize;

  /* Aliased property for compability reasons. */
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DATA,
      g_param_spec_string ("data", "data", "SVG data", "",
          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SVG,
      g_param_spec_string ("svg", "svg", "SVG data", "",
          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SYNC,
      g_param_spec_boolean ("sync", "sync",
          "Require one SVG overlay per frame, or use the last"
          "available.",
          DEFAULT_PROP_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ION,
      g_param_spec_boolean ("ion", "ion",
          "Use the ION allocator for overlays if available.",
          DEFAULT_PROP_ION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_metadata (GST_ELEMENT_CLASS (klass),
      "OpenGL SVG overlay",
      "Filter/Effect/Video",
      "Overlay GL video texture with a SVG image",
      "Coral <coral-support@google.com>");
  GST_ELEMENT_CLASS (klass)->change_state = gst_gl_svg_overlay_change_state;

  gst_gl_svg_overlay_signals[SIGNAL_SET_SVG] =
      g_signal_new ("set-svg", G_TYPE_FROM_CLASS (klass),
          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
          G_STRUCT_OFFSET (GstGLSvgOverlayClass, set_svg),
          NULL, NULL, NULL,
          G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_UINT64);
  klass->set_svg = gst_gl_svg_overlay_set_svg;

  GST_BASE_TRANSFORM_CLASS (klass)->passthrough_on_same_caps = FALSE;
  GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_svg_overlay_transform;

  GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_svg_overlay_gl_start;
  GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_svg_overlay_gl_stop;
  GST_GL_BASE_FILTER_CLASS (klass)->gl_set_caps =
      gst_gl_svg_overlay_gl_set_caps;
  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
      GST_GL_API_GLES2 | GST_GL_API_OPENGL3;
  GST_GL_FILTER_CLASS (klass)->filter_texture =
      gst_gl_svg_overlay_filter_texture;
}

static void
gst_gl_svg_overlay_init (GstGLSvgOverlay * overlay)
{
  GST_DEBUG_OBJECT (overlay, "init");
  overlay->sync = DEFAULT_PROP_SYNC;
  overlay->use_ion = DEFAULT_PROP_ION;
  overlay->num_tasks = 0;
  overlay->started = FALSE;
  overlay->shader = NULL;
  overlay->thread_pool = NULL;
  overlay->buffer_pool = NULL;
  overlay->svg_queue = NULL;
  overlay->gl_queue = NULL;
  overlay->next_pts = 0;
  overlay->current = NULL;
  g_mutex_init (&overlay->mutex);
  g_cond_init (&overlay->cond);

  /* ION allocator is in the "coral" plugin, load it. */
  gst_object_unref (gst_plugin_load_by_name ("coral"));
  overlay->ion_allocator = gst_allocator_find ("ion");
  if (overlay->ion_allocator) {
    GST_INFO_OBJECT (overlay, "Have ION allocator");
  } else {
    GST_INFO_OBJECT (overlay, "ION allocator not present/usable");
  }
}

static void
gst_gl_svg_overlay_finalize (GObject * object)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (object);

  GST_DEBUG_OBJECT (overlay, "finalize");

  if (overlay->ion_allocator) {
    gst_object_unref (overlay->ion_allocator);
    overlay->ion_allocator = NULL;
  }
  if (overlay->buffer_pool) {
    gst_buffer_pool_set_active (overlay->buffer_pool, FALSE);
    gst_object_unref (overlay->buffer_pool);
    overlay->buffer_pool = NULL;
  }

  g_mutex_clear (&overlay->mutex);
  g_cond_clear (&overlay->cond);

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

static void
gst_gl_svg_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (object);

  switch (prop_id) {
    case PROP_DATA:
    case PROP_SVG:
      gst_gl_svg_overlay_set_svg (GST_GL_SVG_OVERLAY (object),
          g_value_get_string (value), GST_CLOCK_TIME_NONE);
      break;
    case PROP_SYNC:
      g_mutex_lock (&overlay->mutex);
      overlay->sync = g_value_get_boolean (value);
      g_mutex_unlock (&overlay->mutex);
      break;
    case PROP_ION:
      overlay->use_ion = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_svg_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (object);

  switch (prop_id) {
    case PROP_SYNC:
      g_mutex_lock (&overlay->mutex);
      g_value_set_boolean (value, overlay->sync);
      g_mutex_unlock (&overlay->mutex);
      break;
    case PROP_ION:
      g_value_set_boolean (value, overlay->use_ion);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
_free_egl_image_texture_gl (GstGLContext * context, gpointer data)
{
  EglImageTexture *tex = (EglImageTexture *) data;
  const GstGLFuncs *gl = context->gl_vtable;

  if (!tex || !tex->tex) {
    return;
  }

  gl->DeleteTextures (1, &tex->tex);
  tex->tex = 0;
}

static void
_free_egl_image_texture (gpointer data)
{
  EglImageTexture *tex = (EglImageTexture *) data;
  EGLBoolean (*_eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
  GstGLDisplayEGL *gst_egl_display;
  EGLDisplay egl_display;
  GstGLSvgOverlay *overlay = tex->overlay;
  GstGLContext *context = overlay->context;

  gst_gl_context_thread_add (context, _free_egl_image_texture_gl, tex);

  gst_egl_display = gst_gl_display_egl_from_gl_display (context->display);
  egl_display = (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (
      gst_egl_display));
  gst_object_unref (gst_egl_display);

  _eglDestroyImage = gst_gl_context_get_proc_address (context,
      "eglDestroyImage");
  if (!_eglDestroyImage) {
    _eglDestroyImage = gst_gl_context_get_proc_address (context,
        "eglDestroyImageKHR");
    if (!_eglDestroyImage) {
      g_free (tex);
      GST_ERROR_OBJECT (overlay, "eglDestroyImage not exposed");
      return;
    }
  }

  if (!_eglDestroyImage (egl_display, tex->image)) {
    GST_ERROR_OBJECT (overlay, "free %p failed", tex);
  }

  g_free (tex);
}

static EglImageTexture *
_get_cached_egl_image_texture (GstGLSvgOverlay * overlay, GstBuffer * buf) {
  EglImageTexture *tex = (EglImageTexture *) gst_mini_object_get_qdata (
      GST_MINI_OBJECT (buf), g_quark_from_static_string (QNAME));
  return tex;
}

static void
_create_egl_image_texture_gl (GstGLContext * context, gpointer data)
{
  EglImageTexture *tex = (EglImageTexture *) data;
  GstGLSvgOverlay *overlay = tex->overlay;
  const GstGLFuncs *gl = context->gl_vtable;

  g_assert (!tex->tex);
  gl->GenTextures (1, &tex->tex);
  gl->BindTexture (GL_TEXTURE_2D, tex->tex);
  gl->TexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, tex->image);
}

static EglImageTexture *
_create_egl_image_texture (GstGLSvgOverlay * overlay, GstBuffer * buf) {
  /* EglImageTexture is cached in GstBuffer qdata. */
  EglImageTexture *tex;
  EGLImageKHR *image;
  EGLDisplay egl_display;
  GstGLDisplayEGL *gst_egl_display;
  GstMemory *mem;
  gint atti = 0, fourcc, i, fd;
  guintptr attribs[16];
  EGLImageKHR (*_eglCreateImage) (EGLDisplay dpy, EGLContext ctx,
      EGLenum target, EGLClientBuffer buffer, const EGLint * attribs);
  GstGLContext *context = overlay->context;

  tex = _get_cached_egl_image_texture (overlay, buf);
  if (tex) {
    return tex;
  }

  mem = gst_buffer_peek_memory (buf, 0);
  g_assert (gst_is_dmabuf_memory (mem));
  fd = gst_dmabuf_memory_get_fd (mem);

  gst_egl_display = gst_gl_display_egl_from_gl_display (context->display);
  egl_display = (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (
      gst_egl_display));
  gst_object_unref (gst_egl_display);

#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  fourcc = DRM_FORMAT_ARGB8888;
#else
  fourcc = DRM_FORMAT_ABGR8888;
#endif

  _eglCreateImage = gst_gl_context_get_proc_address (context,
      "eglCreateImage");
  if (!_eglCreateImage) {
    _eglCreateImage = gst_gl_context_get_proc_address (context,
        "eglCreateImageKHR");
  }
  g_assert (_eglCreateImage);

  GST_DEBUG_OBJECT (overlay, "create image fd=%d w=%d h=%d s=%d", fd,
      GST_VIDEO_INFO_WIDTH (&overlay->info),
      GST_VIDEO_INFO_HEIGHT (&overlay->info),
      GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0));

  attribs[atti++] = EGL_WIDTH;
  attribs[atti++] = GST_VIDEO_INFO_WIDTH (&overlay->info);
  attribs[atti++] = EGL_HEIGHT;
  attribs[atti++] = GST_VIDEO_INFO_HEIGHT (&overlay->info);
  attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
  attribs[atti++] = fourcc;
  attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
  attribs[atti++] = fd;
  attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
  attribs[atti++] = 0;
  attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
  attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0);
  attribs[atti] = EGL_NONE;

  image = _eglCreateImage (egl_display, EGL_NO_CONTEXT,
      EGL_LINUX_DMA_BUF_EXT, NULL, (const EGLint *) attribs);
  GST_DEBUG_OBJECT (overlay, "eglCreateImage %p", image);
  g_assert (image != EGL_NO_IMAGE_KHR);

  tex = g_malloc0 (sizeof (EglImageTexture));
  tex->overlay = overlay;
  tex->image = image;

  GST_DEBUG_OBJECT (overlay, "set buf %p tex %p", buf, tex);
  gst_mini_object_set_qdata (GST_MINI_OBJECT (buf),
      g_quark_from_static_string (QNAME), tex, _free_egl_image_texture);

  gst_gl_context_thread_add (context, _create_egl_image_texture_gl, tex);

  return tex;
}

static gint _task_data_compare (gconstpointer a, gconstpointer b,
    gpointer user_data)
{
  const TaskData *t1 = a;
  const TaskData *t2 = b;

  if (t1->pts < t2->pts) {
    return -1;
  } else if (t1->pts > t2->pts) {
    return 1;
  } else {
    return 0;
  }
}

static void
_task_data_map (TaskData * tdata)
{
  gboolean ret;
  if (tdata->map.data) {
    return;
  }

  ret = gst_buffer_map (tdata->buf, &tdata->map, GST_MAP_READ | GST_MAP_WRITE);
  g_assert (ret);
}

static void
_task_data_unmap (TaskData * tdata)
{
  if (!tdata->map.data) {
    return;
  }

  gst_buffer_unmap (tdata->buf, &tdata->map);
  memset (&tdata->map, 0, sizeof (tdata->map));
}

static void
_task_data_free_gl (GstGLContext * context, gpointer data)
{
  TaskData *tdata = data;
  const GstGLFuncs *gl = context->gl_vtable;

  if (!tdata || !tdata->tex) {
    return;
  }

  gl->DeleteTextures (1, &tdata->tex);
  tdata->tex = 0;
}

static void
_task_data_free (gpointer data)
{
  TaskData *tdata = data;

  if (!tdata) {
    return;
  }

  _task_data_unmap (tdata);
  gst_gl_context_thread_add (tdata->overlay->context, _task_data_free_gl,
      tdata);

  gst_buffer_replace (&tdata->buf, NULL);
  g_free (tdata->svg);
  g_free (tdata);
}

static void
_task_data_upload_gl (GstGLContext * context, gpointer data)
{
  TaskData * tdata = data;
  GstGLSvgOverlay *overlay = tdata->overlay;
  const GstGLFuncs *gl = context->gl_vtable;

  /* TODO: handle non packed stride */
  /* TODO: TexImage2D in a separate derived gl context */

  g_assert (!tdata->egl_tex);

  /* Copy pixels to GPU. */
  gl->GenTextures (1, &tdata->tex);
  gl->BindTexture (GL_TEXTURE_2D, tdata->tex);
  gl->TexImage2D(GL_TEXTURE_2D, 0, overlay->internal_format,
      GST_VIDEO_INFO_WIDTH (&overlay->info),
      GST_VIDEO_INFO_HEIGHT (&overlay->info),
      0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, tdata->map.data);
  gl->GenerateMipmap (GL_TEXTURE_2D);
}

static void
_task_push_locked (GstGLSvgOverlay *overlay, gpointer data)
{
  g_thread_pool_push (overlay->thread_pool, data, NULL);
  overlay->num_tasks++;
}

static GstStateChangeReturn
gst_gl_svg_overlay_change_state (GstElement * element,
    GstStateChange transition)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      g_mutex_lock (&overlay->mutex);
      overlay->svg_queue = g_queue_new ();
      overlay->gl_queue = g_queue_new ();
      overlay->thread_pool = g_thread_pool_new (gst_gl_svg_overlay_task,
          overlay, g_get_num_processors (), FALSE, NULL);
      g_mutex_unlock (&overlay->mutex);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      g_mutex_lock (&overlay->mutex);
      overlay->started = FALSE;
      g_cond_broadcast (&overlay->cond);
      while (overlay->num_tasks) {
        g_cond_wait (&overlay->cond, &overlay->mutex);
      }
      g_thread_pool_free (overlay->thread_pool, FALSE, FALSE);
      overlay->thread_pool = NULL;
      g_queue_free_full (overlay->svg_queue, _task_data_free);
      overlay->svg_queue = NULL;
      g_queue_free_full (overlay->gl_queue, _task_data_free);
      overlay->gl_queue = NULL;
      _task_data_free (overlay->current);
      overlay->current = NULL;
      if (overlay->buffer_pool) {
        gst_buffer_pool_set_active (overlay->buffer_pool, FALSE);
        gst_object_unref (overlay->buffer_pool);
        overlay->buffer_pool = NULL;
      }
      g_mutex_unlock (&overlay->mutex);
      break;
    default:
      break;
  }

  return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
}

static gboolean
gst_gl_svg_overlay_gl_start (GstGLBaseFilter * base_filter)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (base_filter);
  GstGLFilter *filter = GST_GL_FILTER (base_filter);

  GST_DEBUG_OBJECT (overlay, "gl_start");

  /* TODO: create a shared context for upload */
  overlay->context = gst_object_ref (GST_OBJECT (base_filter->context));
  overlay->shader = gst_gl_shader_new_default (overlay->context, NULL);

  filter->draw_attr_position_loc =
      gst_gl_shader_get_attribute_location (overlay->shader, "a_position");
  filter->draw_attr_texture_loc =
      gst_gl_shader_get_attribute_location (overlay->shader, "a_texcoord");

  if (USING_GLES2 (overlay->context) || USING_GLES3 (overlay->context)) {
    gboolean bgra = gst_gl_context_check_feature (overlay->context,
        "GL_EXT_texture_format_BGRA8888");
    if (bgra) {
      GST_DEBUG_OBJECT (overlay, "GL_EXT_texture_format_BGRA8888 supported");
    } else {
      GST_ERROR_OBJECT (overlay, "GL_EXT_texture_format_BGRA8888 unsupported");
      return FALSE;
    }

    overlay->internal_format = GL_BGRA_EXT;
  } else if (USING_OPENGL3 (overlay->context)) {
    /* BGRA8888 supported */
    overlay->internal_format = GL_RGBA;
  } else {
    g_assert_not_reached ();
  }

  if (overlay->use_ion && overlay->ion_allocator) {
    /* TODO: Init check the dma-buf import being supported. */
  } else {
    overlay->use_ion = FALSE;
  }

  return GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter);
}

static void
gst_gl_svg_overlay_gl_stop (GstGLBaseFilter * base_filter)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (base_filter);
  GST_DEBUG_OBJECT (overlay, "gl_stop");

  _task_data_free (overlay->current);
  overlay->current = NULL;

  if (overlay->shader) {
    gst_object_unref (overlay->shader);
    overlay->shader = NULL;
  }

  GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);

  gst_object_unref (GST_OBJECT (overlay->context));
  overlay->context = NULL;
}

static gboolean
gst_gl_svg_overlay_gl_set_caps (GstGLBaseFilter * base_filter, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLFilter *filter = GST_GL_FILTER (base_filter);
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (base_filter);
  GstStructure *config;
  GstCaps *caps;
  gsize size;
  gboolean ret;

  ret = GST_GL_BASE_FILTER_CLASS (parent_class)->gl_set_caps (base_filter,
      incaps, outcaps);

  if (!ret) {
    GST_ERROR_OBJECT (filter, "GstGLBaseFilter failed to start");
    return ret;
  }

  caps = gst_caps_new_simple("video/x-raw",
      "format", G_TYPE_STRING, "BGRA",
      "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH (&filter->out_info),
      "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT (&filter->out_info),
      "framerate", GST_TYPE_FRACTION, 0, 1,
      NULL);
  gst_video_info_from_caps (&overlay->info, caps);
  GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0) =
      cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
          GST_VIDEO_INFO_WIDTH (&overlay->info));

  if (GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0) != GST_VIDEO_INFO_WIDTH (
      &overlay->info) * 4) {
    /* TODO: stride */
    GST_ERROR_OBJECT (overlay, "Unsupported stride");
    gst_caps_unref (caps);
    return FALSE;
  }
  size = GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0) *
      GST_VIDEO_INFO_HEIGHT (&overlay->info);

  g_mutex_lock (&overlay->mutex);

  if (overlay->buffer_pool) {
    gst_buffer_pool_set_active (overlay->buffer_pool, FALSE);
    gst_object_unref (overlay->buffer_pool);
  }
  GST_INFO_OBJECT (overlay, "New pool with max %u buffers ion=%d",
      g_get_num_processors (), overlay->use_ion);
  overlay->buffer_pool = gst_buffer_pool_new ();
  config = gst_buffer_pool_get_config (overlay->buffer_pool);
  gst_buffer_pool_config_set_params (config, caps, size, 0,
      g_get_num_processors ());
  if (overlay->ion_allocator && overlay->use_ion) {
    gst_buffer_pool_config_set_allocator (config, overlay->ion_allocator, NULL);
  }
  ret = gst_buffer_pool_set_config (overlay->buffer_pool, config);
  g_assert (ret);
  ret = gst_buffer_pool_set_active (overlay->buffer_pool, TRUE);
  g_assert (ret);
  gst_caps_unref (caps);

  overlay->started = TRUE;

  g_mutex_unlock (&overlay->mutex);

  GST_DEBUG_OBJECT (filter, "%ux%u px, stride %u bytes",
      GST_VIDEO_INFO_WIDTH (&overlay->info),
      GST_VIDEO_INFO_HEIGHT (&overlay->info),
      GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0));

  return ret;
}

static void
gst_gl_svg_overlay_task (gpointer data, gpointer user_data)
{
  GstGLFilter *filter = GST_GL_FILTER (user_data);
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (user_data);
  TaskData *tdata = NULL;
  GstClockTime start = gst_util_get_timestamp ();
  gdouble elapsed_ms;

  /* TODO: Render SVG to dma-bufs when supported */

#define LOG_ELAPSED(s) \
do { \
  elapsed_ms = ((gdouble) gst_util_get_timestamp () - start) / GST_MSECOND; \
  GST_LOG_OBJECT (overlay, "%s: %.2f", s, elapsed_ms); \
} while (0)

#define TASK_DONE(push) \
do { \
  g_mutex_lock (&overlay->mutex); \
  if (push) { \
    if (overlay->started) { \
      _task_push_locked (overlay, tdata); \
    } else { \
      _task_data_free (tdata); \
    } \
  }\
  overlay->num_tasks--; \
  g_cond_broadcast (&overlay->cond); \
  g_mutex_unlock (&overlay->mutex); \
  return; \
} while (0)

  if (data == overlay->svg_queue) {
    g_mutex_lock (&overlay->mutex);
    if (!overlay->sync) {
      /* Draw only the latest SVG overlay, drop older. */
      while (g_queue_get_length (overlay->svg_queue) > 1) {
        tdata = g_queue_pop_head (overlay->svg_queue);
        _task_data_free (tdata);
        tdata = NULL;
      }
    }
    tdata = g_queue_pop_head (overlay->svg_queue);

    g_mutex_unlock (&overlay->mutex);

    TASK_DONE (TRUE);
  }

  tdata = data;

  if (tdata->op == OP_ALLOC) {
    GstBufferPool *pool;
    GstFlowReturn ret;

    g_mutex_lock (&overlay->mutex);
    pool = overlay->buffer_pool;
    g_mutex_unlock (&overlay->mutex);

    g_assert (gst_buffer_pool_is_active (pool));

    ret = gst_buffer_pool_acquire_buffer (pool, &tdata->buf, NULL);
    g_assert (ret == GST_FLOW_OK);

    tdata->op = OP_DRAW;
    TASK_DONE(tdata);
  }

  if (tdata->op == OP_DRAW) {
    cairo_t *cairo;
    cairo_surface_t *surface;
    RsvgHandle *handle;
    GError *err = NULL;
    gboolean ret;

    _task_data_map (tdata);

    memset (tdata->map.data, 0, tdata->map.size);
    surface = cairo_image_surface_create_for_data (tdata->map.data,
        CAIRO_FORMAT_ARGB32, GST_VIDEO_INFO_WIDTH (&overlay->info),
        GST_VIDEO_INFO_HEIGHT (&overlay->info),
        GST_VIDEO_INFO_PLANE_STRIDE (&overlay->info, 0));
    g_assert (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS);
    cairo = cairo_create (surface);
    g_assert (cairo_status (cairo) == CAIRO_STATUS_SUCCESS);

    handle = rsvg_handle_new_from_data (tdata->svg, strlen (tdata->svg), &err);
    if (err) {
      GST_ERROR_OBJECT (overlay, "Unable to render SVG: %s", err->message);
      g_error_free (err);
    }
    g_assert (handle);
    ret = rsvg_handle_render_cairo (handle, cairo);
    g_assert (ret);

    rsvg_handle_close (handle, NULL);
    g_object_unref (handle);
    cairo_surface_flush (surface);
    cairo_surface_destroy (surface);
    cairo_destroy (cairo);

    tdata->op = OP_UPLOAD;
    LOG_ELAPSED ("draw");
    TASK_DONE (TRUE);
  }

  if (tdata->op == OP_UPLOAD) {
    gboolean dma = overlay->use_ion && gst_is_dmabuf_memory (
        gst_buffer_peek_memory (tdata->buf, 0));
    if (dma) {
      /* Unmap to flush CPU cache. */
      _task_data_unmap (tdata);
      g_assert (!tdata->egl_tex);
      tdata->egl_tex = _create_egl_image_texture (overlay, tdata->buf);
      g_assert (tdata->egl_tex);
    } else {
      /* Copy pixels to GPU, unmap and free buffer. */
      gst_gl_context_thread_add (tdata->overlay->context, _task_data_upload_gl,
          tdata);
      _task_data_unmap (tdata);
      gst_buffer_replace (&tdata->buf, NULL);
    }

    tdata->op = OP_READY;

    g_mutex_lock (&overlay->mutex);
    g_queue_push_tail (overlay->gl_queue, tdata);
    g_queue_sort (overlay->gl_queue, _task_data_compare, NULL);
    g_cond_broadcast (&overlay->cond);
    g_mutex_unlock (&overlay->mutex);
    LOG_ELAPSED ("upload");
    TASK_DONE (FALSE);
  }

  g_assert_not_reached ();

#undef LOG_ELAPSED
#undef TASK_DONE
}

static gboolean
_overlay_ready (GstGLSvgOverlay * overlay, GstClockTime pts)
{
  gint i;

  for (i = 0; i < g_queue_get_length (overlay->gl_queue); i++) {
    TaskData *tdata = g_queue_peek_nth (overlay->gl_queue, i);
    if (tdata && tdata->pts == pts && tdata->op == OP_READY) {
      return TRUE;
    }
  }
  return FALSE;
}

static GstFlowReturn
gst_gl_svg_overlay_transform (GstBaseTransform * bt,
    GstBuffer * inbuf, GstBuffer * outbuf)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (bt);

  g_mutex_lock (&overlay->mutex);
  if (overlay->sync) {
    /* In this mode we require an overlay per frame. Block this thread
     * while the texture is being prepared in the GL thread before
     * transferring execution there. Don't block the GL thread. */
    while (overlay->started && !_overlay_ready (overlay,
        GST_BUFFER_PTS (inbuf))) {
      g_cond_wait (&overlay->cond, &overlay->mutex);
    }
    if (!overlay->started) {
      g_mutex_unlock (&overlay->mutex);
      return GST_FLOW_FLUSHING;
    }
  } else {
    /* Async drawing of SVG was kicked off when property was set.
     * When composing the final output the latest ready overlay will
     * be used, if any.
     */
  }
  overlay->next_pts = GST_BUFFER_PTS (inbuf);
  g_mutex_unlock (&overlay->mutex);

  return GST_BASE_TRANSFORM_CLASS (parent_class)->transform (bt, inbuf, outbuf);
}

static gboolean
gst_gl_svg_overlay_set_svg (GstGLSvgOverlay * overlay, const gchar * svg,
    GstClockTime pts)
{
  TaskData *tdata;

  g_mutex_lock (&overlay->mutex);
  if (!overlay->started) {
    GST_WARNING_OBJECT (overlay, "Wrong state, dropping SVG overlay");
    g_mutex_unlock (&overlay->mutex);
    return FALSE;
  }

  tdata = g_malloc0 (sizeof (TaskData));
  tdata->overlay = overlay;
  tdata->op = OP_ALLOC;
  tdata->svg = g_strdup (svg);
  tdata->pts = pts;
  g_queue_push_tail (overlay->svg_queue, tdata);
  _task_push_locked (overlay, overlay->svg_queue);

  g_mutex_unlock (&overlay->mutex);

  return TRUE;
}

static TaskData *
gst_gl_svg_overlay_next (GstGLSvgOverlay * overlay)
{
  gint i;
  GQueue *q;
  GstClockTime pts;
  TaskData *tdata;

  g_mutex_lock (&overlay->mutex);

  q = overlay->gl_queue;
  pts = overlay->next_pts;

  if (overlay->sync) {
    /* Get overlay with matching pts, drop older. */
    while (!g_queue_is_empty(q) &&
        ((TaskData*) g_queue_peek_tail (q))->pts < pts) {
      _task_data_free (g_queue_pop_head (q));
    }

    for (i = 0; i < g_queue_get_length (q); i++) {
      TaskData *tmp = g_queue_peek_nth (q, i);
      if (tmp && tmp->pts == pts) {
        tdata = g_queue_pop_nth (q, i);
        break;
      }
    }
    g_assert (tdata);
  } else {
    /* Get the latest overlay, drop older. */
    tdata = g_queue_pop_head (q);
    while (!g_queue_is_empty(q)) {
      _task_data_free (g_queue_pop_head (q));
    }
  }

  g_mutex_unlock (&overlay->mutex);

  return tdata;
}

static gboolean
gst_gl_svg_overlay_draw_gl (GstGLFilter * filter, GstGLMemory * in_tex,
    gpointer user_data)
{
  GstGLSvgOverlay *overlay = GST_GL_SVG_OVERLAY (user_data);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
  const GstGLFuncs *gl = context->gl_vtable;
  TaskData *next, *old = NULL;
  guint tex_id, o_tex_id = 0;

  next = gst_gl_svg_overlay_next (overlay);
  if (next) {
    _task_data_free (overlay->current);
    overlay->current = next;
  }

  tex_id = gst_gl_memory_get_texture_id (in_tex);
  if (overlay->current) {
    if (overlay->current->egl_tex) {
      o_tex_id = overlay->current->egl_tex->tex;
    } else {
      o_tex_id = overlay->current->tex;
    }
  }

  g_return_val_if_fail (overlay->shader, FALSE);

  gl->ClearColor (0.0, 0.0, 0.0, 1.0);
  gl->Clear (GL_COLOR_BUFFER_BIT);

  gst_gl_shader_use (overlay->shader);
  gst_gl_shader_set_uniform_1i (overlay->shader, "tex", 0);
  gl->ActiveTexture (GL_TEXTURE0);
  gl->BindTexture (GL_TEXTURE_2D, tex_id);
  gst_gl_filter_draw_fullscreen_quad (filter);

  if (o_tex_id) {
    gst_gl_shader_use (overlay->shader);
    gst_gl_shader_set_uniform_1i (overlay->shader, "tex", 0);
    gl->ActiveTexture (GL_TEXTURE0);
    gl->BindTexture (GL_TEXTURE_2D, o_tex_id);
    gl->Enable (GL_BLEND);
    gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    gl->BlendEquation (GL_FUNC_ADD);
    gst_gl_filter_draw_fullscreen_quad (filter);
    gl->Disable (GL_BLEND);
  }

  return TRUE;
}

static gboolean
gst_gl_svg_overlay_filter_texture (GstGLFilter * filter, GstGLMemory * in_tex,
    GstGLMemory * out_tex)
{
  if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context)) {
    gst_gl_filter_render_to_target (filter, in_tex, out_tex,
        gst_gl_svg_overlay_draw_gl, filter);
  }

  return TRUE;
}
