/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2016> Matthew Waters <matthew@centricular.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.
 */

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

#include "gltestsrc.h"

#define MAX_ATTRIBUTES 4

struct vts_color_struct
{
  gfloat R, G, B;
};

struct XYZWRGB
{
  gfloat X, Y, Z, W, R, G, B;
};

enum
{
  COLOR_WHITE = 0,
  COLOR_YELLOW,
  COLOR_CYAN,
  COLOR_GREEN,
  COLOR_MAGENTA,
  COLOR_RED,
  COLOR_BLUE,
  COLOR_BLACK,
  COLOR_NEG_I,
  COLOR_POS_Q,
  COLOR_SUPER_BLACK,
  COLOR_DARK_GREY
};

static const struct vts_color_struct vts_colors[] = {
  /* 100% white */
  {1.0f, 1.0f, 1.0f},
  /* yellow */
  {1.0f, 1.0f, 0.0f},
  /* cyan */
  {0.0f, 1.0f, 1.0f},
  /* green */
  {0.0f, 1.0f, 0.0f},
  /* magenta */
  {1.0f, 0.0f, 1.0f},
  /* red */
  {1.0f, 0.0f, 0.0f},
  /* blue */
  {0.0f, 0.0f, 1.0f},
  /* black */
  {0.0f, 0.0f, 0.0f},
  /* -I */
  {0.0, 0.0f, 0.5f},
  /* +Q */
  {0.0f, 0.5, 1.0f},
  /* superblack */
  {0.0f, 0.0f, 0.0f},
  /* 7.421875% grey */
  {19. / 256.0f, 19. / 256.0f, 19. / 256.0},
};

/* *INDENT-OFF* */
static const GLfloat positions[] = {
     -1.0,  1.0,  0.0, 1.0,
      1.0,  1.0,  0.0, 1.0,
      1.0, -1.0,  0.0, 1.0,
     -1.0, -1.0,  0.0, 1.0,
};

static const GLushort indices_quad[] = { 0, 1, 2, 0, 2, 3 };
/* *INDENT-ON* */

struct attribute
{
  const gchar *name;
  gint location;
  guint n_elements;
  GLenum element_type;
  guint offset;                 /* in bytes */
  guint stride;                 /* in bytes */
};

struct SrcShader
{
  struct BaseSrcImpl base;

  GstGLShader *shader;

  guint vao;
  guint vbo;
  guint vbo_indices;

  guint n_attributes;
  struct attribute attributes[MAX_ATTRIBUTES];

  gconstpointer vertices;
  gsize vertices_size;
  const gushort *indices;
  guint index_offset;
  guint n_indices;
};

static void
_bind_buffer (struct SrcShader *src)
{
  GstGLContext *context = src->base.context;
  const GstGLFuncs *gl = context->gl_vtable;
  gint i;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, src->vbo_indices);
  gl->BindBuffer (GL_ARRAY_BUFFER, src->vbo);

  /* Load the vertex position */
  for (i = 0; i < src->n_attributes; i++) {
    struct attribute *attr = &src->attributes[i];

    if (attr->location == -1)
      attr->location =
          gst_gl_shader_get_attribute_location (src->shader, attr->name);

    gl->VertexAttribPointer (attr->location, attr->n_elements,
        attr->element_type, GL_FALSE, attr->stride,
        (void *) (gintptr) attr->offset);

    gl->EnableVertexAttribArray (attr->location);
  }
}

static void
_unbind_buffer (struct SrcShader *src)
{
  GstGLContext *context = src->base.context;
  const GstGLFuncs *gl = context->gl_vtable;
  gint i;

  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);

  for (i = 0; i < src->n_attributes; i++) {
    struct attribute *attr = &src->attributes[i];

    gl->DisableVertexAttribArray (attr->location);
  }
}

static gboolean
_src_shader_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
{
  struct SrcShader *src = impl;
  const GstGLFuncs *gl = context->gl_vtable;

  src->base.context = context;

  if (!src->vbo) {
    if (gl->GenVertexArrays) {
      gl->GenVertexArrays (1, &src->vao);
      gl->BindVertexArray (src->vao);
    }

    gl->GenBuffers (1, &src->vbo);
    gl->BindBuffer (GL_ARRAY_BUFFER, src->vbo);
    gl->BufferData (GL_ARRAY_BUFFER, src->vertices_size,
        src->vertices, GL_STATIC_DRAW);

    gl->GenBuffers (1, &src->vbo_indices);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, src->vbo_indices);
    gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, src->n_indices * sizeof (gushort),
        src->indices, GL_STATIC_DRAW);

    if (gl->GenVertexArrays) {
      _bind_buffer (src);
      gl->BindVertexArray (0);
    }

    gl->BindBuffer (GL_ARRAY_BUFFER, 0);
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  }

  return TRUE;
}

static gboolean
_src_shader_fill_bound_fbo (gpointer impl)
{
  struct SrcShader *src = impl;
  const GstGLFuncs *gl;

  g_return_val_if_fail (src->base.context, FALSE);
  g_return_val_if_fail (src->shader, FALSE);
  gl = src->base.context->gl_vtable;

  gst_gl_shader_use (src->shader);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (src->vao);
  _bind_buffer (src);

  gl->DrawElements (GL_TRIANGLES, src->n_indices, GL_UNSIGNED_SHORT,
      (gpointer) (gintptr) src->index_offset);

  if (gl->GenVertexArrays)
    gl->BindVertexArray (0);
  _unbind_buffer (src);

  gst_gl_context_clear_shader (src->base.context);

  return TRUE;
}

static void
_src_shader_deinit (gpointer impl)
{
  struct SrcShader *src = impl;
  const GstGLFuncs *gl = src->base.context->gl_vtable;

  if (src->shader)
    gst_object_unref (src->shader);
  src->shader = NULL;

  if (src->vao)
    gl->DeleteVertexArrays (1, &src->vao);
  src->vao = 0;

  if (src->vbo)
    gl->DeleteBuffers (1, &src->vbo);
  src->vbo = 0;

  if (src->vbo_indices)
    gl->DeleteBuffers (1, &src->vbo_indices);
  src->vbo_indices = 0;
}

/* *INDENT-OFF* */
static const gchar *smpte_vertex_src =
    "attribute vec4 position;\n"
    "attribute vec4 a_color;\n"
    "varying vec4 color;\n"
    "void main()\n"
    "{\n"
    "  gl_Position = position;\n"
    "  color = a_color;\n"
    "}";

static const gchar *smpte_fragment_src =
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "varying vec4 color;\n"
    "void main()\n"
    "{\n"
    "  gl_FragColor = color;\n"
    "}";

static const gchar *snow_vertex_src =
    "attribute vec4 position;\n"
    "varying vec2 out_uv;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = position;\n"
    "   out_uv = position.xy;\n"
    "}";

static const gchar *snow_fragment_src = 
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "uniform float time;\n"
    "varying vec2 out_uv;\n"
    "\n"
    "float rand(vec2 co){\n"
    "    return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);\n"
    "}\n"
    "void main()\n"
    "{\n"
    "  gl_FragColor = vec4(rand(time * out_uv));\n"
    "}";
/* *INDENT-ON* */

#define N_QUADS 21
struct SrcSMPTE
{
  struct SrcShader base;

  GstGLShader *snow_shader;
  GstGLShader *color_shader;
  gint attr_snow_position;
};

static gpointer
_src_smpte_new (GstGLTestSrc * test)
{
  struct SrcSMPTE *src = g_new0 (struct SrcSMPTE, 1);

  src->base.base.src = test;

  return src;
}

static gboolean
_src_smpte_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
{
  struct SrcSMPTE *src = impl;
  struct XYZWRGB *coord;
  gushort *plane_indices;
  GError *error = NULL;
  int color_idx = 0;
  int i;

  src->base.base.context = context;

  coord = g_new0 (struct XYZWRGB, N_QUADS * 4);
  plane_indices = g_new0 (gushort, N_QUADS * 6);

  /* top row */
  for (i = 0; i < 7; i++) {
    coord[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f);
    coord[color_idx * 4 + 0].Y = 1.0f / 3.0f;
    coord[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f);
    coord[color_idx * 4 + 1].Y = 1.0f / 3.0f;
    coord[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f);
    coord[color_idx * 4 + 2].Y = -1.0f;
    coord[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f);
    coord[color_idx * 4 + 3].Y = -1.0f;
    color_idx++;
  }

  /* middle row */
  for (i = 0; i < 7; i++) {
    coord[color_idx * 4 + 0].X = -1.0f + i * (2.0f / 7.0f);
    coord[color_idx * 4 + 0].Y = 0.5f;
    coord[color_idx * 4 + 1].X = -1.0f + (i + 1) * (2.0f / 7.0f);
    coord[color_idx * 4 + 1].Y = 0.5f;
    coord[color_idx * 4 + 2].X = -1.0f + (i + 1) * (2.0f / 7.0f);
    coord[color_idx * 4 + 2].Y = 1.0f / 3.0f;
    coord[color_idx * 4 + 3].X = -1.0f + i * (2.0f / 7.0f);
    coord[color_idx * 4 + 3].Y = 1.0f / 3.0f;
    color_idx++;
  }

  /* bottom row, left three */
  for (i = 0; i < 3; i++) {
    coord[color_idx * 4 + 0].X = -1.0f + i / 3.0f;
    coord[color_idx * 4 + 0].Y = 1.0f;
    coord[color_idx * 4 + 1].X = -1.0f + (i + 1) / 3.0f;
    coord[color_idx * 4 + 1].Y = 1.0f;
    coord[color_idx * 4 + 2].X = -1.0f + (i + 1) / 3.0f;
    coord[color_idx * 4 + 2].Y = 0.5f;
    coord[color_idx * 4 + 3].X = -1.0f + i / 3.0f;
    coord[color_idx * 4 + 3].Y = 0.5f;
    color_idx++;
  }

  /* bottom row, middle three (the blacks) */
  for (i = 0; i < 3; i++) {
    coord[color_idx * 4 + 0].X = i / 6.0f;
    coord[color_idx * 4 + 0].Y = 1.0f;
    coord[color_idx * 4 + 1].X = (i + 1) / 6.0f;
    coord[color_idx * 4 + 1].Y = 1.0f;
    coord[color_idx * 4 + 2].X = (i + 1) / 6.0f;
    coord[color_idx * 4 + 2].Y = 0.5f;
    coord[color_idx * 4 + 3].X = i / 6.0f;
    coord[color_idx * 4 + 3].Y = 0.5f;
    color_idx++;
  }

  g_assert (color_idx < N_QUADS);

  for (i = 0; i < N_QUADS - 1; i++) {
    int j, k;
    if (i < 7) {
      k = i;
    } else if ((i - 7) & 1) {
      k = COLOR_BLACK;
    } else {
      k = 13 - i;
    }

    if (i == 14) {
      k = COLOR_NEG_I;
    } else if (i == 15) {
      k = COLOR_WHITE;
    } else if (i == 16) {
      k = COLOR_POS_Q;
    } else if (i == 17) {
      k = COLOR_SUPER_BLACK;
    } else if (i == 18) {
      k = COLOR_BLACK;
    } else if (i == 19) {
      k = COLOR_DARK_GREY;
    }

    for (j = 0; j < 4; j++) {
      coord[i * 4 + j].Z = 0.0f;
      coord[i * 4 + j].W = 1.0f;
      coord[i * 4 + j].R = vts_colors[k].R;
      coord[i * 4 + j].G = vts_colors[k].G;
      coord[i * 4 + j].B = vts_colors[k].B;
    }

    for (j = 0; j < 6; j++)
      plane_indices[i * 6 + j] = i * 4 + indices_quad[j];
  }

  /* snow */
  coord[color_idx * 4 + 0].X = 0.5f;
  coord[color_idx * 4 + 0].Y = 1.0f;
  coord[color_idx * 4 + 0].Z = 0.0f;
  coord[color_idx * 4 + 0].W = 1.0f;
  coord[color_idx * 4 + 1].X = 1.0f;
  coord[color_idx * 4 + 1].Y = 1.0f;
  coord[color_idx * 4 + 1].Z = 0.0f;
  coord[color_idx * 4 + 1].W = 1.0f;
  coord[color_idx * 4 + 2].X = 1.0f;
  coord[color_idx * 4 + 2].Y = 0.5f;
  coord[color_idx * 4 + 2].Z = 0.0f;
  coord[color_idx * 4 + 2].W = 1.0f;
  coord[color_idx * 4 + 3].X = 0.5f;
  coord[color_idx * 4 + 3].Y = 0.5f;
  coord[color_idx * 4 + 3].Z = 0.0f;
  coord[color_idx * 4 + 3].W = 1.0f;
  for (i = 0; i < 6; i++)
    plane_indices[color_idx * 6 + i] = color_idx * 4 + indices_quad[i];
  color_idx++;

  if (src->color_shader)
    gst_object_unref (src->color_shader);
  src->color_shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          smpte_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          smpte_fragment_src), NULL);
  if (!src->color_shader) {
    GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
    return FALSE;
  }

  if (src->snow_shader)
    gst_object_unref (src->snow_shader);
  src->snow_shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          snow_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          snow_fragment_src), NULL);
  if (!src->snow_shader) {
    GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
    return FALSE;
  }

  src->attr_snow_position = -1;

  src->base.n_attributes = 2;

  src->base.attributes[0].name = "position";
  src->base.attributes[0].location = -1;
  src->base.attributes[0].n_elements = 4;
  src->base.attributes[0].element_type = GL_FLOAT;
  src->base.attributes[0].offset = 0;
  src->base.attributes[0].stride = sizeof (struct XYZWRGB);

  src->base.attributes[1].name = "a_color";
  src->base.attributes[1].location = -1;
  src->base.attributes[1].n_elements = 3;
  src->base.attributes[1].element_type = GL_FLOAT;
  src->base.attributes[1].offset = 4 * sizeof (gfloat);
  src->base.attributes[1].stride = sizeof (struct XYZWRGB);

  if (src->base.shader)
    gst_object_unref (src->base.shader);
  src->base.shader = gst_object_ref (src->color_shader);
  src->base.vertices = (gfloat *) coord;
  src->base.vertices_size = sizeof (struct XYZWRGB) * N_QUADS * 4;
  src->base.indices = plane_indices;
  src->base.n_indices = N_QUADS * 6;

  return _src_shader_init (impl, context, v_info);
}

static gboolean
_src_smpte_fill_bound_fbo (gpointer impl)
{
  struct SrcSMPTE *src = impl;
  gint attr_color_position = -1;

  src->base.n_attributes = 2;
  if (src->base.shader)
    gst_object_unref (src->base.shader);
  src->base.shader = gst_object_ref (src->color_shader);
  src->base.n_indices = (N_QUADS - 1) * 6;
  src->base.index_offset = 0;
  if (!_src_shader_fill_bound_fbo (impl))
    return FALSE;
  attr_color_position = src->base.attributes[0].location;

  src->base.attributes[0].location = src->attr_snow_position;
  src->base.n_attributes = 1;
  if (src->base.shader)
    gst_object_unref (src->base.shader);
  src->base.shader = gst_object_ref (src->snow_shader);
  src->base.n_indices = 6;
  src->base.index_offset = (N_QUADS - 1) * 6 * sizeof (gushort);
  gst_gl_shader_use (src->snow_shader);
  gst_gl_shader_set_uniform_1f (src->snow_shader, "time",
      (gfloat) src->base.base.src->running_time / GST_SECOND);
  if (!_src_shader_fill_bound_fbo (impl))
    return FALSE;
  src->attr_snow_position = src->base.attributes[0].location;
  src->base.attributes[0].location = attr_color_position;

  return TRUE;
}

static void
_src_smpte_free (gpointer impl)
{
  struct SrcSMPTE *src = impl;

  if (!impl)
    return;

  _src_shader_deinit (impl);

  g_free ((gpointer) src->base.vertices);
  g_free ((gpointer) src->base.indices);

  if (src->snow_shader)
    gst_object_unref (src->snow_shader);
  if (src->color_shader)
    gst_object_unref (src->color_shader);

  g_free (impl);
}

static const struct SrcFuncs src_smpte = {
  GST_GL_TEST_SRC_SMPTE,
  _src_smpte_new,
  _src_smpte_init,
  _src_smpte_fill_bound_fbo,
  _src_smpte_free,
};

#undef N_QUADS

struct SrcUniColor
{
  struct BaseSrcImpl base;

  struct vts_color_struct color;
};

static gpointer
_src_uni_color_new (GstGLTestSrc * test)
{
  struct SrcUniColor *src = g_new0 (struct SrcUniColor, 1);

  src->base.src = test;

  return src;
}

static gboolean
_src_uni_color_init (gpointer impl, GstGLContext * context,
    GstVideoInfo * v_info)
{
  struct SrcUniColor *src = impl;

  src->base.context = context;
  src->base.v_info = *v_info;

  return TRUE;
}

static gboolean
_src_uni_color_fill_bound_fbo (gpointer impl)
{
  struct SrcUniColor *src = impl;
  const GstGLFuncs *gl = src->base.context->gl_vtable;

  gl->ClearColor (src->color.R, src->color.G, src->color.B, 1.0f);
  gl->Clear (GL_COLOR_BUFFER_BIT);

  return TRUE;
}

static void
_src_uni_color_free (gpointer impl)
{
  g_free (impl);
}

#define SRC_UNICOLOR(name, cap_name) \
static gpointer \
G_PASTE(G_PASTE(_src_unicolor_,name),_new) (GstGLTestSrc * test) \
{ \
  struct SrcUniColor *src = _src_uni_color_new (test); \
  src->color = vts_colors[G_PASTE(COLOR_,cap_name)]; \
  return src; \
} \
static const struct SrcFuncs G_PASTE (src_,name) = { \
  G_PASTE(GST_GL_TEST_SRC_,cap_name), \
  G_PASTE(G_PASTE(_src_unicolor_,name),_new), \
  _src_uni_color_init, \
  _src_uni_color_fill_bound_fbo, \
  _src_uni_color_free, \
}

SRC_UNICOLOR (white, WHITE);
SRC_UNICOLOR (black, BLACK);
SRC_UNICOLOR (red, RED);
SRC_UNICOLOR (green, GREEN);
SRC_UNICOLOR (blue, BLUE);

static gpointer
_src_blink_new (GstGLTestSrc * test)
{
  struct SrcUniColor *src = _src_uni_color_new (test);

  src->color = vts_colors[COLOR_WHITE];

  return src;
}

static gboolean
_src_blink_fill_bound_fbo (gpointer impl)
{
  struct SrcUniColor *src = impl;

  if (src->color.R > 0.5) {
    src->color = vts_colors[COLOR_BLACK];
  } else {
    src->color = vts_colors[COLOR_WHITE];
  }

  return _src_uni_color_fill_bound_fbo (impl);
}

static const struct SrcFuncs src_blink = {
  GST_GL_TEST_SRC_BLINK,
  _src_blink_new,
  _src_uni_color_init,
  _src_blink_fill_bound_fbo,
  _src_uni_color_free,
};

/* *INDENT-OFF* */
static const gchar *checkers_vertex_src = "attribute vec4 position;\n"
    "varying vec2 uv;\n"
    "void main()\n"
    "{\n"
    "  gl_Position = position;\n"
    /* RPi gives incorrect results for positive uv (plus it makes us start on
     * the right pixel color i.e. red) */
    "  uv = position.xy - 1.0;\n"
    "}";

static const gchar *checkers_fragment_src =
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "uniform float checker_width;\n"
    "uniform float width;\n"
    "uniform float height;\n"
    "varying vec2 uv;\n"
    "void main()\n"
    "{\n"
    "  vec2 xy_mod = floor (0.5 * uv * vec2(width, height) / (checker_width));\n"
    "  float result = mod (xy_mod.x + xy_mod.y, 2.0);\n"
    "  gl_FragColor.r = step (result, 0.5);\n"
    "  gl_FragColor.g = 1.0 - gl_FragColor.r;\n"
    "  gl_FragColor.ba = vec2(0.0, 1.0);\n"
    "}";
/* *INDENT-ON* */

struct SrcCheckers
{
  struct SrcShader base;

  guint checker_width;
};

static gboolean
_src_checkers_init (gpointer impl, GstGLContext * context,
    GstVideoInfo * v_info)
{
  struct SrcCheckers *src = impl;
  GError *error = NULL;

  src->base.base.context = context;

  if (src->base.shader)
    gst_object_unref (src->base.shader);
  src->base.shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          checkers_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          checkers_fragment_src), NULL);
  if (!src->base.shader) {
    GST_ERROR_OBJECT (src->base.base.src, "%s", error->message);
    return FALSE;
  }

  src->base.n_attributes = 1;

  src->base.attributes[0].name = "position";
  src->base.attributes[0].location = -1;
  src->base.attributes[0].n_elements = 4;
  src->base.attributes[0].element_type = GL_FLOAT;
  src->base.attributes[0].offset = 0;
  src->base.attributes[0].stride = 4 * sizeof (gfloat);

  src->base.vertices = positions;
  src->base.vertices_size = sizeof (positions);
  src->base.indices = indices_quad;
  src->base.n_indices = 6;

  gst_gl_shader_use (src->base.shader);
  gst_gl_shader_set_uniform_1f (src->base.shader, "checker_width",
      src->checker_width);
  gst_gl_shader_set_uniform_1f (src->base.shader, "width",
      (gfloat) GST_VIDEO_INFO_WIDTH (v_info));
  gst_gl_shader_set_uniform_1f (src->base.shader, "height",
      (gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
  gst_gl_context_clear_shader (src->base.base.context);

  return _src_shader_init (impl, context, v_info);
}

static void
_src_checkers_free (gpointer impl)
{
  struct SrcCheckers *src = impl;

  if (!src)
    return;

  _src_shader_deinit (impl);

  g_free (impl);
}

static gpointer
_src_checkers_new (GstGLTestSrc * test)
{
  struct SrcCheckers *src = g_new0 (struct SrcCheckers, 1);

  src->base.base.src = test;

  return src;
}

#define SRC_CHECKERS(spacing) \
static gpointer \
G_PASTE(G_PASTE(_src_checkers,spacing),_new) (GstGLTestSrc * test) \
{ \
  struct SrcCheckers *src = _src_checkers_new (test); \
  src->checker_width = spacing; \
  return src; \
} \
static const struct SrcFuncs G_PASTE(src_checkers,spacing) = { \
  G_PASTE(GST_GL_TEST_SRC_CHECKERS,spacing), \
  G_PASTE(G_PASTE(_src_checkers,spacing),_new), \
  _src_checkers_init, \
  _src_shader_fill_bound_fbo, \
  _src_checkers_free, \
}

SRC_CHECKERS (1);
SRC_CHECKERS (2);
SRC_CHECKERS (4);
SRC_CHECKERS (8);

static gboolean
_src_snow_init (gpointer impl, GstGLContext * context, GstVideoInfo * v_info)
{
  struct SrcShader *src = impl;
  GError *error = NULL;

  src->base.context = context;

  if (src->shader)
    gst_object_unref (src->shader);
  src->shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          snow_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          snow_fragment_src), NULL);
  if (!src->shader) {
    GST_ERROR_OBJECT (src->base.src, "%s", error->message);
    return FALSE;
  }

  src->n_attributes = 1;

  src->attributes[0].name = "position";
  src->attributes[0].location = -1;
  src->attributes[0].n_elements = 4;
  src->attributes[0].element_type = GL_FLOAT;
  src->attributes[0].offset = 0;
  src->attributes[0].stride = 4 * sizeof (gfloat);

  src->vertices = positions;
  src->vertices_size = sizeof (positions);
  src->indices = indices_quad;
  src->n_indices = 6;

  return _src_shader_init (impl, context, v_info);
}

static gboolean
_src_snow_fill_bound_fbo (gpointer impl)
{
  struct SrcShader *src = impl;

  g_return_val_if_fail (src->base.context, FALSE);
  g_return_val_if_fail (src->shader, FALSE);

  gst_gl_shader_use (src->shader);
  gst_gl_shader_set_uniform_1f (src->shader, "time",
      (gfloat) src->base.src->running_time / GST_SECOND);

  return _src_shader_fill_bound_fbo (impl);
}

static void
_src_snow_free (gpointer impl)
{
  struct SrcShader *src = impl;

  if (!src)
    return;

  _src_shader_deinit (impl);

  g_free (impl);
}

static gpointer
_src_snow_new (GstGLTestSrc * test)
{
  struct SrcShader *src = g_new0 (struct SrcShader, 1);

  src->base.src = test;

  return src;
}

static const struct SrcFuncs src_snow = {
  GST_GL_TEST_SRC_SNOW,
  _src_snow_new,
  _src_snow_init,
  _src_snow_fill_bound_fbo,
  _src_snow_free,
};

/* *INDENT-OFF* */
static const gchar *mandelbrot_vertex_src = "attribute vec4 position;\n"
    "uniform float aspect_ratio;\n"
    "varying vec2 fractal_position;\n"
    "void main()\n"
    "{\n"
    "  gl_Position = position;\n"
    "  fractal_position = vec2(position.y * 0.5 - 0.3, aspect_ratio * position.x * 0.5);\n"
    "  fractal_position *= 2.5;\n"
    "}";

static const gchar *mandelbrot_fragment_src = 
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "uniform float time;\n"
    "varying vec2 fractal_position;\n"
    "const vec4 K = vec4(1.0, 0.66, 0.33, 3.0);\n"
    "vec4 hsv_to_rgb(float hue, float saturation, float value) {\n"
    "  vec4 p = abs(fract(vec4(hue) + K) * 6.0 - K.wwww);\n"
    "  return value * mix(K.xxxx, clamp(p - K.xxxx, 0.0, 1.0), saturation);\n"
    "}\n"
    "vec4 i_to_rgb(int i) {\n"
    "  float hue = float(i) / 100.0 + sin(time);\n"
    "  return hsv_to_rgb(hue, 0.5, 0.8);\n"
    "}\n"
    "vec2 pow_2_complex(vec2 c) {\n"
    "  return vec2(c.x*c.x - c.y*c.y, 2.0 * c.x * c.y);\n"
    "}\n"
    "vec2 mandelbrot(vec2 c, vec2 c0) {\n"
    "  return pow_2_complex(c) + c0;\n"
    "}\n"
    "vec4 iterate_pixel(vec2 position) {\n"
    "  vec2 c = vec2(0);\n"
    "  for (int i=0; i < 20; i++) {\n"
    "    if (c.x*c.x + c.y*c.y > 2.0*2.0)\n"
    "      return i_to_rgb(i);\n"
    "    c = mandelbrot(c, position);\n"
    "  }\n"
    "  return vec4(0, 0, 0, 1);\n"
    "}\n"
    "void main() {\n"
    "  gl_FragColor = iterate_pixel(fractal_position);\n"
    "}";
/* *INDENT-ON* */

static gboolean
_src_mandelbrot_init (gpointer impl, GstGLContext * context,
    GstVideoInfo * v_info)
{
  struct SrcShader *src = impl;
  GError *error = NULL;

  src->base.context = context;

  if (src->shader)
    gst_object_unref (src->shader);
  src->shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          mandelbrot_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          mandelbrot_fragment_src), NULL);
  if (!src->shader) {
    GST_ERROR_OBJECT (src->base.src, "%s", error->message);
    return FALSE;
  }

  src->n_attributes = 1;

  src->attributes[0].name = "position";
  src->attributes[0].location = -1;
  src->attributes[0].n_elements = 4;
  src->attributes[0].element_type = GL_FLOAT;
  src->attributes[0].offset = 0;
  src->attributes[0].stride = 4 * sizeof (gfloat);

  src->vertices = positions;
  src->vertices_size = sizeof (positions);
  src->indices = indices_quad;
  src->n_indices = 6;

  gst_gl_shader_use (src->shader);
  gst_gl_shader_set_uniform_1f (src->shader, "aspect_ratio",
      (gfloat) GST_VIDEO_INFO_WIDTH (v_info) /
      (gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
  gst_gl_context_clear_shader (src->base.context);

  return _src_shader_init (impl, context, v_info);
}

static gboolean
_src_mandelbrot_fill_bound_fbo (gpointer impl)
{
  struct SrcShader *src = impl;

  g_return_val_if_fail (src->base.context, FALSE);
  g_return_val_if_fail (src->shader, FALSE);

  gst_gl_shader_use (src->shader);
  gst_gl_shader_set_uniform_1f (src->shader, "time",
      (gfloat) src->base.src->running_time / GST_SECOND);

  return _src_shader_fill_bound_fbo (impl);
}

static void
_src_mandelbrot_free (gpointer impl)
{
  struct SrcShader *src = impl;

  if (!src)
    return;

  _src_shader_deinit (impl);

  g_free (impl);
}

static gpointer
_src_mandelbrot_new (GstGLTestSrc * test)
{
  struct SrcShader *src = g_new0 (struct SrcShader, 1);

  src->base.src = test;

  return src;
}

static const struct SrcFuncs src_mandelbrot = {
  GST_GL_TEST_SRC_MANDELBROT,
  _src_mandelbrot_new,
  _src_mandelbrot_init,
  _src_mandelbrot_fill_bound_fbo,
  _src_mandelbrot_free,
};

/* *INDENT-OFF* */
static const gchar *circular_vertex_src =
    "attribute vec4 position;\n"
    "varying vec2 uv;\n"
    "void main()\n"
    "{\n"
    "  gl_Position = position;\n"
    "  uv = position.xy;\n"
    "}";

static const gchar *circular_fragment_src =
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "uniform float aspect_ratio;\n"
    "varying vec2 uv;\n"
    "#define PI 3.14159265\n"
    "void main() {\n"
    "  float dist = 0.5 * sqrt(uv.x * uv.x + uv.y / aspect_ratio * uv.y / aspect_ratio);\n"
    "  float seg = floor(dist * 16.0);\n"
    "  if (seg <= 0.0 || seg >= 8.0) {\n"
    "    gl_FragColor = vec4(vec3(0.0), 1.0);\n"
    "  } else {\n"
    "    float d = floor (256.0 * dist * 200.0 * pow (2.0, - (seg - 1.0) / 4.0) + 0.5) / 128.0;\n"
    "    gl_FragColor = vec4 (vec3(sin (d * PI) * 0.5 + 0.5), 1.0);\n"
    "  }\n"
    "}";
/* *INDENT-ON* */

static gboolean
_src_circular_init (gpointer impl, GstGLContext * context,
    GstVideoInfo * v_info)
{
  struct SrcShader *src = impl;
  GError *error = NULL;

  src->base.context = context;

  if (src->shader)
    gst_object_unref (src->shader);
  src->shader = gst_gl_shader_new_link_with_stages (context, &error,
      gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          circular_vertex_src),
      gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
          GST_GLSL_VERSION_NONE,
          GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
          circular_fragment_src), NULL);
  if (!src->shader) {
    GST_ERROR_OBJECT (src->base.src, "%s", error->message);
    return FALSE;
  }

  src->n_attributes = 1;

  src->attributes[0].name = "position";
  src->attributes[0].location = -1;
  src->attributes[0].n_elements = 4;
  src->attributes[0].element_type = GL_FLOAT;
  src->attributes[0].offset = 0;
  src->attributes[0].stride = 4 * sizeof (gfloat);

  src->vertices = positions;
  src->vertices_size = sizeof (positions);
  src->indices = indices_quad;
  src->n_indices = 6;

  gst_gl_shader_use (src->shader);
  gst_gl_shader_set_uniform_1f (src->shader, "aspect_ratio",
      (gfloat) GST_VIDEO_INFO_WIDTH (v_info) /
      (gfloat) GST_VIDEO_INFO_HEIGHT (v_info));
  gst_gl_context_clear_shader (src->base.context);

  return _src_shader_init (impl, context, v_info);
}

static void
_src_circular_free (gpointer impl)
{
  struct SrcShader *src = impl;

  if (!src)
    return;

  _src_shader_deinit (impl);

  g_free (impl);
}

static gpointer
_src_circular_new (GstGLTestSrc * test)
{
  struct SrcShader *src = g_new0 (struct SrcShader, 1);

  src->base.src = test;

  return src;
}

static const struct SrcFuncs src_circular = {
  GST_GL_TEST_SRC_CIRCULAR,
  _src_circular_new,
  _src_circular_init,
  _src_mandelbrot_fill_bound_fbo,
  _src_circular_free,
};

static const struct SrcFuncs *src_impls[] = {
  &src_smpte,
  &src_snow,
  &src_black,
  &src_white,
  &src_red,
  &src_green,
  &src_blue,
  &src_checkers1,
  &src_checkers2,
  &src_checkers4,
  &src_checkers8,
  &src_circular,
  &src_blink,
  &src_mandelbrot,
};

const struct SrcFuncs *
gst_gl_test_src_get_src_funcs_for_pattern (GstGLTestSrcPattern pattern)
{
  gint i;

  for (i = 0; i < G_N_ELEMENTS (src_impls); i++) {
    if (src_impls[i]->pattern == pattern)
      return src_impls[i];
  }

  return NULL;
}
