diff --git a/cogl/cogl-buffer-private.h b/cogl/cogl-buffer-private.h
index 3cceb19ec..ebd512ca0 100644
--- a/cogl/cogl-buffer-private.h
+++ b/cogl/cogl-buffer-private.h
@@ -86,6 +86,18 @@ struct _CoglBuffer
                                       * fallback paths */
 };
 
+/* This is used to register a type to the list of handle types that
+   will be considered a texture in cogl_is_texture() */
+void
+_cogl_buffer_register_buffer_type (GQuark type);
+
+#define COGL_BUFFER_DEFINE(TypeName, type_name)                         \
+  COGL_OBJECT_DEFINE_WITH_CODE                                          \
+  (TypeName, type_name,                                                 \
+   _cogl_buffer_register_buffer_type (_cogl_object_                     \
+                                      ## type_name ## _get_type ()))
+
+
 void    _cogl_buffer_initialize         (CoglBuffer          *buffer,
                                          unsigned int         size,
                                          CoglBufferUsageHint  usage_hint,
diff --git a/cogl/cogl-buffer.c b/cogl/cogl-buffer.c
index 89c5132a9..f42641e99 100644
--- a/cogl/cogl-buffer.c
+++ b/cogl/cogl-buffer.c
@@ -68,15 +68,37 @@
 
 #endif
 
+/* XXX:
+ * The CoglHandle macros don't support any form of inheritance, so for
+ * now we implement the CoglObject support for the CoglBuffer
+ * abstract class manually.
+ */
+
+void
+_cogl_buffer_register_buffer_type (GQuark type)
+{
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  ctx->buffer_types = g_slist_prepend (ctx->buffer_types,
+                                       GINT_TO_POINTER (type));
+}
+
 gboolean
 cogl_is_buffer (const void *object)
 {
-  CoglObject *obj = (CoglObject *)object;
+  const CoglHandleObject *obj = object;
+  GSList *l;
 
-  if (obj == NULL)
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
+  if (object == NULL)
     return FALSE;
 
-  return obj->klass->type == _cogl_handle_pixel_buffer_get_type ();
+  for (l = ctx->buffer_types; l; l = l->next)
+    if (GPOINTER_TO_INT (l->data) == obj->klass->type)
+      return TRUE;
+
+  return FALSE;
 }
 
 void
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index b3cfdb042..6a0af95c4 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -70,6 +70,7 @@ cogl_create_context (void)
   _context->features_cached = FALSE;
 
   _context->texture_types = NULL;
+  _context->buffer_types = NULL;
 
   /* Initialise the driver specific state */
   /* TODO: combine these two into one function */
@@ -262,6 +263,7 @@ _cogl_destroy_context (void)
   _cogl_bitmask_destroy (&_context->texcoord_arrays_to_disable);
 
   g_slist_free (_context->texture_types);
+  g_slist_free (_context->buffer_types);
 
   g_free (_context);
 }
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index 5c51d2ef4..e0ad904f5 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -167,6 +167,10 @@ typedef struct
      cogl_is_texture */
   GSList           *texture_types;
 
+  /* List of types that will be considered a subclass of CoglBuffer in
+     cogl_is_buffer */
+  GSList           *buffer_types;
+
   CoglContextDriver drv;
   CoglContextWinsys winsys;
 } CoglContext;
diff --git a/cogl/cogl-pixel-buffer.c b/cogl/cogl-pixel-buffer.c
index be12fb34e..01ce71cd4 100644
--- a/cogl/cogl-pixel-buffer.c
+++ b/cogl/cogl-pixel-buffer.c
@@ -84,7 +84,7 @@ cogl_pixel_buffer_vtable;
 static const CoglBufferVtable
 cogl_malloc_pixel_buffer_vtable;
 
-COGL_OBJECT_DEFINE (PixelBuffer, pixel_buffer)
+COGL_BUFFER_DEFINE (PixelBuffer, pixel_buffer)
 
 CoglPixelBuffer *
 cogl_pixel_buffer_new (unsigned int size)