/*
 * GStreamer
 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
 *
 * 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.
 */

/**
 * SECTION:element-gleffects.
 *
 * GL Shading Language effects.
 *
 * <refsect2>
 * <title>Examples</title>
 * |[
 * gst-launch-1.0 videotestsrc ! glupload ! gleffects effect=5 ! glimagesink
 * ]|
 * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
 * </refsect2>
 */

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

#include <gst/gl/gstglconfig.h>
#include "gstgleffects.h"

#define GST_CAT_DEFAULT gst_gl_effects_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0 = 0x0,
  PROP_EFFECT = 0x1 << 1,
  PROP_HSWAP = 0x1 << 2,
  PROP_INVERT = 0x1 << 3
};

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_effects_debug, "gleffects", 0, "gleffects element");

#define gst_gl_effects_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLEffects, gst_gl_effects, GST_TYPE_GL_FILTER,
    DEBUG_INIT);

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

static gboolean gst_gl_effects_init_resources (GstBaseTransform * trans);
static gboolean gst_gl_effects_reset_resources (GstBaseTransform * trans);

static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter);

static void gst_gl_effects_ghash_func_clean (gpointer key, gpointer value,
    gpointer data);

static gboolean gst_gl_effects_filter_texture (GstGLFilter * filter,
    guint in_tex, guint out_tex);
static gboolean gst_gl_effects_filters_is_property_supported (const
    GstGLEffectsFilterDescriptor *, gint property);

/* dont' forget to edit the following when a new effect is added */
typedef enum
{
  GST_GL_EFFECT_IDENTITY,
  GST_GL_EFFECT_MIRROR,
  GST_GL_EFFECT_SQUEEZE,
  GST_GL_EFFECT_STRETCH,
  GST_GL_EFFECT_TUNNEL,
  GST_GL_EFFECT_FISHEYE,
  GST_GL_EFFECT_TWIRL,
  GST_GL_EFFECT_BULGE,
  GST_GL_EFFECT_SQUARE,
  GST_GL_EFFECT_HEAT,
  GST_GL_EFFECT_SEPIA,
  GST_GL_EFFECT_XPRO,
  GST_GL_EFFECT_LUMA_XPRO,
  GST_GL_EFFECT_XRAY,
  GST_GL_EFFECT_SIN,
  GST_GL_EFFECT_GLOW,
  GST_GL_EFFECT_SOBEL,
  GST_GL_EFFECT_BLUR,
  GST_GL_EFFECT_LAPLACIAN,
  GST_GL_N_EFFECTS
} GstGLEffectsEffect;

static const GEnumValue *
gst_gl_effects_get_effects (void)
{
  static const GEnumValue effect_types[] = {
    {GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"},
    {GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"},
    {GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"},
    {GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
    {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
    {GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
    {GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
    {GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge"},
    {GST_GL_EFFECT_SQUARE, "Square Effect", "square"},
    {GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat"},
    {GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia"},
    {GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro"},
    {GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro"},
    {GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray"},
    {GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin"},
    {GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow"},
    {GST_GL_EFFECT_SOBEL, "Sobel edge detection Effect", "sobel"},
    {GST_GL_EFFECT_BLUR, "Blur with 9x9 separable convolution Effect", "blur"},
    {GST_GL_EFFECT_LAPLACIAN, "Laplacian Convolution Demo Effect", "laplacian"},
    {0, NULL, NULL}
  };
  return effect_types;
}

#define GST_TYPE_GL_EFFECTS_EFFECT (gst_gl_effects_effect_get_type ())
static GType
gst_gl_effects_effect_get_type (void)
{
  static GType gl_effects_effect_type = 0;
  if (!gl_effects_effect_type) {
    gl_effects_effect_type =
        g_enum_register_static ("GstGLEffectsEffect",
        gst_gl_effects_get_effects ());
  }
  return gl_effects_effect_type;
}

static void
gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
{
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (effects);

  switch (effect_type) {
    case GST_GL_EFFECT_IDENTITY:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_identity;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_MIRROR:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_mirror;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SQUEEZE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_squeeze;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_STRETCH:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_TUNNEL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_tunnel;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_FISHEYE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_fisheye;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_TWIRL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_twirl;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_BULGE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_bulge;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SQUARE:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_square;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_HEAT:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_heat;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SEPIA:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sepia;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_XPRO:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xpro;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_LUMA_XPRO:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SIN:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_XRAY:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_GLOW:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_SOBEL:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sobel;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_BLUR:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_blur;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    case GST_GL_EFFECT_LAPLACIAN:
      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_laplacian;
      filter_class->supported_gl_api =
          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
      effects->current_effect = effect_type;
      break;
    default:
      g_assert_not_reached ();
  }

  effects->current_effect = effect_type;
}

/* init resources that need a gl context */
static void
gst_gl_effects_init_gl_resources (GstGLFilter * filter)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
  GstGLFuncs *gl = context->gl_vtable;
  guint internal_format;
  gint i = 0;

  for (i = 0; i < NEEDED_TEXTURES; i++) {

    if (effects->midtexture[i]) {
      gl->DeleteTextures (1, &effects->midtexture[i]);
      effects->midtexture[i] = 0;
    }

    gl->GenTextures (1, &effects->midtexture[i]);
    gl->BindTexture (GL_TEXTURE_2D, effects->midtexture[i]);
    internal_format =
        gst_gl_sized_gl_format_from_gl_format_type (context, GL_RGBA,
        GL_UNSIGNED_BYTE);
    gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format,
        GST_VIDEO_INFO_WIDTH (&filter->out_info),
        GST_VIDEO_INFO_HEIGHT (&filter->out_info), 0, GL_RGBA, GL_UNSIGNED_BYTE,
        NULL);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
  }
}

/* free resources that need a gl context */
static void
gst_gl_effects_reset_gl_resources (GstGLFilter * filter)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  gint i = 0;

  for (i = 0; i < NEEDED_TEXTURES; i++) {
    gl->DeleteTextures (1, &effects->midtexture[i]);
    effects->midtexture[i] = 0;
  }
  for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
    gl->DeleteTextures (1, &effects->curve[i]);
    effects->curve[i] = 0;
  }
}

static void
gst_gl_effects_class_init (GstGLEffectsClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_effects_init_resources;
  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_effects_reset_resources;

  GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_effects_filter_texture;
  GST_GL_FILTER_CLASS (klass)->display_init_cb =
      gst_gl_effects_init_gl_resources;
  GST_GL_FILTER_CLASS (klass)->display_reset_cb =
      gst_gl_effects_reset_gl_resources;
  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_effects_on_init_gl_context;

  klass->filter_descriptor = NULL;

  gst_element_class_set_metadata (element_class,
      "Gstreamer OpenGL Effects", "Filter/Effect/Video",
      "GL Shading Language effects",
      "Filippo Argiolas <filippo.argiolas@gmail.com>");

  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
      GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3;
}

static void
gst_gl_effects_filter_class_init (GstGLEffectsClass * klass,
    const GstGLEffectsFilterDescriptor * filter_descriptor)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  klass->filter_descriptor = filter_descriptor;

  gobject_class->set_property = gst_gl_effects_set_property;
  gobject_class->get_property = gst_gl_effects_get_property;

  /* if filterDescriptor is null it's a generic gleffects */
  if (!filter_descriptor) {
    g_object_class_install_property (gobject_class,
        PROP_EFFECT,
        g_param_spec_enum ("effect",
            "Effect",
            "Select which effect apply to GL video texture",
            GST_TYPE_GL_EFFECTS_EFFECT,
            GST_GL_EFFECT_IDENTITY,
            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  } else {
    gchar *description = g_strdup_printf ("GL Shading Language effects - %s",
        filter_descriptor->filter_longname);

    gst_element_class_set_metadata (element_class,
        filter_descriptor->filter_longname, "Filter/Effect/Video",
        description, "Filippo Argiolas <filippo.argiolas@gmail.com>");

    g_free (description);
  }

  g_object_class_install_property (gobject_class,
      PROP_HSWAP,
      g_param_spec_boolean ("hswap",
          "Horizontal Swap",
          "Switch video texture left to right, useful with webcams",
          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* FIXME: make it work on every effect */
  if (gst_gl_effects_filters_is_property_supported (filter_descriptor,
          PROP_INVERT)) {
    g_object_class_install_property (gobject_class, PROP_INVERT,
        g_param_spec_boolean ("invert", "Invert the colors for sobel effect",
            "Invert colors to get dark edges on bright background when using sobel effect",
            FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  }
}

static void
set_horizontal_swap (GstGLContext * context, gpointer data)
{
#if GST_GL_HAVE_OPENGL
  GstGLFuncs *gl = context->gl_vtable;

  if (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) {
    const gfloat mirrormatrix[16] = {
      -1.0, 0.0, 0.0, 0.0,
      0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
    };

    gl->MatrixMode (GL_MODELVIEW);
    gl->LoadMatrixf (mirrormatrix);
  }
#endif
}

static void
gst_gl_effects_init (GstGLEffects * effects)
{
  effects->horizontal_swap = FALSE;
  effects->invert = FALSE;
  effects->effect = gst_gl_effects_identity;
}

static void
gst_gl_effects_filter_init (GstGLEffects * effects)
{
  gst_gl_effects_set_effect (effects,
      GST_GL_EFFECTS_GET_CLASS (effects)->filter_descriptor->effect);
}

static void
gst_gl_effects_ghash_func_clean (gpointer key, gpointer value, gpointer data)
{
  GstGLShader *shader = (GstGLShader *) value;
  GstGLFilter *filter = (GstGLFilter *) data;

  //blocking call, wait the opengl thread has destroyed the shader
  gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context, shader);

  value = NULL;
}

static gboolean
gst_gl_effects_reset_resources (GstBaseTransform * trans)
{
  GstGLEffects *effects = GST_GL_EFFECTS (trans);

  /* release shaders in the gl thread */
  g_hash_table_foreach (effects->shaderstable, gst_gl_effects_ghash_func_clean,
      effects);

  /* clean the htable without calling values destructors
   * because shaders have been released in the glthread
   * through the foreach func */
  g_hash_table_unref (effects->shaderstable);
  effects->shaderstable = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}

static void
gst_gl_effects_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLEffects *effects = GST_GL_EFFECTS (object);

  switch (prop_id) {
    case PROP_EFFECT:
      gst_gl_effects_set_effect (effects, g_value_get_enum (value));
      break;
    case PROP_HSWAP:
      effects->horizontal_swap = g_value_get_boolean (value);
      break;
    case PROP_INVERT:
      effects->invert = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_effects_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLEffects *effects = GST_GL_EFFECTS (object);

  switch (prop_id) {
    case PROP_EFFECT:
      g_value_set_enum (value, effects->current_effect);
      break;
    case PROP_HSWAP:
      g_value_set_boolean (value, effects->horizontal_swap);
      break;
    case PROP_INVERT:
      g_value_set_boolean (value, effects->invert);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_gl_effects_init_resources (GstBaseTransform * trans)
{
  GstGLEffects *effects = GST_GL_EFFECTS (trans);
  gint i;

  effects->shaderstable = g_hash_table_new (g_str_hash, g_str_equal);

  for (i = 0; i < NEEDED_TEXTURES; i++) {
    effects->midtexture[i] = 0;
  }
  for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
    effects->curve[i] = 0;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->start (trans);
}

static gboolean
gst_gl_effects_on_init_gl_context (GstGLFilter * filter)
{
  return TRUE;
}

static gboolean
gst_gl_effects_filter_texture (GstGLFilter * filter, guint in_tex,
    guint out_tex)
{
  GstGLEffects *effects = GST_GL_EFFECTS (filter);

  effects->intexture = in_tex;
  effects->outtexture = out_tex;

  if (effects->horizontal_swap == TRUE)
    gst_gl_context_thread_add (GST_GL_BASE_FILTER (filter)->context,
        set_horizontal_swap, effects);

  effects->effect (effects);

  return TRUE;
}

GstGLShader *
gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
    const gchar * shader_name, const gchar * shader_source_gles2)
{
  GstGLShader *shader = NULL;
  GstGLFilter *filter = GST_GL_FILTER (effects);
  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;

  shader = g_hash_table_lookup (effects->shaderstable, shader_name);

  if (!shader) {
    GError *error = NULL;

    if (!(shader = gst_gl_shader_new_link_with_stages (context, &error,
                gst_glsl_stage_new_default_vertex (context),
                gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
                    GST_GLSL_VERSION_NONE,
                    GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
                    shader_source_gles2), NULL))) {
      GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
          ("Failed to initialize %s shader", shader_name), (NULL));
    }

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

  g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader);

  return shader;
}

static const GstGLEffectsFilterDescriptor *
gst_gl_effects_filters_supported_properties (void)
{
  /* Horizontal swap property is supported by all filters */
  static const GstGLEffectsFilterDescriptor effects[] = {
    {GST_GL_EFFECT_SOBEL, PROP_INVERT, NULL},
    {GST_GL_EFFECT_LAPLACIAN, PROP_INVERT, NULL},
    {0, 0, NULL}
  };
  return effects;
}

static inline gboolean
gst_gl_effects_filters_is_property_supported (const GstGLEffectsFilterDescriptor
    * descriptor, gint property)
{
  /* generic filter (NULL descriptor) supports all properties */
  return !descriptor || (descriptor->supported_properties & property);
}

static const GstGLEffectsFilterDescriptor *
gst_gl_effects_filters_descriptors (void)
{
  static GstGLEffectsFilterDescriptor *descriptors = NULL;
  if (!descriptors) {
    const GEnumValue *e;
    const GEnumValue *effect = gst_gl_effects_get_effects ();
    const GstGLEffectsFilterDescriptor *defined;
    guint n_filters = 0, i;

    for (e = effect; NULL != e->value_nick; ++e, ++n_filters) {
    }

    descriptors = g_new0 (GstGLEffectsFilterDescriptor, n_filters + 1);
    for (i = 0; i < n_filters; ++i, ++effect) {
      descriptors[i].effect = effect->value;
      descriptors[i].filter_name = effect->value_nick;
      descriptors[i].filter_longname = effect->value_name;
    }

    for (defined = gst_gl_effects_filters_supported_properties ();
        0 != defined->supported_properties; ++defined) {

      for (i = 0; i < n_filters; ++i) {
        if (descriptors[i].effect == defined->effect) {
          descriptors[i].supported_properties = defined->supported_properties;
          break;
        }
      }
      if (i >= n_filters) {
        GST_WARNING ("Could not match gstgleffects-%s descriptor",
            defined->filter_name);
      }
    }
  }
  return descriptors;
}

gboolean
gst_gl_effects_register_filters (GstPlugin * plugin, GstRank rank)
{
  static volatile gsize registered = 0;

  if (g_once_init_enter (&registered)) {
    GTypeInfo info = {
      sizeof (GstGLEffectsClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_gl_effects_filter_class_init,
      NULL,
      NULL,
      sizeof (GstGLEffects),
      0,
      NULL
    };
    GType generic_type =
        g_type_register_static (GST_TYPE_GL_EFFECTS, "GstGLEffectsGeneric",
        &info, 0);

    if (gst_element_register (plugin, "gleffects", rank, generic_type)) {
      const GstGLEffectsFilterDescriptor *filters;
      for (filters = gst_gl_effects_filters_descriptors ();
          NULL != filters->filter_name; ++filters) {
        gchar *name = g_strdup_printf ("gleffects_%s", filters->filter_name);
        GTypeInfo info = {
          sizeof (GstGLEffectsClass),
          NULL,
          NULL,
          (GClassInitFunc) gst_gl_effects_filter_class_init,
          NULL,
          filters,
          sizeof (GstGLEffects),
          0,
          (GInstanceInitFunc) gst_gl_effects_filter_init
        };
        GType type =
            g_type_register_static (GST_TYPE_GL_EFFECTS, name, &info, 0);
        if (!gst_element_register (plugin, name, rank, type)) {
          GST_WARNING ("Could not register %s", name);
        }
        g_free (name);
      }
    }
    g_once_init_leave (&registered, generic_type);
  }
  return registered;
}
