4

I am trying to write an application to display video in fullscreen that needs to be as smooth as possible.

My OpenGL code is synchronised to the vertical refresh sync and most of the time the playback is smooth with low cpu usage.

However, sometimes, there is a slight stutter.

To simplify the test and eliminate potential sources of delays I wrote a simple rendering loop that just creates a fullscreen, clears the frame and swaps the buffers.

I timed the buffer swap time ( with mach_absolute_time() ) and printed the times outside the range between 15 and 18 milliseconds.

An example run is shown bellow ( report time is in seconds and frame times are in milliseconds ):

at time:0.903594 ->  frame time:06.943 ms
at time:1.941287 ->  frame time:20.801 ms
at time:1.956124 ->  frame time:14.725 ms
at time:1.969766 ->  frame time:13.533 ms
at time:4.059608 ->  frame time:23.808 ms
at time:4.068953 ->  frame time:09.255 ms
at time:6.090000 ->  frame time:55.086 ms
at time:6.090681 ->  frame time:00.210 ms
at time:6.101372 ->  frame time:10.659 ms
at time:9.684669 ->  frame time:18.014 ms
at time:15.032867 -> frame time:18.463 ms
at time:15.047580 -> frame time:14.618 ms
at time:17.028749 -> frame time:65.096 ms
at time:17.028962 -> frame time:00.108 ms
at time:17.037022 -> frame time:08.034 ms
at time:17.049193 -> frame time:12.069 ms
at time:17.063416 -> frame time:14.130 ms

No other applications were running appart from XCode at the time of the tests. The tests were run on a Macbook Pro 5,1 running OS X 10.7.5.

Switching graphics ( this laptop has the Nvidia 9600 and 9400 ), running from an external monitor or the laptop screen made no difference.

To rule out differences between underlying API's I tried the same code using graphics frameworks such as SDL, Glfw, Cinder and SFML. Finally I also tried timing the official Apple OpenGL fullscreen example. All of them behave more or less the same, though Glfw seems to be a little bit more stable.

Increasing the drawing thread priority to the maximum with SCHED_FIFO policy seems to improve things a little bit, but not by much.

I am starting to think that it is not possible to get a solid 60hz frame rate from OpenGL or if it is then it is not documented properly.

Has anyone been able to get a solid 60hz display rate for a fullscreen OpenGL application in OS X? How?

EDIT: I have noticed that running the tests from the terminal improves the timings imensely. Running from XCode generates more fluctuations and I was using those numbers to draw my conclusions. In any case I still seem to get more stable behaviour under Windows 7 on the same machine. But the current fluctuations are within tolerated requirements.

Eurico
  • 69
  • 3
  • 1
    "*My OpenGL code is synchronised to the vertical refresh sync*" How did you achieve this? – Nicol Bolas Oct 30 '12 at 17:26
  • what resolution and what card is active? – Grimmy Nov 02 '12 at 08:39
  • Hi, as I wrote above I have tried running the code in both the 9400 and the 9600 graphics cards, this MBP model lets you select the gpu you want to use to strike a balance between performance and energy efficiency. Both cards behave the same. I have tried the laptop's native resolution ( 1440 x 900 ) and the exernal monitor native resolution ( 1920 x 1200 ). Resolution is not an issue, since when I turn off the vsync the fps counter reaches numbers above 1000 fps. – Eurico Nov 11 '12 at 23:25
  • By synchronised I mean that the main thread blocks on the buffer swaps waiting for the vertical sync. – Eurico Nov 12 '12 at 08:26

1 Answers1

0
  1. What happens to this test if the viewport is a small window rather than the entire screen? If the behavior is the same with a 100x100 window, then you can assume that it's not a GPU performance issue.

  2. are you calling GLFinish()? If you're not, the graphics driver is free to output the results to the screen pretty much whenever it feels like it. The result could be the performance spikes you observe.

  3. What is the resolution of the timer you are using? I ran into a similar issue attempting to benchmark my own code in windows - the standard windows timer's resolution is awful (~ 19ms), so I had to switch to a higher resolution timer.

Michael Slade
  • 13,802
  • 2
  • 39
  • 44
  • 1. Running this test on a window increases the variance in timing by a lot. Full screen runs much smoother. 2. Yes. 3. mach_absolute_time() is to my knowledge the highest resolution and most accurate timer in OSX ( and iOS ). – Eurico Nov 11 '12 at 23:27