/* Called only when buffers are wrapped as the result of filling the
 * vertex_store struct.  
 */
static void _save_wrap_filled_vertex( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLfloat *data = save->copied.buffer;
   GLuint i;

   /* Emit a glEnd to close off the last vertex list.
    */
   _save_wrap_buffers( ctx );
   
    /* Copy stored stored vertices to start of new list.
    */
   assert(save->max_vert - save->vert_count > save->copied.nr);

   for (i = 0 ; i < save->copied.nr ; i++) {
      _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));
      data += save->vertex_size;
      save->vbptr += save->vertex_size;
      save->vert_count++;
   }
}
示例#2
0
/* Called only when buffers are wrapped as the result of filling the
 * vertex_store struct.  
 */
static void _save_wrap_filled_vertex( GLcontext *ctx )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   GLfloat *data = tnl->save.copied.buffer;
   GLuint i;

   /* Emit a glEnd to close off the last vertex list.
    */
   _save_wrap_buffers( ctx );
   
    /* Copy stored stored vertices to start of new list.
    */
   assert(tnl->save.counter > tnl->save.copied.nr);

   for (i = 0 ; i < tnl->save.copied.nr ; i++) {
      _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat));
      data += tnl->save.vertex_size;
      tnl->save.vbptr += tnl->save.vertex_size;
      tnl->save.counter--;
   }
}
/* Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void _save_upgrade_vertex( GLcontext *ctx, 
				 GLuint attr,
				 GLuint newsz )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLuint oldsz;
   GLuint i;
   GLfloat *tmp;

   /* Store the current run of vertices, and emit a GL_END.  Emit a
    * BEGIN in the new buffer.
    */
   if (save->vert_count) 
      _save_wrap_buffers( ctx );
   else
      assert( save->copied.nr == 0 );

   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   _save_copy_to_current( ctx );

   /* Fix up sizes:
    */
   oldsz = save->attrsz[attr];
   save->attrsz[attr] = newsz;

   save->vertex_size += newsz - oldsz;
   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / 
		      save->vertex_size);
   save->vert_count = 0;

   /* Recalculate all the attrptr[] values:
    */
   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {
      if (save->attrsz[i]) {
	 save->attrptr[i] = tmp;
	 tmp += save->attrsz[i];
      }
      else 
	 save->attrptr[i] = NULL; /* will not be dereferenced. */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   _save_copy_from_current( ctx );

   /* Replay stored vertices to translate them to new format here.
    *
    * If there are copied vertices and the new (upgraded) attribute
    * has not been defined before, this list is somewhat degenerate,
    * and will need fixup at runtime.
    */
   if (save->copied.nr)
   {
      GLfloat *data = save->copied.buffer;
      GLfloat *dest = save->buffer;
      GLuint j;

      /* Need to note this and fix up at runtime (or loopback):
       */
      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
	 assert(oldsz == 0);
	 save->dangling_attr_ref = GL_TRUE;
      }

      for (i = 0 ; i < save->copied.nr ; i++) {
	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
	    if (save->attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     COPY_CLEAN_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  }
		  else {
		     COPY_SZ_4V( dest, newsz, save->current[attr] );
		     dest += newsz;
		  }
	       }
	       else {
		  GLint sz = save->attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  data += sz;
		  dest += sz;
	       }
	    }
	 }
      }

      save->vbptr = dest;
      save->vert_count += save->copied.nr;
   }
}
示例#4
0
/* Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void _save_upgrade_vertex( GLcontext *ctx, 
				 GLuint attr,
				 GLuint newsz )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   GLuint oldsz;
   GLuint i;
   GLfloat *tmp;

   /* Store the current run of vertices, and emit a GL_END.  Emit a
    * BEGIN in the new buffer.
    */
   if (tnl->save.initial_counter != tnl->save.counter) 
      _save_wrap_buffers( ctx );
   else
      assert( tnl->save.copied.nr == 0 );

   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   _save_copy_to_current( ctx );

   /* Fix up sizes:
    */
   oldsz = tnl->save.attrsz[attr];
   tnl->save.attrsz[attr] = newsz;

   tnl->save.vertex_size += newsz - oldsz;
   tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / 
			tnl->save.vertex_size);
   if (tnl->save.counter > ctx->Const.MaxArrayLockSize )
      tnl->save.counter = ctx->Const.MaxArrayLockSize;
   tnl->save.initial_counter = tnl->save.counter;

   /* Recalculate all the attrptr[] values:
    */
   for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) {
      if (tnl->save.attrsz[i]) {
	 tnl->save.attrptr[i] = tmp;
	 tmp += tnl->save.attrsz[i];
      }
      else 
	 tnl->save.attrptr[i] = 0; /* will not be dereferenced. */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   _save_copy_from_current( ctx );

   /* Replay stored vertices to translate them to new format here.
    *
    * If there are copied vertices and the new (upgraded) attribute
    * has not been defined before, this list is somewhat degenerate,
    * and will need fixup at runtime.
    */
   if (tnl->save.copied.nr)
   {
      GLfloat *data = tnl->save.copied.buffer;
      GLfloat *dest = tnl->save.buffer;
      GLuint j;

      /* Need to note this and fix up at runtime (or loopback):
       */
      if (tnl->save.currentsz[attr][0] == 0) {
	 assert(oldsz == 0);
	 tnl->save.dangling_attr_ref = GL_TRUE;
	 _mesa_debug(0, "_save_upgrade_vertex: dangling reference attr %d\n", 
                     attr); 

#if 0
	 /* The current strategy is to punt these degenerate cases
	  * through _tnl_loopback_vertex_list(), a lower-performance
	  * option.  To minimize the impact of this, artificially
	  * reduce the size of this vertex_list.
	  */
	 if (t->save.counter > 10) {
	    t->save.initial_counter = 10;
	    t->save.counter = 10;
	 }
#endif
      }

      for (i = 0 ; i < tnl->save.copied.nr ; i++) {
	 for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) {
	    if (tnl->save.attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     ASSIGN_4V( dest, 0, 0, 0, 1 );
		     COPY_SZ_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  }
		  else {
		     COPY_SZ_4V( dest, newsz, tnl->save.current[attr] );
		     dest += newsz;
		  }
	       }
	       else {
		  GLint sz = tnl->save.attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  data += sz;
		  dest += sz;
	       }
	    }
	 }
      }

      tnl->save.vbptr = dest;
      tnl->save.counter -= tnl->save.copied.nr;
   }
}