/*
 * # 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 <librsvg/rsvg.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);

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

#define DEFAULT_PROP_SYNC TRUE

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));

  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_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2;
  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->num_tasks = 0;
  overlay->started = FALSE;
  overlay->shader = NULL;
  overlay->thread_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);
}

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

  GST_DEBUG_OBJECT (overlay, "finalize");

  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;
    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;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

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_buffer_replace (&tdata->buf, NULL);
  gst_gl_context_thread_add (tdata->overlay->context, _task_data_free_gl,
      tdata);
  g_free (tdata->svg);
  g_free (tdata);
}

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

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

  gl->GenTextures (1, &tdata->tex);
  gl->BindTexture (GL_TEXTURE_2D, tdata->tex);
  gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, overlay->width, overlay->height, 0,
      GL_RGBA, 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);
      overlay->started = TRUE;
      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;
      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");

  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);
  gboolean ret;

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

  overlay->width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
  overlay->height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);
  overlay->stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
      overlay->width);

  GST_DEBUG_OBJECT (filter, "%ux%u px, stride %u bytes", overlay->width,
      overlay->height, overlay->stride);

  if (overlay->stride != overlay->width * 4) {
    /* TODO: stride */
    GST_ERROR_OBJECT (overlay, "Unsupported stride");
    return FALSE;
  }

  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) {
    /* TODO: Buffer pool. */
    const gsize size = GST_VIDEO_INFO_WIDTH (&filter->out_info) *
        GST_VIDEO_INFO_HEIGHT (&filter->out_info) * 4; /* BGRA 4 bpp. */
    tdata->buf = gst_buffer_new_allocate (NULL, size, NULL);
    tdata->op = OP_DRAW;
    LOG_ELAPSED ("alloc");
    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, overlay->width, overlay->height, overlay->stride);
    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) {
    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);

  }

  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) {
    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;
}
