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 <GL/glew.h> 13#include "glut_wrap.h" 14 15static GLint WinWidth = 1000, WinHeight = 800; 16static GLint ImgWidth, ImgHeight; 17 18static GLenum Buffer = GL_FRONT; 19static GLenum AlphaTest = GL_FALSE; 20static GLboolean UseBlit = GL_FALSE; 21 22 23/** 24 * draw teapot in lower-left corner of window 25 */ 26static void 27DrawTestImage(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 67static int 68Rand(int max) 69{ 70 return ((int) rand()) % max; 71} 72 73 74static void 75BlitOne(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 */ 103static void 104RunTest(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 144static void 145Draw(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 169static void 170Reshape(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 182static void 183Key(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 199static void 200SpecialKey(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 218static void 219ParseArgs(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 233static void 234Init(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 245int 246main(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 glewInit(); 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