/** * Execute the buffer and save copied verts. */ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ) { const struct vbo_save_vertex_list *node = (const struct vbo_save_vertex_list *) data; struct vbo_save_context *save = &vbo_context(ctx)->save; FLUSH_CURRENT(ctx, 0); if (node->prim_count > 0 && node->count > 0) { if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && node->prim[0].begin) { /* Degenerate case: list is called inside begin/end pair and * includes operations such as glBegin or glDrawArrays. */ if (0) _mesa_printf("displaylist recursive begin"); vbo_save_loopback_vertex_list( ctx, node ); return; } else if (save->replay_flags) { /* Various degnerate cases: translate into immediate mode * calls rather than trying to execute in place. */ vbo_save_loopback_vertex_list( ctx, node ); return; } if (ctx->NewState) _mesa_update_state( ctx ); /* XXX also need to check if shader enabled, but invalid */ if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); return; } vbo_bind_vertex_list( ctx, node ); vbo_context(ctx)->draw_prims( ctx, save->inputs, node->prim, node->prim_count, NULL, 0, /* Node is a VBO, so this is ok */ node->count - 1); } /* Copy to current? */ _playback_copy_to_current( ctx, node ); }
/** * Execute the buffer and save copied verts. * This is called from the display list code when executing * a drawing command. */ void vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) { const struct vbo_save_vertex_list *node = (const struct vbo_save_vertex_list *) data; struct vbo_save_context *save = &vbo_context(ctx)->save; GLboolean remap_vertex_store = GL_FALSE; if (save->vertex_store && save->vertex_store->buffer) { /* The vertex store is currently mapped but we're about to replay * a display list. This can happen when a nested display list is * being build with GL_COMPILE_AND_EXECUTE. * We never want to have mapped vertex buffers when we're drawing. * Unmap the vertex store, execute the list, then remap the vertex * store. */ vbo_save_unmap_vertex_store(ctx, save->vertex_store); remap_vertex_store = GL_TRUE; } FLUSH_CURRENT(ctx, 0); if (node->prim_count > 0) { if (_mesa_inside_begin_end(ctx) && node->prim[0].begin) { /* Error: we're about to begin a new primitive but we're already * inside a glBegin/End pair. */ _mesa_error(ctx, GL_INVALID_OPERATION, "draw operation inside glBegin/End"); goto end; } else if (save->replay_flags) { /* Various degenerate cases: translate into immediate mode * calls rather than trying to execute in place. */ vbo_save_loopback_vertex_list( ctx, node ); goto end; } if (ctx->NewState) _mesa_update_state( ctx ); /* XXX also need to check if shader enabled, but invalid */ if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); return; } vbo_bind_vertex_list( ctx, node ); vbo_draw_method(vbo_context(ctx), DRAW_DISPLAY_LIST); /* Again... */ if (ctx->NewState) _mesa_update_state( ctx ); if (node->count > 0) { vbo_context(ctx)->draw_prims(ctx, node->prim, node->prim_count, NULL, GL_TRUE, 0, /* Node is a VBO, so this is ok */ node->count - 1, NULL, 0, NULL); } } /* Copy to current? */ _playback_copy_to_current( ctx, node ); end: if (remap_vertex_store) { save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store); } }