/** * Called via glBegin. */ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) { GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (!_mesa_valid_prim_mode(ctx, mode)) { _mesa_error(ctx, GL_INVALID_ENUM, "glBegin"); return; } vbo_draw_method(exec, DRAW_BEGIN_END); if (ctx->Driver.PrepareExecBegin) ctx->Driver.PrepareExecBegin(ctx); if (ctx->NewState) { _mesa_update_state( ctx ); CALL_Begin(ctx->Exec, (mode)); return; } if (!_mesa_valid_to_render(ctx, "glBegin")) { return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal(exec, GL_FALSE); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; exec->vtx.prim[i].num_instances = 1; ctx->Driver.CurrentExecPrimitive = mode; } else _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); }
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; if (0) _mesa_printf("%s\n", __FUNCTION__); if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); return; } vbo_exec_FlushVertices_internal( ctx, GL_TRUE ); /* Need to do this to ensure BeginVertices gets called again: */ if (exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { _mesa_restore_exec_vtxfmt( ctx ); exec->ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; } exec->ctx->Driver.NeedFlush &= ~flags; }
/** * \param flags bitmask of FLUSH_STORED_VERTICES, FLUSH_UPDATE_CURRENT */ void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; #ifdef DEBUG /* debug check: make sure we don't get called recursively */ exec->flush_call_depth++; assert(exec->flush_call_depth == 1); #endif if (0) _mesa_printf("%s\n", __FUNCTION__); if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); #ifdef DEBUG exec->flush_call_depth--; assert(exec->flush_call_depth == 0); #endif return; } vbo_exec_FlushVertices_internal( ctx, GL_TRUE ); /* Need to do this to ensure BeginVertices gets called again: */ if (exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { _mesa_restore_exec_vtxfmt( ctx ); exec->ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; } exec->ctx->Driver.NeedFlush &= ~flags; #ifdef DEBUG exec->flush_call_depth--; assert(exec->flush_call_depth == 0); #endif }
/** * Called via glBegin. */ static void GLAPIENTRY vbo_exec_Begin(GLenum mode) { GET_CURRENT_CONTEXT(ctx); struct vbo_exec_context *exec = &vbo_context(ctx)->exec; int i; if (_mesa_inside_begin_end(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin"); return; } if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) { return; } _mesa_set_drawing_arrays(ctx, exec->vtx.inputs); if (ctx->NewState) { _mesa_update_state(ctx); CALL_Begin(ctx->Exec, (mode)); return; } if (!_mesa_valid_to_render(ctx, "glBegin")) { return; } /* Heuristic: attempt to isolate attributes occurring outside * begin/end pairs. */ if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) vbo_exec_FlushVertices_internal(exec, GL_FALSE); i = exec->vtx.prim_count++; exec->vtx.prim[i].mode = mode; exec->vtx.prim[i].begin = 1; exec->vtx.prim[i].end = 0; exec->vtx.prim[i].indexed = 0; exec->vtx.prim[i].weak = 0; exec->vtx.prim[i].pad = 0; exec->vtx.prim[i].start = exec->vtx.vert_count; exec->vtx.prim[i].count = 0; exec->vtx.prim[i].num_instances = 1; exec->vtx.prim[i].base_instance = 0; exec->vtx.prim[i].is_indirect = 0; ctx->Driver.CurrentExecPrimitive = mode; ctx->Exec = ctx->BeginEnd; /* We may have been called from a display list, in which case we should * leave dlist.c's dispatch table in place. */ if (ctx->CurrentClientDispatch == ctx->OutsideBeginEnd) { ctx->CurrentClientDispatch = ctx->BeginEnd; _glapi_set_dispatch(ctx->CurrentClientDispatch); } else { assert(ctx->CurrentClientDispatch == ctx->Save); } }