/* Insert the active immediate struct onto the display list currently * being built. */ static void _save_compile_vertex_list( GLcontext *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_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); 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++; assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0); if (save->dangling_attr_ref) ctx->ListState.CurrentList->flags |= MESA_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 ); /* 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: */ 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->vbptr = map_vertex_store( ctx, save->vertex_store ); } 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 ); }
/* Insert the active immediate struct onto the display list currently * being built. */ static void _save_compile_vertex_list( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_vertex_list *node; /* Allocate space for this structure in the display list currently * being compiled. */ node = (struct tnl_vertex_list *) _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); node->vertex_size = tnl->save.vertex_size; node->buffer = tnl->save.buffer; node->wrap_count = tnl->save.copied.nr; node->count = tnl->save.initial_counter - tnl->save.counter; node->prim = tnl->save.prim; node->prim_count = tnl->save.prim_count; node->vertex_store = tnl->save.vertex_store; node->prim_store = tnl->save.prim_store; node->dangling_attr_ref = tnl->save.dangling_attr_ref; node->normal_lengths = 0; node->vertex_store->refcount++; node->prim_store->refcount++; assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || node->count == 0); /* Maybe calculate normal lengths: */ if (tnl->CalcDListNormalLengths && node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && !node->dangling_attr_ref) build_normal_lengths( node ); tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; tnl->save.prim_store->used += node->prim_count; /* Decide whether the storage structs are full, or can be used for * the next vertex lists as well. */ if (tnl->save.vertex_store->used > SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { tnl->save.vertex_store->refcount--; assert(tnl->save.vertex_store->refcount != 0); tnl->save.vertex_store = alloc_vertex_store( ctx ); tnl->save.vbptr = tnl->save.vertex_store->buffer; } if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { tnl->save.prim_store->refcount--; assert(tnl->save.prim_store->refcount != 0); tnl->save.prim_store = alloc_prim_store( ctx ); } /* Reset our structures for the next run of vertices: */ _save_reset_counters( ctx ); /* Copy duplicated vertices */ tnl->save.copied.nr = _save_copy_vertices( ctx, node ); /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { _tnl_playback_vertex_list( ctx, (void *) node ); } }