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