From 2f6d2a9e27f8582591dc60655f7d7b14d7552bbc Mon Sep 17 00:00:00 2001
From: Brian Paul <brianp@vmware.com>
Date: Thu, 3 Sep 2009 09:41:41 -0600
Subject: mesa: change ctx->Driver.BufferData() to return GLboolean for
 success/failure

Return GL_FALSE if we failed to allocate the buffer.  Then raise
GL_OUT_OF_MEMORY in core Mesa.
---
 src/mesa/drivers/dri/intel/intel_buffer_objects.c  | 11 ++++++---
 .../drivers/dri/radeon/radeon_buffer_objects.c     |  9 ++++++--
 src/mesa/main/bufferobj.c                          | 26 +++++++++++++++-------
 src/mesa/main/dd.h                                 |  6 ++---
 src/mesa/state_tracker/st_cb_bufferobjects.c       |  9 ++++----
 5 files changed, 41 insertions(+), 20 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index ae6f3064a8..c55c5c426e 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -130,9 +130,10 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
  * Allocate space for and store data in a buffer object.  Any data that was
  * previously stored in the buffer object is lost.  If data is NULL,
  * memory will be allocated, but no copy will occur.
- * Called via glBufferDataARB().
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
  */
-static void
+static GLboolean
 intel_bufferobj_data(GLcontext * ctx,
                      GLenum target,
                      GLsizeiptrARB size,
@@ -167,15 +168,19 @@ intel_bufferobj_data(GLcontext * ctx,
 	 if (intel_obj->sys_buffer != NULL) {
 	    if (data != NULL)
 	       memcpy(intel_obj->sys_buffer, data, size);
-	    return;
+	    return GL_TRUE;
 	 }
       }
 #endif
       intel_bufferobj_alloc_buffer(intel, intel_obj);
+      if (!intel_obj->buffer)
+         return GL_FALSE;
 
       if (data != NULL)
 	 dri_bo_subdata(intel_obj->buffer, 0, size, data);
    }
+
+   return GL_TRUE;
 }
 
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
index e8ae51e6ea..a24b6dac26 100644
--- a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
@@ -78,9 +78,10 @@ radeonDeleteBufferObject(GLcontext * ctx,
  * Allocate space for and store data in a buffer object.  Any data that was
  * previously stored in the buffer object is lost.  If data is NULL,
  * memory will be allocated, but no copy will occur.
- * Called via glBufferDataARB().
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
  */
-static void
+static GLboolean
 radeonBufferData(GLcontext * ctx,
                  GLenum target,
                  GLsizeiptrARB size,
@@ -107,6 +108,9 @@ radeonBufferData(GLcontext * ctx,
                                         RADEON_GEM_DOMAIN_GTT,
                                         0);
 
+        if (!radeon_obj->bo)
+            return GL_FALSE;
+
         if (data != NULL) {
             radeon_bo_map(radeon_obj->bo, GL_TRUE);
 
@@ -115,6 +119,7 @@ radeonBufferData(GLcontext * ctx,
             radeon_bo_unmap(radeon_obj->bo);
         }
     }
+    return GL_TRUE;
 }
 
 /**
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index ebca798635..81b77b6ff2 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -314,9 +314,10 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj,
  * \param usage   Hints about how the data will be used.
  * \param bufObj  Object to be used.
  *
+ * \return GL_TRUE for success, GL_FALSE for failure
  * \sa glBufferDataARB, dd_function_table::BufferData.
  */
-static void
+static GLboolean
 _mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
 		   const GLvoid * data, GLenum usage,
 		   struct gl_buffer_object * bufObj )
@@ -334,6 +335,11 @@ _mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
       if (data) {
 	 _mesa_memcpy( bufObj->Data, data, size );
       }
+
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
    }
 }
 
@@ -1107,8 +1113,6 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
 
    FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
 
-   ASSERT(ctx->Driver.BufferData);
-
    bufObj->Written = GL_TRUE;
 
 #ifdef VBO_DEBUG
@@ -1119,8 +1123,11 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
 #ifdef BOUNDS_CHECK
    size += 100;
 #endif
-   /* Give the buffer object to the driver!  <data> may be null! */
-   ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj );
+
+   ASSERT(ctx->Driver.BufferData);
+   if (!ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj )) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB(access)");
+   }
 }
 
 
@@ -1209,9 +1216,9 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
    map = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
    if (!map) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+      return NULL;
    }
-
-   if (map) {
+   else {
       /* The driver callback should have set these fields.
        * This is important because other modules (like VBO) might call
        * the driver function directly.
@@ -1538,7 +1545,10 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
    ASSERT(ctx->Driver.MapBufferRange);
    map = ctx->Driver.MapBufferRange(ctx, target, offset, length,
                                     access, bufObj);
-   if (map) {
+   if (!map) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+   }
+   else {
       /* The driver callback should have set all these fields.
        * This is important because other modules (like VBO) might call
        * the driver function directly.
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index f02e868d4a..4400e166c6 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -783,9 +783,9 @@ struct dd_function_table {
    
    void (*DeleteBuffer)( GLcontext *ctx, struct gl_buffer_object *obj );
 
-   void (*BufferData)( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
-		       const GLvoid *data, GLenum usage,
-		       struct gl_buffer_object *obj );
+   GLboolean (*BufferData)( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+                            const GLvoid *data, GLenum usage,
+                            struct gl_buffer_object *obj );
 
    void (*BufferSubData)( GLcontext *ctx, GLenum target, GLintptrARB offset,
 			  GLsizeiptrARB size, const GLvoid *data,
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 69dd76d083..8e09d0b932 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -134,9 +134,10 @@ st_bufferobj_get_subdata(GLcontext *ctx,
  * Allocate space for and store data in a buffer object.  Any data that was
  * previously stored in the buffer object is lost.  If data is NULL,
  * memory will be allocated, but no copy will occur.
- * Called via glBufferDataARB().
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
  */
-static void
+static GLboolean
 st_bufferobj_data(GLcontext *ctx,
 		  GLenum target,
 		  GLsizeiptrARB size,
@@ -172,13 +173,13 @@ st_bufferobj_data(GLcontext *ctx,
    st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size );
 
    if (!st_obj->buffer) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB");
-      return;
+      return GL_FALSE;
    }
 
    if (data)
       st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
 				    size, data);
+   return GL_TRUE;
 }
 
 
-- 
cgit v1.2.3