1 /*
2  * Measure glCopyPixels speed
3  *
4  * Brian Paul
5  * 26 Jan 2006
6  */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <math.h>
12 #include <glad/glad.h>
13 #include "glut_wrap.h"
14 
15 static GLint WinWidth = 1000, WinHeight = 800;
16 static GLint ImgWidth, ImgHeight;
17 
18 static GLenum Buffer = GL_FRONT;
19 static GLenum AlphaTest = GL_FALSE;
20 static GLboolean UseBlit = GL_FALSE;
21 
22 
23 /**
24  * draw teapot in lower-left corner of window
25  */
26 static void
DrawTestImage(void)27 DrawTestImage(void)
28 {
29    GLfloat ar;
30 
31    ImgWidth = WinWidth / 3;
32    ImgHeight = WinHeight / 3;
33 
34    glViewport(0, 0, ImgWidth, ImgHeight);
35    glScissor(0, 0, ImgWidth, ImgHeight);
36    glEnable(GL_SCISSOR_TEST);
37 
38    glClearColor(0.5, 0.5, 0.5, 0.0);
39    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
40 
41    ar = (float) WinWidth / WinHeight;
42 
43    glMatrixMode(GL_PROJECTION);
44    glLoadIdentity();
45    glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
46    glMatrixMode(GL_MODELVIEW);
47 
48    glEnable(GL_LIGHTING);
49    glEnable(GL_LIGHT0);
50    glEnable(GL_DEPTH_TEST);
51    glFrontFace(GL_CW);
52    glPushMatrix();
53    glRotatef(45, 1, 0, 0);
54    glutSolidTeapot(2.0);
55    glPopMatrix();
56    glFrontFace(GL_CCW);
57    glDisable(GL_DEPTH_TEST);
58    glDisable(GL_LIGHTING);
59 
60    glDisable(GL_SCISSOR_TEST);
61 
62    glViewport(0, 0, WinWidth, WinHeight);
63    glFinish();
64 }
65 
66 
67 static int
Rand(int max)68 Rand(int max)
69 {
70    return ((int) rand()) % max;
71 }
72 
73 
74 static void
BlitOne(void)75 BlitOne(void)
76 {
77    int x, y;
78 
79    do {
80       x = Rand(WinWidth);
81       y = Rand(WinHeight);
82    } while (x <= ImgWidth && y <= ImgHeight);
83 
84 #ifdef GL_EXT_framebuffer_blit
85    if (UseBlit)
86    {
87       glBlitFramebufferEXT(0, 0, ImgWidth, ImgHeight,
88                            x, y, x + ImgWidth, y + ImgHeight,
89                            GL_COLOR_BUFFER_BIT, GL_LINEAR);
90    }
91    else
92 #endif
93    {
94       glWindowPos2iARB(x, y);
95       glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
96    }
97 }
98 
99 
100 /**
101  * Measure glCopyPixels rate
102  */
103 static void
RunTest(void)104 RunTest(void)
105 {
106    double t1, t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
107    int iters = 0;
108    float copyRate, mbRate;
109    int r, g, b, a, bpp;
110 
111    if (AlphaTest) {
112       glEnable(GL_ALPHA_TEST);
113       glAlphaFunc(GL_GREATER, 0.0);
114    }
115 
116    glGetIntegerv(GL_RED_BITS, &r);
117    glGetIntegerv(GL_GREEN_BITS, &g);
118    glGetIntegerv(GL_BLUE_BITS, &b);
119    glGetIntegerv(GL_ALPHA_BITS, &a);
120    bpp = (r + g + b + a) / 8;
121 
122    do {
123       BlitOne();
124 
125       if (Buffer == GL_FRONT)
126          glFinish(); /* XXX to view progress */
127 
128       iters++;
129 
130       t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
131    } while (t1 - t0 < 5.0);
132 
133    glDisable(GL_ALPHA_TEST);
134 
135    copyRate = iters / (t1 - t0);
136    mbRate = ImgWidth * ImgHeight * bpp * copyRate / (1024 * 1024);
137 
138    printf("Image size: %d x %d, %d Bpp\n", ImgWidth, ImgHeight, bpp);
139    printf("%d copies in %.2f = %.2f copies/sec, %.2f MB/s\n",
140           iters, t1-t0, copyRate, mbRate);
141 }
142 
143 
144 static void
Draw(void)145 Draw(void)
146 {
147    glClearColor(0.0, 0.0, 0.0, 0.0);
148    glClearColor(0.2, 0.2, 0.8, 0);
149    glReadBuffer(Buffer);
150    glDrawBuffer(Buffer);
151    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
152 
153    DrawTestImage();
154 
155    RunTest();
156 
157    if (Buffer == GL_FRONT)
158       glFinish();
159    else
160       glutSwapBuffers();
161 
162 #if 1
163    printf("exiting\n");
164    exit(0);
165 #endif
166 }
167 
168 
169 static void
Reshape(int width,int height)170 Reshape(int width, int height)
171 {
172    glViewport(0, 0, width, height);
173    glMatrixMode(GL_PROJECTION);
174    glLoadIdentity();
175    glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
176    glMatrixMode(GL_MODELVIEW);
177    glLoadIdentity();
178    glTranslatef(0.0, 0.0, -15.0);
179 }
180 
181 
182 static void
Key(unsigned char key,int x,int y)183 Key(unsigned char key, int x, int y)
184 {
185    (void) x;
186    (void) y;
187    switch (key) {
188    case 'b':
189       BlitOne();
190       break;
191    case 27:
192       exit(0);
193       break;
194    }
195    glutPostRedisplay();
196 }
197 
198 
199 static void
SpecialKey(int key,int x,int y)200 SpecialKey(int key, int x, int y)
201 {
202    (void) x;
203    (void) y;
204    switch (key) {
205       case GLUT_KEY_UP:
206          break;
207       case GLUT_KEY_DOWN:
208          break;
209       case GLUT_KEY_LEFT:
210          break;
211       case GLUT_KEY_RIGHT:
212          break;
213    }
214    glutPostRedisplay();
215 }
216 
217 
218 static void
ParseArgs(int argc,char * argv[])219 ParseArgs(int argc, char *argv[])
220 {
221    int i;
222    for (i = 1; i < argc; i++) {
223       if (strcmp(argv[i], "-back") == 0)
224          Buffer = GL_BACK;
225       else if (strcmp(argv[i], "-alpha") == 0)
226          AlphaTest = GL_TRUE;
227       else if (strcmp(argv[i], "-blit") == 0)
228          UseBlit = GL_TRUE;
229    }
230 }
231 
232 
233 static void
Init(void)234 Init(void)
235 {
236    if (glutExtensionSupported("GL_EXT_framebuffer_blit")) {
237    }
238    else if (UseBlit) {
239       printf("Warning: GL_EXT_framebuffer_blit not supported.\n");
240       UseBlit = GL_FALSE;
241    }
242 }
243 
244 
245 int
main(int argc,char * argv[])246 main(int argc, char *argv[])
247 {
248    GLint mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH;
249    glutInit(&argc, argv);
250 
251    ParseArgs(argc, argv);
252    if (AlphaTest)
253       mode |= GLUT_ALPHA;
254 
255    glutInitWindowPosition(0, 0);
256    glutInitWindowSize(WinWidth, WinHeight);
257    glutInitDisplayMode(mode);
258    glutCreateWindow(argv[0]);
259    gladLoadGL();
260    glutReshapeFunc(Reshape);
261    glutKeyboardFunc(Key);
262    glutSpecialFunc(SpecialKey);
263    glutDisplayFunc(Draw);
264 
265    printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
266    printf("Draw Buffer: %s\n", (Buffer == GL_BACK) ? "Back" : "Front");
267    Init();
268 
269    printf("Mode: %s\n", (UseBlit ? "glBlitFramebuffer" : "glCopyPixels"));
270    printf("Alpha Test: %s\n", (AlphaTest ? "yes" : "no"));
271 
272    glutMainLoop();
273    return 0;
274 }
275