summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/dlist.c64
-rw-r--r--src/mesa/main/enums.c22
-rw-r--r--src/mesa/main/enums.h6
-rw-r--r--src/mesa/main/mtypes.h7
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c2
-rw-r--r--src/mesa/vbo/vbo_save_api.c2
-rw-r--r--src/mesa/vbo/vbo_save_loopback.c2
-rw-r--r--src/mesa/vbo/vbo_split_copy.c2
8 files changed, 84 insertions, 23 deletions
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 782f847904..93b8a8f56d 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -3177,14 +3177,22 @@ save_ShadeModel(GLenum mode)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);
+
+ if (ctx->ExecuteFlag) {
+ CALL_ShadeModel(ctx->Exec, (mode));
+ }
+
+ if (ctx->ListState.Current.ShadeModel == mode)
+ return;
+
+ SAVE_FLUSH_VERTICES(ctx);
+ ctx->ListState.Current.ShadeModel = mode;
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_SHADE_MODEL, 1);
if (n) {
n[1].e = mode;
}
- if (ctx->ExecuteFlag) {
- CALL_ShadeModel(ctx->Exec, (mode));
- }
}
@@ -5146,14 +5154,21 @@ save_EdgeFlag(GLboolean x)
save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
}
+static INLINE GLboolean compare4fv( const GLfloat *a,
+ const GLfloat *b,
+ GLuint count )
+{
+ return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
+}
+
+
static void GLAPIENTRY
save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
int args, i;
-
- SAVE_FLUSH_VERTICES(ctx);
+ GLuint bitmask;
switch (face) {
case GL_BACK:
@@ -5183,6 +5198,28 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
_mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
return;
}
+
+ if (ctx->ExecuteFlag) {
+ CALL_Materialfv(ctx->Exec, (face, pname, param));
+ }
+
+ bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
+
+ /* Try to eliminate redundant statechanges
+ */
+ for (i = 0; i < MAT_ATTRIB_MAX; i++) {
+ if (bitmask & (1 << i)) {
+ if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END &&
+ ctx->ListState.ActiveMaterialSize[i] == args &&
+ compare4fv(ctx->ListState.CurrentMaterial[i], param, args))
+ return;
+
+ ctx->ListState.ActiveMaterialSize[i] = args;
+ COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
+ }
+ }
+
+ SAVE_FLUSH_VERTICES(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6);
if (n) {
@@ -5191,19 +5228,6 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
for (i = 0; i < args; i++)
n[3 + i].f = param[i];
}
-
- {
- GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
- for (i = 0; i < MAT_ATTRIB_MAX; i++)
- if (bitmask & (1 << i)) {
- ctx->ListState.ActiveMaterialSize[i] = args;
- COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
- }
- }
-
- if (ctx->ExecuteFlag) {
- CALL_Materialfv(ctx->Exec, (face, pname, param));
- }
}
static void GLAPIENTRY
@@ -6812,6 +6836,8 @@ _mesa_NewList(GLuint name, GLenum mode)
for (i = 0; i < MAT_ATTRIB_MAX; i++)
ctx->ListState.ActiveMaterialSize[i] = 0;
+ memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
+
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
ctx->Driver.NewList(ctx, name, mode);
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
index cf893fdac5..417cee8fb2 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -5059,6 +5059,28 @@ const char *_mesa_lookup_enum_by_nr( int nr )
}
}
+/* Get the name of an enum given that it is a primitive type. Avoids
+ * GL_FALSE/GL_POINTS ambiguity and others.
+ */
+const char *_mesa_lookup_prim_by_nr( int nr )
+{
+ switch (nr) {
+ case GL_POINTS: return "GL_POINTS";
+ case GL_LINES: return "GL_LINES";
+ case GL_LINE_STRIP: return "GL_LINE_STRIP";
+ case GL_LINE_LOOP: return "GL_LINE_LOOP";
+ case GL_TRIANGLES: return "GL_TRIANGLES";
+ case GL_TRIANGLE_STRIP: return "GL_TRIANGLE_STRIP";
+ case GL_TRIANGLE_FAN: return "GL_TRIANGLE_FAN";
+ case GL_QUADS: return "GL_QUADS";
+ case GL_QUAD_STRIP: return "GL_QUAD_STRIP";
+ case GL_POLYGON: return "GL_POLYGON";
+ case GL_POLYGON+1: return "OUTSIDE_BEGIN_END";
+ default: return "<invalid>";
+ }
+}
+
+
int _mesa_lookup_enum_by_name( const char *symbol )
{
enum_elt * f = NULL;
diff --git a/src/mesa/main/enums.h b/src/mesa/main/enums.h
index 23a4767f35..b5f69001b8 100644
--- a/src/mesa/main/enums.h
+++ b/src/mesa/main/enums.h
@@ -40,6 +40,12 @@
#if defined(_HAVE_FULL_GL) && _HAVE_FULL_GL
extern const char *_mesa_lookup_enum_by_nr( int nr );
+
+/* Get the name of an enum given that it is a primitive type. Avoids
+ * GL_FALSE/GL_POINTS ambiguity and others.
+ */
+const char *_mesa_lookup_prim_by_nr( int nr );
+
extern int _mesa_lookup_enum_by_name( const char *symbol );
#else
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 84a082b253..bdaa4977b7 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2806,6 +2806,13 @@ struct gl_dlist_state
GLubyte ActiveEdgeFlag;
GLboolean CurrentEdgeFlag;
+
+ struct {
+ /* State known to have been set by the currently-compiling display
+ * list. Used to eliminate some redundant state changes.
+ */
+ GLenum ShadeModel;
+ } Current;
};
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index fdacb42e35..c53a4eee00 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -50,7 +50,7 @@ static void vbo_exec_debug_verts( struct vbo_exec_context *exec )
struct _mesa_prim *prim = &exec->vtx.prim[i];
_mesa_printf(" prim %d: %s%s %d..%d %s %s\n",
i,
- _mesa_lookup_enum_by_nr(prim->mode),
+ _mesa_lookup_prim_by_nr(prim->mode),
prim->weak ? " (weak)" : "",
prim->start,
prim->start + prim->count,
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index 868226075a..971a338af4 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -1148,7 +1148,7 @@ static void vbo_print_vertex_list( GLcontext *ctx, void *data )
struct _mesa_prim *prim = &node->prim[i];
_mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n",
i,
- _mesa_lookup_enum_by_nr(prim->mode),
+ _mesa_lookup_prim_by_nr(prim->mode),
prim->weak ? " (weak)" : "",
prim->start,
prim->start + prim->count,
diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c
index 92ca4ea95d..b7a74e4535 100644
--- a/src/mesa/vbo/vbo_save_loopback.c
+++ b/src/mesa/vbo/vbo_save_loopback.c
@@ -97,7 +97,7 @@ static void loopback_prim( GLcontext *ctx,
if (0)
_mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n",
- _mesa_lookup_enum_by_nr(prim->mode),
+ _mesa_lookup_prim_by_nr(prim->mode),
prim->begin ? "begin" : "..",
prim->end ? "end" : "..",
start,
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index 5fb66d3318..b9a5c56987 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -180,7 +180,7 @@ static void begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag
{
struct _mesa_prim *prim = &copy->dstprim[copy->dstprim_nr];
-/* _mesa_printf("begin %s (%d)\n", _mesa_lookup_enum_by_nr(mode), begin_flag); */
+/* _mesa_printf("begin %s (%d)\n", _mesa_lookup_prim_by_nr(mode), begin_flag); */
prim->mode = mode;
prim->begin = begin_flag;