diff options
author | Keith Whitwell <keithw@vmware.com> | 2009-07-02 13:29:46 +0100 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2009-07-02 13:29:46 +0100 |
commit | 1668a679c4aadb37f5af0d6126c414fb9fbbf748 (patch) | |
tree | b3edf4157c658f1c37d5e046752135bd2ec566ea | |
parent | b3e8e1cd4c1584f735e35914861ae2e8ae5b6b2b (diff) | |
parent | 1fa4cde757cc94c0afa40d855309911247974e98 (diff) |
Merge commit 'origin/dlist-statechange-shortcircuit' into mesa_7_5_branch
Conflicts:
progs/trivial/Makefile
Pull in a minimal version of statechange shortcircuiting in display
list compilation. This affects only glMaterial and glShadeModel state,
and includes quite a few tests to exercise various tricky cases.
If this goes well, will consider extending to all state in the future.
-rw-r--r-- | progs/trivial/Makefile | 5 | ||||
-rw-r--r-- | progs/trivial/dlist-flat-tri.c | 171 | ||||
-rw-r--r-- | progs/trivial/dlist-mat-tri.c | 182 | ||||
-rw-r--r-- | progs/trivial/dlist-recursive-call.c | 190 | ||||
-rw-r--r-- | progs/trivial/dlist-tri-flat-tri.c | 171 | ||||
-rw-r--r-- | progs/trivial/dlist-tri-mat-tri.c | 174 | ||||
-rw-r--r-- | src/mesa/main/dlist.c | 112 | ||||
-rw-r--r-- | src/mesa/main/enums.c | 22 | ||||
-rw-r--r-- | src/mesa/main/enums.h | 6 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 7 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_exec_draw.c | 2 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 2 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_loopback.c | 2 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_split_copy.c | 2 |
14 files changed, 1011 insertions, 37 deletions
diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index fa200dbf89..3bd8faff99 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -19,6 +19,11 @@ SOURCES = \ clear-random.c \ clear.c \ dlist-dangling.c \ + dlist-flat-tri.c \ + dlist-mat-tri.c \ + dlist-tri-flat-tri.c \ + dlist-tri-mat-tri.c \ + dlist-recursive-call.c \ dlist-begin-call-end.c \ dlist-edgeflag-dangling.c \ dlist-edgeflag.c \ diff --git a/progs/trivial/dlist-flat-tri.c b/progs/trivial/dlist-flat-tri.c new file mode 100644 index 0000000000..c3dd7921e3 --- /dev/null +++ b/progs/trivial/dlist-flat-tri.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + + +GLenum doubleBuffer; +GLint list; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + glClearColor(0.0, 0.0, 1.0, 0.0); + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + /* XXX: this state-change will only be executed if list is called + * from outside a begin/end pair: + */ + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(0,0,.7); + glVertex3f( -0.9, 0.9, -30.0); + glColor3f(0,.9,0); + glVertex3f( -0.9, -0.9, -30.0); + glColor3f(.8,0,0); + glVertex3f( 0.9, 0.0, -30.0); + glEnd(); + + /* This statechange is potentially NOT redundant: + */ + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(0,1,0); + glVertex3f( -0.5, 0.5, -30.0); + glColor3f(0,0,1); + glVertex3f( -0.5, -0.5, -30.0); + glColor3f(1,0,0); + glVertex3f( 0.5, 0.0, -30.0); + glEnd(); + + glEndList(); +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + + + + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glShadeModel( GL_SMOOTH ); + + glBegin(GL_TRIANGLES); + + /* Note: call the list from inside a begin/end pair. The end is + * provided by the display list... + */ + glCallList(list); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB | GLUT_ALPHA; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow(*argv) == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/dlist-mat-tri.c b/progs/trivial/dlist-mat-tri.c new file mode 100644 index 0000000000..ed3a4c5981 --- /dev/null +++ b/progs/trivial/dlist-mat-tri.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + + +GLenum doubleBuffer; +GLint list; + +static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0}; +static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0}; +/*static GLfloat blue[4] = {0.2, 0.2, .7, 1.0};*/ + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glClearColor(0.0, 0.0, 1.0, 0.0); + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + /* XXX: this state-change will be executed regardless of whether + * the list is called from outside a begin/end pair: + */ + glMaterialfv(GL_FRONT, GL_AMBIENT, red); + glBegin(GL_TRIANGLES); + glVertex3f( -0.9, 0.9, -30.0); + glVertex3f( -0.9, -0.9, -30.0); + glVertex3f( 0.9, 0.0, -30.0); + glEnd(); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, red); + glBegin(GL_TRIANGLES); + glVertex3f( -0.7, 0.7, -30.0); + glVertex3f( -0.7, -0.7, -30.0); + glVertex3f( 0.7, 0.0, -30.0); + glEnd(); + + /* This statechange is redundant: + */ + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + glBegin(GL_TRIANGLES); + glVertex3f( -0.5, 0.5, -30.0); + glVertex3f( -0.5, -0.5, -30.0); + glVertex3f( 0.5, 0.0, -30.0); + glEnd(); + + glEndList(); +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + + + + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glShadeModel( GL_SMOOTH ); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + + glBegin(GL_TRIANGLES); + + /* Note: call the list from inside a begin/end pair. The end is + * provided by the display list... + */ + glCallList(list); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB | GLUT_ALPHA; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow(*argv) == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/dlist-recursive-call.c b/progs/trivial/dlist-recursive-call.c new file mode 100644 index 0000000000..fe06b2bbd7 --- /dev/null +++ b/progs/trivial/dlist-recursive-call.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + + +GLenum doubleBuffer; +GLint first_list, list; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + glClearColor(0.0, 0.0, 1.0, 0.0); + + /* First list will disrupt state which might potentially be + * short-circuited in calling list: + */ + first_list = glGenLists(1); + glNewList(first_list, GL_COMPILE); + glShadeModel( GL_SMOOTH ); + glEndList(); + + + /* List that looks like it might have redundant state: + */ + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + glBegin(GL_TRIANGLES); + glColor3f(0,0,.7); + glVertex3f( 0.9, -0.9, -30.0); + glColor3f(.8,0,0); + glVertex3f( 0.9, 0.9, -30.0); + glColor3f(0,.9,0); + glVertex3f(-0.9, 0.0, -30.0); + glEnd(); + + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(0,0,.7); + glVertex3f( -0.9, 0.9, -30.0); + glColor3f(0,.9,0); + glVertex3f( -0.9, -0.9, -30.0); + glColor3f(.8,0,0); + glVertex3f( 0.9, 0.0, -30.0); + glEnd(); + + glCallList( first_list ); + + /* Do a quick begin/end to ensure we are not inside a dangling + * primitive from the called list: + */ + glBegin( GL_POINTS ); + glEnd(); + + /* This statechange is NOT redundant: + */ + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(1,0,0); + glVertex3f( -0.5, 0.5, -30.0); + glColor3f(0,1,0); + glVertex3f( -0.5, -0.5, -30.0); + glColor3f(0,0,1); + glVertex3f( 0.5, 0.0, -30.0); + glEnd(); + + glEndList(); +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + + + + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glShadeModel( GL_SMOOTH ); + glCallList(list); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB | GLUT_ALPHA; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow(*argv) == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/dlist-tri-flat-tri.c b/progs/trivial/dlist-tri-flat-tri.c new file mode 100644 index 0000000000..4dbb788486 --- /dev/null +++ b/progs/trivial/dlist-tri-flat-tri.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + + +GLenum doubleBuffer; +GLint list; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + glClearColor(0.0, 0.0, 1.0, 0.0); + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + glBegin(GL_TRIANGLES); + glColor3f(0,0,.7); + glVertex3f( 0.9, -0.9, -30.0); + glColor3f(.8,0,0); + glVertex3f( 0.9, 0.9, -30.0); + glColor3f(0,.9,0); + glVertex3f(-0.9, 0.0, -30.0); + glEnd(); + + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(0,0,.7); + glVertex3f( -0.9, 0.9, -30.0); + glColor3f(0,.9,0); + glVertex3f( -0.9, -0.9, -30.0); + glColor3f(.8,0,0); + glVertex3f( 0.9, 0.0, -30.0); + glEnd(); + + /* This statechange is redundant: + */ + glShadeModel( GL_FLAT ); + glBegin(GL_TRIANGLES); + glColor3f(1,0,0); + glVertex3f( -0.5, 0.5, -30.0); + glColor3f(0,1,0); + glVertex3f( -0.5, -0.5, -30.0); + glColor3f(0,0,1); + glVertex3f( 0.5, 0.0, -30.0); + glEnd(); + + glEndList(); +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + + + + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glShadeModel( GL_SMOOTH ); + glCallList(list); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB | GLUT_ALPHA; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow(*argv) == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/progs/trivial/dlist-tri-mat-tri.c b/progs/trivial/dlist-tri-mat-tri.c new file mode 100644 index 0000000000..f69854ae58 --- /dev/null +++ b/progs/trivial/dlist-tri-mat-tri.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <GL/glut.h> + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + + +GLenum doubleBuffer; +GLint list; + +static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0}; +static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0}; +static GLfloat blue[4] = {0.2, 0.2, .9, 1.0}; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + fflush(stderr); + + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glClearColor(0.0, 0.0, 1.0, 0.0); + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + + glBegin(GL_TRIANGLES); + glNormal3f(0,0,.7); + glVertex3f( 0.9, -0.9, -30.0); + glVertex3f( 0.9, 0.9, -30.0); + glVertex3f(-0.9, 0.0, -30.0); + glEnd(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + + glBegin(GL_TRIANGLES); + glVertex3f( -0.9, 0.9, -30.0); + glVertex3f( -0.9, -0.9, -30.0); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + glVertex3f( 0.9, 0.0, -30.0); + glEnd(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + glBegin(GL_TRIANGLES); + glVertex3f( -0.5, 0.5, -30.0); + glVertex3f( -0.5, -0.5, -30.0); + glVertex3f( 0.5, 0.0, -30.0); + glEnd(); + + glEndList(); +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + + + + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glShadeModel( GL_SMOOTH ); + glCallList(list); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB | GLUT_ALPHA; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow(*argv) == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 782f847904..c5a1c1f38f 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -957,6 +957,20 @@ save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) } } +static void invalidate_saved_current_state( GLcontext *ctx ) +{ + GLint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + ctx->ListState.ActiveAttribSize[i] = 0; + + 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; +} void GLAPIENTRY _mesa_save_CallList(GLuint list) @@ -970,9 +984,10 @@ _mesa_save_CallList(GLuint list) n[1].ui = list; } - /* After this, we don't know what begin/end state we're in: + /* After this, we don't know what state we're in. Invalidate all + * cached information previously gathered: */ - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; + invalidate_saved_current_state( ctx ); if (ctx->ExecuteFlag) { _mesa_CallList(list); @@ -1015,9 +1030,10 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists) } } - /* After this, we don't know what begin/end state we're in: + /* After this, we don't know what state we're in. Invalidate all + * cached information previously gathered: */ - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; + invalidate_saved_current_state( ctx ); if (ctx->ExecuteFlag) { CALL_CallLists(ctx->Exec, (n, type, lists)); @@ -3177,14 +3193,26 @@ 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); + + /* Only save the value if we know the statechange will take effect: + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) + 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 +5174,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,26 +5218,43 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)"); return; } - - n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6); - if (n) { - n[1].e = face; - n[2].e = pname; - for (i = 0; i < args; i++) - n[3 + i].f = param[i]; + + if (ctx->ExecuteFlag) { + CALL_Materialfv(ctx->Exec, (face, pname, param)); } - { - GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); - for (i = 0; i < MAT_ATTRIB_MAX; i++) - if (bitmask & (1 << i)) { + bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); + + /* Try to eliminate redundant statechanges. Because it is legal to + * call glMaterial even inside begin/end calls, don't need to worry + * about ctx->Driver.CurrentSavePrimitive here. + */ + for (i = 0; i < MAT_ATTRIB_MAX; i++) { + if (bitmask & (1 << i)) { + if (ctx->ListState.ActiveMaterialSize[i] == args && + compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) { + bitmask &= ~(1 << i); + } + else { ctx->ListState.ActiveMaterialSize[i] = args; COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param); } + } } - if (ctx->ExecuteFlag) { - CALL_Materialfv(ctx->Exec, (face, pname, param)); + /* If this call has effect, return early: + */ + if (bitmask == 0) + return; + + SAVE_FLUSH_VERTICES(ctx); + + n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6); + if (n) { + n[1].e = face; + n[2].e = pname; + for (i = 0; i < args; i++) + n[3 + i].f = param[i]; } } @@ -6771,7 +6823,6 @@ void GLAPIENTRY _mesa_NewList(GLuint name, GLenum mode) { GET_CURRENT_CONTEXT(ctx); - GLint i; FLUSH_CURRENT(ctx, 0); /* must be called before assert */ ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -6799,20 +6850,15 @@ _mesa_NewList(GLuint name, GLenum mode) ctx->CompileFlag = GL_TRUE; ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE); + /* Reset acumulated list state: + */ + invalidate_saved_current_state( ctx ); + /* Allocate new display list */ ctx->ListState.CurrentList = make_list(name, BLOCK_SIZE); ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->Head; ctx->ListState.CurrentPos = 0; - /* Reset acumulated list state: - */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) - ctx->ListState.ActiveAttribSize[i] = 0; - - for (i = 0; i < MAT_ATTRIB_MAX; i++) - ctx->ListState.ActiveMaterialSize[i] = 0; - - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; ctx->Driver.NewList(ctx, name, mode); ctx->CurrentDispatch = ctx->Save; 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 7dcb5c8242..85cb79c71c 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -1162,7 +1162,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 = ©->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; |