132001f49Smrg/*
232001f49Smrg * Measure glCopyPixels speed
332001f49Smrg *
432001f49Smrg * Brian Paul
532001f49Smrg * 26 Jan 2006
632001f49Smrg */
732001f49Smrg
832001f49Smrg#include <stdio.h>
932001f49Smrg#include <stdlib.h>
1032001f49Smrg#include <string.h>
1132001f49Smrg#include <math.h>
1232001f49Smrg#include <GL/glew.h>
1332001f49Smrg#include "glut_wrap.h"
1432001f49Smrg
1532001f49Smrgstatic GLint WinWidth = 1000, WinHeight = 800;
1632001f49Smrgstatic GLint ImgWidth, ImgHeight;
1732001f49Smrg
1832001f49Smrgstatic GLenum Buffer = GL_FRONT;
1932001f49Smrgstatic GLenum AlphaTest = GL_FALSE;
2032001f49Smrgstatic GLboolean UseBlit = GL_FALSE;
2132001f49Smrg
2232001f49Smrg
2332001f49Smrg/**
2432001f49Smrg * draw teapot in lower-left corner of window
2532001f49Smrg */
2632001f49Smrgstatic void
2732001f49SmrgDrawTestImage(void)
2832001f49Smrg{
2932001f49Smrg   GLfloat ar;
3032001f49Smrg
3132001f49Smrg   ImgWidth = WinWidth / 3;
3232001f49Smrg   ImgHeight = WinHeight / 3;
3332001f49Smrg
3432001f49Smrg   glViewport(0, 0, ImgWidth, ImgHeight);
3532001f49Smrg   glScissor(0, 0, ImgWidth, ImgHeight);
3632001f49Smrg   glEnable(GL_SCISSOR_TEST);
3732001f49Smrg
3832001f49Smrg   glClearColor(0.5, 0.5, 0.5, 0.0);
3932001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4032001f49Smrg
4132001f49Smrg   ar = (float) WinWidth / WinHeight;
4232001f49Smrg
4332001f49Smrg   glMatrixMode(GL_PROJECTION);
4432001f49Smrg   glLoadIdentity();
4532001f49Smrg   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
4632001f49Smrg   glMatrixMode(GL_MODELVIEW);
4732001f49Smrg
4832001f49Smrg   glEnable(GL_LIGHTING);
4932001f49Smrg   glEnable(GL_LIGHT0);
5032001f49Smrg   glEnable(GL_DEPTH_TEST);
5132001f49Smrg   glFrontFace(GL_CW);
5232001f49Smrg   glPushMatrix();
5332001f49Smrg   glRotatef(45, 1, 0, 0);
5432001f49Smrg   glutSolidTeapot(2.0);
5532001f49Smrg   glPopMatrix();
5632001f49Smrg   glFrontFace(GL_CCW);
5732001f49Smrg   glDisable(GL_DEPTH_TEST);
5832001f49Smrg   glDisable(GL_LIGHTING);
5932001f49Smrg
6032001f49Smrg   glDisable(GL_SCISSOR_TEST);
6132001f49Smrg
6232001f49Smrg   glViewport(0, 0, WinWidth, WinHeight);
6332001f49Smrg   glFinish();
6432001f49Smrg}
6532001f49Smrg
6632001f49Smrg
6732001f49Smrgstatic int
6832001f49SmrgRand(int max)
6932001f49Smrg{
7032001f49Smrg   return ((int) rand()) % max;
7132001f49Smrg}
7232001f49Smrg
7332001f49Smrg
7432001f49Smrgstatic void
7532001f49SmrgBlitOne(void)
7632001f49Smrg{
7732001f49Smrg   int x, y;
7832001f49Smrg
7932001f49Smrg   do {
8032001f49Smrg      x = Rand(WinWidth);
8132001f49Smrg      y = Rand(WinHeight);
8232001f49Smrg   } while (x <= ImgWidth && y <= ImgHeight);
8332001f49Smrg
8432001f49Smrg#ifdef GL_EXT_framebuffer_blit
8532001f49Smrg   if (UseBlit)
8632001f49Smrg   {
8732001f49Smrg      glBlitFramebufferEXT(0, 0, ImgWidth, ImgHeight,
8832001f49Smrg                           x, y, x + ImgWidth, y + ImgHeight,
8932001f49Smrg                           GL_COLOR_BUFFER_BIT, GL_LINEAR);
9032001f49Smrg   }
9132001f49Smrg   else
9232001f49Smrg#endif
9332001f49Smrg   {
9432001f49Smrg      glWindowPos2iARB(x, y);
9532001f49Smrg      glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
9632001f49Smrg   }
9732001f49Smrg}
9832001f49Smrg
9932001f49Smrg
10032001f49Smrg/**
10132001f49Smrg * Measure glCopyPixels rate
10232001f49Smrg */
10332001f49Smrgstatic void
10432001f49SmrgRunTest(void)
10532001f49Smrg{
10632001f49Smrg   double t1, t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
10732001f49Smrg   int iters = 0;
10832001f49Smrg   float copyRate, mbRate;
10932001f49Smrg   int r, g, b, a, bpp;
11032001f49Smrg
11132001f49Smrg   if (AlphaTest) {
11232001f49Smrg      glEnable(GL_ALPHA_TEST);
11332001f49Smrg      glAlphaFunc(GL_GREATER, 0.0);
11432001f49Smrg   }
11532001f49Smrg
11632001f49Smrg   glGetIntegerv(GL_RED_BITS, &r);
11732001f49Smrg   glGetIntegerv(GL_GREEN_BITS, &g);
11832001f49Smrg   glGetIntegerv(GL_BLUE_BITS, &b);
11932001f49Smrg   glGetIntegerv(GL_ALPHA_BITS, &a);
12032001f49Smrg   bpp = (r + g + b + a) / 8;
12132001f49Smrg
12232001f49Smrg   do {
12332001f49Smrg      BlitOne();
12432001f49Smrg
12532001f49Smrg      if (Buffer == GL_FRONT)
12632001f49Smrg         glFinish(); /* XXX to view progress */
12732001f49Smrg
12832001f49Smrg      iters++;
12932001f49Smrg
13032001f49Smrg      t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
13132001f49Smrg   } while (t1 - t0 < 5.0);
13232001f49Smrg
13332001f49Smrg   glDisable(GL_ALPHA_TEST);
13432001f49Smrg
13532001f49Smrg   copyRate = iters / (t1 - t0);
13632001f49Smrg   mbRate = ImgWidth * ImgHeight * bpp * copyRate / (1024 * 1024);
13732001f49Smrg
13832001f49Smrg   printf("Image size: %d x %d, %d Bpp\n", ImgWidth, ImgHeight, bpp);
13932001f49Smrg   printf("%d copies in %.2f = %.2f copies/sec, %.2f MB/s\n",
14032001f49Smrg          iters, t1-t0, copyRate, mbRate);
14132001f49Smrg}
14232001f49Smrg
14332001f49Smrg
14432001f49Smrgstatic void
14532001f49SmrgDraw(void)
14632001f49Smrg{
14732001f49Smrg   glClearColor(0.0, 0.0, 0.0, 0.0);
14832001f49Smrg   glClearColor(0.2, 0.2, 0.8, 0);
14932001f49Smrg   glReadBuffer(Buffer);
15032001f49Smrg   glDrawBuffer(Buffer);
15132001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
15232001f49Smrg
15332001f49Smrg   DrawTestImage();
15432001f49Smrg
15532001f49Smrg   RunTest();
15632001f49Smrg
15732001f49Smrg   if (Buffer == GL_FRONT)
15832001f49Smrg      glFinish();
15932001f49Smrg   else
16032001f49Smrg      glutSwapBuffers();
16132001f49Smrg
16232001f49Smrg#if 1
16332001f49Smrg   printf("exiting\n");
16432001f49Smrg   exit(0);
16532001f49Smrg#endif
16632001f49Smrg}
16732001f49Smrg
16832001f49Smrg
16932001f49Smrgstatic void
17032001f49SmrgReshape(int width, int height)
17132001f49Smrg{
17232001f49Smrg   glViewport(0, 0, width, height);
17332001f49Smrg   glMatrixMode(GL_PROJECTION);
17432001f49Smrg   glLoadIdentity();
17532001f49Smrg   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
17632001f49Smrg   glMatrixMode(GL_MODELVIEW);
17732001f49Smrg   glLoadIdentity();
17832001f49Smrg   glTranslatef(0.0, 0.0, -15.0);
17932001f49Smrg}
18032001f49Smrg
18132001f49Smrg
18232001f49Smrgstatic void
18332001f49SmrgKey(unsigned char key, int x, int y)
18432001f49Smrg{
18532001f49Smrg   (void) x;
18632001f49Smrg   (void) y;
18732001f49Smrg   switch (key) {
18832001f49Smrg   case 'b':
18932001f49Smrg      BlitOne();
19032001f49Smrg      break;
19132001f49Smrg   case 27:
19232001f49Smrg      exit(0);
19332001f49Smrg      break;
19432001f49Smrg   }
19532001f49Smrg   glutPostRedisplay();
19632001f49Smrg}
19732001f49Smrg
19832001f49Smrg
19932001f49Smrgstatic void
20032001f49SmrgSpecialKey(int key, int x, int y)
20132001f49Smrg{
20232001f49Smrg   (void) x;
20332001f49Smrg   (void) y;
20432001f49Smrg   switch (key) {
20532001f49Smrg      case GLUT_KEY_UP:
20632001f49Smrg         break;
20732001f49Smrg      case GLUT_KEY_DOWN:
20832001f49Smrg         break;
20932001f49Smrg      case GLUT_KEY_LEFT:
21032001f49Smrg         break;
21132001f49Smrg      case GLUT_KEY_RIGHT:
21232001f49Smrg         break;
21332001f49Smrg   }
21432001f49Smrg   glutPostRedisplay();
21532001f49Smrg}
21632001f49Smrg
21732001f49Smrg
21832001f49Smrgstatic void
21932001f49SmrgParseArgs(int argc, char *argv[])
22032001f49Smrg{
22132001f49Smrg   int i;
22232001f49Smrg   for (i = 1; i < argc; i++) {
22332001f49Smrg      if (strcmp(argv[i], "-back") == 0)
22432001f49Smrg         Buffer = GL_BACK;
22532001f49Smrg      else if (strcmp(argv[i], "-alpha") == 0)
22632001f49Smrg         AlphaTest = GL_TRUE;
22732001f49Smrg      else if (strcmp(argv[i], "-blit") == 0)
22832001f49Smrg         UseBlit = GL_TRUE;
22932001f49Smrg   }
23032001f49Smrg}
23132001f49Smrg
23232001f49Smrg
23332001f49Smrgstatic void
23432001f49SmrgInit(void)
23532001f49Smrg{
23632001f49Smrg   if (glutExtensionSupported("GL_EXT_framebuffer_blit")) {
23732001f49Smrg   }
23832001f49Smrg   else if (UseBlit) {
23932001f49Smrg      printf("Warning: GL_EXT_framebuffer_blit not supported.\n");
24032001f49Smrg      UseBlit = GL_FALSE;
24132001f49Smrg   }
24232001f49Smrg}
24332001f49Smrg
24432001f49Smrg
24532001f49Smrgint
24632001f49Smrgmain(int argc, char *argv[])
24732001f49Smrg{
24832001f49Smrg   GLint mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH;
24932001f49Smrg   glutInit(&argc, argv);
25032001f49Smrg
25132001f49Smrg   ParseArgs(argc, argv);
25232001f49Smrg   if (AlphaTest)
25332001f49Smrg      mode |= GLUT_ALPHA;
25432001f49Smrg
25532001f49Smrg   glutInitWindowPosition(0, 0);
25632001f49Smrg   glutInitWindowSize(WinWidth, WinHeight);
25732001f49Smrg   glutInitDisplayMode(mode);
25832001f49Smrg   glutCreateWindow(argv[0]);
25932001f49Smrg   glewInit();
26032001f49Smrg   glutReshapeFunc(Reshape);
26132001f49Smrg   glutKeyboardFunc(Key);
26232001f49Smrg   glutSpecialFunc(SpecialKey);
26332001f49Smrg   glutDisplayFunc(Draw);
26432001f49Smrg
26532001f49Smrg   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
26632001f49Smrg   printf("Draw Buffer: %s\n", (Buffer == GL_BACK) ? "Back" : "Front");
26732001f49Smrg   Init();
26832001f49Smrg
26932001f49Smrg   printf("Mode: %s\n", (UseBlit ? "glBlitFramebuffer" : "glCopyPixels"));
27032001f49Smrg   printf("Alpha Test: %s\n", (AlphaTest ? "yes" : "no"));
27132001f49Smrg
27232001f49Smrg   glutMainLoop();
27332001f49Smrg   return 0;
27432001f49Smrg}
275