Remove screenConfigs from __DRIscreen.
[mesa.git] / src / mesa / main / bufferobj.c
index 1d0f4b40679654efbe668ed62e30df5c249794ff..9ad2dccc1243683d76f2e58a7322f2e54429a911 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  6.5.1
  *
  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  *
  * \param ctx     GL context
  * \param target  Buffer object target to be retrieved.  Currently this must
  *                be either \c GL_ARRAY_BUFFER or \c GL_ELEMENT_ARRAY_BUFFER.
- * \param caller  Name of calling function for recording errors.
  * \return   A pointer to the buffer object bound to \c target in the
- *           specified context or \c NULL if \c target is invalid or no
- *           buffer object is bound.
+ *           specified context or \c NULL if \c target is invalid.
  */
 static INLINE struct gl_buffer_object *
-buffer_object_get_target(GLcontext *ctx, GLenum target, const char *caller)
+get_buffer(GLcontext *ctx, GLenum target)
 {
    struct gl_buffer_object * bufObj = NULL;
 
@@ -68,12 +66,12 @@ buffer_object_get_target(GLcontext *ctx, GLenum target, const char *caller)
          bufObj = ctx->Unpack.BufferObj;
          break;
       default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(target)", caller);
+         /* error must be recorded by caller */
          return NULL;
    }
 
-   if (bufObj->Name == 0)
-      return NULL;
+   /* bufObj should point to NullBufferObj or a user-created buffer object */
+   ASSERT(bufObj);
 
    return bufObj;
 }
@@ -112,17 +110,20 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
       return NULL;
    }
 
-   bufObj = buffer_object_get_target(ctx, target, caller);
-   if (!bufObj || bufObj->Name == 0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller);
       return NULL;
    }
-
-   if ((GLuint) (offset + size) > bufObj->Size) {
+   if (bufObj->Name == 0) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+      return NULL;
+   }
+   if (offset + size > bufObj->Size) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                  "%s(size + offset > buffer size)", caller);
       return NULL;
    }
-
    if (bufObj->Pointer) {
       /* Buffer is currently mapped */
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
@@ -295,7 +296,10 @@ _mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
 {
    (void) ctx; (void) target;
 
-   if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) {
+   /* this should have been caught in _mesa_BufferSubData() */
+   ASSERT(size + offset <= bufObj->Size);
+
+   if (bufObj->Data) {
       _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size );
    }
 }
@@ -335,9 +339,9 @@ _mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset,
 /**
  * Fallback function called via ctx->Driver.MapBuffer().
  * Hardware drivers that really implement buffer objects should never use
- * function.
+ * this function.
  *
- * The input parameters will have been already tested for errors.
+ * The function parameters will have been already tested for errors.
  *
  * \param ctx     GL context.
  * \param target  Buffer object target on which to operate.
@@ -405,6 +409,101 @@ _mesa_init_buffer_objects( GLcontext *ctx )
    ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj;
 }
 
+/**
+ * Bind the specified target to buffer for the specified context.
+ */
+static void
+bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer)
+{
+   struct gl_buffer_object *oldBufObj;
+   struct gl_buffer_object *newBufObj = NULL;
+   struct gl_buffer_object **bindTarget = NULL;
+
+   switch (target) {
+   case GL_ARRAY_BUFFER_ARB:
+      bindTarget = &ctx->Array.ArrayBufferObj;
+      break;
+   case GL_ELEMENT_ARRAY_BUFFER_ARB:
+      bindTarget = &ctx->Array.ElementArrayBufferObj;
+      break;
+   case GL_PIXEL_PACK_BUFFER_EXT:
+      bindTarget = &ctx->Pack.BufferObj;
+      break;
+   case GL_PIXEL_UNPACK_BUFFER_EXT:
+      bindTarget = &ctx->Unpack.BufferObj;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)");
+      return;
+   }
+
+   /* Get pointer to old buffer object (to be unbound) */
+   oldBufObj = get_buffer(ctx, target);
+   if (oldBufObj && oldBufObj->Name == buffer)
+      return;   /* rebinding the same buffer object- no change */
+
+   /*
+    * Get pointer to new buffer object (newBufObj)
+    */
+   if (buffer == 0) {
+      /* The spec says there's not a buffer object named 0, but we use
+       * one internally because it simplifies things.
+       */
+      newBufObj = ctx->Array.NullBufferObj;
+   }
+   else {
+      /* non-default buffer object */
+      newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
+      if (!newBufObj) {
+         /* if this is a new buffer object id, allocate a buffer object now */
+         ASSERT(ctx->Driver.NewBufferObject);
+         newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
+         if (!newBufObj) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
+            return;
+         }
+         _mesa_save_buffer_object(ctx, newBufObj);
+      }
+   }
+   
+   /* Make new binding */
+   *bindTarget = newBufObj;
+   newBufObj->RefCount++;
+
+   /* Pass BindBuffer call to device driver */
+   if (ctx->Driver.BindBuffer && newBufObj)
+      ctx->Driver.BindBuffer( ctx, target, newBufObj );
+
+   /* decr ref count on old buffer obj, delete if needed */
+   if (oldBufObj) {
+      oldBufObj->RefCount--;
+      assert(oldBufObj->RefCount >= 0);
+      if (oldBufObj->RefCount == 0) {
+         assert(oldBufObj->Name != 0);
+         ASSERT(ctx->Driver.DeleteBuffer);
+         ctx->Driver.DeleteBuffer( ctx, oldBufObj );
+      }
+   }
+}
+
+
+/**
+ * Update the default buffer objects in the given context to reference those
+ * specified in the shared state and release those referencing the old 
+ * shared state.
+ */
+void
+_mesa_update_default_objects_buffer_objects(GLcontext *ctx)
+{
+   /* Bind the NullBufferObj to remove references to those
+    * in the shared context hash table.
+    */
+   bind_buffer_object( ctx, GL_ARRAY_BUFFER_ARB, 0);
+   bind_buffer_object( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+   bind_buffer_object( ctx, GL_PIXEL_PACK_BUFFER_ARB, 0);
+   bind_buffer_object( ctx, GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+}
+
 
 /**
  * When we're about to read pixel data out of a PBO (via glDrawPixels,
@@ -489,70 +588,9 @@ void GLAPIENTRY
 _mesa_BindBufferARB(GLenum target, GLuint buffer)
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct gl_buffer_object *oldBufObj;
-   struct gl_buffer_object *newBufObj = NULL;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   oldBufObj = buffer_object_get_target( ctx, target, "BindBufferARB" );
-   if (oldBufObj && oldBufObj->Name == buffer)
-      return;   /* rebinding the same buffer object- no change */
-
-   /*
-    * Get pointer to new buffer object (newBufObj)
-    */
-   if (buffer == 0) {
-      /* The spec says there's not a buffer object named 0, but we use
-       * one internally because it simplifies things.
-       */
-      newBufObj = ctx->Array.NullBufferObj;
-   }
-   else {
-      /* non-default buffer object */
-      newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
-      if (!newBufObj) {
-         /* if this is a new buffer object id, allocate a buffer object now */
-         ASSERT(ctx->Driver.NewBufferObject);
-        newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
-         if (!newBufObj) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
-            return;
-         }
-         _mesa_save_buffer_object(ctx, newBufObj);
-      }
-      newBufObj->RefCount++;
-   }
-   
-   switch (target) {
-      case GL_ARRAY_BUFFER_ARB:
-         ctx->Array.ArrayBufferObj = newBufObj;
-         break;
-      case GL_ELEMENT_ARRAY_BUFFER_ARB:
-         ctx->Array.ElementArrayBufferObj = newBufObj;
-         break;
-      case GL_PIXEL_PACK_BUFFER_EXT:
-         ctx->Pack.BufferObj = newBufObj;
-         break;
-      case GL_PIXEL_UNPACK_BUFFER_EXT:
-         ctx->Unpack.BufferObj = newBufObj;
-         break;
-      default:
-         _mesa_problem(ctx, "Bad target in _mesa_BindBufferARB");
-         return;
-   }
-
-   /* Pass BindBuffer call to device driver */
-   if (ctx->Driver.BindBuffer && newBufObj)
-      ctx->Driver.BindBuffer( ctx, target, newBufObj );
-
-   if (oldBufObj) {
-      oldBufObj->RefCount--;
-      assert(oldBufObj->RefCount >= 0);
-      if (oldBufObj->RefCount == 0) {
-        assert(oldBufObj->Name != 0);
-        ASSERT(ctx->Driver.DeleteBuffer);
-        ctx->Driver.DeleteBuffer( ctx, oldBufObj );
-      }
-   }
+   bind_buffer_object(ctx, target, buffer);
 }
 
 
@@ -648,9 +686,9 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
             _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
          }
 
-        /* The ID is immediately freed for re-use */
-        _mesa_remove_buffer_object(ctx, bufObj);
-        _mesa_unbind_buffer_object(ctx, bufObj);
+         /* The ID is immediately freed for re-use */
+         _mesa_remove_buffer_object(ctx, bufObj);
+         _mesa_unbind_buffer_object(ctx, bufObj);
       }
    }
 
@@ -759,8 +797,12 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
          return;
    }
 
-   bufObj = buffer_object_get_target( ctx, target, "BufferDataARB" );
-   if (!bufObj || bufObj->Name ==0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" );
+      return;
+   }
+   if (bufObj->Name == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB" );
       return;
    }
@@ -786,7 +828,7 @@ _mesa_BufferSubDataARB(GLenum target, GLintptrARB offset,
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
-                                              "BufferSubDataARB" );
+                                              "glBufferSubDataARB" );
    if (!bufObj) {
       /* error already recorded */
       return;
@@ -806,7 +848,7 @@ _mesa_GetBufferSubDataARB(GLenum target, GLintptrARB offset,
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
-                                              "GetBufferSubDataARB" );
+                                              "glGetBufferSubDataARB" );
    if (!bufObj) {
       /* error already recorded */
       return;
@@ -835,12 +877,15 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
          return NULL;
    }
 
-   bufObj = buffer_object_get_target( ctx, target, "MapBufferARB" );
-   if (!bufObj || bufObj->Name == 0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" );
+      return NULL;
+   }
+   if (bufObj->Name == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB" );
       return NULL;
    }
-
    if (bufObj->Pointer) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
       return NULL;
@@ -866,12 +911,15 @@ _mesa_UnmapBufferARB(GLenum target)
    GLboolean status = GL_TRUE;
    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
 
-   bufObj = buffer_object_get_target( ctx, target, "UnmapBufferARB" );
-   if (!bufObj || bufObj->Name == 0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" );
+      return GL_FALSE;
+   }
+   if (bufObj->Name == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" );
       return GL_FALSE;
    }
-
    if (!bufObj->Pointer) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
       return GL_FALSE;
@@ -895,8 +943,12 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
    struct gl_buffer_object *bufObj;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   bufObj = buffer_object_get_target( ctx, target, "GetBufferParameterivARB" );
-   if (!bufObj || bufObj->Name == 0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameterivARB(target)" );
+      return;
+   }
+   if (bufObj->Name == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" );
       return;
    }
@@ -933,8 +985,12 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
       return;
    }
 
-   bufObj = buffer_object_get_target( ctx, target, "GetBufferPointervARB" );
-   if (!bufObj || bufObj->Name == 0) {
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" );
+      return;
+   }
+   if (bufObj->Name == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" );
       return;
    }