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