コード例 #1
0
/**
 * For a list of prims, try merging prims that can just be extensions of the
 * previous prim.
 */
static void
merge_prims(struct gl_context *ctx,
            struct _mesa_prim *prim_list,
            GLuint *prim_count)
{
   GLuint i;
   struct _mesa_prim *prev_prim = prim_list;

   for (i = 1; i < *prim_count; i++) {
      struct _mesa_prim *this_prim = prim_list + i;

      vbo_try_prim_conversion(this_prim);

      if (vbo_can_merge_prims(prev_prim, this_prim)) {
         /* We've found a prim that just extend the previous one.  Tack it
          * onto the previous one, and let this primitive struct get dropped.
          */
         vbo_merge_prims(prev_prim, this_prim);
         continue;
      }

      /* If any previous primitives have been dropped, then we need to copy
       * this later one into the next available slot.
       */
      prev_prim++;
      if (prev_prim != this_prim)
         *prev_prim = *this_prim;
   }

   *prim_count = prev_prim - prim_list + 1;
}
コード例 #2
0
ファイル: vbo_exec_api.c プロジェクト: Kalamatee/mesa
/**
 * Try to merge / concatenate the two most recent VBO primitives.
 */
static void
try_vbo_merge(struct vbo_exec_context *exec)
{
   struct _mesa_prim *cur =  &exec->vtx.prim[exec->vtx.prim_count - 1];

   assert(exec->vtx.prim_count >= 1);

   vbo_try_prim_conversion(cur);

   if (exec->vtx.prim_count >= 2) {
      struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2];
      assert(prev == cur - 1);

      if (vbo_can_merge_prims(prev, cur)) {
         assert(cur->begin);
         assert(cur->end);
         assert(prev->begin);
         assert(prev->end);
         vbo_merge_prims(prev, cur);
         exec->vtx.prim_count--;  /* drop the last primitive */
      }
   }
}
コード例 #3
0
ファイル: vbo_save_api.c プロジェクト: RAOF/mesa
/**
 * Insert the active immediate struct onto the display list currently
 * being built.
 */
static void
_save_compile_vertex_list(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   struct vbo_save_vertex_list *node;

   /* Allocate space for this structure in the display list currently
    * being compiled.
    */
   node = (struct vbo_save_vertex_list *)
      _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node));

   if (!node)
      return;

   /* Duplicate our template, increment refcounts to the storage structs:
    */
   memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
   memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype));
   node->vertex_size = save->vertex_size;
   node->buffer_offset =
      (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
   node->count = save->vert_count;
   node->wrap_count = save->copied.nr;
   node->dangling_attr_ref = save->dangling_attr_ref;
   node->prim = save->prim;
   node->prim_count = save->prim_count;
   node->vertex_store = save->vertex_store;
   node->prim_store = save->prim_store;

   node->vertex_store->refcount++;
   node->prim_store->refcount++;

   if (node->prim[0].no_current_update) {
      node->current_size = 0;
      node->current_data = NULL;
   }
   else {
      node->current_size = node->vertex_size - node->attrsz[0];
      node->current_data = NULL;

      if (node->current_size) {
         /* If the malloc fails, we just pull the data out of the VBO
          * later instead.
          */
         node->current_data = malloc(node->current_size * sizeof(GLfloat));
         if (node->current_data) {
            const char *buffer = (const char *) save->vertex_store->buffer;
            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
            unsigned vertex_offset = 0;

            if (node->count)
               vertex_offset =
                  (node->count - 1) * node->vertex_size * sizeof(GLfloat);

            memcpy(node->current_data,
                   buffer + node->buffer_offset + vertex_offset + attr_offset,
                   node->current_size * sizeof(GLfloat));
         }
      }
   }

   assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0);

   if (save->dangling_attr_ref)
      ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;

   save->vertex_store->used += save->vertex_size * node->count;
   save->prim_store->used += node->prim_count;

   /* Copy duplicated vertices 
    */
   save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);

   vbo_merge_prims(ctx, node->prim, &node->prim_count);

   /* Deal with GL_COMPILE_AND_EXECUTE:
    */
   if (ctx->ExecuteFlag) {
      struct _glapi_table *dispatch = GET_DISPATCH();

      _glapi_set_dispatch(ctx->Exec);

      vbo_loopback_vertex_list(ctx,
                               (const GLfloat *) ((const char *) save->
                                                  vertex_store->buffer +
                                                  node->buffer_offset),
                               node->attrsz, node->prim, node->prim_count,
                               node->wrap_count, node->vertex_size);

      _glapi_set_dispatch(dispatch);
   }

   /* Decide whether the storage structs are full, or can be used for
    * the next vertex lists as well.
    */
   if (save->vertex_store->used >
       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {

      /* Unmap old store:
       */
      vbo_save_unmap_vertex_store(ctx, save->vertex_store);

      /* Release old reference:
       */
      save->vertex_store->refcount--;
      assert(save->vertex_store->refcount != 0);
      save->vertex_store = NULL;

      /* Allocate and map new store:
       */
      save->vertex_store = alloc_vertex_store(ctx);
      save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
      save->out_of_memory = save->buffer_ptr == NULL;
   }

   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
      save->prim_store->refcount--;
      assert(save->prim_store->refcount != 0);
      save->prim_store = alloc_prim_store(ctx);
   }

   /* Reset our structures for the next run of vertices:
    */
   _save_reset_counters(ctx);
}