1c041511dScube 2c041511dScube/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ 3c041511dScube 4c041511dScube/* This program is freely distributable without licensing fees 5c041511dScube and is provided without guarantee or warrantee expressed or 6c041511dScube implied. This program is -not- in the public domain. */ 7c041511dScube 8c041511dScube#include <stdio.h> 9c041511dScube#include "glutint.h" 10c041511dScube 11c041511dScubeGLint __glutFPS = 0; 12c041511dScubeGLint __glutSwapCount = 0; 13c041511dScubeGLint __glutSwapTime = 0; 14c041511dScube 15c041511dScube/* CENTRY */ 16c041511dScubevoid GLUTAPIENTRY 17c041511dScubeglutSwapBuffers(void) 18c041511dScube{ 19c041511dScube GLUTwindow *window = __glutCurrentWindow; 20c041511dScube 21b3dfa806Smrg if (__glutPPMFile) { 22b3dfa806Smrg __glutWritePPMFile(); 23b3dfa806Smrg } 24b3dfa806Smrg 25c041511dScube if (window->renderWin == window->win) { 26c041511dScube if (__glutCurrentWindow->treatAsSingle) { 27c041511dScube /* Pretend the double buffered window is single buffered, 28c041511dScube so treat glutSwapBuffers as a no-op. */ 29c041511dScube return; 30c041511dScube } 31c041511dScube } else { 32c041511dScube if (__glutCurrentWindow->overlay->treatAsSingle) { 33c041511dScube /* Pretend the double buffered overlay is single 34c041511dScube buffered, so treat glutSwapBuffers as a no-op. */ 35c041511dScube return; 36c041511dScube } 37c041511dScube } 38c041511dScube 39c041511dScube /* For the MESA_SWAP_HACK. */ 40c041511dScube window->usedSwapBuffers = 1; 41c041511dScube 42c041511dScube SWAP_BUFFERS_LAYER(__glutCurrentWindow); 43c041511dScube 44c041511dScube /* I considered putting the window being swapped on the 45c041511dScube GLUT_FINISH_WORK work list because you could call 46c041511dScube glutSwapBuffers from an idle callback which doesn't call 47c041511dScube __glutSetWindow which normally adds indirect rendering 48c041511dScube windows to the GLUT_FINISH_WORK work list. Not being put 49c041511dScube on the list could lead to the buffering up of multiple 50c041511dScube redisplays and buffer swaps and hamper interactivity. I 51c041511dScube consider this an application bug due to not using 52c041511dScube glutPostRedisplay to trigger redraws. If 53c041511dScube glutPostRedisplay were used, __glutSetWindow would be 54c041511dScube called and a glFinish to throttle buffering would occur. */ 55c041511dScube 56c041511dScube if (__glutFPS) { 57c041511dScube GLint t = glutGet(GLUT_ELAPSED_TIME); 58c041511dScube __glutSwapCount++; 59c041511dScube if (__glutSwapTime == 0) 60c041511dScube __glutSwapTime = t; 61c041511dScube else if (t - __glutSwapTime > __glutFPS) { 62c041511dScube float time = 0.001 * (t - __glutSwapTime); 63c041511dScube float fps = (float) __glutSwapCount / time; 64c041511dScube fprintf(stderr, "GLUT: %d frames in %.2f seconds = %.2f FPS\n", 65c041511dScube __glutSwapCount, time, fps); 66c041511dScube __glutSwapTime = t; 67c041511dScube __glutSwapCount = 0; 68c041511dScube } 69c041511dScube } 70c041511dScube} 71c041511dScube/* ENDCENTRY */ 72