[cogl] Allow propogation of OOM errors to apps



commit f7735e141ad537a253b02afa2a8238f96340b978
Author: Robert Bragg <robert linux intel com>
Date:   Thu Nov 8 17:54:10 2012 +0000

    Allow propogation of OOM errors to apps
    
    This allows apps to catch out-of-memory errors when allocating textures.
    
    Textures can be pretty huge at times and so it's quite possible for an
    application to try and allocate more memory than is available. It's also
    very possible that the application can take some action in response to
    reduce memory pressure (such as freeing up texture caches perhaps) so
    we shouldn't just automatically abort like we do for trivial heap
    allocations.
    
    These public functions now take a CoglError argument so applications can
    catch out of memory errors:
    
    cogl_buffer_map
    cogl_buffer_map_range
    cogl_buffer_set_data
    cogl_framebuffer_read_pixels_into_bitmap
    cogl_pixel_buffer_new
    cogl_texture_new_from_data
    cogl_texture_new_from_bitmap
    
    Note: we've been quite conservative with how many apis we let throw OOM
    CoglErrors since we don't really want to put a burdon on developers to
    be checking for errors with every cogl api call. So long as there is
    some lower level api for apps to use that let them catch OOM errors
    for everything necessary that's enough and we don't have to make more
    convenient apis more awkward to use.
    
    The main focus is on bitmaps and texture allocations since they
    can be particularly large and prone to failing.
    
    A new cogl_attribute_buffer_new_with_size() function has been added in
    case developers need to catch OOM errors when allocating attribute buffers
    whereby they can first use _buffer_new_with_size() (which doesn't take a
    CoglError) followed by cogl_buffer_set_data() which will lazily allocate
    the buffer storage and report OOM errors.
    
    Reviewed-by: Neil Roberts <neil linux intel com>

 cogl-pango/cogl-pango-display-list.c           |   13 +-
 cogl-pango/cogl-pango-render.c                 |    3 +-
 cogl/cogl-atlas-texture-private.h              |    5 +-
 cogl/cogl-atlas-texture.c                      |  104 +++++---
 cogl/cogl-attribute-buffer.c                   |   45 +++-
 cogl/cogl-attribute-buffer.h                   |   49 +++-
 cogl/cogl-bitmap-conversion.c                  |   34 ++-
 cogl/cogl-bitmap-private.h                     |   39 ++-
 cogl/cogl-bitmap.c                             |  107 +++++---
 cogl/cogl-blit.c                               |    5 +-
 cogl/cogl-buffer-private.h                     |   12 +-
 cogl/cogl-buffer.c                             |   79 ++++--
 cogl/cogl-buffer.h                             |   36 +++-
 cogl/cogl-driver.h                             |   14 +-
 cogl/cogl-error-private.h                      |    4 +
 cogl/cogl-error.c                              |   13 +-
 cogl/cogl-framebuffer.c                        |  191 ++++++++-----
 cogl/cogl-framebuffer.h                        |    4 +-
 cogl/cogl-indices.c                            |   10 +-
 cogl/cogl-journal.c                            |   21 +-
 cogl/cogl-path.c                               |    6 +-
 cogl/cogl-pixel-buffer.c                       |   18 +-
 cogl/cogl-pixel-buffer.h                       |    4 +-
 cogl/cogl-sub-texture.c                        |   20 +-
 cogl/cogl-texture-2d-sliced-private.h          |    5 +-
 cogl/cogl-texture-2d-sliced.c                  |  245 +++++++++++-------
 cogl/cogl-texture-2d.c                         |   37 ++--
 cogl/cogl-texture-3d.c                         |   90 ++++---
 cogl/cogl-texture-driver.h                     |   15 +-
 cogl/cogl-texture-private.h                    |   46 ++--
 cogl/cogl-texture-rectangle.c                  |  103 +++++---
 cogl/cogl-texture.c                            |  339 +++++++++++++++---------
 cogl/cogl-texture.h                            |   28 ++-
 cogl/cogl.symbols                              |    1 -
 cogl/driver/gl/cogl-attribute-gl.c             |   12 +-
 cogl/driver/gl/cogl-buffer-gl-private.h        |   10 +-
 cogl/driver/gl/cogl-buffer-gl.c                |  154 ++++++++---
 cogl/driver/gl/cogl-framebuffer-gl.c           |    9 +-
 cogl/driver/gl/cogl-texture-2d-gl-private.h    |    5 +-
 cogl/driver/gl/cogl-texture-2d-gl.c            |  132 ++++++----
 cogl/driver/gl/gl/cogl-texture-driver-gl.c     |  166 ++++++++----
 cogl/driver/gl/gles/cogl-texture-driver-gles.c |  289 ++++++++++++++-------
 cogl/driver/nop/cogl-texture-2d-nop-private.h  |    5 +-
 cogl/driver/nop/cogl-texture-2d-nop.c          |    6 +-
 cogl/winsys/cogl-texture-pixmap-x11.c          |   25 ++-
 doc/reference/cogl2/cogl2-sections.txt         |    1 +
 tests/conform/test-alpha-textures.c            |    3 +-
 tests/conform/test-atlas-migration.c           |    6 +-
 tests/conform/test-backface-culling.c          |    6 +-
 tests/conform/test-blend-strings.c             |    6 +-
 tests/conform/test-just-vertex-shader.c        |    6 +-
 tests/conform/test-map-buffer-range.c          |    3 +-
 tests/conform/test-npot-texture.c              |    6 +-
 tests/conform/test-pixel-buffer.c              |    8 +-
 tests/conform/test-premult.c                   |    3 +-
 tests/conform/test-primitive.c                 |    8 +-
 tests/conform/test-snippets.c                  |    6 +-
 tests/conform/test-sub-texture.c               |    3 +-
 tests/conform/test-wrap-modes.c                |    6 +-
 tests/conform/test-write-texture-formats.c     |   12 +-
 60 files changed, 1727 insertions(+), 914 deletions(-)
---
diff --git a/cogl-pango/cogl-pango-display-list.c b/cogl-pango/cogl-pango-display-list.c
index 5a751a0..1be3f44 100644
--- a/cogl-pango/cogl-pango-display-list.c
+++ b/cogl-pango/cogl-pango-display-list.c
@@ -272,17 +272,21 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb,
       CoglAttribute *attributes[2];
       CoglPrimitive *prim;
       int i;
+      CoglError *ignore_error = NULL;
 
       n_verts = node->d.texture.rectangles->len * 4;
 
       buffer
-        = cogl_attribute_buffer_new (ctx,
-                                     n_verts * sizeof (CoglVertexP2T2), NULL);
+        = cogl_attribute_buffer_new_with_size (ctx,
+                                               n_verts *
+                                               sizeof (CoglVertexP2T2));
 
       if ((verts = cogl_buffer_map (COGL_BUFFER (buffer),
                                     COGL_BUFFER_ACCESS_WRITE,
-                                    COGL_BUFFER_MAP_HINT_DISCARD)) == NULL)
+                                    COGL_BUFFER_MAP_HINT_DISCARD,
+                                    &ignore_error)) == NULL)
         {
+          cogl_error_free (ignore_error);
           verts = g_new (CoglVertexP2T2, n_verts);
           allocated = TRUE;
         }
@@ -324,7 +328,8 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb,
           cogl_buffer_set_data (COGL_BUFFER (buffer),
                                 0, /* offset */
                                 verts,
-                                sizeof (CoglVertexP2T2) * n_verts);
+                                sizeof (CoglVertexP2T2) * n_verts,
+                                NULL);
           g_free (verts);
         }
       else
diff --git a/cogl-pango/cogl-pango-render.c b/cogl-pango/cogl-pango-render.c
index b667a72..6524786 100644
--- a/cogl-pango/cogl-pango-render.c
+++ b/cogl-pango/cogl-pango-render.c
@@ -580,7 +580,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
                            value->draw_height, /* height */
                            format_cogl,
                            cairo_image_surface_get_stride (surface),
-                           cairo_image_surface_get_data (surface));
+                           cairo_image_surface_get_data (surface),
+                           NULL); /* don't catch errors */
 
   cairo_surface_destroy (surface);
 }
diff --git a/cogl/cogl-atlas-texture-private.h b/cogl/cogl-atlas-texture-private.h
index 451bd83..7a70f54 100644
--- a/cogl/cogl-atlas-texture-private.h
+++ b/cogl/cogl-atlas-texture-private.h
@@ -58,9 +58,10 @@ struct _CoglAtlasTexture
 };
 
 CoglAtlasTexture *
-_cogl_atlas_texture_new_from_bitmap (CoglBitmap      *bmp,
+_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
                                      CoglTextureFlags flags,
-                                     CoglPixelFormat  internal_format);
+                                     CoglPixelFormat internal_format,
+                                     CoglError **error);
 
 CoglAtlasTexture *
 _cogl_atlas_texture_new_with_size (unsigned int     width,
diff --git a/cogl/cogl-atlas-texture.c b/cogl/cogl-atlas-texture.c
index 81a89f2..1403c64 100644
--- a/cogl/cogl-atlas-texture.c
+++ b/cogl/cogl-atlas-texture.c
@@ -44,6 +44,7 @@
 #include "cogl-atlas.h"
 #include "cogl1-context.h"
 #include "cogl-sub-texture.h"
+#include "cogl-error-private.h"
 
 #include <stdlib.h>
 
@@ -433,13 +434,14 @@ _cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex)
 
 static CoglBool
 _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
-                                            int             src_x,
-                                            int             src_y,
-                                            int             dst_x,
-                                            int             dst_y,
-                                            unsigned int    dst_width,
-                                            unsigned int    dst_height,
-                                            CoglBitmap     *bmp)
+                                            int src_x,
+                                            int src_y,
+                                            int dst_x,
+                                            int dst_y,
+                                            int dst_width,
+                                            int dst_height,
+                                            CoglBitmap *bmp,
+                                            CoglError **error)
 {
   CoglAtlas *atlas = atlas_tex->atlas;
 
@@ -450,7 +452,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
                                             dst_y + atlas_tex->rectangle.y + 1,
                                             dst_width,
                                             dst_height,
-                                            bmp))
+                                            bmp,
+                                            error))
     return FALSE;
 
   /* Update the left edge pixels */
@@ -460,7 +463,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
                                             atlas_tex->rectangle.x,
                                             dst_y + atlas_tex->rectangle.y + 1,
                                             1, dst_height,
-                                            bmp))
+                                            bmp,
+                                            error))
     return FALSE;
   /* Update the right edge pixels */
   if (dst_x + dst_width == atlas_tex->rectangle.width - 2 &&
@@ -470,7 +474,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
                                             atlas_tex->rectangle.width - 1,
                                             dst_y + atlas_tex->rectangle.y + 1,
                                             1, dst_height,
-                                            bmp))
+                                            bmp,
+                                            error))
     return FALSE;
   /* Update the top edge pixels */
   if (dst_y == 0 &&
@@ -479,7 +484,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
                                             dst_x + atlas_tex->rectangle.x + 1,
                                             atlas_tex->rectangle.y,
                                             dst_width, 1,
-                                            bmp))
+                                            bmp,
+                                            error))
     return FALSE;
   /* Update the bottom edge pixels */
   if (dst_y + dst_height == atlas_tex->rectangle.height - 2 &&
@@ -489,7 +495,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
                                             atlas_tex->rectangle.y +
                                             atlas_tex->rectangle.height - 1,
                                             dst_width, 1,
-                                            bmp))
+                                            bmp,
+                                            error))
     return FALSE;
 
   return TRUE;
@@ -497,7 +504,8 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex,
 
 static CoglBitmap *
 _cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
-                                        CoglBitmap *bmp)
+                                        CoglBitmap *bmp,
+                                        CoglError **error)
 {
   CoglPixelFormat internal_format;
   CoglBitmap *converted_bmp;
@@ -519,7 +527,8 @@ _cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
                                                     NULL, /* dst_format_out */
                                                     NULL, /* glintformat */
                                                     NULL, /* glformat */
-                                                    NULL /* gltype */);
+                                                    NULL, /* gltype */
+                                                    error);
 
   if (converted_bmp == NULL)
     return NULL;
@@ -542,14 +551,15 @@ _cogl_atlas_texture_prepare_for_upload (CoglAtlasTexture *atlas_tex,
 }
 
 static CoglBool
-_cogl_atlas_texture_set_region (CoglTexture    *tex,
-                                int             src_x,
-                                int             src_y,
-                                int             dst_x,
-                                int             dst_y,
-                                unsigned int    dst_width,
-                                unsigned int    dst_height,
-                                CoglBitmap     *bmp)
+_cogl_atlas_texture_set_region (CoglTexture *tex,
+                                int src_x,
+                                int src_y,
+                                int dst_x,
+                                int dst_y,
+                                int dst_width,
+                                int dst_height,
+                                CoglBitmap *bmp,
+                                CoglError **error)
 {
   CoglAtlasTexture  *atlas_tex = COGL_ATLAS_TEXTURE (tex);
 
@@ -560,14 +570,18 @@ _cogl_atlas_texture_set_region (CoglTexture    *tex,
       CoglBool ret;
 
       bmp = _cogl_atlas_texture_prepare_for_upload (atlas_tex,
-                                                    bmp);
+                                                    bmp,
+                                                    error);
+      if (!bmp)
+        return FALSE;
 
       /* Upload the data ignoring the premult bit */
       ret = _cogl_atlas_texture_set_region_with_border (atlas_tex,
                                                         src_x, src_y,
                                                         dst_x, dst_y,
                                                         dst_width, dst_height,
-                                                        bmp);
+                                                        bmp,
+                                                        error);
 
       cogl_object_unref (bmp);
 
@@ -579,7 +593,8 @@ _cogl_atlas_texture_set_region (CoglTexture    *tex,
                                                 src_x, src_y,
                                                 dst_x, dst_y,
                                                 dst_width, dst_height,
-                                                bmp);
+                                                bmp,
+                                                error);
 }
 
 static CoglPixelFormat
@@ -727,9 +742,10 @@ _cogl_atlas_texture_new_with_size (unsigned int width,
 }
 
 CoglAtlasTexture *
-_cogl_atlas_texture_new_from_bitmap (CoglBitmap      *bmp,
+_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
                                      CoglTextureFlags flags,
-                                     CoglPixelFormat  internal_format)
+                                     CoglPixelFormat internal_format,
+                                     CoglError **error)
 {
   CoglAtlasTexture *atlas_tex;
   CoglBitmap *dst_bmp;
@@ -750,11 +766,17 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap      *bmp,
                                                  flags, internal_format);
 
   if (atlas_tex == NULL)
-    return NULL;
+    {
+      _cogl_set_error (error,
+                       COGL_SYSTEM_ERROR,
+                       COGL_SYSTEM_ERROR_UNSUPPORTED,
+                       "Texture type not compatible with atlas");
+      return NULL;
+    }
 
   dst_bmp = _cogl_atlas_texture_prepare_for_upload (atlas_tex,
-                                                    bmp);
-
+                                                    bmp,
+                                                    error);
   if (dst_bmp == NULL)
     {
       cogl_object_unref (atlas_tex);
@@ -763,14 +785,20 @@ _cogl_atlas_texture_new_from_bitmap (CoglBitmap      *bmp,
 
   /* Defer to set_region so that we can share the code for copying the
      edge pixels to the border. */
-  _cogl_atlas_texture_set_region_with_border (atlas_tex,
-                                              0, /* src_x */
-                                              0, /* src_y */
-                                              0, /* dst_x */
-                                              0, /* dst_y */
-                                              bmp_width, /* dst_width */
-                                              bmp_height, /* dst_height */
-                                              dst_bmp);
+  if (!_cogl_atlas_texture_set_region_with_border (atlas_tex,
+                                                   0, /* src_x */
+                                                   0, /* src_y */
+                                                   0, /* dst_x */
+                                                   0, /* dst_y */
+                                                   bmp_width, /* dst_width */
+                                                   bmp_height, /* dst_height */
+                                                   dst_bmp,
+                                                   error))
+    {
+      cogl_object_unref (dst_bmp);
+      cogl_object_unref (atlas_tex);
+      return NULL;
+    }
 
   cogl_object_unref (dst_bmp);
 
diff --git a/cogl/cogl-attribute-buffer.c b/cogl/cogl-attribute-buffer.c
index a122e96..4abdeaf 100644
--- a/cogl/cogl-attribute-buffer.c
+++ b/cogl/cogl-attribute-buffer.c
@@ -39,28 +39,49 @@ static void _cogl_attribute_buffer_free (CoglAttributeBuffer *array);
 COGL_BUFFER_DEFINE (AttributeBuffer, attribute_buffer);
 
 CoglAttributeBuffer *
-cogl_attribute_buffer_new (CoglContext *context,
-                           size_t bytes,
-                           const void *data)
+cogl_attribute_buffer_new_with_size (CoglContext *context,
+                                     size_t bytes)
 {
-  CoglAttributeBuffer *array = g_slice_new (CoglAttributeBuffer);
+  CoglAttributeBuffer *buffer = g_slice_new (CoglAttributeBuffer);
 
   /* parent's constructor */
-  _cogl_buffer_initialize (COGL_BUFFER (array),
+  _cogl_buffer_initialize (COGL_BUFFER (buffer),
                            context,
                            bytes,
                            COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER,
                            COGL_BUFFER_USAGE_HINT_ATTRIBUTE_BUFFER,
                            COGL_BUFFER_UPDATE_HINT_STATIC);
 
-  _cogl_attribute_buffer_object_new (array);
+  return _cogl_attribute_buffer_object_new (buffer);
+}
+
+CoglAttributeBuffer *
+cogl_attribute_buffer_new (CoglContext *context,
+                           size_t bytes,
+                           const void *data)
+{
+  CoglAttributeBuffer *buffer;
+
+  _COGL_RETURN_VAL_IF_FAIL (data, NULL);
+
+  buffer = cogl_attribute_buffer_new_with_size (context, bytes);
+
+  /* Note: to keep the common cases simple this API doesn't throw
+   * CoglErrors, so developers can assume this function never returns
+   * NULL and we will simply abort on error.
+   *
+   * Developers wanting to catch errors can use
+   * cogl_attribute_buffer_new_with_size() and catch errors when later
+   * calling cogl_buffer_set_data() or cogl_buffer_map().
+   */
+
+  cogl_buffer_set_data (COGL_BUFFER (buffer),
+                        0,
+                        data,
+                        bytes,
+                        NULL);
 
-  if (data)
-    cogl_buffer_set_data (COGL_BUFFER (array),
-                          0,
-                          data,
-                          bytes);
-  return array;
+  return buffer;
 }
 
 static void
diff --git a/cogl/cogl-attribute-buffer.h b/cogl/cogl-attribute-buffer.h
index 7b593e5..3150e07 100644
--- a/cogl/cogl-attribute-buffer.h
+++ b/cogl/cogl-attribute-buffer.h
@@ -51,17 +51,56 @@ COGL_BEGIN_DECLS
 #define COGL_ATTRIBUTE_BUFFER(buffer) ((CoglAttributeBuffer *)(buffer))
 
 /**
+ * cogl_attribute_buffer_new_with_size:
+ * @context: A #CoglContext
+ * @bytes: The number of bytes to allocate for vertex attribute data.
+ *
+ * Describes a new #CoglAttributeBuffer of @size bytes to contain
+ * arrays of vertex attribute data. Afterwards data can be set using
+ * cogl_buffer_set_data() or by mapping it into the application's
+ * address space using cogl_buffer_map().
+ *
+ * The underlying storage of this buffer isn't allocated by this
+ * function so that you have an opportunity to use the
+ * cogl_buffer_set_update_hint() and cogl_buffer_set_usage_hint()
+ * functions which may influence how the storage is allocated. The
+ * storage will be allocated once you upload data to the buffer.
+ *
+ * Note: You can assume this function always succeeds and won't return
+ * %NULL
+ *
+ * Return value: A newly allocated #CoglAttributeBuffer. Never %NULL.
+ *
+ * Stability: Unstable
+ */
+CoglAttributeBuffer *
+cogl_attribute_buffer_new_with_size (CoglContext *context,
+                                     size_t bytes);
+
+/**
  * cogl_attribute_buffer_new:
  * @context: A #CoglContext
  * @bytes: The number of bytes to allocate for vertex attribute data.
  * @data: An optional pointer to vertex data to upload immediately.
  *
- * Declares a new #CoglAttributeBuffer of @size bytes to contain arrays of vertex
- * attribute data. Once declared, data can be set using cogl_buffer_set_data()
- * or by mapping it into the application's address space using cogl_buffer_map().
+ * Describes a new #CoglAttributeBuffer of @size bytes to contain
+ * arrays of vertex attribute data and also uploads @size bytes read
+ * from @data to the new buffer.
+ *
+ * You should never pass a %NULL data pointer.
+ *
+ * <note>This function does not report out-of-memory errors back to
+ * the caller by returning %NULL and so you can assume this function
+ * always succeeds.</note>
+ *
+ * <note>In the unlikely case that there is an out of memory problem
+ * then Cogl will abort the application with a message. If your
+ * application needs to gracefully handle out-of-memory errors then
+ * you can use cogl_attribute_buffer_new_with_size() and then
+ * explicitly catch errors with cogl_buffer_set_data() or
+ * cogl_buffer_map().</note>
  *
- * If @data isn't %NULL then @size bytes will be read from @data and
- * immediately copied into the new buffer.
+ * Return value: A newly allocated #CoglAttributeBuffer (never %NULL)
  *
  * Since: 1.4
  * Stability: Unstable
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 77e415e..3ce8c71 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -347,7 +347,8 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
 
 CoglBool
 _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
-                                  CoglBitmap *dst_bmp)
+                                  CoglBitmap *dst_bmp,
+                                  CoglError **error)
 {
   uint8_t *src_data;
   uint8_t *dst_data;
@@ -387,19 +388,20 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
       if (!_cogl_bitmap_copy_subregion (src_bmp, dst_bmp,
                                         0, 0, /* src_x / src_y */
                                         0, 0, /* dst_x / dst_y */
-                                        width, height))
+                                        width, height,
+                                        error))
         return FALSE;
 
       if (need_premult)
         {
           if ((dst_format & COGL_PREMULT_BIT))
             {
-              if (!_cogl_bitmap_premult (dst_bmp))
+              if (!_cogl_bitmap_premult (dst_bmp, error))
                 return FALSE;
             }
           else
             {
-              if (!_cogl_bitmap_unpremult (dst_bmp))
+              if (!_cogl_bitmap_unpremult (dst_bmp, error))
                 return FALSE;
             }
         }
@@ -407,12 +409,13 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
       return TRUE;
     }
 
-  src_data = _cogl_bitmap_map (src_bmp, COGL_BUFFER_ACCESS_READ, 0);
+  src_data = _cogl_bitmap_map (src_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
   if (src_data == NULL)
     return FALSE;
   dst_data = _cogl_bitmap_map (dst_bmp,
                                COGL_BUFFER_ACCESS_WRITE,
-                               COGL_BUFFER_MAP_HINT_DISCARD);
+                               COGL_BUFFER_MAP_HINT_DISCARD,
+                               error);
   if (dst_data == NULL)
     {
       _cogl_bitmap_unmap (src_bmp);
@@ -471,7 +474,8 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
 
 CoglBitmap *
 _cogl_bitmap_convert (CoglBitmap *src_bmp,
-                      CoglPixelFormat dst_format)
+                      CoglPixelFormat dst_format,
+                      CoglError **error)
 {
   CoglBitmap *dst_bmp;
   int width, height;
@@ -485,7 +489,7 @@ _cogl_bitmap_convert (CoglBitmap *src_bmp,
                                                  width, height,
                                                  dst_format);
 
-  if (!_cogl_bitmap_convert_into_bitmap (src_bmp, dst_bmp))
+  if (!_cogl_bitmap_convert_into_bitmap (src_bmp, dst_bmp, error))
     {
       cogl_object_unref (dst_bmp);
       return NULL;
@@ -495,7 +499,8 @@ _cogl_bitmap_convert (CoglBitmap *src_bmp,
 }
 
 CoglBool
-_cogl_bitmap_unpremult (CoglBitmap *bmp)
+_cogl_bitmap_unpremult (CoglBitmap *bmp,
+                        CoglError **error)
 {
   uint8_t *p, *data;
   uint16_t *tmp_row;
@@ -512,12 +517,13 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp)
   if ((data = _cogl_bitmap_map (bmp,
                                 COGL_BUFFER_ACCESS_READ |
                                 COGL_BUFFER_ACCESS_WRITE,
-                                0)) == NULL)
+                                0,
+                                error)) == NULL)
     return FALSE;
 
   /* If we can't directly unpremult the data inline then we'll
      allocate a temporary row and unpack the data. This assumes if we
-     can fast premult then we can also fast unpremult */
+      can fast premult then we can also fast unpremult */
   if (_cogl_bitmap_can_fast_premult (format))
     tmp_row = NULL;
   else
@@ -561,7 +567,8 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp)
 }
 
 CoglBool
-_cogl_bitmap_premult (CoglBitmap *bmp)
+_cogl_bitmap_premult (CoglBitmap *bmp,
+                      CoglError **error)
 {
   uint8_t *p, *data;
   uint16_t *tmp_row;
@@ -578,7 +585,8 @@ _cogl_bitmap_premult (CoglBitmap *bmp)
   if ((data = _cogl_bitmap_map (bmp,
                                 COGL_BUFFER_ACCESS_READ |
                                 COGL_BUFFER_ACCESS_WRITE,
-                                0)) == NULL)
+                                0,
+                                error)) == NULL)
     return FALSE;
 
   /* If we can't directly premult the data inline then we'll allocate
diff --git a/cogl/cogl-bitmap-private.h b/cogl/cogl-bitmap-private.h
index 6610460..ac1fd4b 100644
--- a/cogl/cogl-bitmap-private.h
+++ b/cogl/cogl-bitmap-private.h
@@ -100,11 +100,13 @@ _cogl_bitmap_new_shared (CoglBitmap      *shared_bmp,
 
 CoglBitmap *
 _cogl_bitmap_convert (CoglBitmap *bmp,
-		      CoglPixelFormat   dst_format);
+		      CoglPixelFormat dst_format,
+                      CoglError **error);
 
 CoglBool
 _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
-                                  CoglBitmap *dst_bmp);
+                                  CoglBitmap *dst_bmp,
+                                  CoglError **error);
 
 CoglBitmap *
 _cogl_bitmap_from_file (CoglContext *ctx,
@@ -120,28 +122,33 @@ _cogl_android_bitmap_new_from_asset (CoglContext *ctx,
 #endif
 
 CoglBool
-_cogl_bitmap_unpremult (CoglBitmap *dst_bmp);
+_cogl_bitmap_unpremult (CoglBitmap *dst_bmp,
+                        CoglError **error);
 
 CoglBool
-_cogl_bitmap_premult (CoglBitmap *dst_bmp);
+_cogl_bitmap_premult (CoglBitmap *dst_bmp,
+                      CoglError **error);
 
 CoglBool
-_cogl_bitmap_convert_premult_status (CoglBitmap      *bmp,
-                                     CoglPixelFormat  dst_format);
+_cogl_bitmap_convert_premult_status (CoglBitmap *bmp,
+                                     CoglPixelFormat dst_format,
+                                     CoglError **error);
 
 CoglBool
 _cogl_bitmap_copy_subregion (CoglBitmap *src,
 			     CoglBitmap *dst,
-			     int         src_x,
-			     int         src_y,
-			     int         dst_x,
-			     int         dst_y,
-			     int         width,
-			     int         height);
+			     int src_x,
+			     int src_y,
+			     int dst_x,
+			     int dst_y,
+			     int width,
+			     int height,
+                             CoglError **error);
 
 /* Creates a deep copy of the source bitmap */
 CoglBitmap *
-_cogl_bitmap_copy (CoglBitmap *src_bmp);
+_cogl_bitmap_copy (CoglBitmap *src_bmp,
+                   CoglError **error);
 
 CoglBool
 _cogl_bitmap_get_size_from_file (const char *filename,
@@ -163,7 +170,8 @@ _cogl_bitmap_set_format (CoglBitmap *bitmap,
 uint8_t *
 _cogl_bitmap_map (CoglBitmap *bitmap,
                   CoglBufferAccess access,
-                  CoglBufferMapHint hints);
+                  CoglBufferMapHint hints,
+                  CoglError **error);
 
 void
 _cogl_bitmap_unmap (CoglBitmap *bitmap);
@@ -180,7 +188,8 @@ _cogl_bitmap_unmap (CoglBitmap *bitmap);
 uint8_t *
 _cogl_bitmap_gl_bind (CoglBitmap *bitmap,
                       CoglBufferAccess access,
-                      CoglBufferMapHint hints);
+                      CoglBufferMapHint hints,
+                      CoglError **error);
 
 void
 _cogl_bitmap_gl_unbind (CoglBitmap *bitmap);
diff --git a/cogl/cogl-bitmap.c b/cogl/cogl-bitmap.c
index 95267fa..0e2c394 100644
--- a/cogl/cogl-bitmap.c
+++ b/cogl/cogl-bitmap.c
@@ -33,6 +33,7 @@
 #include "cogl-pixel-buffer.h"
 #include "cogl-context-private.h"
 #include "cogl-buffer-gl-private.h"
+#include "cogl-error-private.h"
 
 #include <string.h>
 
@@ -56,27 +57,29 @@ _cogl_bitmap_free (CoglBitmap *bmp)
 }
 
 CoglBool
-_cogl_bitmap_convert_premult_status (CoglBitmap      *bmp,
-                                     CoglPixelFormat  dst_format)
+_cogl_bitmap_convert_premult_status (CoglBitmap *bmp,
+                                     CoglPixelFormat dst_format,
+                                     CoglError **error)
 {
   /* Do we need to unpremultiply? */
   if ((bmp->format & COGL_PREMULT_BIT) > 0 &&
       (dst_format & COGL_PREMULT_BIT) == 0 &&
       COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (dst_format))
-    return _cogl_bitmap_unpremult (bmp);
+    return _cogl_bitmap_unpremult (bmp, error);
 
   /* Do we need to premultiply? */
   if ((bmp->format & COGL_PREMULT_BIT) == 0 &&
       COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (bmp->format) &&
       (dst_format & COGL_PREMULT_BIT) > 0)
     /* Try premultiplying using imaging library */
-    return _cogl_bitmap_premult (bmp);
+    return _cogl_bitmap_premult (bmp, error);
 
   return TRUE;
 }
 
 CoglBitmap *
-_cogl_bitmap_copy (CoglBitmap *src_bmp)
+_cogl_bitmap_copy (CoglBitmap *src_bmp,
+                   CoglError **error)
 {
   CoglBitmap *dst_bmp;
   CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
@@ -88,11 +91,16 @@ _cogl_bitmap_copy (CoglBitmap *src_bmp)
                                          width, height,
                                          src_format);
 
-  _cogl_bitmap_copy_subregion (src_bmp,
-                               dst_bmp,
-                               0, 0, /* src_x/y */
-                               0, 0, /* dst_x/y */
-                               width, height);
+  if (!_cogl_bitmap_copy_subregion (src_bmp,
+                                    dst_bmp,
+                                    0, 0, /* src_x/y */
+                                    0, 0, /* dst_x/y */
+                                    width, height,
+                                    error))
+    {
+      cogl_object_unref (dst_bmp);
+      return NULL;
+    }
 
   return dst_bmp;
 }
@@ -100,12 +108,13 @@ _cogl_bitmap_copy (CoglBitmap *src_bmp)
 CoglBool
 _cogl_bitmap_copy_subregion (CoglBitmap *src,
 			     CoglBitmap *dst,
-			     int         src_x,
-			     int         src_y,
-			     int         dst_x,
-			     int         dst_y,
-			     int         width,
-			     int         height)
+			     int src_x,
+			     int src_y,
+			     int dst_x,
+			     int dst_y,
+			     int width,
+			     int height,
+                             CoglError **error)
 {
   uint8_t *srcdata;
   uint8_t *dstdata;
@@ -114,19 +123,21 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
   CoglBool succeeded = FALSE;
 
   /* Intended only for fast copies when format is equal! */
-  g_assert ((src->format & ~COGL_PREMULT_BIT) ==
-            (dst->format & ~COGL_PREMULT_BIT));
+  _COGL_RETURN_VAL_IF_FAIL ((src->format & ~COGL_PREMULT_BIT) ==
+                            (dst->format & ~COGL_PREMULT_BIT),
+                            FALSE);
 
   bpp = _cogl_pixel_format_get_bytes_per_pixel (src->format);
 
-  if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0)))
+  if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error)))
     {
-      if ((dstdata = _cogl_bitmap_map (dst, COGL_BUFFER_ACCESS_WRITE, 0)))
+      if ((dstdata =
+           _cogl_bitmap_map (dst, COGL_BUFFER_ACCESS_WRITE, 0, error)))
         {
           srcdata += src_y * src->rowstride + src_x * bpp;
           dstdata += dst_y * dst->rowstride + dst_x * bpp;
 
-          for (line=0; line<height; ++line)
+          for (line = 0; line < height; ++line)
             {
               memcpy (dstdata, srcdata, width * bpp);
               srcdata += src->rowstride;
@@ -270,17 +281,19 @@ cogl_bitmap_new_with_size (CoglContext *context,
   unsigned int rowstride;
 
   /* creating a buffer to store "any" format does not make sense */
-  if (G_UNLIKELY (format == COGL_PIXEL_FORMAT_ANY))
-    return NULL;
+  _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
 
   /* for now we fallback to cogl_pixel_buffer_new, later, we could ask
    * libdrm a tiled buffer for instance */
   rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
 
-  pixel_buffer = cogl_pixel_buffer_new (context, height * rowstride, NULL);
+  pixel_buffer =
+    cogl_pixel_buffer_new (context,
+                           height * rowstride,
+                           NULL, /* data */
+                           NULL); /* don't catch errors */
 
-  if (G_UNLIKELY (pixel_buffer == NULL))
-    return NULL;
+  _COGL_RETURN_VAL_IF_FAIL (pixel_buffer != NULL, NULL);
 
   bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer),
                                         format,
@@ -358,19 +371,21 @@ cogl_bitmap_error_domain (void)
 uint8_t *
 _cogl_bitmap_map (CoglBitmap *bitmap,
                   CoglBufferAccess access,
-                  CoglBufferMapHint hints)
+                  CoglBufferMapHint hints,
+                  CoglError **error)
 {
   /* Divert to another bitmap if this data is shared */
   if (bitmap->shared_bmp)
-    return _cogl_bitmap_map (bitmap->shared_bmp, access, hints);
+    return _cogl_bitmap_map (bitmap->shared_bmp, access, hints, error);
 
   g_assert (!bitmap->mapped);
 
   if (bitmap->buffer)
     {
       uint8_t *data = cogl_buffer_map (bitmap->buffer,
-                                      access,
-                                      hints);
+                                       access,
+                                       hints,
+                                       error);
 
       COGL_NOTE (BITMAP, "A pixel array is being mapped from a bitmap. This "
                  "usually means that some conversion on the pixel array is "
@@ -413,21 +428,23 @@ _cogl_bitmap_unmap (CoglBitmap *bitmap)
 uint8_t *
 _cogl_bitmap_gl_bind (CoglBitmap *bitmap,
                       CoglBufferAccess access,
-                      CoglBufferMapHint hints)
+                      CoglBufferMapHint hints,
+                      CoglError **error)
 {
   uint8_t *ptr;
+  CoglError *internal_error = NULL;
 
   /* Divert to another bitmap if this data is shared */
   if (bitmap->shared_bmp)
-    return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints);
+    return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error);
 
-  g_assert (!bitmap->bound);
+  _COGL_RETURN_VAL_IF_FAIL (!bitmap->bound, NULL);
 
   /* If the bitmap wasn't created from a buffer then the
      implementation of bind is the same as map */
   if (bitmap->buffer == NULL)
     {
-      uint8_t *data = _cogl_bitmap_map (bitmap, access, hints);
+      uint8_t *data = _cogl_bitmap_map (bitmap, access, hints, error);
       if (data)
         bitmap->bound = TRUE;
       return data;
@@ -437,15 +454,29 @@ _cogl_bitmap_gl_bind (CoglBitmap *bitmap,
 
   if (access == COGL_BUFFER_ACCESS_READ)
     ptr = _cogl_buffer_gl_bind (bitmap->buffer,
-                                COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK);
+                                COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK,
+                                &internal_error);
   else if (access == COGL_BUFFER_ACCESS_WRITE)
     ptr = _cogl_buffer_gl_bind (bitmap->buffer,
-                                COGL_BUFFER_BIND_TARGET_PIXEL_PACK);
+                                COGL_BUFFER_BIND_TARGET_PIXEL_PACK,
+                                &internal_error);
   else
-    g_assert_not_reached ();
+    {
+      ptr = NULL;
+      g_assert_not_reached ();
+    }
+
+  /* NB: _cogl_buffer_gl_bind() may return NULL in non-error
+   * conditions so we have to explicitly check internal_error to see
+   * if an exception was thrown */
+  if (internal_error)
+    {
+      _cogl_propogate_error (error, internal_error);
+      return NULL;
+    }
 
   /* The data pointer actually stores the offset */
-  return GPOINTER_TO_INT (bitmap->data) + ptr;
+  return ptr + GPOINTER_TO_INT (bitmap->data);
 }
 
 void
diff --git a/cogl/cogl-blit.c b/cogl/cogl-blit.c
index 50bdf9a..7c495e4 100644
--- a/cogl/cogl-blit.c
+++ b/cogl/cogl-blit.c
@@ -284,6 +284,7 @@ _cogl_blit_get_tex_data_blit (CoglBlitData *data,
                               unsigned int width,
                               unsigned int height)
 {
+  CoglError *ignore = NULL;
   cogl_texture_set_region (data->dst_tex,
                            src_x, src_y,
                            dst_x, dst_y,
@@ -291,7 +292,9 @@ _cogl_blit_get_tex_data_blit (CoglBlitData *data,
                            data->src_width, data->src_height,
                            data->format,
                            data->src_width * data->bpp,
-                           data->image_data);
+                           data->image_data,
+                           &ignore);
+  /* TODO: support chaining up errors during the blit */
 }
 
 static void
diff --git a/cogl/cogl-buffer-private.h b/cogl/cogl-buffer-private.h
index 07a1490..6c7c986 100644
--- a/cogl/cogl-buffer-private.h
+++ b/cogl/cogl-buffer-private.h
@@ -45,14 +45,16 @@ struct _CoglBufferVtable
                         size_t offset,
                         size_t size,
                         CoglBufferAccess access,
-                        CoglBufferMapHint hints);
+                        CoglBufferMapHint hints,
+                        CoglError **error);
 
   void (* unmap) (CoglBuffer *buffer);
 
-  CoglBool (* set_data) (CoglBuffer   *buffer,
-                         unsigned int  offset,
-                         const void   *data,
-                         unsigned int  size);
+  CoglBool (* set_data) (CoglBuffer *buffer,
+                         unsigned int offset,
+                         const void *data,
+                         unsigned int size,
+                         CoglError **error);
 };
 
 typedef enum _CoglBufferFlags
diff --git a/cogl/cogl-buffer.c b/cogl/cogl-buffer.c
index 72fd3f8..16fddf7 100644
--- a/cogl/cogl-buffer.c
+++ b/cogl/cogl-buffer.c
@@ -83,7 +83,8 @@ malloc_map_range (CoglBuffer *buffer,
                   size_t offset,
                   size_t size,
                   CoglBufferAccess access,
-                  CoglBufferMapHint hints)
+                  CoglBufferMapHint hints,
+                  CoglError **error)
 {
   buffer->flags |= COGL_BUFFER_FLAG_MAPPED;
   return buffer->data + offset;
@@ -96,10 +97,11 @@ malloc_unmap (CoglBuffer *buffer)
 }
 
 static CoglBool
-malloc_set_data (CoglBuffer   *buffer,
-                 unsigned int  offset,
-                 const void   *data,
-                 unsigned int  size)
+malloc_set_data (CoglBuffer *buffer,
+                 unsigned int offset,
+                 const void *data,
+                 unsigned int size,
+                 CoglError **error)
 {
   memcpy (buffer->data + offset, data, size);
   return TRUE;
@@ -214,13 +216,14 @@ warn_about_midscene_changes (void)
 }
 
 void *
-cogl_buffer_map (CoglBuffer        *buffer,
-                 CoglBufferAccess   access,
-                 CoglBufferMapHint  hints)
+cogl_buffer_map (CoglBuffer *buffer,
+                 CoglBufferAccess access,
+                 CoglBufferMapHint hints,
+                 CoglError **error)
 {
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
 
-  return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints);
+  return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, error);
 }
 
 void *
@@ -228,21 +231,21 @@ cogl_buffer_map_range (CoglBuffer *buffer,
                        size_t offset,
                        size_t size,
                        CoglBufferAccess access,
-                       CoglBufferMapHint hints)
+                       CoglBufferMapHint hints,
+                       CoglError **error)
 {
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
+  _COGL_RETURN_VAL_IF_FAIL (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL);
 
   if (G_UNLIKELY (buffer->immutable_ref))
     warn_about_midscene_changes ();
 
-  if (buffer->flags & COGL_BUFFER_FLAG_MAPPED)
-    return buffer->data;
-
   buffer->data = buffer->vtable.map_range (buffer,
                                            offset,
                                            size,
                                            access,
-                                           hints);
+                                           hints,
+                                           error);
 
   return buffer->data;
 }
@@ -272,6 +275,7 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
 {
   CoglContext *ctx = buffer->context;
   void *ret;
+  CoglError *ignore_error = NULL;
 
   _COGL_RETURN_VAL_IF_FAIL (!ctx->buffer_map_fallback_in_use, NULL);
 
@@ -281,23 +285,24 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
                                offset,
                                size,
                                COGL_BUFFER_ACCESS_WRITE,
-                               COGL_BUFFER_MAP_HINT_DISCARD);
+                               COGL_BUFFER_MAP_HINT_DISCARD,
+                               &ignore_error);
 
   if (ret)
     return ret;
-  else
-    {
-      /* If the map fails then we'll use a temporary buffer to fill
-         the data and then upload it using cogl_buffer_set_data when
-         the buffer is unmapped. The temporary buffer is shared to
-         avoid reallocating it every time */
-      g_byte_array_set_size (ctx->buffer_map_fallback_array, size);
-      ctx->buffer_map_fallback_offset = offset;
 
-      buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK;
+  cogl_error_free (ignore_error);
 
-      return ctx->buffer_map_fallback_array->data;
-    }
+  /* If the map fails then we'll use a temporary buffer to fill
+     the data and then upload it using cogl_buffer_set_data when
+     the buffer is unmapped. The temporary buffer is shared to
+     avoid reallocating it every time */
+  g_byte_array_set_size (ctx->buffer_map_fallback_array, size);
+  ctx->buffer_map_fallback_offset = offset;
+
+  buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK;
+
+  return ctx->buffer_map_fallback_array->data;
 }
 
 void
@@ -311,10 +316,25 @@ _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer)
 
   if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK))
     {
+      /* Note: don't try to catch OOM errors here since the use cases
+       * we currently have for this api (the journal and path stroke
+       * tesselator) don't have anything particularly sensible they
+       * can do in response to a failure anyway so it seems better to
+       * simply abort instead.
+       *
+       * If we find this is a problem for real world applications
+       * then in the path tesselation case we could potentially add an
+       * explicit cogl_path_tesselate_stroke() api that can throw an
+       * error for the app to cache. For the journal we could
+       * potentially flush the journal in smaller batches so we use
+       * smaller buffers, though that would probably not help for
+       * deferred renderers.
+       */
       cogl_buffer_set_data (buffer,
                             ctx->buffer_map_fallback_offset,
                             ctx->buffer_map_fallback_array->data,
-                            ctx->buffer_map_fallback_array->len);
+                            ctx->buffer_map_fallback_array->len,
+                            NULL);
       buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK;
     }
   else
@@ -325,7 +345,8 @@ CoglBool
 cogl_buffer_set_data (CoglBuffer *buffer,
                       size_t offset,
                       const void *data,
-                      size_t size)
+                      size_t size,
+                      CoglError **error)
 {
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), FALSE);
   _COGL_RETURN_VAL_IF_FAIL ((offset + size) <= buffer->size, FALSE);
@@ -333,7 +354,7 @@ cogl_buffer_set_data (CoglBuffer *buffer,
   if (G_UNLIKELY (buffer->immutable_ref))
     warn_about_midscene_changes ();
 
-  return buffer->vtable.set_data (buffer, offset, data, size);
+  return buffer->vtable.set_data (buffer, offset, data, size, error);
 }
 
 CoglBuffer *
diff --git a/cogl/cogl-buffer.h b/cogl/cogl-buffer.h
index 54c15af..ed6616b 100644
--- a/cogl/cogl-buffer.h
+++ b/cogl/cogl-buffer.h
@@ -33,6 +33,7 @@
 #define __COGL_BUFFER_H__
 
 #include <cogl/cogl-types.h>
+#include <cogl/cogl-error.h>
 
 COGL_BEGIN_DECLS
 
@@ -62,6 +63,25 @@ COGL_BEGIN_DECLS
 
 typedef struct _CoglBuffer CoglBuffer;
 
+#define COGL_BUFFER_ERROR (_cogl_buffer_error_domain ())
+
+/**
+ * CoglBufferError:
+ * @COGL_BUFFER_ERROR_MAP: A buffer could not be mapped either
+ *    because the feature isn't supported or because a system
+ *    limitation was hit.
+ *
+ * Error enumeration for #CoglBuffer
+ *
+ * Stability: unstable
+ */
+typedef enum { /*< prefix=COGL_BUFFER_ERROR >*/
+  COGL_BUFFER_ERROR_MAP,
+} CoglBufferError;
+
+uint32_t
+_cogl_buffer_error_domain (void);
+
 /**
  * cogl_is_buffer:
  * @object: a buffer object
@@ -185,6 +205,7 @@ typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/
  * @access: how the mapped buffer will be used by the application
  * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how
  *   the data will be modified once mapped.
+ * @error: A #CoglError for catching exceptional errors
  *
  * Maps the buffer into the application address space for direct
  * access. This is equivalent to calling cogl_buffer_map_range() with
@@ -207,9 +228,10 @@ typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/
  * Stability: unstable
  */
 void *
-cogl_buffer_map (CoglBuffer        *buffer,
-                 CoglBufferAccess   access,
-                 CoglBufferMapHint  hints);
+cogl_buffer_map (CoglBuffer *buffer,
+                 CoglBufferAccess access,
+                 CoglBufferMapHint hints,
+                 CoglError **error);
 
 /**
  * cogl_buffer_map_range:
@@ -219,6 +241,7 @@ cogl_buffer_map (CoglBuffer        *buffer,
  * @access: how the mapped buffer will be used by the application
  * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how
  *   the data will be modified once mapped.
+ * @error: A #CoglError for catching exceptional errors
  *
  * Maps a sub-region of the buffer into the application's address space
  * for direct access.
@@ -246,7 +269,8 @@ cogl_buffer_map_range (CoglBuffer *buffer,
                        size_t offset,
                        size_t size,
                        CoglBufferAccess access,
-                       CoglBufferMapHint hints);
+                       CoglBufferMapHint hints,
+                       CoglError **error);
 
 /**
  * cogl_buffer_unmap:
@@ -266,6 +290,7 @@ cogl_buffer_unmap (CoglBuffer *buffer);
  * @offset: destination offset (in bytes) in the buffer
  * @data: a pointer to the data to be copied into the buffer
  * @size: number of bytes to copy
+ * @error: A #CoglError for catching exceptional errors
  *
  * Updates part of the buffer with new data from @data. Where to put this new
  * data is controlled by @offset and @offset + @data should be less than the
@@ -280,7 +305,8 @@ CoglBool
 cogl_buffer_set_data (CoglBuffer *buffer,
                       size_t offset,
                       const void *data,
-                      size_t size);
+                      size_t size,
+                      CoglError **error);
 
 COGL_END_DECLS
 
diff --git a/cogl/cogl-driver.h b/cogl/cogl-driver.h
index 36f4c7a..6bfdcd6 100644
--- a/cogl/cogl-driver.h
+++ b/cogl/cogl-driver.h
@@ -190,8 +190,11 @@ struct _CoglDriverVtable
 
   /* Initialize the specified region of storage of the given texture
    * with the contents of the specified bitmap region
+   *
+   * Since this may need to create the underlying storage first
+   * it may throw a NO_MEMORY error.
    */
-  void
+  CoglBool
   (* texture_2d_copy_from_bitmap) (CoglTexture2D *tex_2d,
                                    CoglBitmap *bitmap,
                                    int dst_x,
@@ -199,7 +202,8 @@ struct _CoglDriverVtable
                                    int src_x,
                                    int src_y,
                                    int width,
-                                   int height);
+                                   int height,
+                                   CoglError **error);
 
   /* Reads back the full contents of the given texture and write it to
    * @data in the given @format and with the given @rowstride.
@@ -244,7 +248,8 @@ struct _CoglDriverVtable
                         size_t offset,
                         size_t size,
                         CoglBufferAccess access,
-                        CoglBufferMapHint hints);
+                        CoglBufferMapHint hints,
+                        CoglError **error);
 
   /* Unmaps a buffer */
   void
@@ -256,7 +261,8 @@ struct _CoglDriverVtable
   (* buffer_set_data) (CoglBuffer *buffer,
                        unsigned int offset,
                        const void *data,
-                       unsigned int size);
+                       unsigned int size,
+                       CoglError **error);
 };
 
 #endif /* __COGL_DRIVER_H */
diff --git a/cogl/cogl-error-private.h b/cogl/cogl-error-private.h
index 85b64f7..8842c5d 100644
--- a/cogl/cogl-error-private.h
+++ b/cogl/cogl-error-private.h
@@ -40,6 +40,10 @@ _cogl_set_error_literal (CoglError **error,
                          const char *message);
 
 void
+_cogl_propogate_error (CoglError **dest,
+                       CoglError *src);
+
+void
 _cogl_propogate_gerror (CoglError **dest,
                         GError *src);
 
diff --git a/cogl/cogl-error.c b/cogl/cogl-error.c
index 969c85c..78ad14c 100644
--- a/cogl/cogl-error.c
+++ b/cogl/cogl-error.c
@@ -99,11 +99,18 @@ _cogl_set_error_literal (CoglError **error,
 }
 
 void
-_cogl_propogate_gerror (CoglError **dest,
-                        GError *src)
+_cogl_propogate_error (CoglError **dest,
+                       CoglError *src)
 {
   _COGL_RETURN_IF_FAIL (src != NULL);
 
   _cogl_set_error_literal (dest, src->domain, src->code, src->message);
-  g_error_free (src);
+  cogl_error_free (src);
+}
+
+void
+_cogl_propogate_gerror (CoglError **dest,
+                        GError *src)
+{
+  _cogl_propogate_error (dest, (CoglError *)src);
 }
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 54b7797..f0a41c0 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -1317,6 +1317,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
       y < framebuffer->clear_clip_y1)
     {
       uint8_t *pixel;
+      CoglError *ignore_error = NULL;
 
       /* we currently only care about cases where the premultiplied or
        * unpremultipled colors are equivalent... */
@@ -1325,9 +1326,13 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
 
       pixel = _cogl_bitmap_map (bitmap,
                                 COGL_BUFFER_ACCESS_WRITE,
-                                COGL_BUFFER_MAP_HINT_DISCARD);
+                                COGL_BUFFER_MAP_HINT_DISCARD,
+                                &ignore_error);
       if (pixel == NULL)
-        return FALSE;
+        {
+          cogl_error_free (ignore_error);
+          return FALSE;
+        }
 
       pixel[0] = framebuffer->clear_color_red * 255.0;
       pixel[1] = framebuffer->clear_color_green * 255.0;
@@ -1347,7 +1352,8 @@ _cogl_framebuffer_slow_read_pixels_workaround (CoglFramebuffer *framebuffer,
                                                int x,
                                                int y,
                                                CoglReadPixelsFlags source,
-                                               CoglBitmap *bitmap)
+                                               CoglBitmap *bitmap,
+                                               CoglError **error)
 {
   CoglContext *ctx;
   CoglPixelFormat format;
@@ -1355,6 +1361,8 @@ _cogl_framebuffer_slow_read_pixels_workaround (CoglFramebuffer *framebuffer,
   int width;
   int height;
   CoglBool res;
+  uint8_t *dst;
+  const uint8_t *src;
 
   _COGL_RETURN_VAL_IF_FAIL (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE);
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_framebuffer (framebuffer), FALSE);
@@ -1366,8 +1374,6 @@ _cogl_framebuffer_slow_read_pixels_workaround (CoglFramebuffer *framebuffer,
   format = cogl_bitmap_get_format (bitmap);
 
   pbo = cogl_bitmap_new_with_size (ctx, width, height, format);
-  if (pbo == NULL)
-    return FALSE;
 
   /* Read into the pbo. We need to disable the flipping because the
      blit fast path in the driver does not work with
@@ -1376,57 +1382,58 @@ _cogl_framebuffer_slow_read_pixels_workaround (CoglFramebuffer *framebuffer,
                                                   x, y,
                                                   source |
                                                   COGL_READ_PIXELS_NO_FLIP,
-                                                  pbo);
-
-  if (res)
+                                                  pbo,
+                                                  error);
+  if (!res)
     {
-      uint8_t *dst;
+      cogl_object_unref (pbo);
+      return FALSE;
+    }
 
-      /* Copy the pixels back into application's buffer */
-      dst = _cogl_bitmap_map (bitmap,
-                              COGL_BUFFER_ACCESS_WRITE,
-                              COGL_BUFFER_MAP_HINT_DISCARD);
+  /* Copy the pixels back into application's buffer */
+  dst = _cogl_bitmap_map (bitmap,
+                          COGL_BUFFER_ACCESS_WRITE,
+                          COGL_BUFFER_MAP_HINT_DISCARD,
+                          error);
+  if (!dst)
+    {
+      cogl_object_unref (pbo);
+      return FALSE;
+    }
 
-      if (dst == NULL)
-        res = FALSE;
-      else
+  src = _cogl_bitmap_map (pbo,
+                          COGL_BUFFER_ACCESS_READ,
+                          0, /* hints */
+                          error);
+  if (src)
+    {
+      int src_rowstride = cogl_bitmap_get_rowstride (pbo);
+      int dst_rowstride = cogl_bitmap_get_rowstride (bitmap);
+      int to_copy =
+        _cogl_pixel_format_get_bytes_per_pixel (format) * width;
+      int y;
+
+      /* If the framebuffer is onscreen we need to flip the
+         data while copying */
+      if (!cogl_is_offscreen (framebuffer))
         {
-          const uint8_t *src;
-
-          src = _cogl_bitmap_map (pbo,
-                                  COGL_BUFFER_ACCESS_READ,
-                                  0 /* hints */);
-          if (src == NULL)
-            res = FALSE;
-          else
-            {
-              int src_rowstride = cogl_bitmap_get_rowstride (pbo);
-              int dst_rowstride = cogl_bitmap_get_rowstride (bitmap);
-              int to_copy =
-                _cogl_pixel_format_get_bytes_per_pixel (format) * width;
-              int y;
-
-              /* If the framebuffer is onscreen we need to flip the
-                 data while copying */
-              if (!cogl_is_offscreen (framebuffer))
-                {
-                  src += src_rowstride * (height - 1);
-                  src_rowstride = -src_rowstride;
-                }
-
-              for (y = 0; y < height; y++)
-                {
-                  memcpy (dst, src, to_copy);
-                  dst += dst_rowstride;
-                  src += src_rowstride;
-                }
-
-              _cogl_bitmap_unmap (pbo);
-            }
+          src += src_rowstride * (height - 1);
+          src_rowstride = -src_rowstride;
+        }
 
-          _cogl_bitmap_unmap (bitmap);
+      for (y = 0; y < height; y++)
+        {
+          memcpy (dst, src, to_copy);
+          dst += dst_rowstride;
+          src += src_rowstride;
         }
+
+      _cogl_bitmap_unmap (pbo);
     }
+  else
+    res = FALSE;
+
+  _cogl_bitmap_unmap (bitmap);
 
   cogl_object_unref (pbo);
 
@@ -1438,7 +1445,8 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
                                           int x,
                                           int y,
                                           CoglReadPixelsFlags source,
-                                          CoglBitmap *bitmap)
+                                          CoglBitmap *bitmap,
+                                          CoglError **error)
 {
   CoglContext *ctx;
   int framebuffer_height;
@@ -1450,11 +1458,13 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
   CoglBool pack_invert_set;
   int width;
   int height;
+  int status = FALSE;
+  CoglError *ignore_error = NULL;
 
   _COGL_RETURN_VAL_IF_FAIL (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE);
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_framebuffer (framebuffer), FALSE);
 
-  if (!cogl_framebuffer_allocate (framebuffer, NULL))
+  if (!cogl_framebuffer_allocate (framebuffer, error))
     return FALSE;
 
   ctx = cogl_framebuffer_get_context (framebuffer);
@@ -1499,10 +1509,17 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       (width > 8 || height > 8) &&
       (format & ~COGL_PREMULT_BIT) == COGL_PIXEL_FORMAT_BGRA_8888 &&
       cogl_bitmap_get_buffer (bitmap) == NULL)
-    return _cogl_framebuffer_slow_read_pixels_workaround (framebuffer,
-                                                          x, y,
-                                                          source,
-                                                          bitmap);
+    {
+
+      if (_cogl_framebuffer_slow_read_pixels_workaround (framebuffer,
+                                                         x, y,
+                                                         source,
+                                                         bitmap,
+                                                         &ignore_error))
+        return TRUE;
+      else
+        cogl_error_free (ignore_error);
+    }
 
   /* make sure any batched primitives get emitted to the GL driver
    * before issuing our read pixels...
@@ -1562,7 +1579,7 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       CoglPixelFormat read_format;
       int bpp, rowstride;
       uint8_t *tmp_data;
-      int succeeded;
+      CoglBool succeeded;
 
       if ((ctx->private_feature_flags &
            COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT))
@@ -1589,9 +1606,13 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
                                                         width,
                                                         bpp);
 
+      /* Note: we don't worry about catching errors here since we know
+       * we won't be lazily allocating storage for this buffer so it
+       * won't fail due to lack of memory. */
       tmp_data = _cogl_bitmap_gl_bind (tmp_bmp,
                                        COGL_BUFFER_ACCESS_WRITE,
-                                       COGL_BUFFER_MAP_HINT_DISCARD);
+                                       COGL_BUFFER_MAP_HINT_DISCARD,
+                                       NULL);
 
       GE( ctx, glReadPixels (x, y, width, height,
                              gl_format, gl_type,
@@ -1599,12 +1620,12 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
 
       _cogl_bitmap_gl_unbind (tmp_bmp);
 
-      succeeded = _cogl_bitmap_convert_into_bitmap (tmp_bmp, bitmap);
+      succeeded = _cogl_bitmap_convert_into_bitmap (tmp_bmp, bitmap, error);
 
       cogl_object_unref (tmp_bmp);
 
       if (!succeeded)
-        return FALSE;
+        goto EXIT;
     }
   else
     {
@@ -1613,6 +1634,7 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       int bpp, rowstride;
       CoglBool succeeded = FALSE;
       uint8_t *pixels;
+      CoglError *internal_error = NULL;
 
       rowstride = cogl_bitmap_get_rowstride (bitmap);
 
@@ -1642,7 +1664,17 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
 
       pixels = _cogl_bitmap_gl_bind (shared_bmp,
                                      COGL_BUFFER_ACCESS_WRITE,
-                                     0 /* hints */);
+                                     0, /* hints */
+                                     &internal_error);
+      /* NB: _cogl_bitmap_gl_bind() can return NULL in sucessfull
+       * cases so we have to explicitly check the cogl error pointer
+       * to know if there was a problem */
+      if (internal_error)
+        {
+          cogl_object_unref (shared_bmp);
+          _cogl_propogate_error (error, internal_error);
+          goto EXIT;
+        }
 
       GE( ctx, glReadPixels (x, y,
                              width, height,
@@ -1654,21 +1686,15 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       /* Convert to the premult format specified by the caller
          in-place. This will do nothing if the premult status is already
          correct. */
-      if (_cogl_bitmap_convert_premult_status (shared_bmp, format))
+      if (_cogl_bitmap_convert_premult_status (shared_bmp, format, error))
         succeeded = TRUE;
 
       cogl_object_unref (shared_bmp);
 
       if (!succeeded)
-        return FALSE;
+        goto EXIT;
     }
 
-  /* Currently this function owns the pack_invert state and we don't want this
-   * to interfere with other Cogl components so all other code can assume that
-   * we leave the pack_invert state off. */
-  if (pack_invert_set)
-    GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, FALSE));
-
   /* NB: All offscreen rendering is done upside down so there is no need
    * to flip in this case... */
   if (!cogl_is_offscreen (framebuffer) &&
@@ -1683,10 +1709,11 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       pixels = _cogl_bitmap_map (bitmap,
                                  COGL_BUFFER_ACCESS_READ |
                                  COGL_BUFFER_ACCESS_WRITE,
-                                 0 /* hints */);
+                                 0, /* hints */
+                                 error);
 
       if (pixels == NULL)
-        return FALSE;
+        goto EXIT;
 
       temprow = g_alloca (rowstride * sizeof (uint8_t));
 
@@ -1708,7 +1735,17 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       _cogl_bitmap_unmap (bitmap);
     }
 
-  return TRUE;
+  status = TRUE;
+
+EXIT:
+
+  /* Currently this function owns the pack_invert state and we don't want this
+   * to interfere with other Cogl components so all other code can assume that
+   * we leave the pack_invert state off. */
+  if (pack_invert_set)
+    GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, FALSE));
+
+  return status;
 }
 
 CoglBool
@@ -1729,10 +1766,17 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
                                      format,
                                      bpp * width, /* rowstride */
                                      pixels);
+
+  /* Note: we don't try and catch errors here since we created the
+   * bitmap storage up-front and can assume we wont hit an
+   * out-of-memory error which should be the only exception
+   * this api throws.
+   */
   ret = cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
                                                   x, y,
                                                   COGL_READ_PIXELS_COLOR_BUFFER,
-                                                  bitmap);
+                                                  bitmap,
+                                                  NULL);
   cogl_object_unref (bitmap);
 
   return ret;
@@ -2363,7 +2407,8 @@ get_wire_line_indices (CoglContext *ctx,
     {
       index_buffer = cogl_indices_get_buffer (user_indices);
       indices = cogl_buffer_map (COGL_BUFFER (index_buffer),
-                                 COGL_BUFFER_ACCESS_READ, 0);
+                                 COGL_BUFFER_ACCESS_READ, 0,
+                                 NULL);
       indices_type = cogl_indices_get_type (user_indices);
     }
   else
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index 0855d0f..efcf780 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -1658,6 +1658,7 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer);
  * @source: Identifies which auxillary buffer you want to read
  *          (only COGL_READ_PIXELS_COLOR_BUFFER supported currently)
  * @bitmap: The bitmap to store the results in.
+ * @error: A #CoglError to catch exceptional errors
  *
  * This reads a rectangle of pixels from the given framebuffer where
  * position (0, 0) is the top left. The pixel at (x, y) is the first
@@ -1681,7 +1682,8 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
                                           int x,
                                           int y,
                                           CoglReadPixelsFlags source,
-                                          CoglBitmap *bitmap);
+                                          CoglBitmap *bitmap,
+                                          CoglError **error);
 
 /**
  * cogl_framebuffer_read_pixels:
diff --git a/cogl/cogl-indices.c b/cogl/cogl-indices.c
index a018559..80041d1 100644
--- a/cogl/cogl-indices.c
+++ b/cogl/cogl-indices.c
@@ -85,11 +85,19 @@ cogl_indices_new (CoglContext *context,
   CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes);
   CoglBuffer *buffer = COGL_BUFFER (index_buffer);
   CoglIndices *indices;
+  CoglError *ignore_error = NULL;
 
   cogl_buffer_set_data (buffer,
                         0,
                         indices_data,
-                        buffer_bytes);
+                        buffer_bytes,
+                        &ignore_error);
+  if (ignore_error)
+    {
+      cogl_error_free (ignore_error);
+      cogl_object_unref (index_buffer);
+      return NULL;
+    }
 
   indices = cogl_indices_new_for_buffer (type, index_buffer, 0);
   cogl_object_unref (index_buffer);
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index 45752fc..a774003 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -658,7 +658,8 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
          do but this will only happen during debugging so it probably
          doesn't matter */
       verts = ((uint8_t *)cogl_buffer_map (COGL_BUFFER (state->attribute_buffer),
-                                          COGL_BUFFER_ACCESS_READ, 0) +
+                                           COGL_BUFFER_ACCESS_READ, 0,
+                                           NULL) +
                state->array_offset);
 
       _cogl_journal_dump_quad_batch (verts,
@@ -1056,14 +1057,14 @@ create_attribute_buffer (CoglJournal *journal,
 
   if (vbo == NULL)
     {
-      vbo = cogl_attribute_buffer_new (ctx, n_bytes, NULL);
+      vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes);
       journal->vbo_pool[journal->next_vbo_in_pool] = vbo;
     }
   else if (cogl_buffer_get_size (COGL_BUFFER (vbo)) < n_bytes)
     {
       /* If the buffer is too small then we'll just recreate it */
       cogl_object_unref (vbo);
-      vbo = cogl_attribute_buffer_new (ctx, n_bytes, NULL);
+      vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes);
       journal->vbo_pool[journal->next_vbo_in_pool] = vbo;
     }
 
@@ -1709,11 +1710,10 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
                               CoglBitmap *bitmap,
                               CoglBool *found_intersection)
 {
+  CoglContext *ctx;
   CoglPixelFormat format;
   int i;
 
-  _COGL_GET_CONTEXT (ctx, FALSE);
-
   /* XXX: this number has been plucked out of thin air, but the idea
    * is that if so many pixels are being read from the same un-changed
    * journal than we expect that it will be more efficient to fail
@@ -1731,6 +1731,8 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
       format != COGL_PIXEL_FORMAT_RGBA_8888)
     return FALSE;
 
+  ctx = _cogl_bitmap_get_context (bitmap);
+
   *found_intersection = FALSE;
 
   /* NB: The most recently added journal entry is the last entry, and
@@ -1750,6 +1752,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
       float poly[16];
       CoglFramebuffer *framebuffer = journal->framebuffer;
       uint8_t *pixel;
+      CoglError *ignore_error;
 
       entry_to_screen_polygon (framebuffer, entry, vertices, poly);
 
@@ -1790,9 +1793,13 @@ _cogl_journal_try_read_pixel (CoglJournal *journal,
 
       pixel = _cogl_bitmap_map (bitmap,
                                 COGL_BUFFER_ACCESS_WRITE,
-                                COGL_BUFFER_MAP_HINT_DISCARD);
+                                COGL_BUFFER_MAP_HINT_DISCARD,
+                                &ignore_error);
       if (pixel == NULL)
-        return FALSE;
+        {
+          cogl_error_free (ignore_error);
+          return FALSE;
+        }
 
       pixel[0] = color[0];
       pixel[1] = color[1];
diff --git a/cogl/cogl-path.c b/cogl/cogl-path.c
index 15bab83..af82950 100644
--- a/cogl/cogl-path.c
+++ b/cogl/cogl-path.c
@@ -1385,9 +1385,9 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
     return;
 
   data->stroke_attribute_buffer =
-    cogl_attribute_buffer_new (data->context,
-                               data->path_nodes->len * sizeof (floatVec2),
-                               NULL);
+    cogl_attribute_buffer_new_with_size (data->context,
+                                         data->path_nodes->len *
+                                         sizeof (floatVec2));
 
   buffer = COGL_BUFFER (data->stroke_attribute_buffer);
   buffer_p = _cogl_buffer_map_for_fill_or_fallback (buffer);
diff --git a/cogl/cogl-pixel-buffer.c b/cogl/cogl-pixel-buffer.c
index 0c7502c..430247b 100644
--- a/cogl/cogl-pixel-buffer.c
+++ b/cogl/cogl-pixel-buffer.c
@@ -69,7 +69,8 @@ COGL_BUFFER_DEFINE (PixelBuffer, pixel_buffer)
 CoglPixelBuffer *
 cogl_pixel_buffer_new (CoglContext *context,
                        size_t size,
-                       const void *data)
+                       const void *data,
+                       CoglError **error)
 {
   CoglPixelBuffer *pixel_buffer = g_slice_new0 (CoglPixelBuffer);
   CoglBuffer *buffer = COGL_BUFFER (pixel_buffer);
@@ -85,10 +86,17 @@ cogl_pixel_buffer_new (CoglContext *context,
   _cogl_pixel_buffer_object_new (pixel_buffer);
 
   if (data)
-    cogl_buffer_set_data (COGL_BUFFER (pixel_buffer),
-                          0,
-                          data,
-                          size);
+    {
+      if (!cogl_buffer_set_data (COGL_BUFFER (pixel_buffer),
+                                 0,
+                                 data,
+                                 size,
+                                 error))
+        {
+          cogl_object_unref (pixel_buffer);
+          return NULL;
+        }
+    }
 
   return pixel_buffer;
 }
diff --git a/cogl/cogl-pixel-buffer.h b/cogl/cogl-pixel-buffer.h
index 09ee5e9..0e5ea38 100644
--- a/cogl/cogl-pixel-buffer.h
+++ b/cogl/cogl-pixel-buffer.h
@@ -46,6 +46,7 @@ typedef struct _CoglPixelBuffer CoglPixelBuffer;
  * @context: A #CoglContext
  * @size: The number of bytes to allocate for the pixel data.
  * @data: An optional pointer to vertex data to upload immediately
+ * @error: A #CoglError for catching exceptional errors
  *
  * Declares a new #CoglPixelBuffer of @size bytes to contain arrays of
  * pixels. Once declared, data can be set using cogl_buffer_set_data()
@@ -61,7 +62,8 @@ typedef struct _CoglPixelBuffer CoglPixelBuffer;
 CoglPixelBuffer *
 cogl_pixel_buffer_new (CoglContext *context,
                        size_t size,
-                       const void *data);
+                       const void *data,
+                       CoglError **error);
 
 /**
  * cogl_is_pixel_buffer:
diff --git a/cogl/cogl-sub-texture.c b/cogl/cogl-sub-texture.c
index b3e3a97..eb8f097 100644
--- a/cogl/cogl-sub-texture.c
+++ b/cogl/cogl-sub-texture.c
@@ -366,14 +366,15 @@ _cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex)
 }
 
 static CoglBool
-_cogl_sub_texture_set_region (CoglTexture    *tex,
-                              int             src_x,
-                              int             src_y,
-                              int             dst_x,
-                              int             dst_y,
-                              unsigned int    dst_width,
-                              unsigned int    dst_height,
-                              CoglBitmap     *bmp)
+_cogl_sub_texture_set_region (CoglTexture *tex,
+                              int src_x,
+                              int src_y,
+                              int dst_x,
+                              int dst_y,
+                              int dst_width,
+                              int dst_height,
+                              CoglBitmap *bmp,
+                              CoglError **error)
 {
   CoglSubTexture  *sub_tex = COGL_SUB_TEXTURE (tex);
 
@@ -382,7 +383,8 @@ _cogl_sub_texture_set_region (CoglTexture    *tex,
                                               dst_x + sub_tex->sub_x,
                                               dst_y + sub_tex->sub_y,
                                               dst_width, dst_height,
-                                              bmp);
+                                              bmp,
+                                              error);
 }
 
 static CoglPixelFormat
diff --git a/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl-texture-2d-sliced-private.h
index 0a388ee..760db98 100644
--- a/cogl/cogl-texture-2d-sliced-private.h
+++ b/cogl/cogl-texture-2d-sliced-private.h
@@ -53,8 +53,9 @@ _cogl_texture_2d_sliced_new_from_foreign (GLuint           gl_handle,
                                           CoglPixelFormat  format);
 
 CoglTexture2DSliced *
-_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap      *bmp,
+_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
                                          CoglTextureFlags flags,
-                                         CoglPixelFormat  internal_format);
+                                         CoglPixelFormat internal_format,
+                                         CoglError **error);
 
 #endif /* __COGL_TEXTURE_2D_SLICED_PRIVATE_H */
diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c
index b03f41f..579759e 100644
--- a/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl-texture-2d-sliced.c
@@ -162,7 +162,7 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds,
   return waste_buf;
 }
 
-static void
+static CoglBool
 _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
                                    CoglBitmap *source_bmp,
                                    CoglTexture2D *slice_tex,
@@ -174,7 +174,8 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
                                    int src_x,
                                    int src_y,
                                    int dst_x,
-                                   int dst_y)
+                                   int dst_y,
+                                   CoglError **error)
 {
   CoglBool need_x, need_y;
   CoglContext *ctx = COGL_TEXTURE (tex_2ds)->context;
@@ -200,10 +201,9 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
       unsigned int wy, wx;
       CoglBitmap *waste_bmp;
 
-      bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0);
-
+      bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
       if (bmp_data == NULL)
-        return;
+        return FALSE;
 
       if (need_x)
         {
@@ -234,18 +234,24 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
                                                 x_span->waste * bpp,
                                                 waste_buf);
 
-          cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
-                                               0, /* src_x */
-                                               0, /* src_y */
-                                               /* dst_x */
-                                               x_span->size - x_span->waste,
-                                               y_iter->intersect_start -
-                                               y_span->start, /* dst_y */
-                                               x_span->waste, /* dst_width */
-                                               /* dst_height */
-                                               y_iter->intersect_end -
-                                               y_iter->intersect_start,
-                                               waste_bmp);
+          if (!cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
+                                                    0, /* src_x */
+                                                    0, /* src_y */
+                                                    /* dst_x */
+                                                    x_span->size - x_span->waste,
+                                                    y_iter->intersect_start -
+                                                    y_span->start, /* dst_y */
+                                                    x_span->waste, /* dst_width */
+                                                    /* dst_height */
+                                                    y_iter->intersect_end -
+                                                    y_iter->intersect_start,
+                                                    waste_bmp,
+                                                    error))
+            {
+              cogl_object_unref (waste_bmp);
+              _cogl_bitmap_unmap (source_bmp);
+              return FALSE;
+            }
 
           cogl_object_unref (waste_bmp);
         }
@@ -288,28 +294,37 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
                                                 copy_width * bpp,
                                                 waste_buf);
 
-          cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
-                                               0, /* src_x */
-                                               0, /* src_y */
-                                               /* dst_x */
-                                               x_iter->intersect_start -
-                                               x_iter->pos,
-                                               /* dst_y */
-                                               y_span->size - y_span->waste,
-                                               copy_width, /* dst_width */
-                                               y_span->waste, /* dst_height */
-                                               waste_bmp);
+          if (!cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
+                                                    0, /* src_x */
+                                                    0, /* src_y */
+                                                    /* dst_x */
+                                                    x_iter->intersect_start -
+                                                    x_iter->pos,
+                                                    /* dst_y */
+                                                    y_span->size - y_span->waste,
+                                                    copy_width, /* dst_width */
+                                                    y_span->waste, /* dst_height */
+                                                    waste_bmp,
+                                                    error))
+            {
+              cogl_object_unref (waste_bmp);
+              _cogl_bitmap_unmap (source_bmp);
+              return FALSE;
+            }
 
           cogl_object_unref (waste_bmp);
         }
 
       _cogl_bitmap_unmap (source_bmp);
     }
+
+  return TRUE;
 }
 
 static CoglBool
 _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
-                                      CoglBitmap          *bmp)
+                                      CoglBitmap *bmp,
+                                      CoglError **error)
 {
   CoglSpan *x_span;
   CoglSpan *y_span;
@@ -340,16 +355,22 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
           slice_tex = g_array_index (tex_2ds->slice_textures,
                                      CoglTexture2D *, slice_num);
 
-          cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
-                                               x_span->start, /* src x */
-                                               y_span->start, /* src y */
-                                               0, /* dst x */
-                                               0, /* dst y */
-                                               x_span->size -
-                                               x_span->waste, /* width */
-                                               y_span->size -
-                                               y_span->waste, /* height */
-                                               bmp);
+          if (!cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
+                                                    x_span->start, /* src x */
+                                                    y_span->start, /* src y */
+                                                    0, /* dst x */
+                                                    0, /* dst y */
+                                                    x_span->size -
+                                                    x_span->waste, /* width */
+                                                    y_span->size -
+                                                    y_span->waste, /* height */
+                                                    bmp,
+                                                    error))
+            {
+              if (waste_buf)
+                g_free (waste_buf);
+              return FALSE;
+            }
 
           /* Set up a fake iterator that covers the whole slice */
           x_iter.intersect_start = x_span->start;
@@ -364,16 +385,22 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
                                   y_span->waste);
           y_iter.pos = y_span->start;
 
-          _cogl_texture_2d_sliced_set_waste (tex_2ds,
-                                             bmp,
-                                             slice_tex,
-                                             waste_buf,
-                                             x_span, y_span,
-                                             &x_iter, &y_iter,
-                                             0, /* src_x */
-                                             0, /* src_y */
-                                             0, /* dst_x */
-                                             0); /* dst_y */
+          if (!_cogl_texture_2d_sliced_set_waste (tex_2ds,
+                                                  bmp,
+                                                  slice_tex,
+                                                  waste_buf,
+                                                  x_span, y_span,
+                                                  &x_iter, &y_iter,
+                                                  0, /* src_x */
+                                                  0, /* src_y */
+                                                  0, /* dst_x */
+                                                  0,
+                                                  error)) /* dst_y */
+            {
+              if (waste_buf)
+                g_free (waste_buf);
+              return FALSE;
+            }
         }
     }
 
@@ -385,15 +412,16 @@ _cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds,
 
 static CoglBool
 _cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds,
-                                                int          src_x,
-                                                int          src_y,
-                                                int          dst_x,
-                                                int          dst_y,
-                                                int          width,
-                                                int          height,
-                                                CoglBitmap  *source_bmp,
-                                                GLuint       source_gl_format,
-                                                GLuint       source_gl_type)
+                                                int src_x,
+                                                int src_y,
+                                                int dst_x,
+                                                int dst_y,
+                                                int width,
+                                                int height,
+                                                CoglBitmap *source_bmp,
+                                                GLuint source_gl_format,
+                                                GLuint source_gl_type,
+                                                CoglError **error)
 {
   CoglSpan *x_span;
   CoglSpan *y_span;
@@ -463,27 +491,40 @@ _cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds,
           slice_tex = g_array_index (tex_2ds->slice_textures,
                                      CoglTexture2D *, slice_num);
 
-          cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
-                                               source_x,
-                                               source_y,
-                                               local_x, /* dst x */
-                                               local_y, /* dst y */
-                                               inter_w, /* width */
-                                               inter_h, /* height */
-                                               source_bmp);
-
-          _cogl_texture_2d_sliced_set_waste (tex_2ds,
-                                             source_bmp,
-                                             slice_tex,
-                                             waste_buf,
-                                             x_span, y_span,
-                                             &x_iter, &y_iter,
-                                             src_x, src_y,
-                                             dst_x, dst_y);
+          if (!cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
+                                                    source_x,
+                                                    source_y,
+                                                    local_x, /* dst x */
+                                                    local_y, /* dst y */
+                                                    inter_w, /* width */
+                                                    inter_h, /* height */
+                                                    source_bmp,
+                                                    error))
+            {
+              if (waste_buf)
+                g_free (waste_buf);
+              return FALSE;
+            }
+
+          if (!_cogl_texture_2d_sliced_set_waste (tex_2ds,
+                                                  source_bmp,
+                                                  slice_tex,
+                                                  waste_buf,
+                                                  x_span, y_span,
+                                                  &x_iter, &y_iter,
+                                                  src_x, src_y,
+                                                  dst_x, dst_y,
+                                                  error))
+            {
+              if (waste_buf)
+                g_free (waste_buf);
+              return FALSE;
+            }
         }
     }
 
-  g_free (waste_buf);
+  if (waste_buf)
+    g_free (waste_buf);
 
   return TRUE;
 }
@@ -875,9 +916,10 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
 }
 
 CoglTexture2DSliced *
-_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap      *bmp,
+_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
                                          CoglTextureFlags flags,
-                                         CoglPixelFormat  internal_format)
+                                         CoglPixelFormat internal_format,
+                                         CoglError **error)
 {
   CoglTexture2DSliced *tex_2ds;
   CoglBitmap          *dst_bmp;
@@ -908,7 +950,8 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap      *bmp,
                                               &internal_format,
                                               &gl_intformat,
                                               &gl_format,
-                                              &gl_type);
+                                              &gl_type,
+                                              error);
   if (dst_bmp == NULL)
     {
       _cogl_texture_2d_sliced_free (tex_2ds);
@@ -922,7 +965,8 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap      *bmp,
     goto error;
 
   if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds,
-                                             dst_bmp))
+                                             dst_bmp,
+                                             error))
     goto error;
 
   cogl_object_unref (dst_bmp);
@@ -1234,38 +1278,45 @@ _cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex)
 }
 
 static CoglBool
-_cogl_texture_2d_sliced_set_region (CoglTexture    *tex,
-                                    int             src_x,
-                                    int             src_y,
-                                    int             dst_x,
-                                    int             dst_y,
-                                    unsigned int    dst_width,
-                                    unsigned int    dst_height,
-                                    CoglBitmap     *bmp)
+_cogl_texture_2d_sliced_set_region (CoglTexture *tex,
+                                    int src_x,
+                                    int src_y,
+                                    int dst_x,
+                                    int dst_y,
+                                    int dst_width,
+                                    int dst_height,
+                                    CoglBitmap *bmp,
+                                    CoglError **error)
 {
   CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
   GLenum gl_format;
   GLenum gl_type;
+  CoglBool status;
 
   bmp = _cogl_texture_prepare_for_upload (bmp,
                                           cogl_texture_get_format (tex),
                                           NULL,
                                           NULL,
                                           &gl_format,
-                                          &gl_type);
+                                          &gl_type,
+                                          error);
+  if (!bmp)
+    return FALSE;
 
   /* Send data to GL */
-  _cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds,
-                                                  src_x, src_y,
-                                                  dst_x, dst_y,
-                                                  dst_width, dst_height,
-                                                  bmp,
-                                                  gl_format,
-                                                  gl_type);
+  status =
+    _cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds,
+                                                    src_x, src_y,
+                                                    dst_x, dst_y,
+                                                    dst_width, dst_height,
+                                                    bmp,
+                                                    gl_format,
+                                                    gl_type,
+                                                    error);
 
   cogl_object_unref (bmp);
 
-  return TRUE;
+  return status;
 }
 
 static CoglPixelFormat
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 950ccce..8517d23 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -476,26 +476,31 @@ _cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex)
 }
 
 static CoglBool
-_cogl_texture_2d_set_region (CoglTexture    *tex,
-                             int             src_x,
-                             int             src_y,
-                             int             dst_x,
-                             int             dst_y,
-                             unsigned int    width,
-                             unsigned int    height,
-                             CoglBitmap     *bmp)
+_cogl_texture_2d_set_region (CoglTexture *tex,
+                             int src_x,
+                             int src_y,
+                             int dst_x,
+                             int dst_y,
+                             int width,
+                             int height,
+                             CoglBitmap *bmp,
+                             CoglError **error)
 {
   CoglContext *ctx = tex->context;
   CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
 
-  ctx->driver_vtable->texture_2d_copy_from_bitmap (tex_2d,
-                                                   bmp,
-                                                   dst_x,
-                                                   dst_y,
-                                                   src_x,
-                                                   src_y,
-                                                   width,
-                                                   height);
+  if (!ctx->driver_vtable->texture_2d_copy_from_bitmap (tex_2d,
+                                                        bmp,
+                                                        dst_x,
+                                                        dst_y,
+                                                        src_x,
+                                                        src_y,
+                                                        width,
+                                                        height,
+                                                        error))
+    {
+      return FALSE;
+    }
 
   tex_2d->mipmaps_dirty = TRUE;
 
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c
index 0c883f9..c901c6a 100644
--- a/cogl/cogl-texture-3d.c
+++ b/cogl/cogl-texture-3d.c
@@ -271,7 +271,6 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
   GLenum gl_intformat;
   GLenum gl_format;
   GLenum gl_type;
-  uint8_t *data;
   CoglContext *ctx;
 
   ctx = _cogl_bitmap_get_context (bmp);
@@ -293,14 +292,10 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
                                               &internal_format,
                                               &gl_intformat,
                                               &gl_format,
-                                              &gl_type);
-
+                                              &gl_type,
+                                              error);
   if (dst_bmp == NULL)
-    {
-      _cogl_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_FAILED,
-                       "Bitmap conversion failed");
-      return NULL;
-    }
+    return NULL;
 
   tex_3d = _cogl_texture_3d_create_base (ctx,
                                          bmp_width, height, depth,
@@ -308,32 +303,53 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
 
   /* Keep a copy of the first pixel so that if glGenerateMipmap isn't
      supported we can fallback to using GL_GENERATE_MIPMAP */
-  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
-      (data = _cogl_bitmap_map (dst_bmp,
-                                COGL_BUFFER_ACCESS_READ, 0)))
+  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
     {
+      CoglError *ignore = NULL;
+      uint8_t *data = _cogl_bitmap_map (dst_bmp,
+                                        COGL_BUFFER_ACCESS_READ, 0,
+                                        &ignore);
+
       CoglPixelFormat format = cogl_bitmap_get_format (dst_bmp);
+
       tex_3d->first_pixel.gl_format = gl_format;
       tex_3d->first_pixel.gl_type = gl_type;
-      memcpy (tex_3d->first_pixel.data, data,
-              _cogl_pixel_format_get_bytes_per_pixel (format));
 
-      _cogl_bitmap_unmap (dst_bmp);
+      if (data)
+        {
+          memcpy (tex_3d->first_pixel.data, data,
+                  _cogl_pixel_format_get_bytes_per_pixel (format));
+          _cogl_bitmap_unmap (dst_bmp);
+        }
+      else
+        {
+          g_warning ("Failed to read first pixel of bitmap for "
+                     "glGenerateMipmap fallback");
+          cogl_error_free (ignore);
+          memset (tex_3d->first_pixel.data, 0,
+                  _cogl_pixel_format_get_bytes_per_pixel (format));
+        }
     }
 
   tex_3d->gl_texture =
     ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format);
 
-  ctx->texture_driver->upload_to_gl_3d (ctx,
-                                        GL_TEXTURE_3D,
-                                        tex_3d->gl_texture,
-                                        FALSE, /* is_foreign */
-                                        height,
-                                        depth,
-                                        dst_bmp,
-                                        gl_intformat,
-                                        gl_format,
-                                        gl_type);
+  if (!ctx->texture_driver->upload_to_gl_3d (ctx,
+                                             GL_TEXTURE_3D,
+                                             tex_3d->gl_texture,
+                                             FALSE, /* is_foreign */
+                                             height,
+                                             depth,
+                                             dst_bmp,
+                                             gl_intformat,
+                                             gl_format,
+                                             gl_type,
+                                             error))
+    {
+      cogl_object_unref (dst_bmp);
+      cogl_object_unref (tex_3d);
+      return NULL;
+    }
 
   tex_3d->gl_format = gl_intformat;
 
@@ -393,7 +409,8 @@ cogl_texture_3d_new_from_data (CoglContext *context,
 
       bmp_data = _cogl_bitmap_map (bitmap,
                                    COGL_BUFFER_ACCESS_WRITE,
-                                   COGL_BUFFER_MAP_HINT_DISCARD);
+                                   COGL_BUFFER_MAP_HINT_DISCARD,
+                                   error);
 
       if (bmp_data == NULL)
         {
@@ -569,17 +586,24 @@ _cogl_texture_3d_ensure_non_quad_rendering (CoglTexture *tex)
 }
 
 static CoglBool
-_cogl_texture_3d_set_region (CoglTexture    *tex,
-                             int             src_x,
-                             int             src_y,
-                             int             dst_x,
-                             int             dst_y,
-                             unsigned int    dst_width,
-                             unsigned int    dst_height,
-                             CoglBitmap     *bmp)
+_cogl_texture_3d_set_region (CoglTexture *tex,
+                             int src_x,
+                             int src_y,
+                             int dst_x,
+                             int dst_y,
+                             int dst_width,
+                             int dst_height,
+                             CoglBitmap *bmp,
+                             CoglError **error)
 {
   /* This function doesn't really make sense for 3D textures because
      it can't specify which image to upload to */
+  _cogl_set_error (error,
+                   COGL_SYSTEM_ERROR,
+                   COGL_SYSTEM_ERROR_UNSUPPORTED,
+                   "Setting a 2D region on a 3D texture isn't "
+                   "currently supported");
+
   return FALSE;
 }
 
diff --git a/cogl/cogl-texture-driver.h b/cogl/cogl-texture-driver.h
index 7a186ba..780f40d 100644
--- a/cogl/cogl-texture-driver.h
+++ b/cogl/cogl-texture-driver.h
@@ -63,7 +63,7 @@ struct _CoglTextureDriver
    *
    * XXX: sorry for the ridiculous number of arguments :-(
    */
-  void
+  CoglBool
   (* upload_subregion_to_gl) (CoglContext *ctx,
                               GLenum gl_target,
                               GLuint gl_handle,
@@ -76,7 +76,8 @@ struct _CoglTextureDriver
                               int height,
                               CoglBitmap *source_bmp,
                               GLuint source_gl_format,
-                              GLuint source_gl_type);
+                              GLuint source_gl_type,
+                              CoglError **error);
 
   /*
    * Replaces the contents of the GL texture with the entire bitmap. On
@@ -84,7 +85,7 @@ struct _CoglTextureDriver
    * to copy the bitmap if the rowstride is not a multiple of a possible
    * alignment value because there is no GL_UNPACK_ROW_LENGTH
    */
-  void
+  CoglBool
   (* upload_to_gl) (CoglContext *ctx,
                     GLenum gl_target,
                     GLuint gl_handle,
@@ -92,7 +93,8 @@ struct _CoglTextureDriver
                     CoglBitmap *source_bmp,
                     GLint internal_gl_format,
                     GLuint source_gl_format,
-                    GLuint source_gl_type);
+                    GLuint source_gl_type,
+                    CoglError **error);
 
   /*
    * Replaces the contents of the GL texture with the entire bitmap. The
@@ -101,7 +103,7 @@ struct _CoglTextureDriver
    * is the number of rows between images) is inferred by dividing the
    * height of the bitmap by the depth.
    */
-  void
+  CoglBool
   (* upload_to_gl_3d) (CoglContext *ctx,
                        GLenum gl_target,
                        GLuint gl_handle,
@@ -111,7 +113,8 @@ struct _CoglTextureDriver
                        CoglBitmap *source_bmp,
                        GLint internal_gl_format,
                        GLuint source_gl_format,
-                       GLuint source_gl_type);
+                       GLuint source_gl_type,
+                       CoglError **error);
 
   /*
    * This sets up the glPixelStore state for an download to a destination with
diff --git a/cogl/cogl-texture-private.h b/cogl/cogl-texture-private.h
index f4b3b40..ceec118 100644
--- a/cogl/cogl-texture-private.h
+++ b/cogl/cogl-texture-private.h
@@ -65,14 +65,15 @@ struct _CoglTextureVtable
      before being passed so the implementation is expected to call
      _cogl_texture_prepare_for_upload with a suitable destination
      format before uploading */
-  CoglBool (* set_region) (CoglTexture    *tex,
-                           int             src_x,
-                           int             src_y,
-                           int             dst_x,
-                           int             dst_y,
-                           unsigned int    dst_width,
-                           unsigned int    dst_height,
-                           CoglBitmap     *bitmap);
+  CoglBool (* set_region) (CoglTexture *tex,
+                           int src_x,
+                           int src_y,
+                           int dst_x,
+                           int dst_y,
+                           int dst_width,
+                           int dst_height,
+                           CoglBitmap *bitmap,
+                           CoglError **error);
 
   /* This should copy the image data of the texture into @data. The
      requested format will have been first passed through
@@ -233,17 +234,19 @@ _cogl_texture_determine_internal_format (CoglPixelFormat src_format,
                                          CoglPixelFormat dst_format);
 
 /* Utility function to help uploading a bitmap. If the bitmap needs
-   premult conversion then it will be copied and *copied_bitmap will
-   be set to TRUE. Otherwise dst_bmp will be set to a shallow copy of
-   src_bmp. The GLenums needed for uploading are returned */
-
+ * premult conversion then a converted copy will be returned,
+ * otherwise a reference to the original source will be returned.
+ *
+ * The GLenums needed for uploading are returned
+ */
 CoglBitmap *
-_cogl_texture_prepare_for_upload (CoglBitmap      *src_bmp,
-                                  CoglPixelFormat  dst_format,
+_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
+                                  CoglPixelFormat dst_format,
                                   CoglPixelFormat *dst_format_out,
-                                  GLenum          *out_glintformat,
-                                  GLenum          *out_glformat,
-                                  GLenum          *out_gltype);
+                                  GLenum *out_glintformat,
+                                  GLenum *out_glformat,
+                                  GLenum *out_gltype,
+                                  CoglError **error);
 
 void
 _cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
@@ -253,15 +256,6 @@ _cogl_texture_prep_gl_alignment_for_pixels_download (int bpp,
                                                      int width,
                                                      int rowstride);
 
-/* Utility function to use as a fallback for getting the data of any
-   texture via the framebuffer */
-
-CoglBool
-_cogl_texture_draw_and_read (CoglTexture *texture,
-                             CoglBitmap  *target_bmp,
-                             GLuint       target_gl_format,
-                             GLuint       target_gl_type);
-
 CoglBool
 _cogl_texture_is_foreign (CoglTexture *texture);
 
diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c
index 1ffeb83..e8bb965 100644
--- a/cogl/cogl-texture-rectangle.c
+++ b/cogl/cogl-texture-rectangle.c
@@ -38,6 +38,7 @@
 #include "cogl-journal-private.h"
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-error-private.h"
+#include "cogl-util-gl-private.h"
 
 #include <string.h>
 #include <math.h>
@@ -185,7 +186,7 @@ _cogl_texture_rectangle_create_base (CoglContext *ctx,
 
   tex_rect->format = internal_format;
 
-  return tex_rect;
+  return _cogl_texture_rectangle_object_new (tex_rect);
 }
 
 CoglTextureRectangle *
@@ -196,9 +197,10 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,
                                       CoglError **error)
 {
   CoglTextureRectangle *tex_rect;
-  GLenum                gl_intformat;
-  GLenum                gl_format;
-  GLenum                gl_type;
+  GLenum gl_intformat;
+  GLenum gl_format;
+  GLenum gl_type;
+  GLenum gl_error;
 
   /* Since no data, we need some internal format */
   if (internal_format == COGL_PIXEL_FORMAT_ANY)
@@ -226,10 +228,21 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,
   _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
                                    tex_rect->gl_texture,
                                    tex_rect->is_foreign);
-  GE( ctx, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat,
-                         width, height, 0, gl_format, gl_type, NULL) );
 
-  return _cogl_texture_rectangle_object_new (tex_rect);
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat,
+                     width, height, 0, gl_format, gl_type, NULL);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    {
+      cogl_object_unref (tex_rect);
+      return NULL;
+    }
+
+  return tex_rect;
 }
 
 CoglTextureRectangle *
@@ -264,7 +277,8 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
                                               &internal_format,
                                               &gl_intformat,
                                               &gl_format,
-                                              &gl_type);
+                                              &gl_type,
+                                              error);
 
   if (dst_bmp == NULL)
     return NULL;
@@ -278,20 +292,26 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
     ctx->texture_driver->gen (ctx,
                               GL_TEXTURE_RECTANGLE_ARB,
                               internal_format);
-  ctx->texture_driver->upload_to_gl (ctx,
-                                     GL_TEXTURE_RECTANGLE_ARB,
-                                     tex_rect->gl_texture,
-                                     FALSE,
-                                     dst_bmp,
-                                     gl_intformat,
-                                     gl_format,
-                                     gl_type);
+  if (!ctx->texture_driver->upload_to_gl (ctx,
+                                          GL_TEXTURE_RECTANGLE_ARB,
+                                          tex_rect->gl_texture,
+                                          FALSE,
+                                          dst_bmp,
+                                          gl_intformat,
+                                          gl_format,
+                                          gl_type,
+                                          error))
+    {
+      cogl_object_unref (dst_bmp);
+      cogl_object_unref (tex_rect);
+      return NULL;
+    }
 
   tex_rect->gl_format = gl_intformat;
 
   cogl_object_unref (dst_bmp);
 
-  return _cogl_texture_rectangle_object_new (tex_rect);
+  return tex_rect;
 }
 
 CoglTextureRectangle *
@@ -416,7 +436,7 @@ cogl_texture_rectangle_new_from_foreign (CoglContext *ctx,
   tex_rect->gl_legacy_texobj_min_filter = GL_FALSE;
   tex_rect->gl_legacy_texobj_mag_filter = GL_FALSE;
 
-  return _cogl_texture_rectangle_object_new (tex_rect);
+  return tex_rect;
 }
 
 static int
@@ -527,42 +547,49 @@ _cogl_texture_rectangle_ensure_non_quad_rendering (CoglTexture *tex)
 }
 
 static CoglBool
-_cogl_texture_rectangle_set_region (CoglTexture    *tex,
-                                    int             src_x,
-                                    int             src_y,
-                                    int             dst_x,
-                                    int             dst_y,
-                                    unsigned int    dst_width,
-                                    unsigned int    dst_height,
-                                    CoglBitmap     *bmp)
+_cogl_texture_rectangle_set_region (CoglTexture *tex,
+                                    int src_x,
+                                    int src_y,
+                                    int dst_x,
+                                    int dst_y,
+                                    int dst_width,
+                                    int dst_height,
+                                    CoglBitmap *bmp,
+                                    CoglError **error)
 {
   CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
   GLenum gl_format;
   GLenum gl_type;
   CoglContext *ctx = tex->context;
+  CoglBool status;
 
   bmp = _cogl_texture_prepare_for_upload (bmp,
                                           cogl_texture_get_format (tex),
                                           NULL,
                                           NULL,
                                           &gl_format,
-                                          &gl_type);
+                                          &gl_type,
+                                          error);
+  if (!bmp)
+    return FALSE;
 
   /* Send data to GL */
-  ctx->texture_driver->upload_subregion_to_gl (ctx,
-                                               GL_TEXTURE_RECTANGLE_ARB,
-                                               tex_rect->gl_texture,
-                                               FALSE,
-                                               src_x, src_y,
-                                               dst_x, dst_y,
-                                               dst_width, dst_height,
-                                               bmp,
-                                               gl_format,
-                                               gl_type);
+  status =
+    ctx->texture_driver->upload_subregion_to_gl (ctx,
+                                                 GL_TEXTURE_RECTANGLE_ARB,
+                                                 tex_rect->gl_texture,
+                                                 FALSE,
+                                                 src_x, src_y,
+                                                 dst_x, dst_y,
+                                                 dst_width, dst_height,
+                                                 bmp,
+                                                 gl_format,
+                                                 gl_type,
+                                                 error);
 
   cogl_object_unref (bmp);
 
-  return TRUE;
+  return status;
 }
 
 static CoglBool
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 7fc796c..4fa223f 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -54,6 +54,7 @@
 #include "cogl1-context.h"
 #include "cogl-sub-texture.h"
 #include "cogl-primitive-texture.h"
+#include "cogl-error-private.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -153,18 +154,18 @@ _cogl_texture_determine_internal_format (CoglPixelFormat src_format,
 }
 
 CoglBitmap *
-_cogl_texture_prepare_for_upload (CoglBitmap      *src_bmp,
-                                  CoglPixelFormat  dst_format,
+_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
+                                  CoglPixelFormat dst_format,
                                   CoglPixelFormat *dst_format_out,
-                                  GLenum          *out_glintformat,
-                                  GLenum          *out_glformat,
-                                  GLenum          *out_gltype)
+                                  GLenum *out_glintformat,
+                                  GLenum *out_glformat,
+                                  GLenum *out_gltype,
+                                  CoglError **error)
 {
+  CoglContext *ctx = _cogl_bitmap_get_context (src_bmp);
   CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
   CoglBitmap *dst_bmp;
 
-  _COGL_GET_CONTEXT (ctx, NULL);
-
   dst_format = _cogl_texture_determine_internal_format (src_format,
                                                         dst_format);
 
@@ -192,7 +193,8 @@ _cogl_texture_prepare_for_upload (CoglBitmap      *src_bmp,
                                                   dst_format))
         {
           dst_bmp = _cogl_bitmap_convert (src_bmp,
-                                          src_format ^ COGL_PREMULT_BIT);
+                                          src_format ^ COGL_PREMULT_BIT,
+                                          error);
 
           if (dst_bmp == NULL)
             return NULL;
@@ -226,7 +228,7 @@ _cogl_texture_prepare_for_upload (CoglBitmap      *src_bmp,
                                                                out_gltype);
 
       if (closest_format != src_format)
-        dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format);
+        dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format, error);
       else
         dst_bmp = cogl_object_ref (src_bmp);
     }
@@ -325,24 +327,21 @@ cogl_texture_new_with_size (unsigned int     width,
 }
 
 CoglTexture *
-cogl_texture_new_from_data (unsigned int width,
-			    unsigned int height,
+cogl_texture_new_from_data (CoglContext *ctx,
+                            int width,
+			    int height,
                             CoglTextureFlags flags,
 			    CoglPixelFormat format,
 			    CoglPixelFormat internal_format,
-			    unsigned int rowstride,
-			    const uint8_t *data)
+			    int rowstride,
+			    const uint8_t *data,
+                            CoglError **error)
 {
   CoglBitmap *bmp;
   CoglTexture *tex;
 
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  if (format == COGL_PIXEL_FORMAT_ANY)
-    return NULL;
-
-  if (data == NULL)
-    return NULL;
+  _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
+  _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
 
   /* Rowstride from width if not given */
   if (rowstride == 0)
@@ -355,7 +354,7 @@ cogl_texture_new_from_data (unsigned int width,
                                   rowstride,
                                   (uint8_t *) data);
 
-  tex = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
+  tex = cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
 
   cogl_object_unref (bmp);
 
@@ -365,19 +364,32 @@ cogl_texture_new_from_data (unsigned int width,
 CoglTexture *
 cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
                               CoglTextureFlags flags,
-                              CoglPixelFormat  internal_format)
+                              CoglPixelFormat internal_format,
+                              CoglError **error)
 {
+  CoglContext *ctx = _cogl_bitmap_get_context (bitmap);
   CoglAtlasTexture *atlas_tex;
   CoglTexture *tex;
-
-  _COGL_GET_CONTEXT (ctx, FALSE);
+  CoglError *internal_error = NULL;
 
   /* First try putting the texture in the atlas */
   if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
                                                         flags,
-                                                        internal_format)))
+                                                        internal_format,
+                                                        &internal_error)))
     return COGL_TEXTURE (atlas_tex);
 
+  if (cogl_error_matches (internal_error,
+                          COGL_SYSTEM_ERROR,
+                          COGL_SYSTEM_ERROR_NO_MEMORY))
+    {
+      _cogl_propogate_error (error, internal_error);
+      return NULL;
+    }
+
+  cogl_error_free (internal_error);
+  internal_error = NULL;
+
   /* If that doesn't work try a fast path 2D texture */
   if ((_cogl_util_is_pot (bitmap->width) &&
        _cogl_util_is_pot (bitmap->height)) ||
@@ -386,7 +398,21 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
     {
       tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
                                                            internal_format,
-                                                           NULL));
+                                                           &internal_error));
+
+      if (cogl_error_matches (internal_error,
+                              COGL_SYSTEM_ERROR,
+                              COGL_SYSTEM_ERROR_NO_MEMORY))
+        {
+          _cogl_propogate_error (error, internal_error);
+          return NULL;
+        }
+
+      if (!tex)
+        {
+          cogl_error_free (internal_error);
+          internal_error = NULL;
+        }
     }
   else
     tex = NULL;
@@ -402,7 +428,8 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
       /* Otherwise create a sliced texture */
       tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
                                                              flags,
-                                                             internal_format));
+                                                             internal_format,
+                                                             error));
     }
 
   return tex;
@@ -435,8 +462,13 @@ cogl_texture_new_from_file (const char        *filename,
   internal_format =
     _cogl_texture_determine_internal_format (src_format, internal_format);
   if (!_cogl_texture_needs_premult_conversion (src_format, internal_format) ||
-      _cogl_bitmap_convert_premult_status (bmp, src_format ^ COGL_PREMULT_BIT))
-    texture = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
+      _cogl_bitmap_convert_premult_status (bmp,
+                                           src_format ^ COGL_PREMULT_BIT,
+                                           error))
+    {
+      texture =
+        cogl_texture_new_from_bitmap (bmp, flags, internal_format, error);
+    }
 
   cogl_object_unref (bmp);
 
@@ -615,7 +647,8 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture,
                                      int dst_y,
                                      unsigned int dst_width,
                                      unsigned int dst_height,
-                                     CoglBitmap *bmp)
+                                     CoglBitmap *bmp,
+                                     CoglError **error)
 {
   CoglBool ret;
 
@@ -639,7 +672,8 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture,
                                      src_x, src_y,
                                      dst_x, dst_y,
                                      dst_width, dst_height,
-                                     bmp);
+                                     bmp,
+                                     error);
 
   return ret;
 }
@@ -656,7 +690,8 @@ cogl_texture_set_region (CoglTexture *texture,
 			 int height,
 			 CoglPixelFormat format,
 			 unsigned int rowstride,
-			 const uint8_t *data)
+			 const uint8_t *data,
+                         CoglError **error)
 {
   CoglContext *ctx = texture->context;
   CoglBitmap *source_bmp;
@@ -684,7 +719,8 @@ cogl_texture_set_region (CoglTexture *texture,
                                              src_x, src_y,
                                              dst_x, dst_y,
                                              dst_width, dst_height,
-                                             source_bmp);
+                                             source_bmp,
+                                             error);
 
   cogl_object_unref (source_bmp);
 
@@ -704,12 +740,13 @@ cogl_texture_set_region (CoglTexture *texture,
  * NB: Normally this approach isn't normally used since we can just use
  * glGetTexImage, but may be used as a fallback in some circumstances.
  */
-static void
+static CoglBool
 do_texture_draw_and_read (CoglFramebuffer *fb,
                           CoglPipeline *pipeline,
                           CoglTexture *texture,
                           CoglBitmap *target_bmp,
-                          float *viewport)
+                          float *viewport,
+                          CoglError **error)
 {
   float rx1, ry1;
   float rx2, ry2;
@@ -772,24 +809,36 @@ do_texture_draw_and_read (CoglFramebuffer *fb,
                                                width, height,
                                                COGL_PIXEL_FORMAT_RGBA_8888_PRE);
 
-          cogl_framebuffer_read_pixels_into_bitmap
-                                   (fb,
-                                    viewport[0], viewport[1],
-                                    COGL_READ_PIXELS_COLOR_BUFFER,
-                                    rect_bmp);
+          if (!cogl_framebuffer_read_pixels_into_bitmap
+                                               (fb,
+                                                viewport[0], viewport[1],
+                                                COGL_READ_PIXELS_COLOR_BUFFER,
+                                                rect_bmp,
+                                                error))
+            {
+              cogl_object_unref (rect_bmp);
+              return FALSE;
+            }
 
           /* Copy to target bitmap */
-          _cogl_bitmap_copy_subregion (rect_bmp,
-                                       target_bmp,
-                                       0,0,
-                                       rx1,ry1,
-                                       width,
-                                       height);
+          if (!_cogl_bitmap_copy_subregion (rect_bmp,
+                                            target_bmp,
+                                            0, 0,
+                                            rx1, ry1,
+                                            width,
+                                            height,
+                                            error))
+            {
+              cogl_object_unref (rect_bmp);
+              return FALSE;
+            }
 
           /* Free temp bitmap */
           cogl_object_unref (rect_bmp);
         }
     }
+
+  return TRUE;
 }
 
 /* Reads back the contents of a texture by rendering it to the framebuffer
@@ -798,38 +847,30 @@ do_texture_draw_and_read (CoglFramebuffer *fb,
  * NB: Normally this approach isn't normally used since we can just use
  * glGetTexImage, but may be used as a fallback in some circumstances.
  */
-CoglBool
+static CoglBool
 _cogl_texture_draw_and_read (CoglTexture *texture,
                              CoglBitmap *target_bmp,
                              GLuint target_gl_format,
-                             GLuint target_gl_type)
+                             GLuint target_gl_type,
+                             CoglError **error)
 {
-  int bpp;
   CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
-  float viewport[4];
-  CoglBitmap *alpha_bmp;
-  int target_width = cogl_bitmap_get_width (target_bmp);
-  int target_height = cogl_bitmap_get_height (target_bmp);
-  int target_rowstride = cogl_bitmap_get_rowstride (target_bmp);
   CoglContext *ctx = framebuffer->context;
+  float save_viewport[4];
+  float viewport[4];
+  CoglBool status = FALSE;
 
-  bpp = _cogl_pixel_format_get_bytes_per_pixel (COGL_PIXEL_FORMAT_RGBA_8888);
-
-  /* Viewport needs to have some size and be inside the window for this */
-  cogl_framebuffer_get_viewport4fv (framebuffer, viewport);
-  if (viewport[0] <  0 || viewport[1] <  0 ||
-      viewport[2] <= 0 || viewport[3] <= 0)
-    return FALSE;
-
-  /* Setup orthographic projection into current viewport (0,0 in top-left
-   * corner to draw the texture upside-down so we match the way cogl_read_pixels
-   * works)
-   */
+  viewport[0] = 0;
+  viewport[1] = 0;
+  viewport[2] = cogl_framebuffer_get_width (framebuffer);
+  viewport[3] = cogl_framebuffer_get_height (framebuffer);
 
+  cogl_framebuffer_get_viewport4fv (framebuffer, save_viewport);
   _cogl_framebuffer_push_projection (framebuffer);
   cogl_framebuffer_orthographic (framebuffer,
                                  0, 0,
-                                 viewport[2], viewport[3],
+                                 viewport[2],
+                                 viewport[3],
                                  0, 100);
 
   cogl_framebuffer_push_matrix (framebuffer);
@@ -856,36 +897,38 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
                                    COGL_PIPELINE_FILTER_NEAREST,
                                    COGL_PIPELINE_FILTER_NEAREST);
 
-  do_texture_draw_and_read (framebuffer,
-                            ctx->texture_download_pipeline,
-                            texture, target_bmp, viewport);
-
-  /* Check whether texture has alpha and framebuffer not */
-  /* FIXME: For some reason even if ALPHA_BITS is 8, the framebuffer
-     still doesn't seem to have an alpha buffer. This might be just
-     a PowerVR issue.
-  GLint r_bits, g_bits, b_bits, a_bits;
-  GE( ctx, glGetIntegerv (GL_ALPHA_BITS, &a_bits) );
-  GE( ctx, glGetIntegerv (GL_RED_BITS, &r_bits) );
-  GE( ctx, glGetIntegerv (GL_GREEN_BITS, &g_bits) );
-  GE( ctx, glGetIntegerv (GL_BLUE_BITS, &b_bits) );
-  printf ("R bits: %d\n", r_bits);
-  printf ("G bits: %d\n", g_bits);
-  printf ("B bits: %d\n", b_bits);
-  printf ("A bits: %d\n", a_bits); */
+  if (!do_texture_draw_and_read (framebuffer,
+                                 ctx->texture_download_pipeline,
+                                 texture, target_bmp, viewport,
+                                 error))
+    return FALSE;
+
+  /* XXX: As an alleged PowerVR driver bug workaround where the driver
+   * is apparently not maintaining the alpha component of some
+   * framebuffers we render the alpha component of the texture
+   * separately to be sure we retrieve all components of the texture.
+   *
+   * TODO: verify if this is still an issue
+   */
   if ((cogl_texture_get_format (texture) & COGL_A_BIT)/* && a_bits == 0*/)
     {
       uint8_t *srcdata;
       uint8_t *dstdata;
       uint8_t *srcpixel;
       uint8_t *dstpixel;
-      int x,y;
+      int target_width = cogl_bitmap_get_width (target_bmp);
+      int target_height = cogl_bitmap_get_height (target_bmp);
+      int target_rowstride = cogl_bitmap_get_rowstride (target_bmp);
+      int bpp = _cogl_pixel_format_get_bytes_per_pixel (COGL_PIXEL_FORMAT_RGBA_8888);
       int alpha_rowstride = bpp * target_width;
+      CoglBitmap *alpha_bmp;
+      int x,y;
 
       if ((dstdata = _cogl_bitmap_map (target_bmp,
                                        COGL_BUFFER_ACCESS_WRITE,
-                                       COGL_BUFFER_MAP_HINT_DISCARD)) == NULL)
-        return FALSE;
+                                       COGL_BUFFER_MAP_HINT_DISCARD,
+                                       error)) == NULL)
+        goto EXIT;
 
       /* Create temp bitmap for alpha values */
       alpha_bmp =
@@ -900,15 +943,24 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
                                        "RGBA = REPLACE (TEXTURE[A])",
                                        NULL);
 
-      do_texture_draw_and_read (framebuffer,
-                                ctx->texture_download_pipeline,
-                                texture, alpha_bmp, viewport);
+      if (!do_texture_draw_and_read (framebuffer,
+                                     ctx->texture_download_pipeline,
+                                     texture, alpha_bmp, viewport,
+                                     error))
+        {
+          cogl_object_unref (alpha_bmp);
+          _cogl_bitmap_unmap (target_bmp);
+          goto EXIT;
+        }
 
       /* Copy temp R to target A */
 
+      /* Note: we don't try to catch errors since "mapping" an
+       * malloc buffer should never fail */
       srcdata = _cogl_bitmap_map (alpha_bmp,
                                   COGL_BUFFER_ACCESS_READ,
-                                  0 /* hints */);
+                                  0 /* hints */,
+                                  NULL);
 
       for (y=0; y<target_height; ++y)
         {
@@ -929,11 +981,19 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
       cogl_object_unref (alpha_bmp);
     }
 
+  status = TRUE;
+
+EXIT:
   /* Restore old state */
   cogl_framebuffer_pop_matrix (framebuffer);
   _cogl_framebuffer_pop_projection (framebuffer);
+  cogl_framebuffer_set_viewport (framebuffer,
+                                 save_viewport[0],
+                                 save_viewport[1],
+                                 save_viewport[2],
+                                 save_viewport[3]);
 
-  return TRUE;
+  return status;
 }
 
 static CoglBool
@@ -951,6 +1011,7 @@ get_texture_bits_via_offscreen (CoglTexture    *texture,
   CoglFramebuffer *framebuffer;
   CoglBitmap *bitmap;
   CoglBool ret;
+  CoglError *ignore_error = NULL;
 
   if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
     return FALSE;
@@ -973,7 +1034,12 @@ get_texture_bits_via_offscreen (CoglTexture    *texture,
   ret = cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
                                                   x, y,
                                                   COGL_READ_PIXELS_COLOR_BUFFER,
-                                                  bitmap);
+                                                  bitmap,
+                                                  &ignore_error);
+
+  if (!ret)
+    cogl_error_free (ignore_error);
+
   cogl_object_unref (bitmap);
 
   cogl_object_unref (framebuffer);
@@ -1036,6 +1102,7 @@ typedef struct
   CoglBitmap *target_bmp;
   uint8_t *target_bits;
   CoglBool success;
+  CoglError *error;
 } CoglTextureGetData;
 
 static void
@@ -1120,6 +1187,7 @@ cogl_texture_get_data (CoglTexture *texture,
   int tex_width;
   int tex_height;
   CoglPixelFormat texture_format;
+  CoglError *ignore_error = NULL;
 
   CoglTextureGetData tg_data;
 
@@ -1196,50 +1264,68 @@ cogl_texture_get_data (CoglTexture *texture,
                                                       tex_width, tex_height,
                                                       closest_format);
 
-  tg_data.orig_width = tex_width;
-  tg_data.orig_height = tex_height;
-  tg_data.target_bmp = target_bmp;
   tg_data.target_bits = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE,
-                                          COGL_BUFFER_MAP_HINT_DISCARD);
-  if (tg_data.target_bits == NULL)
+                                          COGL_BUFFER_MAP_HINT_DISCARD,
+                                          &ignore_error);
+  if (tg_data.target_bits)
     {
-      cogl_object_unref (target_bmp);
-      return 0;
+      tg_data.orig_width = tex_width;
+      tg_data.orig_height = tex_height;
+      tg_data.target_bmp = target_bmp;
+      tg_data.error = NULL;
+      tg_data.success = TRUE;
+
+      /* If there are any dependent framebuffers on the texture then we
+         need to flush their journals so the texture contents will be
+         up-to-date */
+      _cogl_texture_flush_journal_rendering (texture);
+
+      /* Iterating through the subtextures allows piecing together
+       * the data for a sliced texture, and allows us to do the
+       * read-from-framebuffer logic here in a simple fashion rather than
+       * passing offsets down through the code. */
+      cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
+                                           0, 0, 1, 1,
+                                           COGL_PIPELINE_WRAP_MODE_REPEAT,
+                                           COGL_PIPELINE_WRAP_MODE_REPEAT,
+                                           texture_get_cb,
+                                           &tg_data);
+
+      _cogl_bitmap_unmap (target_bmp);
+    }
+  else
+    {
+      cogl_error_free (ignore_error);
+      tg_data.success = FALSE;
     }
-  tg_data.success = TRUE;
-
-  /* If there are any dependent framebuffers on the texture then we
-     need to flush their journals so the texture contents will be
-     up-to-date */
-  _cogl_texture_flush_journal_rendering (texture);
-
-  /* Iterating through the subtextures allows piecing together
-   * the data for a sliced texture, and allows us to do the
-   * read-from-framebuffer logic here in a simple fashion rather than
-   * passing offsets down through the code. */
-  cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
-                                       0, 0, 1, 1,
-                                       COGL_PIPELINE_WRAP_MODE_REPEAT,
-                                       COGL_PIPELINE_WRAP_MODE_REPEAT,
-                                       texture_get_cb,
-                                       &tg_data);
-
-  _cogl_bitmap_unmap (target_bmp);
 
   /* XXX: In some cases _cogl_texture_2d_download_from_gl may fail
    * to read back the texture data; such as for GLES which doesn't
    * support glGetTexImage, so here we fallback to drawing the
    * texture and reading the pixels from the framebuffer. */
   if (!tg_data.success)
-    _cogl_texture_draw_and_read (texture, target_bmp,
-                                 closest_gl_format,
-                                 closest_gl_type);
+    {
+      if (!_cogl_texture_draw_and_read (texture, target_bmp,
+                                        closest_gl_format,
+                                        closest_gl_type,
+                                        &ignore_error))
+        {
+          /* We have no more fallbacks so we just give up and
+           * hope for the best */
+          g_warning ("Failed to read texture since draw-and-read "
+                     "fallback failed: %s", ignore_error->message);
+          cogl_error_free (ignore_error);
+          cogl_object_unref (target_bmp);
+          return 0;
+        }
+    }
 
   /* Was intermediate used? */
   if (closest_format != format)
     {
       CoglBitmap *new_bmp;
       CoglBool result;
+      CoglError *error = NULL;
 
       /* Convert to requested format directly into the user's buffer */
       new_bmp = cogl_bitmap_new_for_data (ctx,
@@ -1247,11 +1333,14 @@ cogl_texture_get_data (CoglTexture *texture,
                                           format,
                                           rowstride,
                                           data);
-      result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp);
+      result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp, &error);
 
       if (!result)
-        /* Return failure after cleaning up */
-        byte_size = 0;
+        {
+          cogl_error_free (error);
+          /* Return failure after cleaning up */
+          byte_size = 0;
+        }
 
       cogl_object_unref (new_bmp);
     }
diff --git a/cogl/cogl-texture.h b/cogl/cogl-texture.h
index 0a61197..6bac91e 100644
--- a/cogl/cogl-texture.h
+++ b/cogl/cogl-texture.h
@@ -163,6 +163,7 @@ cogl_texture_new_from_file (const char       *filename,
  * @rowstride: the memory offset in bytes between the starts of
  *    scanlines in @data
  * @data: pointer the memory region where the source buffer resides
+ * @error: A #CoglError for returning exceptional errors
  *
  * Creates a new #CoglTexture based on data residing in memory.
  *
@@ -171,13 +172,15 @@ cogl_texture_new_from_file (const char       *filename,
  * Since: 0.8
  */
 CoglTexture *
-cogl_texture_new_from_data (unsigned int      width,
-                            unsigned int      height,
-                            CoglTextureFlags  flags,
-                            CoglPixelFormat   format,
-                            CoglPixelFormat   internal_format,
-                            unsigned int      rowstride,
-                            const uint8_t     *data);
+cogl_texture_new_from_data (CoglContext *ctx,
+                            int width,
+                            int height,
+                            CoglTextureFlags flags,
+                            CoglPixelFormat format,
+                            CoglPixelFormat internal_format,
+                            int rowstride,
+                            const uint8_t *data,
+                            CoglError **error);
 
 /**
  * cogl_texture_new_from_foreign:
@@ -229,7 +232,8 @@ cogl_texture_new_from_foreign (unsigned int gl_handle,
 CoglTexture *
 cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
                               CoglTextureFlags flags,
-                              CoglPixelFormat internal_format);
+                              CoglPixelFormat internal_format,
+                              CoglError **error);
 
 /**
  * cogl_is_texture:
@@ -363,6 +367,7 @@ cogl_texture_get_data (CoglTexture *texture,
  * @rowstride: rowstride of source buffer (computed from width if none
  * specified)
  * @data: the actual pixel data.
+ * @error: A #CoglError to return exceptional errors
  *
  * Sets the pixels in a rectangular subregion of @texture from an in-memory
  * buffer containing pixel data.
@@ -384,7 +389,8 @@ cogl_texture_set_region (CoglTexture *texture,
                          int height,
                          CoglPixelFormat format,
                          unsigned int rowstride,
-                         const uint8_t *data);
+                         const uint8_t *data,
+                         CoglError **error);
 
 /**
  * cogl_texture_set_region_from_bitmap:
@@ -398,6 +404,7 @@ cogl_texture_set_region (CoglTexture *texture,
  * @dst_height: height of destination region to write. (Must be less
  *   than or equal to the bitmap height)
  * @bitmap: The source bitmap to read from
+ * @error: A #CoglError to return exceptional errors
  *
  * Copies a specified source region from @bitmap to the position
  * (@src_x, @src_y) of the given destination texture @handle.
@@ -419,7 +426,8 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture,
                                      int dst_y,
                                      unsigned int dst_width,
                                      unsigned int dst_height,
-                                     CoglBitmap *bitmap);
+                                     CoglBitmap *bitmap,
+                                     CoglError **error);
 
 COGL_END_DECLS
 
diff --git a/cogl/cogl.symbols b/cogl/cogl.symbols
index da8f658..9c773dc 100644
--- a/cogl/cogl.symbols
+++ b/cogl/cogl.symbols
@@ -665,7 +665,6 @@ _cogl_system_error_domain
 _cogl_texture_associate_framebuffer
 _cogl_texture_can_hardware_repeat
 _cogl_texture_determine_internal_format
-_cogl_texture_draw_and_read
 _cogl_texture_ensure_non_quad_rendering
 _cogl_texture_flush_journal_rendering
 _cogl_texture_free
diff --git a/cogl/driver/gl/cogl-attribute-gl.c b/cogl/driver/gl/cogl-attribute-gl.c
index af89380..cf3f29c 100644
--- a/cogl/driver/gl/cogl-attribute-gl.c
+++ b/cogl/driver/gl/cogl-attribute-gl.c
@@ -467,8 +467,16 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
         {
           attribute_buffer = cogl_attribute_get_buffer (attribute);
           buffer = COGL_BUFFER (attribute_buffer);
-          base = _cogl_buffer_gl_bind (buffer,
-                                       COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER);
+
+          /* Note: we don't try and catch errors with binding buffers
+           * here since OOM errors at this point indicate that nothing
+           * has yet been uploaded to attribute buffer which we
+           * consider to be a programmer error.
+           */
+          base =
+            _cogl_buffer_gl_bind (buffer,
+                                  COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER,
+                                  NULL);
 
           if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL)
             setup_generic_buffered_attribute (ctx, pipeline, attribute, base);
diff --git a/cogl/driver/gl/cogl-buffer-gl-private.h b/cogl/driver/gl/cogl-buffer-gl-private.h
index 583e0c1..975927f 100644
--- a/cogl/driver/gl/cogl-buffer-gl-private.h
+++ b/cogl/driver/gl/cogl-buffer-gl-private.h
@@ -44,7 +44,8 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer,
                            size_t offset,
                            size_t size,
                            CoglBufferAccess access,
-                           CoglBufferMapHint hints);
+                           CoglBufferMapHint hints,
+                           CoglError **error);
 
 void
 _cogl_buffer_gl_unmap (CoglBuffer *buffer);
@@ -53,10 +54,13 @@ CoglBool
 _cogl_buffer_gl_set_data (CoglBuffer *buffer,
                           unsigned int offset,
                           const void *data,
-                          unsigned int size);
+                          unsigned int size,
+                          CoglError **error);
 
 void *
-_cogl_buffer_gl_bind (CoglBuffer *buffer, CoglBufferBindTarget target);
+_cogl_buffer_gl_bind (CoglBuffer *buffer,
+                      CoglBufferBindTarget target,
+                      CoglError **error);
 
 void
 _cogl_buffer_gl_unbind (CoglBuffer *buffer);
diff --git a/cogl/driver/gl/cogl-buffer-gl.c b/cogl/driver/gl/cogl-buffer-gl.c
index 673dbf1..e955437 100644
--- a/cogl/driver/gl/cogl-buffer-gl.c
+++ b/cogl/driver/gl/cogl-buffer-gl.c
@@ -31,6 +31,8 @@
 
 #include "cogl-context-private.h"
 #include "cogl-buffer-gl-private.h"
+#include "cogl-error-private.h"
+#include "cogl-util-gl-private.h"
 
 /*
  * GL/GLES compatibility defines for the buffer API:
@@ -126,22 +128,34 @@ convert_bind_target_to_gl_target (CoglBufferBindTarget target)
     }
 }
 
-static void
-recreate_store (CoglBuffer *buffer)
+static CoglBool
+recreate_store (CoglBuffer *buffer,
+                CoglError **error)
 {
+  CoglContext *ctx = buffer->context;
   GLenum gl_target;
   GLenum gl_enum;
+  GLenum gl_error;
 
   /* This assumes the buffer is already bound */
 
   gl_target = convert_bind_target_to_gl_target (buffer->last_target);
   gl_enum = update_hints_to_gl_enum (buffer);
 
-  GE( buffer->context, glBufferData (gl_target,
-                                     buffer->size,
-                                     NULL,
-                                     gl_enum) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glBufferData (gl_target,
+                     buffer->size,
+                     NULL,
+                     gl_enum);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    return FALSE;
+
   buffer->store_created = TRUE;
+  return TRUE;
 }
 
 GLenum
@@ -188,19 +202,26 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer,
                            size_t offset,
                            size_t size,
                            CoglBufferAccess access,
-                           CoglBufferMapHint hints)
+                           CoglBufferMapHint hints,
+                           CoglError **error)
 {
   uint8_t *data;
   CoglBufferBindTarget target;
   GLenum gl_target;
   CoglContext *ctx = buffer->context;
+  GLenum gl_error;
 
-  if ((access & COGL_BUFFER_ACCESS_READ) &&
-      !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ))
-    return NULL;
-  if ((access & COGL_BUFFER_ACCESS_WRITE) &&
-      !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))
-    return NULL;
+  if (((access & COGL_BUFFER_ACCESS_READ) &&
+       !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) ||
+      ((access & COGL_BUFFER_ACCESS_WRITE) &&
+       !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE)))
+    {
+      _cogl_set_error (error,
+                       COGL_SYSTEM_ERROR,
+                       COGL_SYSTEM_ERROR_UNSUPPORTED,
+                       "Tried to map a buffer with unsupported access mode");
+      return NULL;
+    }
 
   target = buffer->last_target;
   _cogl_buffer_bind_no_create (buffer, target);
@@ -226,14 +247,30 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer,
         gl_access |= GL_MAP_INVALIDATE_RANGE_BIT;
 
       if (!buffer->store_created)
-        recreate_store (buffer);
-
-      GE_RET( data,
-              ctx,
-              glMapBufferRange (gl_target,
-                                offset,
-                                size,
-                                gl_access) );
+        {
+          if (!recreate_store (buffer, error))
+            {
+              _cogl_buffer_gl_unbind (buffer);
+              return NULL;
+            }
+        }
+
+      /* Clear any GL errors */
+      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+        ;
+
+      data = ctx->glMapBufferRange (gl_target,
+                                    offset,
+                                    size,
+                                    gl_access);
+
+      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+        {
+          _cogl_buffer_gl_unbind (buffer);
+          return NULL;
+        }
+
+      _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
     }
   else
     {
@@ -244,15 +281,30 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer,
           (hints & COGL_BUFFER_MAP_HINT_DISCARD) ||
           ((hints & COGL_BUFFER_MAP_HINT_DISCARD_RANGE) &&
            offset == 0 && size >= buffer->size))
-        recreate_store (buffer);
-
-      GE_RET( data,
-              ctx,
-              glMapBuffer (gl_target,
-                           _cogl_buffer_access_to_gl_enum (access)) );
-
-      if (data)
-        data += offset;
+        {
+          if (!recreate_store (buffer, error))
+            {
+              _cogl_buffer_gl_unbind (buffer);
+              return NULL;
+            }
+        }
+
+      /* Clear any GL errors */
+      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+        ;
+
+      data = ctx->glMapBuffer (gl_target,
+                               _cogl_buffer_access_to_gl_enum (access));
+
+      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+        {
+          _cogl_buffer_gl_unbind (buffer);
+          return NULL;
+        }
+
+      _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
+
+      data += offset;
     }
 
   if (data)
@@ -281,26 +333,50 @@ CoglBool
 _cogl_buffer_gl_set_data (CoglBuffer *buffer,
                           unsigned int offset,
                           const void *data,
-                          unsigned int size)
+                          unsigned int size,
+                          CoglError **error)
 {
   CoglBufferBindTarget target;
   GLenum gl_target;
   CoglContext *ctx = buffer->context;
+  GLenum gl_error;
+  CoglBool status = TRUE;
+  CoglError *internal_error = NULL;
 
   target = buffer->last_target;
-  _cogl_buffer_gl_bind (buffer, target);
+
+  _cogl_buffer_gl_bind (buffer, target, &internal_error);
+
+  /* NB: _cogl_buffer_gl_bind() may return NULL in non-error
+   * conditions so we have to explicity check internal_error
+   * to see if an exception was thrown.
+   */
+  if (internal_error)
+    {
+      _cogl_propogate_error (error, internal_error);
+      return FALSE;
+    }
 
   gl_target = convert_bind_target_to_gl_target (target);
 
-  GE( ctx, glBufferSubData (gl_target, offset, size, data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glBufferSubData (gl_target, offset, size, data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_buffer_gl_unbind (buffer);
 
-  return TRUE;
+  return status;
 }
 
 void *
-_cogl_buffer_gl_bind (CoglBuffer *buffer, CoglBufferBindTarget target)
+_cogl_buffer_gl_bind (CoglBuffer *buffer,
+                      CoglBufferBindTarget target,
+                      CoglError **error)
 {
   void *ret;
 
@@ -311,7 +387,13 @@ _cogl_buffer_gl_bind (CoglBuffer *buffer, CoglBufferBindTarget target)
    * store is created. */
   if ((buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) &&
       !buffer->store_created)
-    recreate_store (buffer);
+    {
+      if (!recreate_store (buffer, error))
+        {
+          _cogl_buffer_gl_unbind (buffer);
+          return NULL;
+        }
+    }
 
   return ret;
 }
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index 4a6f62a..43874f6 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -1067,7 +1067,14 @@ _cogl_framebuffer_gl_draw_indexed_attributes (CoglFramebuffer *framebuffer,
                                 attributes, n_attributes);
 
   buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
-  base = _cogl_buffer_gl_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
+
+  /* Note: we don't try and catch errors with binding the index buffer
+   * here since OOM errors at this point indicate that nothing has yet
+   * been uploaded to the indices buffer which we consider to be a
+   * programmer error.
+   */
+  base = _cogl_buffer_gl_bind (buffer,
+                               COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, NULL);
   buffer_offset = cogl_indices_get_offset (indices);
   index_size = sizeof_index_type (cogl_indices_get_type (indices));
 
diff --git a/cogl/driver/gl/cogl-texture-2d-gl-private.h b/cogl/driver/gl/cogl-texture-2d-gl-private.h
index 52378ff..ac0c89f 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl-private.h
+++ b/cogl/driver/gl/cogl-texture-2d-gl-private.h
@@ -93,7 +93,7 @@ _cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d);
 void
 _cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d);
 
-void
+CoglBool
 _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
                                       CoglBitmap *bitmap,
                                       int dst_x,
@@ -101,7 +101,8 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
                                       int src_x,
                                       int src_y,
                                       int width,
-                                      int height);
+                                      int height,
+                                      CoglError **error);
 
 void
 _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d,
diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c
index 6d4ec2f..96a70ca 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -143,20 +143,16 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
   GLenum gl_intformat;
   GLenum gl_format;
   GLenum gl_type;
-  uint8_t *data;
-
-  if ((dst_bmp = _cogl_texture_prepare_for_upload (bmp,
-                                                   internal_format,
-                                                   &internal_format,
-                                                   &gl_intformat,
-                                                   &gl_format,
-                                                   &gl_type)) == NULL)
-    {
-      _cogl_set_error (error, COGL_TEXTURE_ERROR,
-                       COGL_TEXTURE_ERROR_FORMAT,
-                       "Failed to prepare texture upload due to format");
-      return NULL;
-    }
+
+  dst_bmp = _cogl_texture_prepare_for_upload (bmp,
+                                              internal_format,
+                                              &internal_format,
+                                              &gl_intformat,
+                                              &gl_format,
+                                              &gl_type,
+                                              error);
+  if (!dst_bmp)
+    return NULL;
 
   tex_2d = _cogl_texture_2d_create_base (ctx,
                                          cogl_bitmap_get_width (bmp),
@@ -165,29 +161,49 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,
 
   /* Keep a copy of the first pixel so that if glGenerateMipmap isn't
      supported we can fallback to using GL_GENERATE_MIPMAP */
-  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
-      (data = _cogl_bitmap_map (dst_bmp,
-                                COGL_BUFFER_ACCESS_READ, 0)))
+  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
     {
+      CoglError *ignore = NULL;
+      uint8_t *data = _cogl_bitmap_map (dst_bmp,
+                                        COGL_BUFFER_ACCESS_READ, 0,
+                                        &ignore);
       CoglPixelFormat format = cogl_bitmap_get_format (dst_bmp);
+
       tex_2d->first_pixel.gl_format = gl_format;
       tex_2d->first_pixel.gl_type = gl_type;
-      memcpy (tex_2d->first_pixel.data, data,
-              _cogl_pixel_format_get_bytes_per_pixel (format));
 
-      _cogl_bitmap_unmap (dst_bmp);
+      if (data)
+        {
+          memcpy (tex_2d->first_pixel.data, data,
+                  _cogl_pixel_format_get_bytes_per_pixel (format));
+          _cogl_bitmap_unmap (dst_bmp);
+        }
+      else
+        {
+          g_warning ("Failed to read first pixel of bitmap for "
+                     "glGenerateMipmap fallback");
+          cogl_error_free (ignore);
+          memset (tex_2d->first_pixel.data, 0,
+                  _cogl_pixel_format_get_bytes_per_pixel (format));
+        }
     }
 
   tex_2d->gl_texture =
     ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format);
-  ctx->texture_driver->upload_to_gl (ctx,
-                                     GL_TEXTURE_2D,
-                                     tex_2d->gl_texture,
-                                     FALSE,
-                                     dst_bmp,
-                                     gl_intformat,
-                                     gl_format,
-                                     gl_type);
+  if (!ctx->texture_driver->upload_to_gl (ctx,
+                                          GL_TEXTURE_2D,
+                                          tex_2d->gl_texture,
+                                          FALSE,
+                                          dst_bmp,
+                                          gl_intformat,
+                                          gl_format,
+                                          gl_type,
+                                          error))
+    {
+      cogl_object_unref (dst_bmp);
+      cogl_object_unref (tex_2d);
+      return NULL;
+    }
 
   tex_2d->gl_format = gl_intformat;
 
@@ -502,7 +518,7 @@ _cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d)
 #endif
 }
 
-void
+CoglBool
 _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
                                       CoglBitmap *bmp,
                                       int dst_x,
@@ -510,50 +526,70 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
                                       int src_x,
                                       int src_y,
                                       int width,
-                                      int height)
+                                      int height,
+                                      CoglError **error)
 {
   CoglTexture *tex = COGL_TEXTURE (tex_2d);
   CoglContext *ctx = tex->context;
   GLenum gl_format;
   GLenum gl_type;
-  uint8_t *data;
+  CoglBool status = TRUE;
 
   bmp = _cogl_texture_prepare_for_upload (bmp,
                                           cogl_texture_get_format (tex),
                                           NULL,
                                           NULL,
                                           &gl_format,
-                                          &gl_type);
+                                          &gl_type,
+                                          error);
+  if (!bmp)
+    return FALSE;
 
   /* If this touches the first pixel then we'll update our copy */
   if (dst_x == 0 && dst_y == 0 &&
-      !cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
-      (data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0)))
+      !cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
     {
+      CoglError *ignore = NULL;
+      uint8_t *data =
+        _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore);
       CoglPixelFormat bpp =
         _cogl_pixel_format_get_bytes_per_pixel (cogl_bitmap_get_format (bmp));
+
       tex_2d->first_pixel.gl_format = gl_format;
       tex_2d->first_pixel.gl_type = gl_type;
-      memcpy (tex_2d->first_pixel.data,
-              data + cogl_bitmap_get_rowstride (bmp) * src_y + bpp * src_x,
-              bpp);
 
-      _cogl_bitmap_unmap (bmp);
+      if (data)
+        {
+          memcpy (tex_2d->first_pixel.data,
+                  data + cogl_bitmap_get_rowstride (bmp) * src_y + bpp * src_x,
+                  bpp);
+          _cogl_bitmap_unmap (bmp);
+        }
+      else
+        {
+          g_warning ("Failed to read first bitmap pixel for "
+                     "glGenerateMipmap fallback");
+          cogl_error_free (ignore);
+          memset (tex_2d->first_pixel.data, 0, bpp);
+        }
     }
 
   /* Send data to GL */
-  ctx->texture_driver->upload_subregion_to_gl (ctx,
-                                               GL_TEXTURE_2D,
-                                               tex_2d->gl_texture,
-                                               FALSE,
-                                               src_x, src_y,
-                                               dst_x, dst_y,
-                                               width, height,
-                                               bmp,
-                                               gl_format,
-                                               gl_type);
+  status = ctx->texture_driver->upload_subregion_to_gl (ctx,
+                                                        GL_TEXTURE_2D,
+                                                        tex_2d->gl_texture,
+                                                        FALSE,
+                                                        src_x, src_y,
+                                                        dst_x, dst_y,
+                                                        width, height,
+                                                        bmp,
+                                                        gl_format,
+                                                        gl_type,
+                                                        error);
 
   cogl_object_unref (bmp);
+
+  return status;
 }
 
 void
diff --git a/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/gl/cogl-texture-driver-gl.c
index 87c33ba..2443b16 100644
--- a/cogl/driver/gl/gl/cogl-texture-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-texture-driver-gl.c
@@ -39,6 +39,8 @@
 #include "cogl-context-private.h"
 #include "cogl-object-private.h"
 #include "cogl-pipeline-opengl-private.h"
+#include "cogl-util-gl-private.h"
+#include "cogl-error-private.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -163,26 +165,39 @@ _cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx,
                                     pixels_bpp);
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
-                                             GLenum       gl_target,
-                                             GLuint       gl_handle,
-                                             CoglBool     is_foreign,
-                                             int          src_x,
-                                             int          src_y,
-                                             int          dst_x,
-                                             int          dst_y,
-                                             int          width,
-                                             int          height,
+                                             GLenum gl_target,
+                                             GLuint gl_handle,
+                                             CoglBool is_foreign,
+                                             int src_x,
+                                             int src_y,
+                                             int dst_x,
+                                             int dst_y,
+                                             int width,
+                                             int height,
                                              CoglBitmap  *source_bmp,
-				             GLuint       source_gl_format,
-				             GLuint       source_gl_type)
+				             GLuint source_gl_format,
+				             GLuint source_gl_type,
+                                             CoglError **error)
 {
   uint8_t *data;
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
+  GLenum gl_error;
+  CoglBool status = TRUE;
+  CoglError *internal_error = NULL;
+
+  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
 
-  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);
+  /* NB: _cogl_bitmap_gl_bind() may return NULL when successfull so we
+   * have to explicitly check the cogl error pointer to catch
+   * problems... */
+  if (internal_error)
+    {
+      _cogl_propogate_error (error, internal_error);
+      return FALSE;
+    }
 
   /* Setup gl alignment to match rowstride and top-left corner */
   prep_gl_for_pixels_upload_full (ctx,
@@ -194,31 +209,45 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
-  GE( ctx, glTexSubImage2D (gl_target, 0,
-                            dst_x, dst_y,
-                            width, height,
-                            source_gl_format,
-                            source_gl_type,
-                            data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexSubImage2D (gl_target, 0,
+                        dst_x, dst_y,
+                        width, height,
+                        source_gl_format,
+                        source_gl_type,
+                        data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_bitmap_gl_unbind (source_bmp);
+
+  return status;
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
-                                   GLenum       gl_target,
-                                   GLuint       gl_handle,
-                                   CoglBool     is_foreign,
-                                   CoglBitmap  *source_bmp,
-                                   GLint        internal_gl_format,
-                                   GLuint       source_gl_format,
-                                   GLuint       source_gl_type)
+                                   GLenum gl_target,
+                                   GLuint gl_handle,
+                                   CoglBool is_foreign,
+                                   CoglBitmap *source_bmp,
+                                   GLint internal_gl_format,
+                                   GLuint source_gl_format,
+                                   GLuint source_gl_type,
+                                   CoglError **error)
 {
   uint8_t *data;
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
+  GLenum gl_error;
+  CoglBool status = TRUE;
 
-  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);
+  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
+  if (!data)
+    return FALSE;
 
   /* Setup gl alignment to match rowstride and top-left corner */
   prep_gl_for_pixels_upload_full (ctx,
@@ -227,35 +256,49 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
-  GE( ctx, glTexImage2D (gl_target, 0,
-                         internal_gl_format,
-                         cogl_bitmap_get_width (source_bmp),
-                         cogl_bitmap_get_height (source_bmp),
-                         0,
-                         source_gl_format,
-                         source_gl_type,
-                         data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexImage2D (gl_target, 0,
+                     internal_gl_format,
+                     cogl_bitmap_get_width (source_bmp),
+                     cogl_bitmap_get_height (source_bmp),
+                     0,
+                     source_gl_format,
+                     source_gl_type,
+                     data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_bitmap_gl_unbind (source_bmp);
+
+  return status;
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
-                                      GLenum       gl_target,
-                                      GLuint       gl_handle,
-                                      CoglBool     is_foreign,
-                                      GLint        height,
-                                      GLint        depth,
-                                      CoglBitmap  *source_bmp,
-                                      GLint        internal_gl_format,
-                                      GLuint       source_gl_format,
-                                      GLuint       source_gl_type)
+                                      GLenum gl_target,
+                                      GLuint gl_handle,
+                                      CoglBool is_foreign,
+                                      GLint height,
+                                      GLint depth,
+                                      CoglBitmap *source_bmp,
+                                      GLint internal_gl_format,
+                                      GLuint source_gl_format,
+                                      GLuint source_gl_type,
+                                      CoglError **error)
 {
   uint8_t *data;
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
+  GLenum gl_error;
+  CoglBool status = TRUE;
 
-  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);
+  data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
+  if (!data)
+    return FALSE;
 
   /* Setup gl alignment to match rowstride and top-left corner */
   prep_gl_for_pixels_upload_full (ctx,
@@ -266,18 +309,27 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
-  GE( ctx, glTexImage3D (gl_target,
-                         0, /* level */
-                         internal_gl_format,
-                         cogl_bitmap_get_width (source_bmp),
-                         height,
-                         depth,
-                         0,
-                         source_gl_format,
-                         source_gl_type,
-                         data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexImage3D (gl_target,
+                     0, /* level */
+                     internal_gl_format,
+                     cogl_bitmap_get_width (source_bmp),
+                     height,
+                     depth,
+                     0,
+                     source_gl_format,
+                     source_gl_type,
+                     data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_bitmap_gl_unbind (source_bmp);
+
+  return status;
 }
 
 static CoglBool
diff --git a/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/driver/gl/gles/cogl-texture-driver-gles.c
index 1e45a53..6a9d064 100644
--- a/cogl/driver/gl/gles/cogl-texture-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-texture-driver-gles.c
@@ -39,6 +39,8 @@
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-context-private.h"
 #include "cogl-object-private.h"
+#include "cogl-util-gl-private.h"
+#include "cogl-error-private.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -139,7 +141,8 @@ _cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx,
 
 static CoglBitmap *
 prepare_bitmap_alignment_for_upload (CoglContext *ctx,
-                                     CoglBitmap *src_bmp)
+                                     CoglBitmap *src_bmp,
+                                     CoglError **error)
 {
   CoglPixelFormat format = cogl_bitmap_get_format (src_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
@@ -162,29 +165,33 @@ prepare_bitmap_alignment_for_upload (CoglContext *ctx,
   /* Otherwise we need to copy the bitmap to pack the alignment
      because GLES has no GL_ROW_LENGTH */
   else
-    return _cogl_bitmap_copy (src_bmp);
+    return _cogl_bitmap_copy (src_bmp, error);
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
-                                             GLenum       gl_target,
-                                             GLuint       gl_handle,
-                                             CoglBool     is_foreign,
-                                             int          src_x,
-                                             int          src_y,
-                                             int          dst_x,
-                                             int          dst_y,
-                                             int          width,
-                                             int          height,
-                                             CoglBitmap  *source_bmp,
-				             GLuint       source_gl_format,
-				             GLuint       source_gl_type)
+                                             GLenum gl_target,
+                                             GLuint gl_handle,
+                                             CoglBool is_foreign,
+                                             int src_x,
+                                             int src_y,
+                                             int dst_x,
+                                             int dst_y,
+                                             int width,
+                                             int height,
+                                             CoglBitmap *source_bmp,
+				             GLuint source_gl_format,
+				             GLuint source_gl_type,
+                                             CoglError **error)
 {
   uint8_t *data;
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
   CoglBitmap *slice_bmp;
   int rowstride;
+  GLenum gl_error;
+  CoglBool status = TRUE;
+  CoglError *internal_error = NULL;
 
   /* If we have the GL_EXT_unpack_subimage extension then we can
      upload from subregions directly. Otherwise we may need to copy
@@ -198,47 +205,76 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
         _cogl_bitmap_new_with_malloc_buffer (ctx,
                                              width, height,
                                              source_format);
-      _cogl_bitmap_copy_subregion (source_bmp,
-                                   slice_bmp,
-                                   src_x, src_y,
-                                   0, 0, /* dst_x/y */
-                                   width, height);
+      if (!_cogl_bitmap_copy_subregion (source_bmp,
+                                        slice_bmp,
+                                        src_x, src_y,
+                                        0, 0, /* dst_x/y */
+                                        width, height,
+                                        error))
+        {
+          cogl_object_unref (slice_bmp);
+          return FALSE;
+        }
 
       src_x = src_y = 0;
     }
   else
-    slice_bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp);
+    {
+      slice_bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error);
+      if (!slice_bmp)
+        return FALSE;
+    }
 
   rowstride = cogl_bitmap_get_rowstride (slice_bmp);
 
   /* Setup gl alignment to match rowstride and top-left corner */
   prep_gl_for_pixels_upload_full (ctx, rowstride, src_x, src_y, bpp);
 
-  data = _cogl_bitmap_gl_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0);
+  data = _cogl_bitmap_gl_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
+
+  /* NB: _cogl_bitmap_gl_bind() may return NULL when successfull so we
+   * have to explicitly check the cogl error pointer to catch
+   * problems... */
+  if (internal_error)
+    {
+      _cogl_propogate_error (error, internal_error);
+      cogl_object_unref (slice_bmp);
+      return FALSE;
+    }
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
-  GE( ctx, glTexSubImage2D (gl_target, 0,
-                            dst_x, dst_y,
-                            width, height,
-                            source_gl_format,
-                            source_gl_type,
-                            data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexSubImage2D (gl_target, 0,
+                        dst_x, dst_y,
+                        width, height,
+                        source_gl_format,
+                        source_gl_type,
+                        data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_bitmap_gl_unbind (slice_bmp);
 
   cogl_object_unref (slice_bmp);
+
+  return status;
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
-                                   GLenum       gl_target,
-                                   GLuint       gl_handle,
-                                   CoglBool     is_foreign,
-                                   CoglBitmap  *source_bmp,
-                                   GLint        internal_gl_format,
-                                   GLuint       source_gl_format,
-                                   GLuint       source_gl_type)
+                                   GLenum gl_target,
+                                   GLuint gl_handle,
+                                   CoglBool is_foreign,
+                                   CoglBitmap *source_bmp,
+                                   GLint internal_gl_format,
+                                   GLuint source_gl_format,
+                                   GLuint source_gl_type,
+                                   CoglError **error)
 {
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
@@ -247,8 +283,13 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
   int bmp_height = cogl_bitmap_get_height (source_bmp);
   CoglBitmap *bmp;
   uint8_t *data;
+  GLenum gl_error;
+  CoglBool status = TRUE;
+
+  bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error);
+  if (!bmp)
+    return FALSE;
 
-  bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp);
   rowstride = cogl_bitmap_get_rowstride (bmp);
 
   /* Setup gl alignment to match rowstride and top-left corner */
@@ -256,32 +297,47 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
-  data = _cogl_bitmap_gl_bind (bmp, COGL_BUFFER_ACCESS_READ, 0);
+  data = _cogl_bitmap_gl_bind (bmp, COGL_BUFFER_ACCESS_READ, 0, error);
+  if (!data)
+    {
+      cogl_object_unref (bmp);
+      return FALSE;
+    }
 
-  GE( ctx, glTexImage2D (gl_target, 0,
-                         internal_gl_format,
-                         bmp_width, bmp_height,
-                         0,
-                         source_gl_format,
-                         source_gl_type,
-                         data) );
+  /* Clear any GL errors */
+  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+    ;
+
+  ctx->glTexImage2D (gl_target, 0,
+                     internal_gl_format,
+                     bmp_width, bmp_height,
+                     0,
+                     source_gl_format,
+                     source_gl_type,
+                     data);
+
+  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+    status = FALSE;
 
   _cogl_bitmap_gl_unbind (bmp);
 
   cogl_object_unref (bmp);
+
+  return status;
 }
 
-static void
+static CoglBool
 _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
-                                      GLenum       gl_target,
-                                      GLuint       gl_handle,
-                                      CoglBool     is_foreign,
-                                      GLint        height,
-                                      GLint        depth,
-                                      CoglBitmap  *source_bmp,
-                                      GLint        internal_gl_format,
-                                      GLuint       source_gl_format,
-                                      GLuint       source_gl_type)
+                                      GLenum gl_target,
+                                      GLuint gl_handle,
+                                      CoglBool is_foreign,
+                                      GLint height,
+                                      GLint depth,
+                                      CoglBitmap *source_bmp,
+                                      GLint internal_gl_format,
+                                      GLuint source_gl_format,
+                                      GLuint source_gl_type,
+                                      CoglError **error)
 {
   CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
   int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
@@ -289,6 +345,7 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
   int bmp_width = cogl_bitmap_get_width (source_bmp);
   int bmp_height = cogl_bitmap_get_height (source_bmp);
   uint8_t *data;
+  GLenum gl_error;
 
   _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);
 
@@ -308,16 +365,23 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
       /* Initialize the texture with empty data and then upload each
          image with a sub-region update */
 
-      GE( ctx, glTexImage3D (gl_target,
-                             0, /* level */
-                             internal_gl_format,
-                             bmp_width,
-                             height,
-                             depth,
-                             0,
-                             source_gl_format,
-                             source_gl_type,
-                             NULL) );
+      /* Clear any GL errors */
+      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+        ;
+
+      ctx->glTexImage3D (gl_target,
+                         0, /* level */
+                         internal_gl_format,
+                         bmp_width,
+                         height,
+                         depth,
+                         0,
+                         source_gl_format,
+                         source_gl_type,
+                         NULL);
+
+      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+        return FALSE;
 
       bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
                                                  bmp_width,
@@ -326,27 +390,48 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
 
       for (i = 0; i < depth; i++)
         {
-          _cogl_bitmap_copy_subregion (source_bmp,
-                                       bmp,
-                                       0, image_height * i,
-                                       0, 0,
-                                       bmp_width,
-                                       height);
+          if (!_cogl_bitmap_copy_subregion (source_bmp,
+                                            bmp,
+                                            0, image_height * i,
+                                            0, 0,
+                                            bmp_width,
+                                            height,
+                                            error))
+            {
+              cogl_object_unref (bmp);
+              return FALSE;
+            }
 
           data = _cogl_bitmap_gl_bind (bmp,
-                                       COGL_BUFFER_ACCESS_READ, 0);
-
-          GE( ctx, glTexSubImage3D (gl_target,
-                                    0, /* level */
-                                    0, /* xoffset */
-                                    0, /* yoffset */
-                                    i, /* zoffset */
-                                    bmp_width, /* width */
-                                    height, /* height */
-                                    1, /* depth */
-                                    source_gl_format,
-                                    source_gl_type,
-                                    data) );
+                                       COGL_BUFFER_ACCESS_READ, 0, error);
+          if (!data)
+            {
+              cogl_object_unref (bmp);
+              return FALSE;
+            }
+
+          /* Clear any GL errors */
+          while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+            ;
+
+          ctx->glTexSubImage3D (gl_target,
+                                0, /* level */
+                                0, /* xoffset */
+                                0, /* yoffset */
+                                i, /* zoffset */
+                                bmp_width, /* width */
+                                height, /* height */
+                                1, /* depth */
+                                source_gl_format,
+                                source_gl_type,
+                                data);
+
+          if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+            {
+              cogl_object_unref (bmp);
+              _cogl_bitmap_gl_unbind (bmp);
+              return FALSE;
+            }
 
           _cogl_bitmap_gl_unbind (bmp);
         }
@@ -355,23 +440,37 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx,
     }
   else
     {
-      data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);
+      data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
+      if (!data)
+        return FALSE;
 
       _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp);
 
-      GE( ctx, glTexImage3D (gl_target,
-                             0, /* level */
-                             internal_gl_format,
-                             bmp_width,
-                             height,
-                             depth,
-                             0,
-                             source_gl_format,
-                             source_gl_type,
-                             data) );
+      /* Clear any GL errors */
+      while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
+        ;
+
+      ctx->glTexImage3D (gl_target,
+                         0, /* level */
+                         internal_gl_format,
+                         bmp_width,
+                         height,
+                         depth,
+                         0,
+                         source_gl_format,
+                         source_gl_type,
+                         data);
+
+      if (_cogl_gl_util_catch_out_of_memory (ctx, error))
+        {
+          _cogl_bitmap_gl_unbind (source_bmp);
+          return FALSE;
+        }
 
       _cogl_bitmap_gl_unbind (source_bmp);
     }
+
+  return TRUE;
 }
 
 /* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead
diff --git a/cogl/driver/nop/cogl-texture-2d-nop-private.h b/cogl/driver/nop/cogl-texture-2d-nop-private.h
index 5374cad..957a194 100644
--- a/cogl/driver/nop/cogl-texture-2d-nop-private.h
+++ b/cogl/driver/nop/cogl-texture-2d-nop-private.h
@@ -93,7 +93,7 @@ _cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d);
 void
 _cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d);
 
-void
+CoglBool
 _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d,
                                        CoglBitmap *bitmap,
                                        int dst_x,
@@ -101,7 +101,8 @@ _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d,
                                        int src_x,
                                        int src_y,
                                        int width,
-                                       int height);
+                                       int height,
+                                       CoglError **error);
 
 void
 _cogl_texture_2d_nop_get_data (CoglTexture2D *tex_2d,
diff --git a/cogl/driver/nop/cogl-texture-2d-nop.c b/cogl/driver/nop/cogl-texture-2d-nop.c
index ea4e321..5118e26 100644
--- a/cogl/driver/nop/cogl-texture-2d-nop.c
+++ b/cogl/driver/nop/cogl-texture-2d-nop.c
@@ -135,7 +135,7 @@ _cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d)
 {
 }
 
-void
+CoglBool
 _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d,
                                        CoglBitmap *bitmap,
                                        int dst_x,
@@ -143,8 +143,10 @@ _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d,
                                        int src_x,
                                        int src_y,
                                        int width,
-                                       int height)
+                                       int height,
+                                       CoglError **error)
 {
+  return TRUE;
 }
 
 void
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
index 397cda3..ddeee44 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11.c
+++ b/cogl/winsys/cogl-texture-pixmap-x11.c
@@ -480,6 +480,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
   XImage *image;
   int src_x, src_y;
   int x, y, width, height;
+  CoglError *ignore = NULL;
 
   display = cogl_xlib_get_display ();
   visual = tex_pixmap->visual;
@@ -591,7 +592,8 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
                            image->height,
                            image_format,
                            image->bytes_per_line,
-                           (const uint8_t *) image->data);
+                           (const uint8_t *) image->data,
+                           &ignore);
 
   /* If we have a shared memory segment then the XImage would be a
      temporary one with no data allocated so we can just XFree it */
@@ -677,17 +679,22 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
 }
 
 static CoglBool
-_cogl_texture_pixmap_x11_set_region (CoglTexture     *tex,
-                                     int              src_x,
-                                     int              src_y,
-                                     int              dst_x,
-                                     int              dst_y,
-                                     unsigned int     dst_width,
-                                     unsigned int     dst_height,
-                                     CoglBitmap      *bmp)
+_cogl_texture_pixmap_x11_set_region (CoglTexture *tex,
+                                     int src_x,
+                                     int src_y,
+                                     int dst_x,
+                                     int dst_y,
+                                     int dst_width,
+                                     int dst_height,
+                                     CoglBitmap *bmp,
+                                     CoglError **error)
 {
   /* This doesn't make much sense for texture from pixmap so it's not
      supported */
+  _cogl_set_error (error,
+                   COGL_SYSTEM_ERROR,
+                   COGL_SYSTEM_ERROR_UNSUPPORTED,
+                   "Explicitly setting a region of a TFP texture unsupported");
   return FALSE;
 }
 
diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
index 5d58d10..654a23d 100644
--- a/doc/reference/cogl2/cogl2-sections.txt
+++ b/doc/reference/cogl2/cogl2-sections.txt
@@ -685,6 +685,7 @@ cogl_buffer_usage_hint_get_type
 <FILE>cogl-attribute-buffer</FILE>
 <TITLE>CoglAttributeBuffer: Buffers of vertex attributes</TITLE>
 CoglAttributeBuffer
+cogl_attribute_buffer_new_with_size
 cogl_attribute_buffer_new
 cogl_is_attribute_buffer
 </SECTION>
diff --git a/tests/conform/test-alpha-textures.c b/tests/conform/test-alpha-textures.c
index 9063b80..1861536 100644
--- a/tests/conform/test-alpha-textures.c
+++ b/tests/conform/test-alpha-textures.c
@@ -70,7 +70,8 @@ test_alpha_textures (void)
                            1, 1, /* width / height */
                            COGL_PIXEL_FORMAT_A_8,
                            1, /* rowstride */
-                           replacement_data);
+                           replacement_data,
+                           NULL); /* abort on error */
 
   cogl_framebuffer_draw_rectangle (test_fb,
                                    pipeline2,
diff --git a/tests/conform/test-atlas-migration.c b/tests/conform/test-atlas-migration.c
index 55660a8..21f375a 100644
--- a/tests/conform/test-atlas-migration.c
+++ b/tests/conform/test-atlas-migration.c
@@ -53,7 +53,8 @@ create_texture (int size)
         }
     }
 
-  texture = cogl_texture_new_from_data (size, /* width */
+  texture = cogl_texture_new_from_data (test_ctx,
+                                        size, /* width */
                                         size, /* height */
                                         COGL_TEXTURE_NONE, /* flags */
                                         /* format */
@@ -62,7 +63,8 @@ create_texture (int size)
                                         COGL_PIXEL_FORMAT_RGBA_8888,
                                         /* rowstride */
                                         size * 4,
-                                        data);
+                                        data,
+                                        NULL); /* don't catch errors */
 
   g_free (data);
 
diff --git a/tests/conform/test-backface-culling.c b/tests/conform/test-backface-culling.c
index e952680..13dde32 100644
--- a/tests/conform/test-backface-culling.c
+++ b/tests/conform/test-backface-culling.c
@@ -210,13 +210,15 @@ make_texture (void)
       *(--p) = 255;
     }
 
-  tex = cogl_texture_new_from_data (TEXTURE_SIZE,
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    TEXTURE_SIZE,
                                     TEXTURE_SIZE,
                                     COGL_TEXTURE_NO_ATLAS,
                                     COGL_PIXEL_FORMAT_RGBA_8888,
                                     COGL_PIXEL_FORMAT_ANY,
                                     TEXTURE_SIZE * 4,
-                                    tex_data);
+                                    tex_data,
+                                    NULL); /* don't catch errors */
 
   g_free (tex_data);
 
diff --git a/tests/conform/test-blend-strings.c b/tests/conform/test-blend-strings.c
index 5907428..0cabc55 100644
--- a/tests/conform/test-blend-strings.c
+++ b/tests/conform/test-blend-strings.c
@@ -144,13 +144,15 @@ make_texture (uint32_t color)
 
   /* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here
    * since we don't want to allow Cogl to premultiply our data. */
-  tex = cogl_texture_new_from_data (QUAD_WIDTH,
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    QUAD_WIDTH,
                                     QUAD_WIDTH,
                                     COGL_TEXTURE_NONE,
                                     COGL_PIXEL_FORMAT_RGBA_8888,
                                     COGL_PIXEL_FORMAT_RGBA_8888,
                                     QUAD_WIDTH * 4,
-                                    tex_data);
+                                    tex_data,
+                                    NULL); /* don't catch errors */
 
   g_free (tex_data);
 
diff --git a/tests/conform/test-just-vertex-shader.c b/tests/conform/test-just-vertex-shader.c
index 26f5072..3aba7ab 100644
--- a/tests/conform/test-just-vertex-shader.c
+++ b/tests/conform/test-just-vertex-shader.c
@@ -16,12 +16,14 @@ create_dummy_texture (void)
      vertex shader */
   static const uint8_t data[4] = { 0x00, 0xff, 0x00, 0xff };
 
-  return cogl_texture_new_from_data (1, 1, /* size */
+  return cogl_texture_new_from_data (test_ctx,
+                                     1, 1, /* size */
                                      COGL_TEXTURE_NONE,
                                      COGL_PIXEL_FORMAT_RGB_888,
                                      COGL_PIXEL_FORMAT_ANY,
                                      4, /* rowstride */
-                                     data);
+                                     data,
+                                     NULL); /* don't catch errors */
 }
 
 static void
diff --git a/tests/conform/test-map-buffer-range.c b/tests/conform/test-map-buffer-range.c
index 9eb4770..a223bbc 100644
--- a/tests/conform/test-map-buffer-range.c
+++ b/tests/conform/test-map-buffer-range.c
@@ -65,7 +65,8 @@ test_map_buffer_range (void)
                                 sizeof (vertex_data[0]) * 2,
                                 sizeof (vertex_data[0]),
                                 COGL_BUFFER_ACCESS_WRITE,
-                                COGL_BUFFER_MAP_HINT_DISCARD_RANGE);
+                                COGL_BUFFER_MAP_HINT_DISCARD_RANGE,
+                                NULL); /* don't catch errors */
   g_assert (data != NULL);
 
   data->x = vertex_data[2].x;
diff --git a/tests/conform/test-npot-texture.c b/tests/conform/test-npot-texture.c
index a2bbd9f..d22ba65 100644
--- a/tests/conform/test-npot-texture.c
+++ b/tests/conform/test-npot-texture.c
@@ -87,13 +87,15 @@ make_texture (void)
         }
     }
 
-  tex = cogl_texture_new_from_data (TEXTURE_SIZE,
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    TEXTURE_SIZE,
                                     TEXTURE_SIZE,
                                     COGL_TEXTURE_NO_ATLAS,
                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                     COGL_PIXEL_FORMAT_ANY,
                                     TEXTURE_SIZE * 4,
-                                    tex_data);
+                                    tex_data,
+                                    NULL); /* ignore errors */
 
   g_free (tex_data);
 
diff --git a/tests/conform/test-pixel-buffer.c b/tests/conform/test-pixel-buffer.c
index 8d5550a..cd0272b 100644
--- a/tests/conform/test-pixel-buffer.c
+++ b/tests/conform/test-pixel-buffer.c
@@ -35,7 +35,8 @@ create_texture_from_bitmap (CoglBitmap *bitmap)
 
   texture = cogl_texture_new_from_bitmap (bitmap,
                                           COGL_TEXTURE_NONE,
-                                          COGL_PIXEL_FORMAT_RGBA_8888);
+                                          COGL_PIXEL_FORMAT_RGBA_8888,
+                                          NULL); /* don't catch errors */
 
   g_assert (texture != NULL);
 
@@ -70,7 +71,8 @@ create_map_tile (CoglContext *context,
 
   map = cogl_buffer_map (buffer,
                          COGL_BUFFER_ACCESS_WRITE,
-                         COGL_BUFFER_MAP_HINT_DISCARD);
+                         COGL_BUFFER_MAP_HINT_DISCARD,
+                         NULL); /* don't catch errors */
   g_assert (map);
 
   line = g_alloca (TILE_SIZE * 4);
@@ -169,7 +171,7 @@ create_set_data_tile (CoglContext *context,
       memcpy (data + i, tile->color, 4);
 
   /* FIXME: this doesn't consider the rowstride */
-  res = cogl_buffer_set_data (buffer, 0, data, TILE_SIZE * TILE_SIZE * 4);
+  res = cogl_buffer_set_data (buffer, 0, data, TILE_SIZE * TILE_SIZE * 4, NULL);
   g_assert (res);
 
   g_free (data);
diff --git a/tests/conform/test-premult.c b/tests/conform/test-premult.c
index fed9347..32983b7 100644
--- a/tests/conform/test-premult.c
+++ b/tests/conform/test-premult.c
@@ -74,7 +74,8 @@ set_region (CoglTexture *tex,
                            QUAD_WIDTH, QUAD_WIDTH, /* src width, height */
                            format,
                            0, /* auto compute row stride */
-                           tex_data);
+                           tex_data,
+                           NULL); /* don't catch errors */
 }
 
 static void
diff --git a/tests/conform/test-primitive.c b/tests/conform/test-primitive.c
index bda6e41..c446bf9 100644
--- a/tests/conform/test-primitive.c
+++ b/tests/conform/test-primitive.c
@@ -170,12 +170,14 @@ test_paint (TestState *state)
   tex_data[3] = (TEX_COLOR >> 24) & 0xff;
   tex_data[4] = (TEX_COLOR >> 16) & 0xff;
   tex_data[5] = (TEX_COLOR >> 8) & 0xff;
-  tex = cogl_texture_new_from_data (2, 1, /* size */
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    2, 1, /* size */
                                     COGL_TEXTURE_NO_ATLAS,
                                     COGL_PIXEL_FORMAT_RGB_888,
                                     COGL_PIXEL_FORMAT_ANY,
                                     6, /* rowstride */
-                                    tex_data);
+                                    tex_data,
+                                    NULL); /* don't catch errors */
   pipeline = cogl_pipeline_new (test_ctx);
   cogl_pipeline_set_color4ub (pipeline,
                               (PRIM_COLOR >> 24) & 0xff,
@@ -234,7 +236,7 @@ test_copy (TestState *state)
 {
   static const uint16_t indices_data[2] = { 1, 2 };
   CoglAttributeBuffer *buffer =
-    cogl_attribute_buffer_new (test_ctx, 100, NULL);
+    cogl_attribute_buffer_new_with_size (test_ctx, 100);
   CoglAttribute *attributes[N_ATTRIBS];
   CoglAttribute *attributes_a[N_ATTRIBS], *attributes_b[N_ATTRIBS];
   CoglAttribute **p;
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index eeb1cdb..df85042 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -22,12 +22,14 @@ create_texture_pipeline (TestState *state)
       0x00, 0x00, 0xff, 0xff, /* blue */ 0xff, 0xff, 0x00, 0xff, /* yellow */
     };
 
-  tex = cogl_texture_new_from_data (2, 2, /* width/height */
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    2, 2, /* width/height */
                                     COGL_TEXTURE_NO_ATLAS,
                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                     COGL_PIXEL_FORMAT_ANY,
                                     8, /* rowstride */
-                                    tex_data);
+                                    tex_data,
+                                    NULL); /* don't catch errors */
 
   pipeline = cogl_pipeline_new (test_ctx);
 
diff --git a/tests/conform/test-sub-texture.c b/tests/conform/test-sub-texture.c
index 592690a..0291afb 100644
--- a/tests/conform/test-sub-texture.c
+++ b/tests/conform/test-sub-texture.c
@@ -269,7 +269,8 @@ validate_result (TestState *state)
   cogl_texture_set_region (COGL_TEXTURE (sub_texture),
                            0, 0, 32, 32, 64, 64, 256, 256,
                            COGL_PIXEL_FORMAT_RGBA_8888_PRE, 256 * 4,
-                           texture_data);
+                           texture_data,
+                           NULL); /* don't catch errors */
   g_free (texture_data);
   cogl_object_unref (sub_texture);
   /* Get the texture data */
diff --git a/tests/conform/test-wrap-modes.c b/tests/conform/test-wrap-modes.c
index 8bc5a3e..d59b71d 100644
--- a/tests/conform/test-wrap-modes.c
+++ b/tests/conform/test-wrap-modes.c
@@ -28,11 +28,13 @@ create_texture (CoglTextureFlags flags)
         *(p++) = 255;
       }
 
-  tex = cogl_texture_new_from_data (TEX_SIZE, TEX_SIZE, flags,
+  tex = cogl_texture_new_from_data (test_ctx,
+                                    TEX_SIZE, TEX_SIZE, flags,
                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                     COGL_PIXEL_FORMAT_ANY,
                                     TEX_SIZE * 4,
-                                    data);
+                                    data,
+                                    NULL); /* don't catch errors */
   g_free (data);
 
   return tex;
diff --git a/tests/conform/test-write-texture-formats.c b/tests/conform/test-write-texture-formats.c
index cb820bf..80002f1 100644
--- a/tests/conform/test-write-texture-formats.c
+++ b/tests/conform/test-write-texture-formats.c
@@ -44,7 +44,8 @@ test_write_byte (CoglPixelFormat format,
                            1, 1, /* width / height */
                            format,
                            1, /* rowstride */
-                           &byte);
+                           &byte,
+                           NULL); /* don't catch errors */
 
   test_color (texture, expected_pixel);
 
@@ -65,7 +66,8 @@ test_write_short (CoglPixelFormat format,
                            1, 1, /* width / height */
                            format,
                            2, /* rowstride */
-                           (uint8_t *) &value);
+                           (uint8_t *) &value,
+                           NULL); /* don't catch errors */
 
   test_color (texture, expected_pixel);
 
@@ -88,7 +90,8 @@ test_write_bytes (CoglPixelFormat format,
                            1, 1, /* width / height */
                            format,
                            4, /* rowstride */
-                           (uint8_t *) &value);
+                           (uint8_t *) &value,
+                           NULL); /* don't catch errors */
 
   test_color (texture, expected_pixel);
 
@@ -127,7 +130,8 @@ test_write_int (CoglPixelFormat format,
                            1, 1, /* width / height */
                            format,
                            4, /* rowstride */
-                           (uint8_t *) &tex_data);
+                           (uint8_t *) &tex_data,
+                           NULL); /* don't catch errors */
 
   test_color (texture, expected_pixel);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]