Example #1
0
/**
 * Generate a set of unique array object IDs and store them in \c arrays.
 * Helper for _mesa_GenVertexArrays[APPLE]() functions below.
 * \param n       Number of IDs to generate.
 * \param arrays  Array of \c n locations to store the IDs.
 * \param vboOnly Will arrays have to reside in VBOs?
 */
static void 
gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays)
{
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenVertexArraysAPPLE");
      return;
   }

   if (!arrays) {
      return;
   }

   first = _mesa_HashFindFreeKeyBlock(ctx->Array.Objects, n);

   /* Allocate new, empty array objects and return identifiers */
   for (i = 0; i < n; i++) {
      struct gl_array_object *obj;
      GLuint name = first + i;

      obj = (*ctx->Driver.NewArrayObject)( ctx, name );
      if (!obj) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE");
         return;
      }
      save_array_object(ctx, obj);
      arrays[i] = first + i;
   }
}
Example #2
0
/**
 * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
 * \param genRequired  specifies behavour when id was not generated with
 *                     glGenVertexArrays().
 */
static void
bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
{
   struct gl_array_object * const oldObj = ctx->Array.ArrayObj;
   struct gl_array_object *newObj = NULL;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   ASSERT(oldObj != NULL);

   if ( oldObj->Name == id )
      return;   /* rebinding the same array object- no change */

   /*
    * Get pointer to new array object (newObj)
    */
   if (id == 0) {
      /* The spec says there is no array object named 0, but we use
       * one internally because it simplifies things.
       */
      newObj = ctx->Array.DefaultArrayObj;
   }
   else {
      /* non-default array object */
      newObj = lookup_arrayobj(ctx, id);
      if (!newObj) {
         if (genRequired) {
            _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexArray(id)");
            return;
         }

         /* For APPLE version, generate a new array object now */
	 newObj = (*ctx->Driver.NewArrayObject)(ctx, id);
         if (!newObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
            return;
         }

         save_array_object(ctx, newObj);
      }

      if (!newObj->_Used) {
         /* The "Interactions with APPLE_vertex_array_object" section of the
          * GL_ARB_vertex_array_object spec says:
          *
          *     "The first bind call, either BindVertexArray or
          *     BindVertexArrayAPPLE, determines the semantic of the object."
          */
         newObj->ARBsemantics = genRequired;
         newObj->_Used = GL_TRUE;
      }
   }

   ctx->NewState |= _NEW_ARRAY;
   ctx->Array.NewState |= VERT_BIT_ALL;
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj);

   /* Pass BindVertexArray call to device driver */
   if (ctx->Driver.BindArrayObject && newObj)
      ctx->Driver.BindArrayObject(ctx, newObj);
}
Example #3
0
/**
 * Generate a set of unique array object IDs and store them in \c arrays.
 * Helper for _mesa_GenVertexArrays[APPLE]() and _mesa_CreateVertexArrays()
 * below.
 *
 * \param n       Number of IDs to generate.
 * \param arrays  Array of \c n locations to store the IDs.
 * \param create  Indicates that the objects should also be created.
 * \param func    The name of the GL entry point.
 */
static void
gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays,
                  bool create, const char *func)
{
   GLuint first;
   GLint i;

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
      return;
   }

   if (!arrays) {
      return;
   }

   first = _mesa_HashFindFreeKeyBlock(ctx->Array.Objects, n);

   /* For the sake of simplicity we create the array objects in both
    * the Gen* and Create* cases.  The only difference is the value of
    * EverBound, which is set to true in the Create* case.
    */
   for (i = 0; i < n; i++) {
      struct gl_vertex_array_object *obj;
      GLuint name = first + i;

      obj = _mesa_new_vao(ctx, name);
      if (!obj) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
         return;
      }
      obj->EverBound = create;
      save_array_object(ctx, obj);
      arrays[i] = first + i;
   }
}
Example #4
0
/**
 * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
 * \param genRequired  specifies behavour when id was not generated with
 *                     glGenVertexArrays().
 */
static void
bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
{
   struct gl_vertex_array_object * const oldObj = ctx->Array.VAO;
   struct gl_vertex_array_object *newObj = NULL;

   assert(oldObj != NULL);

   if ( oldObj->Name == id )
      return;   /* rebinding the same array object- no change */

   /*
    * Get pointer to new array object (newObj)
    */
   if (id == 0) {
      /* The spec says there is no array object named 0, but we use
       * one internally because it simplifies things.
       */
      newObj = ctx->Array.DefaultVAO;
   }
   else {
      /* non-default array object */
      newObj = _mesa_lookup_vao(ctx, id);
      if (!newObj) {
         if (genRequired) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glBindVertexArray(non-gen name)");
            return;
         }

         /* For APPLE version, generate a new array object now */
	 newObj = _mesa_new_vao(ctx, id);
         if (!newObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
            return;
         }

         save_array_object(ctx, newObj);
      }

      if (!newObj->EverBound) {
         /* The "Interactions with APPLE_vertex_array_object" section of the
          * GL_ARB_vertex_array_object spec says:
          *
          *     "The first bind call, either BindVertexArray or
          *     BindVertexArrayAPPLE, determines the semantic of the object."
          */
         newObj->ARBsemantics = genRequired;
         newObj->EverBound = GL_TRUE;
      }
   }

   if (ctx->Array.DrawMethod == DRAW_ARRAYS) {
      /* The _DrawArrays pointer is pointing at the VAO being unbound and
       * that VAO may be in the process of being deleted. If it's not going
       * to be deleted, this will have no effect, because the pointer needs
       * to be updated by the VBO module anyway.
       *
       * Before the VBO module can update the pointer, we have to set it
       * to NULL for drivers not to set up arrays which are not bound,
       * or to prevent a crash if the VAO being unbound is going to be
       * deleted.
       */
      ctx->Array._DrawArrays = NULL;
      ctx->Array.DrawMethod = DRAW_NONE;
   }

   ctx->NewState |= _NEW_ARRAY;
   _mesa_reference_vao(ctx, &ctx->Array.VAO, newObj);
}