1
2/*
3 * Simple GLUT program to measure glClear() and glutSwapBuffers() speed.
4 * Brian Paul  February 15, 1997  This file in public domain.
5 */
6
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <math.h>
11#include <string.h>
12#include "glut_wrap.h"
13
14
15static float MinPeriod = 2.0;   /* 2 seconds */
16static int ColorMode = GLUT_RGB;
17static int Width = 400.0;
18static int Height = 400.0;
19static int Loops = 100;
20static float ClearColor = 0.0;
21static GLbitfield BufferMask = GL_COLOR_BUFFER_BIT;
22static GLboolean SwapFlag = GL_FALSE;
23
24
25
26static void Idle( void )
27{
28   glutPostRedisplay();
29}
30
31
32static void Display( void )
33{
34   double t0, t1;
35   double clearRate;
36   double pixelRate;
37   int i;
38
39   glClearColor( ClearColor, ClearColor, ClearColor, 0.0 );
40   ClearColor += 0.1;
41   if (ClearColor>1.0)
42      ClearColor = 0.0;
43
44   if (SwapFlag) {
45      t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
46      for (i=0;i<Loops;i++) {
47         glClear( BufferMask );
48         glutSwapBuffers();
49      }
50      glFinish();
51      t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
52   }
53   else {
54      t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
55      for (i=0;i<Loops;i++) {
56         glClear( BufferMask );
57      }
58      glFinish();
59      t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
60      glutSwapBuffers();
61   }
62
63   /* NOTE: If clearspd doesn't map it's window immediately on
64    * starting, swaps will be istantaneous, so this will send Loops
65    * towards infinity.  When a window is finally mapped, it may be
66    * minutes before the first call to glutSwapBuffers, making it look
67    * like there's a driver bug.
68    */
69   if (t1-t0 < MinPeriod) {
70      /* Next time do more clears to get longer elapsed time */
71      Loops *= 2;
72      return;
73   }
74
75   clearRate = Loops / (t1-t0);
76   pixelRate = clearRate * Width * Height;
77   if (SwapFlag) {
78      printf("Rate: %d clears+swaps in %gs = %g clears+swaps/s   %g pixels/s\n",
79             Loops, t1-t0, clearRate, pixelRate );
80   }
81   else {
82      printf("Rate: %d clears in %gs = %g clears/s   %g pixels/s\n",
83             Loops, t1-t0, clearRate, pixelRate);
84   }
85}
86
87
88static void Reshape( int width, int height )
89{
90   Width = width;
91   Height = height;
92   glViewport( 0, 0, width, height );
93   glMatrixMode( GL_PROJECTION );
94   glLoadIdentity();
95   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
96   glMatrixMode( GL_MODELVIEW );
97   glLoadIdentity();
98}
99
100
101static void Key( unsigned char key, int x, int y )
102{
103   (void) x;
104   (void) y;
105   switch (key) {
106      case 27:
107         exit(0);
108         break;
109   }
110   glutPostRedisplay();
111}
112
113
114static void Init( int argc, char *argv[] )
115{
116   int i;
117   for (i=1; i<argc; i++) {
118      if (strcmp(argv[i],"+rgb")==0)
119         ColorMode = GLUT_RGB;
120      else if (strcmp(argv[i],"+ci")==0)
121         ColorMode = GLUT_INDEX;
122      else if (strcmp(argv[i],"-color")==0)
123         BufferMask = 0;
124      else if (strcmp(argv[i],"+depth")==0)
125         BufferMask |= GL_DEPTH_BUFFER_BIT;
126      else if (strcmp(argv[i],"+alpha")==0)
127         ColorMode = GLUT_RGB | GLUT_ALPHA;
128      else if (strcmp(argv[i],"+stencil")==0)
129         BufferMask |= GL_STENCIL_BUFFER_BIT;
130      else if (strcmp(argv[i],"+accum")==0)
131         BufferMask |= GL_ACCUM_BUFFER_BIT;
132      else if (strcmp(argv[i],"-width")==0) {
133         Width = atoi(argv[i+1]);
134         i++;
135      }
136      else if (strcmp(argv[i],"-height")==0) {
137         Height = atoi(argv[i+1]);
138         i++;
139      }
140      else if (strcmp(argv[i],"+swap")==0) {
141         SwapFlag = GL_TRUE;
142      }
143      else if (strcmp(argv[i],"-swap")==0) {
144         SwapFlag = GL_FALSE;
145      }
146      else
147         printf("Unknown option: %s\n", argv[i]);
148   }
149
150   if (ColorMode & GLUT_ALPHA)
151      printf("Mode:  RGB + Alpha\n");
152   else if (ColorMode==GLUT_RGB)
153      printf("Mode:  RGB\n");
154   else
155      printf("Mode:  Color Index\n");
156   printf("SwapBuffers: %s\n", SwapFlag ? "yes" : "no" );
157   printf("Size: %d x %d\n", Width, Height);
158   printf("Buffers: ");
159   if (BufferMask & GL_COLOR_BUFFER_BIT)  printf("color ");
160   if (BufferMask & GL_DEPTH_BUFFER_BIT)  printf("depth ");
161   if (BufferMask & GL_STENCIL_BUFFER_BIT)  printf("stencil ");
162   if (BufferMask & GL_ACCUM_BUFFER_BIT)  printf("accum ");
163   printf("\n");
164}
165
166
167static void Help( const char *program )
168{
169   printf("%s options:\n", program);
170   printf("  +rgb       RGB mode\n");
171   printf("  +ci        color index mode\n");
172   printf("  -color     don't clear color buffer\n");
173   printf("  +alpha     clear alpha buffer\n");
174   printf("  +depth     clear depth buffer\n");
175   printf("  +stencil   clear stencil buffer\n");
176   printf("  +accum     clear accum buffer\n");
177   printf("  +swap      also do SwapBuffers\n");
178   printf("  -swap      don't do SwapBuffers\n");
179}
180
181
182int main( int argc, char *argv[] )
183{
184   GLint mode;
185
186   printf("For options:  %s -help\n", argv[0]);
187
188   Init( argc, argv );
189
190   glutInitWindowSize( (int) Width, (int) Height );
191   glutInit( &argc, argv );
192
193   mode = ColorMode | GLUT_DOUBLE;
194   if (BufferMask & GL_STENCIL_BUFFER_BIT)
195      mode |= GLUT_STENCIL;
196   if (BufferMask & GL_ACCUM_BUFFER_BIT)
197      mode |= GLUT_ACCUM;
198   if (BufferMask & GL_DEPTH_BUFFER_BIT)
199      mode |= GLUT_DEPTH;
200
201   glutInitDisplayMode(mode);
202
203   glutCreateWindow( argv[0] );
204
205   if (argc==2 && strcmp(argv[1],"-help")==0) {
206      Help(argv[0]);
207      return 0;
208   }
209
210   glutReshapeFunc( Reshape );
211   glutKeyboardFunc( Key );
212   glutDisplayFunc( Display );
213   glutIdleFunc( Idle );
214
215   glutMainLoop();
216   return 0;
217}
218