diff --git a/cogl/cogl/cogl-primitives.h b/cogl/cogl/cogl-primitives.h
index a24dc5990..60e0f4c68 100644
--- a/cogl/cogl/cogl-primitives.h
+++ b/cogl/cogl/cogl-primitives.h
@@ -40,8 +40,7 @@ G_BEGIN_DECLS
  * @short_description: Functions that draw various primitive 3D shapes
  *
  * The primitives API provides utilities for drawing some
- * common 3D shapes in a more convenient way than the CoglVertexBuffer
- * API provides.
+ * common 3D shapes.
  */
 
 /**
diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h
index c9c5ffcbf..29601cc58 100644
--- a/cogl/cogl/cogl.h
+++ b/cogl/cogl/cogl.h
@@ -88,7 +88,6 @@
 #include <cogl/deprecated/cogl-auto-texture.h>
 #include <cogl/deprecated/cogl-shader.h>
 #include <cogl/deprecated/cogl-material-compat.h>
-#include <cogl/deprecated/cogl-vertex-buffer.h>
 
 #ifdef COGL_ENABLE_MUTTER_API
 #include <cogl/cogl-mutter.h>
diff --git a/cogl/cogl/deprecated/cogl-auto-texture.h b/cogl/cogl/deprecated/cogl-auto-texture.h
index b184ee364..df2b1da29 100644
--- a/cogl/cogl/deprecated/cogl-auto-texture.h
+++ b/cogl/cogl/deprecated/cogl-auto-texture.h
@@ -160,8 +160,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
  * data is actually allocated.
  *
  * Sub textures have undefined behaviour texture coordinates outside
- * of the range [0,1] are used. They also do not work with
- * CoglVertexBuffers.
+ * of the range [0,1] are used.
  *
  * The sub texture will keep a reference to the full texture so you do
  * not need to keep one separately if you only want to use the sub
diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer-private.h b/cogl/cogl/deprecated/cogl-vertex-buffer-private.h
deleted file mode 100644
index 69af36ebf..000000000
--- a/cogl/cogl/deprecated/cogl-vertex-buffer-private.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Cogl
- *
- * A Low Level GPU Graphics and Utilities API
- *
- * Copyright (C) 2008,2009 Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- *
- *
- * Authors:
- *   Robert Bragg <robert@linux.intel.com>
- */
-
-#ifndef __COGL_VERTEX_BUFFER_H
-#define __COGL_VERTEX_BUFFER_H
-
-#include "cogl-object-private.h"
-
-#include "cogl-primitive.h"
-
-#include <glib.h>
-
-/* Note we put quite a bit into the flags here to help keep
- * the down size of the CoglVertexBufferAttrib struct below. */
-typedef enum _CoglVertexBufferAttribFlags
-{
-  /* Types */
-  /* NB: update the _TYPE_MASK below if these are changed */
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY	  = 1<<0,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY	  = 1<<1,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY  = 1<<2,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY	  = 1<<3,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY	  = 1<<4,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID	  = 1<<5,
-
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED	  = 1<<6,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED	  = 1<<7,
-
-  /* Usage hints */
-  /* FIXME - flatten into one flag, since its used as a boolean */
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT  = 1<<8,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT	  = 1<<9,
-
-  /* GL Data types */
-  /* NB: Update the _GL_TYPE_MASK below if these are changed */
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE	    = 1<<10,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE  = 1<<11,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT	    = 1<<12,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT	    = 1<<14,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT   = 1<<15,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT	    = 1<<16,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE	    = 1<<17,
-
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED		    = 1<<18,
-  COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED		    = 1<<19
-
-  /* XXX NB: If we need > 24 bits then look at changing the layout
-   * of struct _CoglVertexBufferAttrib below */
-} CoglVertexBufferAttribFlags;
-
-#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK \
-  (COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY \
-   | COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY \
-   | COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY \
-   | COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY \
-   | COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY \
-   | COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
-
-typedef struct _CoglVertexBufferAttrib
-{
-  /* TODO: look at breaking up the flags into seperate
-   * bitfields and seperate enums */
-  CoglVertexBufferAttribFlags   flags:24;
-  uint8_t	           id;
-  GQuark		   name;
-  char                    *name_without_detail;
-  union _u
-  {
-    const void		  *pointer;
-    size_t		   vbo_offset;
-  } u;
-  CoglAttributeType        type;
-  size_t		   span_bytes;
-  uint16_t                 stride;
-  uint8_t                  n_components;
-  uint8_t                  texture_unit;
-
-  int                      attribute_first;
-  CoglAttribute           *attribute;
-
-} CoglVertexBufferAttrib;
-
-typedef enum _CoglVertexBufferVBOFlags
-{
-  COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED	= 1<<0,
-  COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK	= 1<<1,
-
-  /* FIXME - flatten into one flag, since its used as a boolean */
-  COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT  = 1<<3,
-  COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT    = 1<<4,
-
-  COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED	= 1<<5
-} CoglVertexBufferVBOFlags;
-
-/*
- * A CoglVertexBufferVBO represents one or more attributes in a single
- * buffer object
- */
-typedef struct _CoglVertexBufferVBO
-{
-  CoglVertexBufferVBOFlags flags;
-
-  CoglAttributeBuffer *attribute_buffer;
-  size_t buffer_bytes;
-
-  GList *attributes;
-} CoglVertexBufferVBO;
-
-typedef struct _CoglVertexBufferIndices
-{
-  CoglHandleObject _parent;
-
-  CoglIndices *indices;
-} CoglVertexBufferIndices;
-
-typedef struct _CoglVertexBuffer
-{
-  CoglHandleObject _parent;
-
-  int     n_vertices; /*!< The number of vertices in the buffer */
-  GList  *submitted_vbos; /* The VBOs currently submitted to the GPU */
-
-  /* Note: new_attributes is normally NULL and only valid while
-   * modifying a buffer. */
-  GList  *new_attributes; /*!< attributes pending submission */
-
-  gboolean dirty_attributes;
-
-  CoglPrimitive *primitive;
-
-} CoglVertexBuffer;
-
-#endif /* __COGL_VERTEX_BUFFER_H */
-
diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer.c b/cogl/cogl/deprecated/cogl-vertex-buffer.c
deleted file mode 100644
index e1ce7dd3d..000000000
--- a/cogl/cogl/deprecated/cogl-vertex-buffer.c
+++ /dev/null
@@ -1,1792 +0,0 @@
-/*
- * Cogl
- *
- * A Low Level GPU Graphics and Utilities API
- *
- * Copyright (C) 2008,2009,2010 Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- *
- *
- * Authors:
- *   Robert Bragg <robert@linux.intel.com>
- */
-
-/* XXX: For an overview of the functionality implemented here, please
- * see cogl-vertex-buffer.h, which contains the gtk-doc section overview
- * for the Vertex Buffers API.
- */
-
-/*
- * TODO: We need to do a better job of minimizing when we call glVertexPointer
- * and pals in enable_state_for_drawing_buffer
- *
- * We should have an internal 2-tuple cache of (VBO, offset) for each of them
- * so we can avoid some GL calls. We could have cogl wrappers for the
- * gl*Pointer funcs that look like this:
- *
- * cogl_vertex_pointer (n_components, gl_type, stride, vbo, offset);
- * cogl_color_pointer (n_components, gl_type, stride, vbo, offset);
- *
- * They would also accept NULL for the VBO handle to support old style vertex
- * arrays.
- *
- * TODO:
- * Actually hook this up to the cogl shaders infrastructure. The vertex
- * buffer API has been designed to allow adding of arbitrary attributes for use
- * with shaders, but this has yet to be actually plumbed together and tested.
- * The bits we are missing:
- * - cogl_program_use doesn't currently record within ctx-> which program
- *   is currently in use so a.t.m only Clutter knows the current shader.
- * - We don't query the current shader program for the generic vertex indices
- *   (using glGetAttribLocation) so that we can call glEnableVertexAttribArray
- *   with those indices.
- *   (currently we just make up consecutive indices)
- * - some dirty flag mechanims to know when the shader program has changed
- *   so we don't need to re-query it each time we draw a buffer.
- *
- * TODO
- * Expose API that lets developers get back a buffer handle for a particular
- * polygon so they may add custom attributes to them.
- * - It should be possible to query/modify attributes efficiently, in place,
- *   avoiding copies. It would not be acceptable to simply require that
- *   developers must query back the n_vertices of a buffer and then the
- *   n_components, type and stride etc of each attribute since there
- *   would be too many combinations to realistically handle.
- *
- * - In practice, some cases might be best solved with a higher level
- *   EditableMesh API, (see futher below) but for many cases I think an
- *   API like this might be appropriate:
- *
- * cogl_vertex_buffer_foreach_vertex (buffer_handle,
- *                                    (AttributesBufferIteratorFunc)callback,
- *			              "gl_Vertex", "gl_Color", NULL);
- * static void callback (CoglVertexBufferVertex *vert)
- * {
- *    GLfloat *pos = vert->attrib[0];
- *    GLubyte *color = vert->attrib[1];
- *    GLfloat *new_attrib = buf[vert->index];
- *
- *    new_attrib = pos*color;
- * }
- *
- * TODO
- * Think about a higher level Mesh API for building/modifying attribute buffers
- * - E.g. look at Blender for inspiration here. They can build a mesh from
- *   "MVert", "MFace" and "MEdge" primitives.
- */
-
-#include "cogl-config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-
-#include "cogl-util.h"
-#include "cogl-context-private.h"
-#include "cogl-object-private.h"
-#include "cogl-texture-private.h"
-#include "cogl-pipeline.h"
-#include "cogl-pipeline-private.h"
-#include "cogl-primitives.h"
-#include "cogl-framebuffer-private.h"
-#include "cogl-primitive-private.h"
-#include "cogl-journal-private.h"
-#include "cogl1-context.h"
-#include "cogl-vertex-buffer.h"
-#include "deprecated/cogl-vertex-buffer-private.h"
-
-#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
-  (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
-
-static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer);
-static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices);
-static CoglUserDataKey _cogl_vertex_buffer_pipeline_priv_key;
-
-COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer);
-COGL_HANDLE_DEFINE (VertexBufferIndices, vertex_buffer_indices);
-
-CoglHandle
-cogl_vertex_buffer_new (unsigned int n_vertices)
-{
-  CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer));
-
-  buffer->n_vertices = n_vertices;
-
-  buffer->submitted_vbos = NULL;
-  buffer->new_attributes = NULL;
-  buffer->primitive = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES,
-                                          n_vertices, NULL);
-
-  /* return NULL; */
-  return _cogl_vertex_buffer_handle_new (buffer);
-}
-
-unsigned int
-cogl_vertex_buffer_get_n_vertices (CoglHandle handle)
-{
-  CoglVertexBuffer *buffer;
-
-  if (!cogl_is_vertex_buffer (handle))
-    return 0;
-
-  buffer = handle;
-
-  return buffer->n_vertices;
-}
-
-/* There are a number of standard OpenGL attributes that we deal with
- * specially. These attributes are all namespaced with a "gl_" prefix
- * so we should catch any typos instead of silently adding a custom
- * attribute.
- */
-static CoglVertexBufferAttribFlags
-validate_gl_attribute (const char *gl_attribute,
-		       uint8_t n_components,
-		       uint8_t *texture_unit)
-{
-  CoglVertexBufferAttribFlags type;
-  char *detail_seperator = NULL;
-  int name_len;
-
-  detail_seperator = strstr (gl_attribute, "::");
-  if (detail_seperator)
-    name_len = detail_seperator - gl_attribute;
-  else
-    name_len = strlen (gl_attribute);
-
-  if (strncmp (gl_attribute, "Vertex", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components == 1))
-        g_critical ("glVertexPointer doesn't allow 1 component vertex "
-                    "positions so we currently only support \"gl_Vertex\" "
-                    "attributes where n_components == 2, 3 or 4");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY;
-    }
-  else if (strncmp (gl_attribute, "Color", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components != 3 && n_components != 4))
-        g_critical ("glColorPointer expects 3 or 4 component colors so we "
-                    "currently only support \"gl_Color\" attributes where "
-                    "n_components == 3 or 4");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY;
-    }
-  else if (strncmp (gl_attribute,
-		    "MultiTexCoord",
-		    strlen ("MultiTexCoord")) == 0)
-    {
-      unsigned int unit;
-
-      if (sscanf (gl_attribute, "MultiTexCoord%u", &unit) != 1)
-	{
-	  g_warning ("gl_MultiTexCoord attributes should include a\n"
-		     "texture unit number, E.g. gl_MultiTexCoord0\n");
-	  unit = 0;
-	}
-      /* FIXME: validate any '::' delimiter for this case */
-      *texture_unit = unit;
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY;
-    }
-  else if (strncmp (gl_attribute, "Normal", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components != 3))
-        g_critical ("glNormalPointer expects 3 component normals so we "
-                    "currently only support \"gl_Normal\" attributes where "
-                    "n_components == 3");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY;
-    }
-  else
-    {
-      g_warning ("Unknown gl_* attribute name gl_%s\n", gl_attribute);
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID;
-    }
-
-  return type;
-}
-
-/* There are a number of standard OpenGL attributes that we deal with
- * specially. These attributes are all namespaced with a "gl_" prefix
- * so we should catch any typos instead of silently adding a custom
- * attribute.
- */
-static CoglVertexBufferAttribFlags
-validate_cogl_attribute (const char *cogl_attribute,
-		         uint8_t n_components,
-		         uint8_t *texture_unit)
-{
-  CoglVertexBufferAttribFlags type;
-  char *detail_seperator = NULL;
-  int name_len;
-
-  detail_seperator = strstr (cogl_attribute, "::");
-  if (detail_seperator)
-    name_len = detail_seperator - cogl_attribute;
-  else
-    name_len = strlen (cogl_attribute);
-
-  if (strncmp (cogl_attribute, "position_in", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components == 1))
-        g_critical ("glVertexPointer doesn't allow 1 component vertex "
-                    "positions so we currently only support "
-                    "\"cogl_position_in\" attributes where "
-                    "n_components == 2, 3 or 4");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY;
-    }
-  else if (strncmp (cogl_attribute, "color_in", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components != 3 && n_components != 4))
-        g_critical ("glColorPointer expects 3 or 4 component colors so we "
-                    "currently only support \"cogl_color_in\" attributes "
-                    "where n_components == 3 or 4");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY;
-    }
-  else if (strncmp (cogl_attribute,
-		    "cogl_tex_coord",
-		    strlen ("cogl_tex_coord")) == 0)
-    {
-      unsigned int unit;
-
-      if (strcmp (cogl_attribute, "cogl_tex_coord_in") == 0)
-        unit = 0;
-      else if (sscanf (cogl_attribute, "cogl_tex_coord%u_in", &unit) != 1)
-	{
-	  g_warning ("texture coordinate attributes should either be "
-                     "referenced as \"cogl_tex_coord_in\" or with a"
-                     "texture unit number like \"cogl_tex_coord1_in\"");
-	  unit = 0;
-	}
-      /* FIXME: validate any '::' delimiter for this case */
-      *texture_unit = unit;
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY;
-    }
-  else if (strncmp (cogl_attribute, "normal_in", name_len) == 0)
-    {
-      if (G_UNLIKELY (n_components != 3))
-        g_critical ("glNormalPointer expects 3 component normals so we "
-                    "currently only support \"cogl_normal_in\" attributes "
-                    "where n_components == 3");
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY;
-    }
-  else
-    {
-      g_warning ("Unknown cogl_* attribute name cogl_%s\n", cogl_attribute);
-      type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID;
-    }
-
-  return type;
-}
-
-/* This validates that a custom attribute name is a valid GLSL variable name
- *
- * NB: attribute names may have a detail component delimited using '::' E.g.
- * custom_attrib::foo or custom_attrib::bar
- *
- * maybe I should hang a compiled regex somewhere to handle this
- */
-static gboolean
-validate_custom_attribute_name (const char *attribute_name)
-{
-  char *detail_seperator = NULL;
-  int name_len;
-  int i;
-
-  detail_seperator = strstr (attribute_name, "::");
-  if (detail_seperator)
-    name_len = detail_seperator - attribute_name;
-  else
-    name_len = strlen (attribute_name);
-
-  if (name_len == 0
-      || !g_ascii_isalpha (attribute_name[0])
-      || attribute_name[0] != '_')
-    return FALSE;
-
-  for (i = 1; i < name_len; i++)
-    if (!g_ascii_isalnum (attribute_name[i]) || attribute_name[i] != '_')
-      return FALSE;
-
-  return TRUE;
-}
-
-/* Iterates the CoglVertexBufferVBOs of a buffer and creates a flat list
- * of all the submitted attributes
- *
- * Note: The CoglVertexBufferAttrib structs are deep copied, except the
- * internal CoglAttribute pointer is set to NULL.
- */
-static GList *
-copy_submitted_attributes_list (CoglVertexBuffer *buffer)
-{
-  GList *tmp;
-  GList *submitted_attributes = NULL;
-
-  for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = tmp->data;
-      GList *tmp2;
-
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *attribute = tmp2->data;
-	  CoglVertexBufferAttrib *copy =
-            g_slice_alloc (sizeof (CoglVertexBufferAttrib));
-	  *copy = *attribute;
-          copy->name_without_detail =
-            g_strdup (attribute->name_without_detail);
-          copy->attribute = NULL;
-	  submitted_attributes = g_list_prepend (submitted_attributes, copy);
-	}
-    }
-  return submitted_attributes;
-}
-
-static size_t
-sizeof_attribute_type (CoglAttributeType type)
-{
-  switch (type)
-    {
-    case COGL_ATTRIBUTE_TYPE_BYTE:
-      return 1;
-    case COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE:
-      return 1;
-    case COGL_ATTRIBUTE_TYPE_SHORT:
-      return 2;
-    case COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT:
-      return 2;
-    case COGL_ATTRIBUTE_TYPE_FLOAT:
-      return 4;
-    }
-  g_return_val_if_reached (0);
-}
-
-static size_t
-strideof (CoglAttributeType type, int n_components)
-{
-  return sizeof_attribute_type (type) * n_components;
-}
-
-static char *
-canonize_attribute_name (const char *attribute_name)
-{
-  const char *detail_seperator = NULL;
-  int name_len;
-
-  if (strncmp (attribute_name, "gl_", 3) != 0)
-    return g_strdup (attribute_name);
-
-  /* skip past the "gl_" */
-  attribute_name += 3;
-
-  detail_seperator = strstr (attribute_name, "::");
-  if (detail_seperator)
-    name_len = detail_seperator - attribute_name;
-  else
-    {
-      name_len = strlen (attribute_name);
-      detail_seperator = "";
-    }
-
-  if (strncmp (attribute_name, "Vertex", name_len) == 0)
-    return g_strconcat ("cogl_position_in", detail_seperator, NULL);
-  else if (strncmp (attribute_name, "Color", name_len) == 0)
-    return g_strconcat ("cogl_color_in", detail_seperator, NULL);
-  else if (strncmp (attribute_name,
-		    "MultiTexCoord",
-		    strlen ("MultiTexCoord")) == 0)
-    {
-      unsigned int unit;
-
-      if (sscanf (attribute_name, "MultiTexCoord%u", &unit) != 1)
-	{
-	  g_warning ("gl_MultiTexCoord attributes should include a\n"
-		     "texture unit number, E.g. gl_MultiTexCoord0\n");
-	  unit = 0;
-	}
-      return g_strdup_printf ("cogl_tex_coord%u_in%s",
-                              unit, detail_seperator);
-    }
-  else if (strncmp (attribute_name, "Normal", name_len) == 0)
-    return g_strconcat ("cogl_normal_in", detail_seperator, NULL);
-  else
-    {
-      g_warning ("Unknown gl_* attribute name gl_%s\n", attribute_name);
-      return g_strdup (attribute_name);
-    }
-}
-
-void
-cogl_vertex_buffer_add (CoglHandle         handle,
-		        const char        *attribute_name,
-			uint8_t            n_components,
-			CoglAttributeType  type,
-			gboolean           normalized,
-			uint16_t           stride,
-			const void        *pointer)
-{
-  CoglVertexBuffer *buffer;
-  char *cogl_attribute_name;
-  GQuark name_quark;
-  gboolean modifying_an_attrib = FALSE;
-  CoglVertexBufferAttrib *attribute;
-  CoglVertexBufferAttribFlags flags = 0;
-  uint8_t texture_unit = 0;
-  GList *tmp;
-  char *detail;
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-  buffer->dirty_attributes = TRUE;
-
-  cogl_attribute_name = canonize_attribute_name (attribute_name);
-  name_quark = g_quark_from_string (cogl_attribute_name);
-
-  /* The submit function works by diffing between submitted_attributes
-   * and new_attributes to minimize the upload bandwidth + cost of
-   * allocating new VBOs, so if there isn't already a list of new_attributes
-   * we create one: */
-  if (!buffer->new_attributes)
-    buffer->new_attributes = copy_submitted_attributes_list (buffer);
-
-  /* Note: we first look for an existing attribute that we are modifying
-   * so we may skip needing to validate the name */
-  for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *submitted_attribute = tmp->data;
-      if (submitted_attribute->name == name_quark)
-	{
-	  modifying_an_attrib = TRUE;
-
-	  attribute = submitted_attribute;
-
-	  /* since we will skip validate_gl/cogl_attribute in this case, we
-           * need to pluck out the attribute type before overwriting the
-           * flags: */
-	  flags |=
-            attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK;
-	  break;
-	}
-    }
-
-  if (!modifying_an_attrib)
-    {
-      /* Validate the attribute name, is suitable as a variable name */
-      if (strncmp (attribute_name, "gl_", 3) == 0)
-	{
-          /* Note: we pass the original attribute name here so that
-           * any warning messages correspond to the users original
-           * attribute name... */
-	  flags |= validate_gl_attribute (attribute_name + 3,
-					  n_components,
-					  &texture_unit);
-	  if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
-	    return;
-	}
-      else if (strncmp (attribute_name, "cogl_", 5) == 0)
-	{
-	  flags |= validate_cogl_attribute (attribute_name + 5,
-					    n_components,
-					    &texture_unit);
-	  if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
-	    return;
-	}
-      else
-	{
-	  flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY;
-	  if (validate_custom_attribute_name (attribute_name))
-	    return;
-	}
-
-      attribute = g_slice_alloc0 (sizeof (CoglVertexBufferAttrib));
-    }
-
-  attribute->name = name_quark;
-  detail = strstr (cogl_attribute_name, "::");
-  if (detail)
-    attribute->name_without_detail = g_strndup (cogl_attribute_name,
-                                                detail - cogl_attribute_name);
-  else
-    attribute->name_without_detail = g_strdup (cogl_attribute_name);
-  attribute->type = type;
-  attribute->n_components = n_components;
-  if (stride == 0)
-    stride = strideof (type, n_components);
-  attribute->stride = stride;
-  attribute->u.pointer = pointer;
-  attribute->texture_unit = texture_unit;
-  attribute->attribute = NULL;
-
-  flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
-
-  /* Note: We currently just assume, if an attribute is *ever* updated
-   * then it should be taged as frequently changing. */
-  if (modifying_an_attrib)
-    flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT;
-  else
-    flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT;
-
-  if (normalized)
-    flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED;
-  attribute->flags = flags;
-
-  attribute->span_bytes = buffer->n_vertices * attribute->stride;
-
-  if (!modifying_an_attrib)
-    buffer->new_attributes =
-      g_list_prepend (buffer->new_attributes, attribute);
-
-  g_free (cogl_attribute_name);
-}
-
-static void
-_cogl_vertex_buffer_attrib_free (CoglVertexBufferAttrib *attribute)
-{
-  if (attribute->attribute)
-    cogl_object_unref (attribute->attribute);
-  g_free (attribute->name_without_detail);
-  g_slice_free (CoglVertexBufferAttrib, attribute);
-}
-
-void
-cogl_vertex_buffer_delete (CoglHandle handle,
-			   const char *attribute_name)
-{
-  CoglVertexBuffer *buffer;
-  char *cogl_attribute_name = canonize_attribute_name (attribute_name);
-  GQuark name = g_quark_from_string (cogl_attribute_name);
-  GList *tmp;
-
-  g_free (cogl_attribute_name);
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-  buffer->dirty_attributes = TRUE;
-
-  /* The submit function works by diffing between submitted_attributes
-   * and new_attributes to minimize the upload bandwidth + cost of
-   * allocating new VBOs, so if there isn't already a list of new_attributes
-   * we create one: */
-  if (!buffer->new_attributes)
-    buffer->new_attributes = copy_submitted_attributes_list (buffer);
-
-  for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *submitted_attribute = tmp->data;
-      if (submitted_attribute->name == name)
-	{
-	  buffer->new_attributes =
-	    g_list_delete_link (buffer->new_attributes, tmp);
-          _cogl_vertex_buffer_attrib_free (submitted_attribute);
-	  return;
-	}
-    }
-
-  g_warning ("Failed to find an attribute named %s to delete\n",
-	     attribute_name);
-}
-
-static void
-set_attribute_enable (CoglHandle handle,
-		      const char *attribute_name,
-		      gboolean state)
-{
-  CoglVertexBuffer *buffer;
-  char *cogl_attribute_name = canonize_attribute_name (attribute_name);
-  GQuark name_quark = g_quark_from_string (cogl_attribute_name);
-  GList *tmp;
-
-  g_free (cogl_attribute_name);
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-  buffer->dirty_attributes = TRUE;
-
-  /* NB: If a buffer is currently being edited, then there can be two seperate
-   * lists of attributes; those that are currently submitted and a new list yet
-   * to be submitted, we need to modify both. */
-
-  for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      if (attribute->name == name_quark)
-	{
-	  if (state)
-	    attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
-	  else
-	    attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
-	  break;
-	}
-    }
-
-  for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = tmp->data;
-      GList *tmp2;
-
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *attribute = tmp2->data;
-	  if (attribute->name == name_quark)
-	    {
-	      if (state)
-		attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
-	      else
-		attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED;
-	      return;
-	    }
-	}
-    }
-
-  g_warning ("Failed to %s attribute named %s/%s\n",
-	     state == TRUE ? "enable" : "disable",
-	     attribute_name, cogl_attribute_name);
-}
-
-void
-cogl_vertex_buffer_enable (CoglHandle handle,
-			       const char *attribute_name)
-{
-  set_attribute_enable (handle, attribute_name, TRUE);
-}
-
-void
-cogl_vertex_buffer_disable (CoglHandle handle,
-			    const char *attribute_name)
-{
-  set_attribute_enable (handle, attribute_name, FALSE);
-}
-
-/* Given an attribute that we know has already been submitted before, this
- * function looks for the existing VBO that contains it.
- *
- * Note: It will free redundant attribute struct once the corresponding
- * VBO has been found.
- */
-static void
-filter_already_submitted_attribute (CoglVertexBufferAttrib *attribute,
-				    GList **reuse_vbos,
-				    GList **submitted_vbos)
-{
-  GList *tmp;
-
-  /* First check the cogl_vbos we already know are being reused since we
-   * are more likley to get a match here */
-  for (tmp = *reuse_vbos; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = tmp->data;
-      GList *tmp2;
-
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *vbo_attribute = tmp2->data;
-
-	  if (vbo_attribute->name == attribute->name)
-	    {
-	      vbo_attribute->flags &=
-                ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED;
-	      /* Note: we don't free the redundant attribute here, since it
-	       * will be freed after all filtering in
-               * cogl_vertex_buffer_submit */
-	      return;
-	    }
-	}
-    }
-
-  for (tmp = *submitted_vbos; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = tmp->data;
-      CoglVertexBufferAttrib *reuse_attribute = NULL;
-      GList *tmp2;
-
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *vbo_attribute = tmp2->data;
-	  if (vbo_attribute->name == attribute->name)
-	    {
-	      reuse_attribute = vbo_attribute;
-	      /* Note: we don't free the redundant attribute here, since it
-	       * will be freed after all filtering in
-               * cogl_vertex_buffer_submit */
-
-	      *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp);
-	      tmp->next = *reuse_vbos;
-	      *reuse_vbos = tmp;
-	      break;
-	    }
-	}
-
-      if (!reuse_attribute)
-	continue;
-
-      /* Mark all but the matched attribute as UNUSED, so that when we
-       * finish filtering all our attributes any attrributes still
-       * marked as UNUSED can be removed from their cogl_vbo */
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *vbo_attribute = tmp2->data;
-	  if (vbo_attribute != reuse_attribute)
-	    vbo_attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED;
-	}
-
-      return;
-    }
-
-  g_critical ("Failed to find the cogl vbo that corresponds to an\n"
-	      "attribute that had apparently already been submitted!");
-}
-
-/* When we first mark a CoglVertexBufferVBO to be reused, we mark the
- * attributes as unsed, so that when filtering of attributes into VBOs is done
- * we can then prune the now unsed attributes. */
-static void
-remove_unused_attributes (CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-  GList *next;
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      next = tmp->next;
-
-      if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED)
-	{
-	  cogl_vbo->attributes =
-	    g_list_delete_link (cogl_vbo->attributes, tmp);
-	  g_slice_free (CoglVertexBufferAttrib, attribute);
-	}
-    }
-}
-
-/* Give a newly added, strided, attribute, this function looks for a
- * CoglVertexBufferVBO that the attribute is interleved with. If it can't
- * find one then a new CoglVertexBufferVBO is allocated and added to the
- * list of new_strided_vbos.
- */
-static void
-filter_strided_attribute (CoglVertexBufferAttrib *attribute,
-			  GList **new_vbos)
-{
-  GList *tmp;
-  CoglVertexBufferVBO *new_cogl_vbo;
-
-  for (tmp = *new_vbos; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = tmp->data;
-      GList *tmp2;
-
-      if (!(cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED))
-	continue;
-
-      for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *vbo_attribute = tmp2->data;
-	  const char *attribute_start = attribute->u.pointer;
-	  const char *vbo_attribute_start = vbo_attribute->u.pointer;
-
-	  /* NB: All attributes have buffer->n_vertices values which
-	   * simplifies determining which attributes are interleved
-	   * since we assume they will start no farther than +- a
-	   * stride away from each other:
-	   */
-	  if (attribute_start <= (vbo_attribute_start - vbo_attribute->stride)
-	      || attribute_start
-		 >= (vbo_attribute_start + vbo_attribute->stride))
-	    continue; /* Not interleved */
-
-	  cogl_vbo->attributes =
-	    g_list_prepend (cogl_vbo->attributes, attribute);
-
-	  if (attribute->flags &
-              COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT)
-	    {
-	      cogl_vbo->flags &=
-                ~COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT;
-	      cogl_vbo->flags |=
-                COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT;
-	    }
-	      return;
-	}
-    }
-  new_cogl_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO));
-  new_cogl_vbo->attributes = NULL;
-  new_cogl_vbo->attributes =
-    g_list_prepend (new_cogl_vbo->attributes, attribute);
-  /* Any one of the interleved attributes will have the same span_bytes */
-  new_cogl_vbo->attribute_buffer = NULL;
-  new_cogl_vbo->buffer_bytes = attribute->span_bytes;
-  new_cogl_vbo->flags = COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED;
-
-  if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT)
-    new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT;
-  else
-    new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT;
-
-  *new_vbos = g_list_prepend (*new_vbos, new_cogl_vbo);
-  return;
-}
-
-/* This iterates through the list of submitted VBOs looking for one that
- * contains attribute. If found the list *link* is removed and returned */
-static GList *
-unlink_submitted_vbo_containing_attribute (GList **submitted_vbos,
-					   CoglVertexBufferAttrib *attribute)
-{
-  GList *tmp;
-  GList *next = NULL;
-
-  for (tmp = *submitted_vbos; tmp != NULL; tmp = next)
-    {
-      CoglVertexBufferVBO *submitted_vbo = tmp->data;
-      GList *tmp2;
-
-      next = tmp->next;
-
-      for (tmp2 = submitted_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *submitted_attribute = tmp2->data;
-
-	  if (submitted_attribute->name == attribute->name)
-	    {
-	      *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp);
-	      return tmp;
-	    }
-	}
-    }
-
-  return NULL;
-}
-
-/* Unlinks all the submitted VBOs that conflict with the new cogl_vbo and
- * returns them as a list. */
-static GList *
-get_submitted_vbo_conflicts (GList **submitted_vbos,
-                             CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-  GList *conflicts = NULL;
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    {
-      GList *link =
-	unlink_submitted_vbo_containing_attribute (submitted_vbos,
-						   tmp->data);
-      if (link)
-	{
-	  /* prepend the link to the list of conflicts: */
-	  link->next = conflicts;
-	  conflicts = link;
-	}
-    }
-  return conflicts;
-}
-
-/* Any attributes in cogl_vbo gets removed from conflict_vbo */
-static void
-disassociate_conflicting_attributes (CoglVertexBufferVBO *conflict_vbo,
-				     CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-
-  /* NB: The attributes list in conflict_vbo will be shrinking so
-   * we iterate those in the inner loop. */
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      GList *tmp2;
-      for (tmp2 = conflict_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next)
-	{
-	  CoglVertexBufferAttrib *conflict_attribute = tmp2->data;
-
-	  if (conflict_attribute->name == attribute->name)
-	    {
-	      _cogl_vertex_buffer_attrib_free (conflict_attribute);
-	      conflict_vbo->attributes =
-		g_list_delete_link (conflict_vbo->attributes, tmp2);
-	      break;
-	    }
-	}
-    }
-}
-
-static void
-cogl_vertex_buffer_vbo_free (CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    _cogl_vertex_buffer_attrib_free (tmp->data);
-  g_list_free (cogl_vbo->attributes);
-
-  if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED)
-    cogl_object_unref (cogl_vbo->attribute_buffer);
-
-  g_slice_free (CoglVertexBufferVBO, cogl_vbo);
-}
-
-/* This figures out the lowest attribute client pointer. (This pointer is used
- * to upload all the interleved attributes).
- *
- * In the process it also replaces the client pointer with the attributes
- * offset, and marks the attribute as submitted.
- */
-static const void *
-prep_strided_vbo_for_upload (CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-  const char *lowest_pointer = NULL;
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      const char *client_pointer = attribute->u.pointer;
-
-      if (!lowest_pointer || client_pointer < lowest_pointer)
-	lowest_pointer = client_pointer;
-    }
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      const char *client_pointer = attribute->u.pointer;
-      attribute->u.vbo_offset = client_pointer - lowest_pointer;
-      attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED;
-    }
-
-  return lowest_pointer;
-}
-
-static gboolean
-upload_multipack_vbo_via_map_buffer (CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *tmp;
-  unsigned int offset = 0;
-  uint8_t *buf;
-
-  _COGL_GET_CONTEXT (ctx, FALSE);
-
-  buf = cogl_buffer_map (COGL_BUFFER (cogl_vbo->attribute_buffer),
-                         COGL_BUFFER_ACCESS_WRITE,
-                         COGL_BUFFER_MAP_HINT_DISCARD);
-  if (!buf)
-    return FALSE;
-
-  for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-      gsize attribute_size = attribute->span_bytes;
-      gsize type_size = sizeof_attribute_type (attribute->type);
-
-      PAD_FOR_ALIGNMENT (offset, type_size);
-
-      memcpy (buf + offset, attribute->u.pointer, attribute_size);
-
-      attribute->u.vbo_offset = offset;
-      attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED;
-      offset += attribute_size;
-    }
-
-  cogl_buffer_unmap (COGL_BUFFER (cogl_vbo->attribute_buffer));
-
-  return TRUE;
-}
-
-static void
-upload_multipack_vbo_via_buffer_sub_data (CoglVertexBufferVBO *cogl_vbo)
-{
-  GList *l;
-  unsigned int offset = 0;
-
-  for (l = cogl_vbo->attributes; l != NULL; l = l->next)
-    {
-      CoglVertexBufferAttrib *attribute = l->data;
-      gsize attribute_size = attribute->span_bytes;
-      gsize type_size = sizeof_attribute_type (attribute->type);
-
-      PAD_FOR_ALIGNMENT (offset, type_size);
-
-      cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->attribute_buffer),
-                            offset,
-                            attribute->u.pointer,
-                            attribute_size);
-
-      attribute->u.vbo_offset = offset;
-      attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED;
-      offset += attribute_size;
-    }
-}
-
-static void
-upload_attributes (CoglVertexBufferVBO *cogl_vbo)
-{
-  CoglBufferUpdateHint usage;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT)
-    usage = COGL_BUFFER_UPDATE_HINT_DYNAMIC;
-  else
-    usage = COGL_BUFFER_UPDATE_HINT_STATIC;
-  cogl_buffer_set_update_hint (COGL_BUFFER (cogl_vbo->attribute_buffer), usage);
-
-  if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED)
-    {
-      const void *pointer = prep_strided_vbo_for_upload (cogl_vbo);
-      cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->attribute_buffer),
-                            0, /* offset */
-                            pointer,
-                            cogl_vbo->buffer_bytes);
-    }
-  else /* MULTIPACK */
-    {
-      /* I think it might depend on the specific driver/HW whether its better
-       * to use glMapBuffer here or glBufferSubData here. There is even a good
-       * thread about this topic here:
-       * http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg35004.html
-       * For now I have gone with glMapBuffer, but the jury is still out.
-       */
-
-      if (!upload_multipack_vbo_via_map_buffer (cogl_vbo))
-	upload_multipack_vbo_via_buffer_sub_data  (cogl_vbo);
-    }
-
-  cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED;
-}
-
-/* Note: although there ends up being quite a few inner loops involved with
- * resolving buffers, the number of attributes will be low so I don't expect
- * them to cause a problem. */
-static void
-cogl_vertex_buffer_vbo_resolve (CoglVertexBuffer *buffer,
-			        CoglVertexBufferVBO *new_cogl_vbo,
-			        GList **final_vbos)
-{
-  GList *conflicts;
-  GList *tmp;
-  GList *next;
-  gboolean found_target_vbo = FALSE;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  conflicts =
-    get_submitted_vbo_conflicts (&buffer->submitted_vbos, new_cogl_vbo);
-
-  for (tmp = conflicts; tmp != NULL; tmp = next)
-    {
-      CoglVertexBufferVBO *conflict_vbo = tmp->data;
-
-      next = tmp->next;
-
-      disassociate_conflicting_attributes (conflict_vbo, new_cogl_vbo);
-
-      if (!conflict_vbo->attributes)
-	{
-	  /* See if we can re-use this now empty VBO: */
-
-	  if (!found_target_vbo
-	      && conflict_vbo->buffer_bytes == new_cogl_vbo->buffer_bytes)
-	    {
-	      found_target_vbo = TRUE;
-	      new_cogl_vbo->attribute_buffer =
-                cogl_object_ref (conflict_vbo->attribute_buffer);
-	      cogl_vertex_buffer_vbo_free (conflict_vbo);
-
-	      upload_attributes (new_cogl_vbo);
-
-	      *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo);
-	    }
-	  else
-	    cogl_vertex_buffer_vbo_free (conflict_vbo);
-	}
-      else
-	{
-	  /* Relink the VBO back into buffer->submitted_vbos since it may
-	   * be involved in other conflicts later */
-	  tmp->next = buffer->submitted_vbos;
-	  tmp->prev = NULL;
-	  buffer->submitted_vbos = tmp;
-	}
-    }
-
-  if (!found_target_vbo)
-    {
-      _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-      new_cogl_vbo->attribute_buffer =
-        cogl_attribute_buffer_new (ctx, new_cogl_vbo->buffer_bytes, NULL);
-
-      upload_attributes (new_cogl_vbo);
-      *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo);
-    }
-}
-
-static void
-update_primitive_attributes (CoglVertexBuffer *buffer)
-{
-  GList *l;
-  int n_attributes = 0;
-  CoglAttribute **attributes;
-  int i;
-
-  if (!buffer->dirty_attributes)
-    return;
-
-  buffer->dirty_attributes = FALSE;
-
-  for (l = buffer->submitted_vbos; l; l = l->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = l->data;
-      GList *l2;
-
-      for (l2 = cogl_vbo->attributes; l2; l2 = l2->next, n_attributes++)
-        ;
-    }
-
-  g_return_if_fail (n_attributes > 0);
-
-  attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
-
-  i = 0;
-  for (l = buffer->submitted_vbos; l; l = l->next)
-    {
-      CoglVertexBufferVBO *cogl_vbo = l->data;
-      GList *l2;
-
-      for (l2 = cogl_vbo->attributes; l2; l2 = l2->next)
-        {
-	  CoglVertexBufferAttrib *attribute = l2->data;
-	  if (G_LIKELY (attribute->flags &
-                        COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED))
-            {
-              if (G_UNLIKELY (!attribute->attribute))
-                {
-                  attribute->attribute =
-                    cogl_attribute_new (cogl_vbo->attribute_buffer,
-                                        attribute->name_without_detail,
-                                        attribute->stride,
-                                        attribute->u.vbo_offset,
-                                        attribute->n_components,
-                                        attribute->type);
-                }
-
-              attributes[i++] = attribute->attribute;
-            }
-        }
-    }
-
-  cogl_primitive_set_attributes (buffer->primitive, attributes, i);
-}
-
-static void
-cogl_vertex_buffer_submit_real (CoglVertexBuffer *buffer)
-{
-  GList *tmp;
-  CoglVertexBufferVBO *new_multipack_vbo;
-  GList *new_multipack_vbo_link;
-  GList *new_vbos = NULL;
-  GList *reuse_vbos = NULL;
-  GList *final_vbos = NULL;
-
-  if (!buffer->new_attributes)
-    goto done;
-
-  /* The objective now is to copy the attribute data supplied by the client
-   * into buffer objects, but it's important to minimize the number of
-   * redundant data uploads.
-   *
-   * We obviously aim to group together the attributes that are interleved so
-   * that they can be delivered in one go to the driver.
-   * All BOs for interleved data are created as STATIC_DRAW_ARB.
-   *
-   * Non interleved attributes tagged as INFREQUENT_RESUBMIT will be grouped
-   * together back to back in a single BO created as STATIC_DRAW_ARB
-   *
-   * Non interleved attributes tagged as FREQUENT_RESUBMIT will be copied into
-   * individual buffer objects, and the BO itself created DYNAMIC_DRAW_ARB
-   *
-   * If we are modifying a previously submitted CoglVertexBuffer then we are
-   * carefull not to needlesly delete OpenGL buffer objects and replace with
-   * new ones, instead we upload new data to the existing buffers.
-   */
-
-  /* NB: We must forget attribute->pointer after submitting since the user
-   * is free to re-use that memory for other purposes now. */
-
-  /* Pseudo code:
-   *
-   * Broadly speaking we start with a list of unsorted attributes, and filter
-   * those into 'new' and 're-use' CoglVertexBufferVBO (CBO) lists. We then
-   * take the list of new CBO structs and compare with the CBOs that have
-   * already been submitted to the GPU (but ignoring those we already know will
-   * be re-used) to determine what other CBOs can be re-used, due to being
-   * superseded, and what new GL VBOs need to be created.
-   *
-   * We have two kinds of CBOs:
-   * - Multi Pack CBOs
-   *     These contain multiple attributes tightly packed back to back)
-   * - Strided CBOs
-   *	 These typically contain multiple interleved sets of attributes,
-   *	 though they can contain just one attribute with a stride
-   *
-   * First create a new-CBOs entry "new-multipack-CBO"
-   * Tag "new-multipack-CBO" as MULTIPACK + INFREQUENT_RESUBMIT
-   * For each unsorted attrib:
-   *   if already marked as submitted:
-   *	 iterate reuse-CBOs:
-   *	   if we find one that contains this attribute:
-   *	     free redundant unsorted attrib struct
-   *	     remove the UNUSED flag from the attrib found in the reuse-CBO
-   *	     continue to next unsorted attrib
-   *	 iterate submitted VBOs:
-   *	   if we find one that contains this attribute:
-   *	     free redundant unsorted attrib struct
-   *	     unlink the vbo and move it to the list of reuse-CBOs
-   *	     mark all attributes except the one just matched as UNUSED
-   *	 assert (found)
-   *	 continue to next unsorted attrib
-   *   if strided:
-   * 	 iterate the new, strided, CBOs, to see if the attribute is
-   *	 interleved with one of them, if found:
-   *	   add to the matched CBO
-   *	 else if not found:
-   *	   create a new-CBOs entry tagged STRIDED + INFREQUENT_RESUBMIT
-   *   else if unstrided && tagged with FREQUENT_RESUBMIT:
-   *     create a new-CBOs entry tagged MULTIPACK + FREQUENT_RESUBMIT
-   *   else
-   *     add to the new-multipack-CBO
-   * free list of unsorted-attribs
-   *
-   * Next compare the new list of CBOs with the submitted set and try to
-   * minimize the memory bandwidth required to upload the attributes and the
-   * overhead of creating new GL-BOs.
-   *
-   * We deal with four sets of CBOs:
-   * - The "new" CBOs
-   *    (as determined above during filtering)
-   * - The "re-use" CBOs
-   *    (as determined above during filtering)
-   * - The "submitted" CBOs
-   *    (I.e. ones currently submitted to the GPU)
-   * - The "final" CBOs
-   *	(The result of resolving the differences between the above sets)
-   *
-   * The re-use CBOs are dealt with first, and we simply delete any remaining
-   * attributes in these that are still marked as UNUSED, and move them
-   * to the list of final CBOs.
-   *
-   * Next we iterate through the "new" CBOs, searching for conflicts
-   * with the "submitted" CBOs and commit our decision to the "final" CBOs
-   *
-   * When searching for submitted entries we always unlink items from the
-   * submitted list once we make matches (before we make descisions
-   * based on the matches). If the CBO node is superseded it is freed,
-   * if it is modified but may be needed for more descisions later it is
-   * relinked back into the submitted list and if it's identical to a new
-   * CBO it will be linked into the final list.
-   *
-   * At the end the list of submitted CBOs represents the attributes that were
-   * deleted from the buffer.
-   *
-   * Iterate re-use-CBOs:
-   *   Iterate attribs for each:
-   *	 if attrib UNUSED:
-   *	   remove the attrib from the CBO + free
-   *	   |Note: we could potentially mark this as a re-useable gap
-   *	   |if needs be later.
-   *   add re-use CBO to the final-CBOs
-   * Iterate new-CBOs:
-   *   List submitted CBOs conflicting with the this CBO (Unlinked items)
-   *   found-target-BO=FALSE
-   *   Iterate conflicting CBOs:
-   *	 Disassociate conflicting attribs from conflicting CBO struct
-   *	 If no attribs remain:
-   *	   If found-target-BO!=TRUE
-   *	   _AND_ If the total size of the conflicting CBO is compatible:
-   *	   |Note: We don't currently consider re-using oversized buffers
-   *	     found-target-BO=TRUE
-   *	     upload replacement data
-   *	     free submitted CBO struct
-   *	     add new CBO struct to final-CBOs
-   *	   else:
-   *	     delete conflict GL-BO
-   *	     delete conflict CBO struct
-   *	 else:
-   *	   relink CBO back into submitted-CBOs
-   *
-   *   if found-target-BO == FALSE:
-   *	 create a new GL-BO
-   *	 upload data
-   *	 add new CBO struct to final-BOs
-   *
-   * Iterate through the remaining "submitted" CBOs:
-   *   delete the submitted GL-BO
-   *   free the submitted CBO struct
-   */
-
-  new_multipack_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO));
-  new_multipack_vbo->attribute_buffer = NULL;
-  new_multipack_vbo->buffer_bytes = 0;
-  new_multipack_vbo->flags =
-    COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK
-    | COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT;
-  new_multipack_vbo->attributes = NULL;
-  new_vbos = g_list_prepend (new_vbos, new_multipack_vbo);
-  /* We save the link pointer here, just so we can do a fast removal later if
-   * no attributes get added to this vbo. */
-  new_multipack_vbo_link = new_vbos;
-
-  /* Start with a list of unsorted attributes, and filter those into
-   * potential new Cogl BO structs
-   */
-  for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
-    {
-      CoglVertexBufferAttrib *attribute = tmp->data;
-
-      if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED)
-	{
-	  /* If the attribute is already marked as submitted, then we need
-	   * to find the existing VBO that contains it so we dont delete it.
-	   *
-	   * NB: this also frees the attribute struct since it's implicitly
-	   * redundant in this case.
-	   */
-	  filter_already_submitted_attribute (attribute,
-					      &reuse_vbos,
-					      &buffer->submitted_vbos);
-	}
-      else if (attribute->stride)
-	{
-	  /* look for a CoglVertexBufferVBO that the attribute is
-           * interleved with. If one can't be found then a new
-           * CoglVertexBufferVBO is allocated and added to the list of
-           * new_vbos: */
-	  filter_strided_attribute (attribute, &new_vbos);
-	}
-      else if (attribute->flags &
-               COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT)
-	{
-	  CoglVertexBufferVBO *cogl_vbo =
-            g_slice_alloc (sizeof (CoglVertexBufferVBO));
-
-	  /* attributes we expect will be frequently resubmitted are placed
-	   * in their own VBO so that updates don't impact other attributes
-	   */
-
-	  cogl_vbo->flags =
-            COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK
-	    | COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT;
-	  cogl_vbo->attributes = NULL;
-	  cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes,
-						 attribute);
-	  cogl_vbo->attribute_buffer = NULL;
-	  cogl_vbo->buffer_bytes = attribute->span_bytes;
-	  new_vbos = g_list_prepend (new_vbos, cogl_vbo);
-	}
-      else
-	{
-	  gsize type_size = sizeof_attribute_type (attribute->flags);
-
-	  /* Infrequently updated attributes just get packed back to back
-	   * in a single VBO: */
-	  new_multipack_vbo->attributes =
-	    g_list_prepend (new_multipack_vbo->attributes,
-			    attribute);
-
-	  /* Note: we have to ensure that each run of attributes is
-	   * naturally aligned according to its data type, which may
-	   * require some padding bytes: */
-
-	  /* XXX: We also have to be sure that the attributes aren't
-	   * reorderd before being uploaded because the alignment padding
-	   * is based on the adjacent attribute.
-	   */
-
-	  PAD_FOR_ALIGNMENT (new_multipack_vbo->buffer_bytes, type_size);
-
-	  new_multipack_vbo->buffer_bytes += attribute->span_bytes;
-	}
-    }
-
-  /* At this point all buffer->new_attributes have been filtered into
-   * CoglVertexBufferVBOs... */
-  g_list_free (buffer->new_attributes);
-  buffer->new_attributes = NULL;
-
-  /* If the multipack vbo wasn't needed: */
-  if (new_multipack_vbo->attributes == NULL)
-    {
-      new_vbos = g_list_delete_link (new_vbos, new_multipack_vbo_link);
-      g_slice_free (CoglVertexBufferVBO, new_multipack_vbo);
-    }
-
-  for (tmp = reuse_vbos; tmp != NULL; tmp = tmp->next)
-    remove_unused_attributes (tmp->data);
-  final_vbos = g_list_concat (final_vbos, reuse_vbos);
-
-  for (tmp = new_vbos; tmp != NULL; tmp = tmp->next)
-    cogl_vertex_buffer_vbo_resolve (buffer, tmp->data, &final_vbos);
-
-  /* Anything left corresponds to deleted attributes: */
-  for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
-    cogl_vertex_buffer_vbo_free (tmp->data);
-  g_list_free (buffer->submitted_vbos);
-  g_list_free (new_vbos);
-
-  buffer->submitted_vbos = final_vbos;
-
-done:
-  update_primitive_attributes (buffer);
-}
-
-void
-cogl_vertex_buffer_submit (CoglHandle handle)
-{
-  CoglVertexBuffer *buffer;
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-
-  cogl_vertex_buffer_submit_real (buffer);
-}
-
-typedef struct
-{
-  /* We have a ref-count on this private structure because we need to
-     refer to it both from the private data on a pipeline and any weak
-     pipelines that we create from it. If we didn't have the ref count
-     then we would depend on the order of destruction of a
-     CoglPipeline and the weak materials to avoid a crash */
-  unsigned int ref_count;
-
-  CoglPipeline *real_source;
-} VertexBufferMaterialPrivate;
-
-static void
-unref_pipeline_priv (VertexBufferMaterialPrivate *priv)
-{
-  if (--priv->ref_count < 1)
-    g_slice_free (VertexBufferMaterialPrivate, priv);
-}
-
-static void
-weak_override_source_destroyed_cb (CoglPipeline *pipeline,
-                                   void *user_data)
-{
-  VertexBufferMaterialPrivate *pipeline_priv = user_data;
-  /* Unref the weak pipeline copy since it is no longer valid - probably because
-   * one of its ancestors has been changed. */
-  cogl_object_unref (pipeline_priv->real_source);
-  pipeline_priv->real_source = NULL;
-  /* A reference was added when we copied the weak material so we need
-     to unref it here */
-  unref_pipeline_priv (pipeline_priv);
-}
-
-static gboolean
-validate_layer_cb (CoglPipeline *pipeline,
-                   int layer_index,
-                   void *user_data)
-{
-  VertexBufferMaterialPrivate *pipeline_priv = user_data;
-  CoglPipeline *source = pipeline_priv->real_source;
-
-  if (!cogl_pipeline_get_layer_point_sprite_coords_enabled (source,
-                                                            layer_index))
-    {
-      CoglPipelineWrapMode wrap_s;
-      CoglPipelineWrapMode wrap_t;
-      CoglPipelineWrapMode wrap_p;
-      gboolean need_override_source = FALSE;
-
-      /* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes
-       * GL_CLAMP_TO_EDGE but we want GL_REPEAT to maintain
-       * compatibility with older versions of Cogl so we'll override
-       * it. We don't want to do this for point sprites because in
-       * that case the whole texture is drawn so you would usually
-       * want clamp-to-edge.
-       */
-      wrap_s = cogl_pipeline_get_layer_wrap_mode_s (source, layer_index);
-      if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
-        {
-          need_override_source = TRUE;
-          wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT;
-        }
-      wrap_t = cogl_pipeline_get_layer_wrap_mode_t (source, layer_index);
-      if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
-        {
-          need_override_source = TRUE;
-          wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT;
-        }
-      wrap_p = cogl_pipeline_get_layer_wrap_mode_p (source, layer_index);
-      if (wrap_p == COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
-        {
-          need_override_source = TRUE;
-          wrap_p = COGL_PIPELINE_WRAP_MODE_REPEAT;
-        }
-
-      if (need_override_source)
-        {
-          if (pipeline_priv->real_source == pipeline)
-            {
-              pipeline_priv->ref_count++;
-              pipeline_priv->real_source = source =
-                _cogl_pipeline_weak_copy (pipeline,
-                                          weak_override_source_destroyed_cb,
-                                          pipeline_priv);
-            }
-
-          cogl_pipeline_set_layer_wrap_mode_s (source, layer_index, wrap_s);
-          cogl_pipeline_set_layer_wrap_mode_t (source, layer_index, wrap_t);
-          cogl_pipeline_set_layer_wrap_mode_p (source, layer_index, wrap_p);
-        }
-    }
-
-  return TRUE;
-}
-
-static void
-destroy_pipeline_priv_cb (void *user_data)
-{
-  unref_pipeline_priv (user_data);
-}
-
-static void
-update_primitive_and_draw (CoglVertexBuffer *buffer,
-                           CoglVerticesMode mode,
-                           int first,
-                           int count,
-                           CoglVertexBufferIndices *buffer_indices)
-{
-  VertexBufferMaterialPrivate *pipeline_priv;
-  CoglPipeline *users_source;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  cogl_primitive_set_mode (buffer->primitive, mode);
-  cogl_primitive_set_first_vertex (buffer->primitive, first);
-  cogl_primitive_set_n_vertices (buffer->primitive, count);
-
-  if (buffer_indices)
-    cogl_primitive_set_indices (buffer->primitive, buffer_indices->indices, count);
-  else
-    cogl_primitive_set_indices (buffer->primitive, NULL, count);
-
-  cogl_vertex_buffer_submit_real (buffer);
-
-  users_source = cogl_get_source ();
-  pipeline_priv =
-    cogl_object_get_user_data (COGL_OBJECT (users_source),
-                               &_cogl_vertex_buffer_pipeline_priv_key);
-  if (G_UNLIKELY (!pipeline_priv))
-    {
-      pipeline_priv = g_slice_new0 (VertexBufferMaterialPrivate);
-      pipeline_priv->ref_count = 1;
-      cogl_object_set_user_data (COGL_OBJECT (users_source),
-                                 &_cogl_vertex_buffer_pipeline_priv_key,
-                                 pipeline_priv,
-                                 destroy_pipeline_priv_cb);
-    }
-
-  if (G_UNLIKELY (!pipeline_priv->real_source))
-    {
-      pipeline_priv->real_source = users_source;
-      cogl_pipeline_foreach_layer (pipeline_priv->real_source,
-                                   validate_layer_cb,
-                                   pipeline_priv);
-    }
-
-  /* XXX: although this may seem redundant, we need to do this since
-   * CoglVertexBuffers can be used with legacy state and its the source stack
-   * which track whether legacy state is enabled.
-   *
-   * (We only have a CoglDrawFlag to disable legacy state not one
-   *  to enable it) */
-  cogl_push_source (pipeline_priv->real_source);
-
-  _cogl_primitive_draw (buffer->primitive,
-                        cogl_get_draw_framebuffer (),
-                        pipeline_priv->real_source,
-                        0 /* no draw flags */);
-
-  cogl_pop_source ();
-}
-
-void
-cogl_vertex_buffer_draw (CoglHandle       handle,
-		         CoglVerticesMode mode,
-		         int              first,
-		         int              count)
-{
-  CoglVertexBuffer *buffer;
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-
-  update_primitive_and_draw (buffer, mode, first, count, NULL);
-}
-
-static CoglHandle
-_cogl_vertex_buffer_indices_new_real (CoglIndices *indices)
-{
-  CoglVertexBufferIndices *buffer_indices =
-    g_slice_alloc (sizeof (CoglVertexBufferIndices));
-  buffer_indices->indices = indices;
-
-  return _cogl_vertex_buffer_indices_handle_new (buffer_indices);
-}
-
-CoglHandle
-cogl_vertex_buffer_indices_new (CoglIndicesType  indices_type,
-                                const void      *indices_array,
-                                int              indices_len)
-{
-  CoglIndices *indices;
-
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  indices = cogl_indices_new (ctx, indices_type, indices_array, indices_len);
-  return _cogl_vertex_buffer_indices_new_real (indices);
-}
-
-CoglIndicesType
-cogl_vertex_buffer_indices_get_type (CoglHandle indices_handle)
-{
-  CoglVertexBufferIndices *buffer_indices = NULL;
-
-  if (!cogl_is_vertex_buffer_indices (indices_handle))
-    return COGL_INDICES_TYPE_UNSIGNED_SHORT;
-
-  buffer_indices = indices_handle;
-
-  return cogl_indices_get_type (buffer_indices->indices);
-}
-
-void
-_cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices)
-{
-  cogl_object_unref (buffer_indices->indices);
-  g_slice_free (CoglVertexBufferIndices, buffer_indices);
-}
-
-void
-cogl_vertex_buffer_draw_elements (CoglHandle       handle,
-			          CoglVerticesMode mode,
-                                  CoglHandle       indices_handle,
-                                  int              min_index,
-                                  int              max_index,
-                                  int              indices_offset,
-                                  int              count)
-{
-  CoglVertexBuffer *buffer;
-  CoglVertexBufferIndices *buffer_indices;
-
-  if (!cogl_is_vertex_buffer (handle))
-    return;
-
-  buffer = handle;
-
-  if (!cogl_is_vertex_buffer_indices (indices_handle))
-    return;
-
-  buffer_indices = indices_handle;
-
-  update_primitive_and_draw (buffer, mode, indices_offset, count,
-                             buffer_indices);
-}
-
-static void
-_cogl_vertex_buffer_free (CoglVertexBuffer *buffer)
-{
-  GList *tmp;
-
-  for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next)
-    cogl_vertex_buffer_vbo_free (tmp->data);
-  g_list_free (buffer->submitted_vbos);
-
-  for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next)
-    _cogl_vertex_buffer_attrib_free (tmp->data);
-  g_list_free (buffer->new_attributes);
-
-  if (buffer->primitive)
-    cogl_object_unref (buffer->primitive);
-
-  g_slice_free (CoglVertexBuffer, buffer);
-}
-
-CoglHandle
-cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices)
-{
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  if (n_indices <= 256 / 4 * 6)
-    {
-      if (ctx->quad_buffer_indices_byte == NULL)
-        {
-          /* NB: cogl_get_quad_indices takes n_quads not n_indices... */
-          CoglIndices *indices = cogl_get_rectangle_indices (ctx, 256 / 4);
-          cogl_object_ref (indices);
-          ctx->quad_buffer_indices_byte =
-            _cogl_vertex_buffer_indices_new_real (indices);
-        }
-
-      return ctx->quad_buffer_indices_byte;
-    }
-  else
-    {
-      if (ctx->quad_buffer_indices &&
-          ctx->quad_buffer_indices_len < n_indices)
-        {
-          cogl_object_unref (ctx->quad_buffer_indices);
-          ctx->quad_buffer_indices = NULL;
-        }
-
-      if (ctx->quad_buffer_indices == NULL)
-        {
-          /* NB: cogl_get_quad_indices takes n_quads not n_indices... */
-          CoglIndices *indices =
-            cogl_get_rectangle_indices (ctx, n_indices / 6);
-          cogl_object_ref (indices);
-          ctx->quad_buffer_indices =
-            _cogl_vertex_buffer_indices_new_real (indices);
-        }
-
-      ctx->quad_buffer_indices_len = n_indices;
-
-      return ctx->quad_buffer_indices;
-    }
-
-  g_return_val_if_reached (NULL);
-}
-
diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer.h b/cogl/cogl/deprecated/cogl-vertex-buffer.h
deleted file mode 100644
index cf440cb1a..000000000
--- a/cogl/cogl/deprecated/cogl-vertex-buffer.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Cogl
- *
- * A Low Level GPU Graphics and Utilities API
- *
- * Copyright (C) 2008,2009 Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- *
- *
- * Authors:
- *   Robert Bragg <robert@linux.intel.com>
- */
-
-#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
-#error "Only <cogl/cogl.h> can be included directly."
-#endif
-
-#ifndef __COGL_VERTEX_BUFFER_H__
-#define __COGL_VERTEX_BUFFER_H__
-
-#include <glib.h>
-#include <cogl/cogl-defines.h>
-#include <cogl/cogl-types.h>
-#include <cogl/cogl-macros.h>
-
-G_BEGIN_DECLS
-
-/**
- * SECTION:cogl-vertex-buffer
- * @short_description: An API for submitting extensible arrays of vertex
- *   attributes to be mapped into the GPU for fast drawing.
- *
- * For example to describe a textured triangle, you could create a new cogl
- * vertex buffer with 3 vertices, and then you might add 2 attributes for each
- * vertex:
- * <orderedlist>
- * <listitem>
- * a "gl_Position" describing the (x,y,z) position for each vertex.
- * </listitem>
- * <listitem>
- * a "gl_MultiTexCoord0" describing the (tx,ty) texture coordinates for each
- * vertex.
- * </listitem>
- * </orderedlist>
- *
- * The Vertex Buffer API is designed to be a fairly raw mechanism for
- * developers to be able to submit geometry to Cogl in a format that can be
- * directly consumed by an OpenGL driver and mapped into your GPU for fast
- * re-use. It is designed to avoid repeated validation of the attributes by the
- * driver; to minimize transport costs (e.g. considering indirect GLX
- * use-cases) and to potentially avoid repeated format conversions when
- * attributes are supplied in a format that is not natively supported by the
- * GPU.
- *
- * Although this API does allow you to modify attributes after they have been
- * submitted to the GPU you should be aware that modification is not that
- * cheap, since it implies validating the new data and potentially the
- * OpenGL driver will need to reformat it for the GPU.
- *
- * If at all possible think of tricks that let you re-use static attributes,
- * and if you do need to repeatedly update attributes (e.g. for some kind of
- * morphing geometry) then only update and re-submit the specific attributes
- * that have changed.
- */
-
-/**
- * cogl_vertex_buffer_new:
- * @n_vertices: The number of vertices that your attributes will correspond to.
- *
- * Creates a new vertex buffer that you can use to add attributes.
- *
- * Return value: a new #CoglHandle
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-CoglHandle
-cogl_vertex_buffer_new (unsigned int n_vertices);
-
-/**
- * cogl_vertex_buffer_get_n_vertices:
- * @handle: A vertex buffer handle
- *
- * Retrieves the number of vertices that @handle represents
- *
- * Return value: the number of vertices
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-unsigned int
-cogl_vertex_buffer_get_n_vertices (CoglHandle handle);
-
-/**
- * cogl_vertex_buffer_add:
- * @handle: A vertex buffer handle
- * @attribute_name: The name of your attribute. It should be a valid GLSL
- *   variable name and standard attribute types must use one of following
- *   built-in names: (Note: they correspond to the built-in names of GLSL)
- *   <itemizedlist>
- *     <listitem>"gl_Color"</listitem>
- *     <listitem>"gl_Normal"</listitem>
- *     <listitem>"gl_MultiTexCoord0, gl_MultiTexCoord1, ..."</listitem>
- *     <listitem>"gl_Vertex"</listitem>
- *   </itemizedlist>
- *   To support adding multiple variations of the same attribute the name
- *   can have a detail component, E.g. "gl_Color::active" or
- *   "gl_Color::inactive"
- * @n_components: The number of components per attribute and must be 1, 2,
- *   3 or 4
- * @type: a #CoglAttributeType specifying the data type of each component.
- * @normalized: If %TRUE, this specifies that values stored in an integer
- *   format should be mapped into the range [-1.0, 1.0] or [0.0, 1.0]
- *   for unsigned values. If %FALSE they are converted to floats
- *   directly.
- * @stride: This specifies the number of bytes from the start of one attribute
- *   value to the start of the next value (for the same attribute). So, for
- *   example, with a position interleved with color like this:
- *   XYRGBAXYRGBAXYRGBA, then if each letter represents a byte, the
- *   stride for both attributes is 6. The special value 0 means the
- *   values are stored sequentially in memory.
- * @pointer: This addresses the first attribute in the vertex array. This
- *   must remain valid until you either call cogl_vertex_buffer_submit() or
- *   issue a draw call.
- *
- * Adds an attribute to a buffer, or replaces a previously added
- * attribute with the same name.
- *
- * You either can use one of the built-in names such as "gl_Vertex", or
- * "gl_MultiTexCoord0" to add standard attributes, like positions, colors
- * and normals, or you can add custom attributes for use in shaders.
- *
- * The number of vertices declared when calling cogl_vertex_buffer_new()
- * determines how many attribute values will be read from the supplied
- * @pointer.
- *
- * The data for your attribute isn't copied anywhere until you call
- * cogl_vertex_buffer_submit(), or issue a draw call which automatically
- * submits pending attribute changes. so the supplied pointer must remain
- * valid until then. If you are updating an existing attribute (done by
- * re-adding it) then you still need to re-call cogl_vertex_buffer_submit()
- * to commit the changes to the GPU. Be carefull to minimize the number
- * of calls to cogl_vertex_buffer_submit(), though.
- *
- * <note>If you are interleving attributes it is assumed that each interleaved
- * attribute starts no farther than +- stride bytes from the other attributes
- * it is interleved with. I.e. this is ok:
- * <programlisting>
- * |-0-0-0-0-0-0-0-0-0-0|
- * </programlisting>
- * This is not ok:
- * <programlisting>
- * |- - - - -0-0-0-0-0-0 0 0 0 0|
- * </programlisting>
- * (Though you can have multiple groups of interleved attributes)</note>
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_add (CoglHandle         handle,
-		        const char        *attribute_name,
-			uint8_t            n_components,
-			CoglAttributeType  type,
-			gboolean           normalized,
-			uint16_t           stride,
-			const void        *pointer);
-
-/**
- * cogl_vertex_buffer_delete:
- * @handle: A vertex buffer handle
- * @attribute_name: The name of a previously added attribute
- *
- * Deletes an attribute from a buffer. You will need to call
- * cogl_vertex_buffer_submit() or issue a draw call to commit this
- * change to the GPU.
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_delete (CoglHandle   handle,
-			   const char  *attribute_name);
-
-/**
- * cogl_vertex_buffer_submit:
- * @handle: A vertex buffer handle
- *
- * Submits all the user added attributes to the GPU; once submitted, the
- * attributes can be used for drawing.
- *
- * You should aim to minimize calls to this function since it implies
- * validating your data; it potentially incurs a transport cost (especially if
- * you are using GLX indirect rendering) and potentially a format conversion
- * cost if the GPU doesn't natively support any of the given attribute formats.
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_submit (CoglHandle handle);
-
-/**
- * cogl_vertex_buffer_disable:
- * @handle: A vertex buffer handle
- * @attribute_name: The name of the attribute you want to disable
- *
- * Disables a previosuly added attribute.
- *
- * Since it can be costly to add and remove new attributes to buffers; to make
- * individual buffers more reuseable it is possible to enable and disable
- * attributes before using a buffer for drawing.
- *
- * You don't need to call cogl_vertex_buffer_submit() after using this
- * function.
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_disable (CoglHandle  handle,
-			    const char *attribute_name);
-
-/**
- * cogl_vertex_buffer_enable:
- * @handle: A vertex buffer handle
- * @attribute_name: The name of the attribute you want to enable
- *
- * Enables a previosuly disabled attribute.
- *
- * Since it can be costly to add and remove new attributes to buffers; to make
- * individual buffers more reuseable it is possible to enable and disable
- * attributes before using a buffer for drawing.
- *
- * You don't need to call cogl_vertex_buffer_submit() after using this function
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_enable (CoglHandle  handle,
-			   const char *attribute_name);
-
-/**
- * cogl_vertex_buffer_draw:
- * @handle: A vertex buffer handle
- * @mode: A #CoglVerticesMode specifying how the vertices should be
- *   interpreted.
- * @first: Specifies the index of the first vertex you want to draw with
- * @count: Specifies the number of vertices you want to draw.
- *
- * Allows you to draw geometry using all or a subset of the
- * vertices in a vertex buffer.
- *
- * Any un-submitted attribute changes are automatically submitted before
- * drawing.
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_draw (CoglHandle       handle,
-		         CoglVerticesMode mode,
-		         int              first,
-		         int              count);
-
-/**
- * cogl_vertex_buffer_indices_new: (skip)
- * @indices_type: a #CoglIndicesType specifying the data type used for
- *    the indices.
- * @indices_array: (array length=indices_len): Specifies the address of
- *   your array of indices
- * @indices_len: The number of indices in indices_array
- *
- * Depending on how much geometry you are submitting it can be worthwhile
- * optimizing the number of redundant vertices you submit. Using an index
- * array allows you to reference vertices multiple times, for example
- * during triangle strips.
- *
- * Return value: A CoglHandle for the indices which you can pass to
- *   cogl_vertex_buffer_draw_elements().
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-CoglHandle
-cogl_vertex_buffer_indices_new (CoglIndicesType  indices_type,
-                                const void      *indices_array,
-                                int              indices_len);
-
-/**
- * cogl_vertex_buffer_indices_get_type:
- * @indices: An indices handle
- *
- * Queries back the data type used for the given indices
- *
- * Returns: The CoglIndicesType used
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-CoglIndicesType
-cogl_vertex_buffer_indices_get_type (CoglHandle indices);
-
-/**
- * cogl_vertex_buffer_draw_elements:
- * @handle: A vertex buffer handle
- * @mode: A #CoglVerticesMode specifying how the vertices should be
- *    interpreted.
- * @indices: A CoglHandle for a set of indices allocated via
- *    cogl_vertex_buffer_indices_new ()
- * @min_index: Specifies the minimum vertex index contained in indices
- * @max_index: Specifies the maximum vertex index contained in indices
- * @indices_offset: An offset into named indices. The offset marks the first
- *    index to use for drawing.
- * @count: Specifies the number of vertices you want to draw.
- *
- * This function lets you use an array of indices to specify the vertices
- * within your vertex buffer that you want to draw. The indices themselves
- * are created by calling cogl_vertex_buffer_indices_new ()
- *
- * Any un-submitted attribute changes are automatically submitted before
- * drawing.
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-void
-cogl_vertex_buffer_draw_elements (CoglHandle       handle,
-			          CoglVerticesMode mode,
-                                  CoglHandle       indices,
-                                  int              min_index,
-                                  int              max_index,
-                                  int              indices_offset,
-                                  int              count);
-
-/**
- * cogl_vertex_buffer_indices_get_for_quads:
- * @n_indices: the number of indices in the vertex buffer.
- *
- * Creates a vertex buffer containing the indices needed to draw pairs
- * of triangles from a list of vertices grouped as quads. There will
- * be at least @n_indices entries in the buffer (but there may be
- * more).
- *
- * The indices will follow this pattern:
- *
- * 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 ... etc
- *
- * For example, if you submit vertices for a quad like like that shown
- * in <xref linkend="quad-indices-order"/> then you can request 6
- * indices to render two triangles like those shown in <xref
- * linkend="quad-indices-triangles"/>.
- *
- * <figure id="quad-indices-order">
- *   <title>Example of vertices submitted to form a quad</title>
- *   <graphic fileref="quad-indices-order.png" format="PNG"/>
- * </figure>
- *
- * <figure id="quad-indices-triangles">
- *   <title>Illustration of the triangle indices that will be generated</title>
- *   <graphic fileref="quad-indices-triangles.png" format="PNG"/>
- * </figure>
- *
- * Returns: A %CoglHandle containing the indices. The handled is
- * owned by Cogl and should not be modified or unref'd.
- *
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-CoglHandle
-cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices);
-
-/**
- * cogl_is_vertex_buffer:
- * @handle: a #CoglHandle for a vertex buffer object
- *
- * Checks whether @handle is a Vertex Buffer Object
- *
- * Return value: %TRUE if the handle is a VBO, and %FALSE
- *   otherwise
- *
- * Since: 1.0
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-gboolean
-cogl_is_vertex_buffer (CoglHandle handle);
-
-/**
- * cogl_is_vertex_buffer_indices:
- * @handle: a #CoglHandle
- *
- * Checks whether @handle is a handle to the indices for a vertex
- * buffer object
- *
- * Return value: %TRUE if the handle is indices, and %FALSE
- *   otherwise
- *
- * Since: 1.4
- * Deprecated: 1.16: Use the #CoglPrimitive api instead
- */
-COGL_DEPRECATED_FOR (cogl_primitive_API)
-gboolean
-cogl_is_vertex_buffer_indices (CoglHandle handle);
-G_END_DECLS
-
-#endif /* __COGL_VERTEX_BUFFER_H__ */
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
index 89696b966..ebdb0981c 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -985,7 +985,7 @@ fragend_add_layer_cb (CoglPipelineLayer *layer,
  *
  *    Currently for textured rectangles we manually calculate the texture
  *    coords for each slice based on the users given coords, but this solution
- *    isn't ideal, and can't be used with CoglVertexBuffers.
+ *    isn't ideal.
  */
 void
 _cogl_pipeline_flush_gl_state (CoglContext *ctx,
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index f6f8c0163..f9d5c5ef4 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -65,7 +65,6 @@ built_headers += [cogl_gl_header_h]
 
 cogl_deprecated_headers = [
   'deprecated/cogl-material-compat.h',
-  'deprecated/cogl-vertex-buffer.h',
   'deprecated/cogl-shader.h',
   'deprecated/cogl-clutter.h',
   'deprecated/cogl-type-casts.h',
@@ -352,8 +351,6 @@ cogl_sources = [
   'cogl-closure-list.c',
   'cogl-fence.c',
   'cogl-fence-private.h',
-  'deprecated/cogl-vertex-buffer-private.h',
-  'deprecated/cogl-vertex-buffer.c',
   'deprecated/cogl-material-compat.c',
   'deprecated/cogl-program.c',
   'deprecated/cogl-program-private.h',
diff --git a/cogl/tests/conform/meson.build b/cogl/tests/conform/meson.build
index b36467593..2a7917aaa 100644
--- a/cogl/tests/conform/meson.build
+++ b/cogl/tests/conform/meson.build
@@ -54,8 +54,6 @@ cogl_test_conformance_sources = [
 #  "test-readpixels.c",
 #  "test-texture-mipmaps.c",
 #  "test-texture-pixmap-x11.c",",
-#  "test-vertex-buffer-contiguous.c",
-#  "test-vertex-buffer-interleved.c",
 #]
 
 cogl_test_conformance_includes = [
diff --git a/cogl/tests/conform/test-vertex-buffer-contiguous.c b/cogl/tests/conform/test-vertex-buffer-contiguous.c
deleted file mode 100644
index f74e3ac7a..000000000
--- a/cogl/tests/conform/test-vertex-buffer-contiguous.c
+++ /dev/null
@@ -1,259 +0,0 @@
-
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "test-conform-common.h"
-
-/* This test verifies that the simplest usage of the vertex buffer API,
- * where we add contiguous (x,y) GLfloat vertices, and RGBA GLubyte color
- * attributes to a buffer, submit, and draw.
- *
- * It also tries to verify that the enable/disable attribute APIs are working
- * too.
- *
- * If you want visual feedback of what this test paints for debugging purposes,
- * then remove the call to clutter_main_quit() in validate_result.
- */
-
-typedef struct _TestState
-{
-  CoglHandle buffer;
-  CoglHandle texture;
-  CoglHandle material;
-  ClutterGeometry stage_geom;
-} TestState;
-
-static void
-validate_result (TestState *state)
-{
-  GLubyte pixel[4];
-  GLint y_off = 90;
-
-  if (cogl_test_verbose ())
-    g_print ("y_off = %d\n", y_off);
-
-  /* NB: We ignore the alpha, since we don't know if our render target is
-   * RGB or RGBA */
-
-#define RED 0
-#define GREEN 1
-#define BLUE 2
-
-  /* Should see a blue pixel */
-  cogl_read_pixels (10, y_off, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
-
-  /* Should see a red pixel */
-  cogl_read_pixels (110, y_off, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 1 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[RED] != 0 && pixel[GREEN] == 0 && pixel[BLUE] == 0);
-
-  /* Should see a blue pixel */
-  cogl_read_pixels (210, y_off, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 2 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
-
-  /* Should see a green pixel, at bottom of 4th triangle */
-  cogl_read_pixels (310, y_off, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 3 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[GREEN] > pixel[RED] && pixel[GREEN] > pixel[BLUE]);
-
-  /* Should see a red pixel, at top of 4th triangle */
-  cogl_read_pixels (310, y_off - 70, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 4 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[RED] > pixel[GREEN] && pixel[RED] > pixel[BLUE]);
-
-
-#undef RED
-#undef GREEN
-#undef BLUE
-
-  /* Comment this out if you want visual feedback of what this test
-   * paints.
-   */
-  clutter_main_quit ();
-}
-
-static void
-on_paint (ClutterActor        *actor,
-          ClutterPaintContext *paint_context,
-          TestState           *state)
-{
-  /* Draw a faded blue triangle */
-  cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue");
-  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
-  cogl_vertex_buffer_draw (state->buffer,
-			   GL_TRIANGLE_STRIP, /* mode */
-			   0, /* first */
-			   3); /* count */
-
-  /* Draw a red triangle */
-  /* Here we are testing that the disable attribute works; if it doesn't
-   * the triangle will remain faded blue */
-  cogl_translate (100, 0, 0);
-  cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue");
-  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
-  cogl_vertex_buffer_draw (state->buffer,
-			   GL_TRIANGLE_STRIP, /* mode */
-			   0, /* first */
-			   3); /* count */
-
-  /* Draw a faded blue triangle */
-  /* Here we are testing that the re-enable works; if it doesn't
-   * the triangle will remain red */
-  cogl_translate (100, 0, 0);
-  cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue");
-  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
-  cogl_vertex_buffer_draw (state->buffer,
-			   GL_TRIANGLE_STRIP, /* mode */
-			   0, /* first */
-			   3); /* count */
-
-  /* Draw a textured triangle */
-  cogl_translate (100, 0, 0);
-  cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue");
-  cogl_set_source (state->material);
-  cogl_material_set_color4ub (state->material, 0xff, 0xff, 0xff, 0xff);
-  cogl_vertex_buffer_draw (state->buffer,
-                           GL_TRIANGLE_STRIP, /* mode */
-                           0, /* first */
-                           3); /* count */
-
-  validate_result (state);
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
-  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
-  return TRUE;
-}
-
-
-
-void
-test_vertex_buffer_contiguous (TestUtilsGTestFixture *fixture,
-		                    void *data)
-{
-  TestState state;
-  ClutterActor *stage;
-  ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff};
-  ClutterActor *group;
-  unsigned int idle_source;
-  guchar tex_data[] = {
-    0xff, 0x00, 0x00, 0xff,
-    0xff, 0x00, 0x00, 0xff,
-    0x00, 0xff, 0x00, 0xff,
-    0x00, 0xff, 0x00, 0xff
-  };
-
-  stage = clutter_stage_get_default ();
-
-  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
-  clutter_actor_get_geometry (stage, &state.stage_geom);
-
-  group = clutter_group_new ();
-  clutter_actor_set_size (group,
-			  state.stage_geom.width,
-			  state.stage_geom.height);
-  clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
-
-  /* We force continuous redrawing incase someone comments out the
-   * clutter_main_quit and wants visual feedback for the test since we
-   * wont be doing anything else that will trigger redrawing. */
-  idle_source = g_idle_add (queue_redraw, stage);
-
-  g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
-
-  state.texture = cogl_texture_new_from_data (2, 2,
-                                              COGL_TEXTURE_NO_SLICING,
-                                              COGL_PIXEL_FORMAT_RGBA_8888,
-                                              COGL_PIXEL_FORMAT_ANY,
-                                              0, /* auto calc row stride */
-                                              tex_data);
-
-  state.material = cogl_material_new ();
-  cogl_material_set_color4ub (state.material, 0x00, 0xff, 0x00, 0xff);
-  cogl_material_set_layer (state.material, 0, state.texture);
-
-  {
-    GLfloat triangle_verts[3][2] =
-      {
-	{0.0,	0.0},
-	{100.0, 100.0},
-	{0.0,	100.0}
-      };
-    GLbyte triangle_colors[3][4] =
-      {
-	{0x00, 0x00, 0xff, 0xff}, /* blue */
-	{0x00, 0x00, 0xff, 0x00}, /* transparent blue */
-	{0x00, 0x00, 0xff, 0x00}  /* transparent blue */
-      };
-    GLfloat triangle_tex_coords[3][2] =
-      {
-        {0.0, 0.0},
-        {1.0, 1.0},
-        {0.0, 1.0}
-      };
-    state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
-    cogl_vertex_buffer_add (state.buffer,
-			    "gl_Vertex",
-			    2, /* n components */
-			    GL_FLOAT,
-			    FALSE, /* normalized */
-			    0, /* stride */
-			    triangle_verts);
-    cogl_vertex_buffer_add (state.buffer,
-			    "gl_Color::blue",
-			    4, /* n components */
-			    GL_UNSIGNED_BYTE,
-			    FALSE, /* normalized */
-			    0, /* stride */
-			    triangle_colors);
-    cogl_vertex_buffer_add (state.buffer,
-			    "gl_MultiTexCoord0",
-			    2, /* n components */
-			    GL_FLOAT,
-			    FALSE, /* normalized */
-			    0, /* stride */
-			    triangle_tex_coords);
-
-    cogl_vertex_buffer_submit (state.buffer);
-  }
-
-  clutter_actor_show_all (stage);
-
-  clutter_main ();
-
-  cogl_object_unref (state.buffer);
-  cogl_object_unref (state.material);
-  cogl_object_unref (state.texture);
-
-  g_clear_handle_id (&idle_source, g_source_remove);
-
-  if (cogl_test_verbose ())
-    g_print ("OK\n");
-}
-
diff --git a/cogl/tests/conform/test-vertex-buffer-interleved.c b/cogl/tests/conform/test-vertex-buffer-interleved.c
deleted file mode 100644
index 057adc94a..000000000
--- a/cogl/tests/conform/test-vertex-buffer-interleved.c
+++ /dev/null
@@ -1,164 +0,0 @@
-
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-
-#include "test-conform-common.h"
-
-/* This test verifies that interleved attributes work with the vertex buffer
- * API. We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color
- * attributes to a buffer, submit and draw.
- *
- * If you want visual feedback of what this test paints for debugging purposes,
- * then remove the call to clutter_main_quit() in validate_result.
- */
-
-typedef struct _TestState
-{
-  CoglHandle buffer;
-  ClutterGeometry stage_geom;
-} TestState;
-
-typedef struct _InterlevedVertex
-{
-  GLfloat x;
-  GLfloat y;
-
-  GLubyte r;
-  GLubyte g;
-  GLubyte b;
-  GLubyte a;
-} InterlevedVertex;
-
-
-static void
-validate_result (TestState *state)
-{
-  GLubyte pixel[4];
-  GLint y_off = 90;
-
-  /* NB: We ignore the alpha, since we don't know if our render target is
-   * RGB or RGBA */
-
-#define RED 0
-#define GREEN 1
-#define BLUE 2
-
-  /* Should see a blue pixel */
-  cogl_read_pixels (10, y_off, 1, 1,
-                    COGL_READ_PIXELS_COLOR_BUFFER,
-                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                    pixel);
-  if (cogl_test_verbose ())
-    g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
-  g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
-
-#undef RED
-#undef GREEN
-#undef BLUE
-
-  /* Comment this out if you want visual feedback of what this test
-   * paints.
-   */
-  clutter_main_quit ();
-}
-
-static void
-on_paint (ClutterActor        *actor,
-          ClutterPaintContext *paint_context,
-          TestState           *state)
-{
-  /* Draw a faded blue triangle */
-  cogl_vertex_buffer_draw (state->buffer,
-			   GL_TRIANGLE_STRIP, /* mode */
-			   0, /* first */
-			   3); /* count */
-
-  validate_result (state);
-}
-
-static gboolean
-queue_redraw (gpointer stage)
-{
-  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
-
-  return TRUE;
-}
-
-void
-test_vertex_buffer_interleved (TestUtilsGTestFixture *fixture,
-		                    void *data)
-{
-  TestState state;
-  ClutterActor *stage;
-  ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff};
-  ClutterActor *group;
-  unsigned int idle_source;
-
-  stage = clutter_stage_get_default ();
-
-  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
-  clutter_actor_get_geometry (stage, &state.stage_geom);
-
-  group = clutter_group_new ();
-  clutter_actor_set_size (group,
-			  state.stage_geom.width,
-			  state.stage_geom.height);
-  clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
-
-  /* We force continuous redrawing incase someone comments out the
-   * clutter_main_quit and wants visual feedback for the test since we
-   * wont be doing anything else that will trigger redrawing. */
-  idle_source = g_idle_add (queue_redraw, stage);
-
-  g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
-
-  {
-    InterlevedVertex verts[3] =
-      {
-	{ /* .x = */ 0.0, /* .y = */ 0.0,
-	  /* blue */
-	  /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0xff },
-
-	{ /* .x = */ 100.0, /* .y = */ 100.0,
-	  /* transparent blue */
-	  /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 },
-
-	{ /* .x = */ 0.0, /* .y = */ 100.0,
-	  /* transparent blue */
-	  /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 },
-      };
-
-    /* We assume the compiler is doing no funny struct padding for this test:
-     */
-    g_assert (sizeof (InterlevedVertex) == 12);
-
-    state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
-    cogl_vertex_buffer_add (state.buffer,
-			    "gl_Vertex",
-			    2, /* n components */
-			    GL_FLOAT,
-			    FALSE, /* normalized */
-                            12, /* stride */
-			    &verts[0].x);
-    cogl_vertex_buffer_add (state.buffer,
-                            "gl_Color",
-			    4, /* n components */
-			    GL_UNSIGNED_BYTE,
-			    FALSE, /* normalized */
-			    12, /* stride */
-			    &verts[0].r);
-    cogl_vertex_buffer_submit (state.buffer);
-  }
-
-  clutter_actor_show_all (stage);
-
-  clutter_main ();
-
-  cogl_object_unref (state.buffer);
-
-  g_clear_handle_id (&idle_source, g_source_remove);
-
-  if (cogl_test_verbose ())
-    g_print ("OK\n");
-}
-
diff --git a/cogl/tests/conform/test-wrap-modes.c b/cogl/tests/conform/test-wrap-modes.c
index 92a609ec3..1c524f295 100644
--- a/cogl/tests/conform/test-wrap-modes.c
+++ b/cogl/tests/conform/test-wrap-modes.c
@@ -139,43 +139,6 @@ draw_tests_polygon (TestState *state)
     }
 }
 
-static void
-draw_tests_vbo (TestState *state)
-{
-  CoglHandle vbo;
-  int i;
-
-  vbo = cogl_vertex_buffer_new (4);
-  cogl_vertex_buffer_add (vbo, "gl_Vertex", 3,
-                          COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
-                          sizeof (vertices[0]),
-                          &vertices[0].x);
-  cogl_vertex_buffer_add (vbo, "gl_MultiTexCoord0", 2,
-                          COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
-                          sizeof (vertices[0]),
-                          &vertices[0].tx);
-  cogl_vertex_buffer_submit (vbo);
-
-  for (i = 0; i < G_N_ELEMENTS (wrap_modes); i += 2)
-    {
-      CoglPipelineWrapMode wrap_mode_s, wrap_mode_t;
-      CoglPipeline *pipeline;
-
-      wrap_mode_s = wrap_modes[i];
-      wrap_mode_t = wrap_modes[i + 1];
-      pipeline = create_pipeline (state, wrap_mode_s, wrap_mode_t);
-      cogl_set_source (pipeline);
-      cogl_object_unref (pipeline);
-      cogl_push_matrix ();
-      cogl_translate (TEX_SIZE * i, 0.0f, 0.0f);
-      /* Render the pipeline at four times the size of the texture */
-      cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_TRIANGLE_FAN, 0, 4);
-      cogl_pop_matrix ();
-    }
-
-  cogl_object_unref (vbo);
-}
-
 static void
 validate_set (TestState *state, int offset)
 {
@@ -232,7 +195,6 @@ validate_result (TestState *state)
   validate_set (state, 1); /* atlased rectangle */
 #endif
   validate_set (state, 2); /* cogl_polygon */
-  validate_set (state, 3); /* vertex buffer */
 }
 
 static void
@@ -260,14 +222,6 @@ paint (TestState *state)
   cogl_pop_matrix ();
   cogl_object_unref (state->texture);
 
-  /* Draw the tests using a vertex buffer */
-  state->texture = create_texture (TEST_UTILS_TEXTURE_NO_ATLAS);
-  cogl_push_matrix ();
-  cogl_translate (0.0f, TEX_SIZE * 6.0f, 0.0f);
-  draw_tests_vbo (state);
-  cogl_pop_matrix ();
-  cogl_object_unref (state->texture);
-
   validate_result (state);
 }
 
diff --git a/src/tests/clutter/interactive/meson.build b/src/tests/clutter/interactive/meson.build
index 7a12d8ae2..12274768e 100644
--- a/src/tests/clutter/interactive/meson.build
+++ b/src/tests/clutter/interactive/meson.build
@@ -36,7 +36,6 @@ clutter_tests_interactive_test_sources = [
   'test-text-field.c',
   'test-cairo-clock.c',
   'test-cairo-flowers.c',
-  'test-cogl-vertex-buffer.c',
   'test-stage-sizing.c',
   'test-scrolling.c',
   'test-swipe-action.c',
diff --git a/src/tests/clutter/interactive/test-cogl-point-sprites.c b/src/tests/clutter/interactive/test-cogl-point-sprites.c
index 453d6fffe..30b2567bc 100644
--- a/src/tests/clutter/interactive/test-cogl-point-sprites.c
+++ b/src/tests/clutter/interactive/test-cogl-point-sprites.c
@@ -102,7 +102,6 @@ paint_cb (ClutterActor        *stage,
   CoglMatrix old_matrix, new_matrix;
   int i;
   float diff_time;
-  CoglHandle vbo;
 
   cogl_get_projection_matrix (&old_matrix);
   /* Use an orthogonal projection from -1 -> 1 in both axes */
@@ -197,22 +196,6 @@ paint_cb (ClutterActor        *stage,
       g_timer_reset (data->last_spark_time);
     }
 
-  vbo = cogl_vertex_buffer_new (N_SPARKS);
-  cogl_vertex_buffer_add (vbo, "gl_Vertex", 2,
-                          COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
-                          sizeof (Spark),
-                          &data->sparks[0].x);
-  cogl_vertex_buffer_add (vbo, "gl_Color", 4,
-                          COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, TRUE,
-                          sizeof (Spark),
-                          &data->sparks[0].color.red);
-  cogl_vertex_buffer_submit (vbo);
-
-  cogl_set_source (data->material);
-  cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_POINTS, 0, N_SPARKS);
-
-  cogl_object_unref (vbo);
-
   cogl_set_projection_matrix (&old_matrix);
   cogl_pop_matrix ();
 }
diff --git a/src/tests/clutter/interactive/test-cogl-vertex-buffer.c b/src/tests/clutter/interactive/test-cogl-vertex-buffer.c
deleted file mode 100644
index 33dbbc3e1..000000000
--- a/src/tests/clutter/interactive/test-cogl-vertex-buffer.c
+++ /dev/null
@@ -1,398 +0,0 @@
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <clutter/clutter.h>
-#include <cogl/cogl.h>
-#include <math.h>
-
-/* Defines the size and resolution of the quad mesh we morph:
- */
-#define MESH_WIDTH  100.0 /* number of quads along x axis */
-#define MESH_HEIGHT 100.0 /* number of quads along y axis */
-#define QUAD_WIDTH  5.0 /* width in pixels of a single quad */
-#define QUAD_HEIGHT 5.0 /* height in pixels of a single quad */
-
-/* Defines a sine wave that sweeps across the mesh:
- */
-#define WAVE_DEPTH    ((MESH_WIDTH * QUAD_WIDTH) / 16.0) /* peak amplitude */
-#define WAVE_PERIODS  4.0
-#define WAVE_SPEED    10.0
-
-/* Defines a rippling sine wave emitted from a point:
- */
-#define RIPPLE_CENTER_X ((MESH_WIDTH / 2.0) * QUAD_WIDTH)
-#define RIPPLE_CENTER_Y ((MESH_HEIGHT / 2.0) * QUAD_HEIGHT)
-#define RIPPLE_RADIUS   (MESH_WIDTH * QUAD_WIDTH)
-#define RIPPLE_DEPTH    ((MESH_WIDTH * QUAD_WIDTH) / 16.0) /* peak amplitude */
-#define RIPPLE_PERIODS  4.0
-#define RIPPLE_SPEED    -10.0
-
-/* Defines the width of the gaussian bell used to fade out the alpha
- * towards the edges of the mesh (starting from the ripple center):
- */
-#define GAUSSIAN_RADIUS ((MESH_WIDTH * QUAD_WIDTH) / 6.0)
-
-/* Our hues lie in the range [0, 1], and this defines how we map amplitude
- * to hues (before scaling by {WAVE,RIPPLE}_DEPTH)
- * As we are interferring two sine waves together; amplitudes lie in the
- * range [-2, 2]
- */
-#define HSL_OFFSET    0.5 /* the hue that we map an amplitude of 0 too */
-#define HSL_SCALE     0.25
-
-typedef struct _TestState
-{
-  ClutterActor    *dummy;
-  CoglHandle       buffer;
-  float           *quad_mesh_verts;
-  guint8          *quad_mesh_colors;
-  guint16         *static_indices;
-  guint            n_static_indices;
-  CoglHandle       indices;
-  ClutterTimeline *timeline;
-  guint            frame_id;
-} TestState;
-
-int
-test_cogl_vertex_buffer_main (int argc, char *argv[]);
-
-const char *
-test_cogl_vertex_buffer_describe (void);
-
-static void
-frame_cb (ClutterTimeline *timeline,
-          gint             elapsed_msecs,
-          TestState       *state)
-{
-  guint x, y;
-  float period_progress = clutter_timeline_get_progress (timeline);
-  float period_progress_sin = sinf (period_progress);
-  float wave_shift = period_progress * WAVE_SPEED;
-  float ripple_shift = period_progress * RIPPLE_SPEED;
-
-  for (y = 0; y <= MESH_HEIGHT; y++)
-    for (x = 0; x <= MESH_WIDTH; x++)
-      {
-        guint    vert_index = (MESH_WIDTH + 1) * y + x;
-        float   *vert = &state->quad_mesh_verts[3 * vert_index];
-
-        float    real_x = x * QUAD_WIDTH;
-        float    real_y = y * QUAD_HEIGHT;
-
-        float    wave_offset = (float)x / (MESH_WIDTH + 1);
-        float    wave_angle =
-                    (WAVE_PERIODS * 2 * G_PI * wave_offset) + wave_shift;
-        float    wave_sin = sinf (wave_angle);
-
-        float    a_sqr = (RIPPLE_CENTER_X - real_x) * (RIPPLE_CENTER_X - real_x);
-        float    b_sqr = (RIPPLE_CENTER_Y - real_y) * (RIPPLE_CENTER_Y - real_y);
-        float    ripple_offset = sqrtf (a_sqr + b_sqr) / RIPPLE_RADIUS;
-        float    ripple_angle =
-                    (RIPPLE_PERIODS * 2 * G_PI * ripple_offset) + ripple_shift;
-        float    ripple_sin = sinf (ripple_angle);
-
-        float    h, s, l;
-        guint8  *color;
-
-        vert[2] = (wave_sin * WAVE_DEPTH) + (ripple_sin * RIPPLE_DEPTH);
-
-        /* Burn some CPU time picking a pretty color... */
-        h = (HSL_OFFSET
-             + wave_sin
-             + ripple_sin
-             + period_progress_sin) * HSL_SCALE;
-        s = 0.5;
-        l = 0.25 + (period_progress_sin + 1.0) / 4.0;
-        color = &state->quad_mesh_colors[4 * vert_index];
-        /* A bit of a sneaky cast, but it seems safe to assume the ClutterColor
-         * typedef is set in stone... */
-        clutter_color_from_hls ((ClutterColor *)color, h * 360.0, l, s);
-
-        color[0] = (color[0] * color[3] + 128) / 255;
-        color[1] = (color[1] * color[3] + 128) / 255;
-        color[2] = (color[2] * color[3] + 128) / 255;
-      }
-
-  cogl_vertex_buffer_add (state->buffer,
-                          "gl_Vertex",
-                          3, /* n components */
-                          COGL_ATTRIBUTE_TYPE_FLOAT,
-                          FALSE, /* normalized */
-                          0, /* stride */
-                          state->quad_mesh_verts);
-  cogl_vertex_buffer_add (state->buffer,
-                          "gl_Color",
-                          4, /* n components */
-                          COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
-                          FALSE, /* normalized */
-                          0, /* stride */
-                          state->quad_mesh_colors);
-
-  cogl_vertex_buffer_submit (state->buffer);
-
-  clutter_actor_set_rotation (state->dummy,
-                              CLUTTER_Z_AXIS,
-                              360 * period_progress,
-                              (MESH_WIDTH * QUAD_WIDTH) / 2,
-                              (MESH_HEIGHT * QUAD_HEIGHT) / 2,
-                              0);
-  clutter_actor_set_rotation (state->dummy,
-                              CLUTTER_X_AXIS,
-                              360 * period_progress,
-                              (MESH_WIDTH * QUAD_WIDTH) / 2,
-                              (MESH_HEIGHT * QUAD_HEIGHT) / 2,
-                              0);
-}
-
-static void
-on_paint (ClutterActor        *actor,
-          ClutterPaintContext *paint_context,
-          TestState           *state)
-{
-  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
-  cogl_vertex_buffer_draw_elements (state->buffer,
-                                    COGL_VERTICES_MODE_TRIANGLE_STRIP,
-                                    state->indices,
-                                    0, /* min index */
-                                    (MESH_WIDTH + 1) *
-                                    (MESH_HEIGHT + 1) - 1, /* max index */
-                                    0, /* indices offset */
-                                    state->n_static_indices);
-}
-
-static void
-init_static_index_arrays (TestState *state)
-{
-  guint     n_indices;
-  int       x, y;
-  guint16  *i;
-  guint     dir;
-
-  /* - Each row takes (2 + 2 * MESH_WIDTH indices)
-   *    - Thats 2 to start the triangle strip then 2 indices to add 2 triangles
-   *      per mesh quad.
-   * - We have MESH_HEIGHT rows
-   * - It takes one extra index for linking between rows (MESH_HEIGHT - 1)
-   * - A 2 x 3 mesh == 20 indices... */
-  n_indices = (2 + 2 * MESH_WIDTH) * MESH_HEIGHT + (MESH_HEIGHT - 1);
-  state->static_indices = g_malloc (sizeof (guint16) * n_indices);
-  state->n_static_indices = n_indices;
-
-#define MESH_INDEX(X, Y) (Y) * (MESH_WIDTH + 1) + (X)
-
-  i = state->static_indices;
-
-  /* NB: front facing == anti-clockwise winding */
-
-  i[0] = MESH_INDEX (0, 0);
-  i[1] = MESH_INDEX (0, 1);
-  i += 2;
-
-#define LEFT  0
-#define RIGHT 1
-
-  dir = RIGHT;
-
-  for (y = 0; y < MESH_HEIGHT; y++)
-    {
-      for (x = 0; x < MESH_WIDTH; x++)
-        {
-          /* Add 2 triangles per mesh quad... */
-          if (dir == RIGHT)
-            {
-              i[0] = MESH_INDEX (x + 1, y);
-              i[1] = MESH_INDEX (x + 1, y + 1);
-            }
-          else
-            {
-              i[0] = MESH_INDEX (MESH_WIDTH - x - 1, y);
-              i[1] = MESH_INDEX (MESH_WIDTH - x - 1, y + 1);
-            }
-          i += 2;
-        }
-
-      /* Link rows... */
-
-      if (y == (MESH_HEIGHT - 1))
-        break;
-
-      if (dir == RIGHT)
-        {
-          i[0] = MESH_INDEX (MESH_WIDTH, y + 1);
-          i[1] = MESH_INDEX (MESH_WIDTH, y + 1);
-          i[2] = MESH_INDEX (MESH_WIDTH, y + 2);
-        }
-      else
-        {
-          i[0] = MESH_INDEX (0, y + 1);
-          i[1] = MESH_INDEX (0, y + 1);
-          i[2] = MESH_INDEX (0, y + 2);
-        }
-      i += 3;
-      dir = !dir;
-    }
-
-#undef MESH_INDEX
-
-  state->indices =
-    cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
-                                    state->static_indices,
-                                    state->n_static_indices);
-}
-
-static float
-gaussian (float x, float y)
-{
-  /* Bell width */
-  float c = GAUSSIAN_RADIUS;
-
-  /* Peak amplitude */
-  float a = 1.0;
-  /* float a = 1.0 / (c * sqrtf (2.0 * G_PI)); */
-
-  /* Center offset */
-  float b = 0.0;
-
-  float dist;
-  x = x - RIPPLE_CENTER_X;
-  y = y - RIPPLE_CENTER_Y;
-  dist = sqrtf (x*x + y*y);
-
-  return a * exp ((- ((dist - b) * (dist - b))) / (2.0 * c * c));
-}
-
-static void
-init_quad_mesh (TestState *state)
-{
-  int x, y;
-  float *vert;
-  guint8 *color;
-
-  /* Note: we maintain the minimum number of vertices possible. This minimizes
-   * the work required when we come to morph the geometry.
-   *
-   * We use static indices into our mesh so that we can treat the data like a
-   * single triangle list and drawing can be done in one operation (Note: We
-   * are using degenerate triangles at the edges to link to the next row)
-   */
-  state->quad_mesh_verts =
-    g_malloc0 (sizeof (float) * 3 * (MESH_WIDTH + 1) * (MESH_HEIGHT + 1));
-
-  state->quad_mesh_colors =
-    g_malloc0 (sizeof (guint8) * 4 * (MESH_WIDTH + 1) * (MESH_HEIGHT + 1));
-
-  vert = state->quad_mesh_verts;
-  color = state->quad_mesh_colors;
-  for (y = 0; y <= MESH_HEIGHT; y++)
-    for (x = 0; x <= MESH_WIDTH; x++)
-      {
-        vert[0] = x * QUAD_WIDTH;
-        vert[1] = y * QUAD_HEIGHT;
-        vert += 3;
-
-        color[3] = gaussian (x * QUAD_WIDTH,
-                             y * QUAD_HEIGHT) * 255.0;
-        color += 4;
-      }
-
-  state->buffer = cogl_vertex_buffer_new ((MESH_WIDTH + 1)*(MESH_HEIGHT + 1));
-  cogl_vertex_buffer_add (state->buffer,
-                          "gl_Vertex",
-                          3, /* n components */
-                          COGL_ATTRIBUTE_TYPE_FLOAT,
-                          FALSE, /* normalized */
-                          0, /* stride */
-                          state->quad_mesh_verts);
-
-  cogl_vertex_buffer_add (state->buffer,
-                          "gl_Color",
-                          4, /* n components */
-                          COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
-                          FALSE, /* normalized */
-                          0, /* stride */
-                          state->quad_mesh_colors);
-
-  cogl_vertex_buffer_submit (state->buffer);
-
-  init_static_index_arrays (state);
-}
-
-/* This creates an actor that has a specific size but that does not result
- * in any drawing so we can do our own drawing using Cogl... */
-static ClutterActor *
-create_dummy_actor (guint width, guint height)
-{
-  ClutterActor *group, *rect;
-  ClutterColor clr = { 0xff, 0xff, 0xff, 0xff};
-
-  group = clutter_group_new ();
-  rect = clutter_rectangle_new_with_color (&clr);
-  clutter_actor_set_size (rect, width, height);
-  clutter_actor_hide (rect);
-  clutter_container_add_actor (CLUTTER_CONTAINER (group), rect);
-  return group;
-}
-
-static void
-stop_and_quit (ClutterActor *actor,
-               TestState    *state)
-{
-  clutter_timeline_stop (state->timeline);
-  clutter_main_quit ();
-}
-
-G_MODULE_EXPORT int
-test_cogl_vertex_buffer_main (int argc, char *argv[])
-{
-  TestState       state;
-  ClutterActor   *stage;
-  gfloat          stage_w, stage_h;
-  gint            dummy_width, dummy_height;
-
-  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
-    return 1;
-
-  stage = clutter_stage_new ();
-
-  clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Vertex Buffers");
-  clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
-  g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), &state);
-  clutter_actor_get_size (stage, &stage_w, &stage_h);
-
-  dummy_width = MESH_WIDTH * QUAD_WIDTH;
-  dummy_height = MESH_HEIGHT * QUAD_HEIGHT;
-  state.dummy = create_dummy_actor (dummy_width, dummy_height);
-  clutter_container_add_actor (CLUTTER_CONTAINER (stage), state.dummy);
-  clutter_actor_set_position (state.dummy,
-                              (stage_w / 2.0) - (dummy_width / 2.0),
-                              (stage_h / 2.0) - (dummy_height / 2.0));
-
-  state.timeline = clutter_timeline_new (1000);
-  clutter_timeline_set_loop (state.timeline, TRUE);
-
-  state.frame_id = g_signal_connect (state.timeline,
-                                     "new-frame",
-                                     G_CALLBACK (frame_cb),
-                                     &state);
-
-  g_signal_connect (state.dummy, "paint", G_CALLBACK (on_paint), &state);
-
-  init_quad_mesh (&state);
-
-  clutter_actor_show_all (stage);
-
-  clutter_timeline_start (state.timeline);
-
-  clutter_main ();
-
-  cogl_object_unref (state.buffer);
-  cogl_object_unref (state.indices);
-
-  return 0;
-}
-
-G_MODULE_EXPORT const char *
-test_cogl_vertex_buffer_describe (void)
-{
-  return "Vertex buffers support in Cogl.";
-}