{
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;
+
+ 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));
- }
}
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:
_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) {
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
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);