aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/vbo/vbo_exec_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/vbo/vbo_exec_api.c')
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c182
1 files changed, 45 insertions, 137 deletions
diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c
index 353f8cfde..600398c58 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_api.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_api.c
@@ -34,7 +34,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/bufferobj.h"
#include "main/context.h"
#include "main/macros.h"
-#include "main/mfeatures.h"
#include "main/vtxfmt.h"
#include "main/dlist.h"
#include "main/eval.h"
@@ -75,7 +74,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin;
GLuint last_count;
- if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ if (_mesa_inside_begin_end(exec->ctx)) {
GLint i = exec->vtx.prim_count - 1;
assert(i >= 0);
exec->vtx.prim[i].count = (exec->vtx.vert_count -
@@ -97,7 +96,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
*/
assert(exec->vtx.prim_count == 0);
- if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ if (_mesa_inside_begin_end(exec->ctx)) {
exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive;
exec->vtx.prim[0].start = 0;
exec->vtx.prim[0].count = 0;
@@ -270,7 +269,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
/* Heuristic: Attempt to isolate attributes received outside
* begin/end so that they don't bloat the vertices.
*/
- if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
+ if (!_mesa_inside_begin_end(ctx) &&
!oldSize && lastcount > 8 && exec->vtx.vertex_size) {
vbo_exec_copy_to_current( exec );
reset_attrfv( exec );
@@ -655,132 +654,6 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
}
-static void GLAPIENTRY
-vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint i;
- GLfloat u, du;
- GLenum prim;
-
- switch (mode) {
- case GL_POINT:
- prim = GL_POINTS;
- break;
- case GL_LINE:
- prim = GL_LINE_STRIP;
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
- return;
- }
-
- /* No effect if vertex maps disabled.
- */
- if (!ctx->Eval.Map1Vertex4 &&
- !ctx->Eval.Map1Vertex3)
- return;
-
- du = ctx->Eval.MapGrid1du;
- u = ctx->Eval.MapGrid1u1 + i1 * du;
-
- CALL_Begin(GET_DISPATCH(), (prim));
- for (i=i1;i<=i2;i++,u+=du) {
- CALL_EvalCoord1f(GET_DISPATCH(), (u));
- }
- CALL_End(GET_DISPATCH(), ());
-}
-
-
-static void GLAPIENTRY
-vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat u, du, v, dv, v1, u1;
- GLint i, j;
-
- switch (mode) {
- case GL_POINT:
- case GL_LINE:
- case GL_FILL:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
- return;
- }
-
- /* No effect if vertex maps disabled.
- */
- if (!ctx->Eval.Map2Vertex4 &&
- !ctx->Eval.Map2Vertex3)
- return;
-
- du = ctx->Eval.MapGrid2du;
- dv = ctx->Eval.MapGrid2dv;
- v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
- u1 = ctx->Eval.MapGrid2u1 + i1 * du;
-
- switch (mode) {
- case GL_POINT:
- CALL_Begin(GET_DISPATCH(), (GL_POINTS));
- for (v=v1,j=j1;j<=j2;j++,v+=dv) {
- for (u=u1,i=i1;i<=i2;i++,u+=du) {
- CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
- }
- }
- CALL_End(GET_DISPATCH(), ());
- break;
- case GL_LINE:
- for (v=v1,j=j1;j<=j2;j++,v+=dv) {
- CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
- for (u=u1,i=i1;i<=i2;i++,u+=du) {
- CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
- }
- CALL_End(GET_DISPATCH(), ());
- }
- for (u=u1,i=i1;i<=i2;i++,u+=du) {
- CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
- for (v=v1,j=j1;j<=j2;j++,v+=dv) {
- CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
- }
- CALL_End(GET_DISPATCH(), ());
- }
- break;
- case GL_FILL:
- for (v=v1,j=j1;j<j2;j++,v+=dv) {
- CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
- for (u=u1,i=i1;i<=i2;i++,u+=du) {
- CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
- CALL_EvalCoord2f(GET_DISPATCH(), (u, v+dv));
- }
- CALL_End(GET_DISPATCH(), ());
- }
- break;
- }
-}
-
-
-/**
- * Execute a glRectf() function. This is not suitable for GL_COMPILE
- * modes (as the test for outside begin/end is not compiled),
- * but may be useful for drivers in circumstances which exclude
- * display list interactions.
- *
- * (None of the functions in this file are suitable for GL_COMPILE
- * modes).
- */
-static void GLAPIENTRY
-vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
- CALL_Begin(GET_DISPATCH(), (GL_QUADS));
- CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
- CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
- CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
- CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
- CALL_End(GET_DISPATCH(), ());
-}
-
-
/**
* Called via glBegin.
*/
@@ -790,7 +663,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
int i;
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ if (_mesa_inside_begin_end(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBegin");
return;
}
@@ -846,6 +719,34 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
/**
+ * 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 */
+ }
+ }
+}
+
+
+/**
* Called via glEnd.
*/
static void GLAPIENTRY vbo_exec_End( void )
@@ -853,7 +754,7 @@ static void GLAPIENTRY vbo_exec_End( void )
GET_CURRENT_CONTEXT( ctx );
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
- if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
+ if (!_mesa_inside_begin_end(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glEnd");
return;
}
@@ -871,6 +772,8 @@ static void GLAPIENTRY vbo_exec_End( void )
exec->vtx.prim[i].end = 1;
exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start;
+
+ try_vbo_merge(exec);
}
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
@@ -911,16 +814,21 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
struct gl_context *ctx = exec->ctx;
GLvertexformat *vfmt = &exec->vtxfmt;
- _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
+ vfmt->ArrayElement = _ae_ArrayElement;
vfmt->Begin = vbo_exec_Begin;
vfmt->End = vbo_exec_End;
vfmt->PrimitiveRestartNV = vbo_exec_PrimitiveRestartNV;
- _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_);
- _MESA_INIT_EVAL_VTXFMT(vfmt, vbo_exec_);
+ vfmt->CallList = _mesa_CallList;
+ vfmt->CallLists = _mesa_CallLists;
- vfmt->Rectf = vbo_exec_Rectf;
+ vfmt->EvalCoord1f = vbo_exec_EvalCoord1f;
+ vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv;
+ vfmt->EvalCoord2f = vbo_exec_EvalCoord2f;
+ vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv;
+ vfmt->EvalPoint1 = vbo_exec_EvalPoint1;
+ vfmt->EvalPoint2 = vbo_exec_EvalPoint2;
/* from attrib_tmp.h:
*/
@@ -1243,7 +1151,7 @@ void vbo_exec_FlushVertices( struct gl_context *ctx, GLuint flags )
assert(exec->flush_call_depth == 1);
#endif
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ if (_mesa_inside_begin_end(ctx)) {
/* We've had glBegin but not glEnd! */
#ifdef DEBUG
exec->flush_call_depth--;