Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: How vsync work ? Why i not have a multiple of 16.6 ms between each eglSwapBuffers?

  1. #1
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12

    How vsync work ? Why i not have a multiple of 16.6 ms between each eglSwapBuffers?

    I do not understand, I took the source code of delphi to see how it is performed with OpenGL (under android). so on every paint delphi do :

    eglSwapBuffers(TCustomAndroidContext.SharedDisplay , TCustomAndroidContext.SharedSurface)
    so this make OpenGL swapping the back buffer with the display buffer (if i understand well), waiting for the vsync signal first (is this really true?). So as the vsync signal is fired every 16.6 ms I must have between every eglSwapBuffers a multiple of 16.6 (ex 16.6 or 33.2 or 49.8, etc).

    To measure it I do like this :

    I replace

    procedure ContextFlip;
    begin
    if eglSwapBuffers(TCustomAndroidContext.SharedDisplay , TCustomAndroidContext.SharedSurface) = 0 then
    glGetError;
    end;
    with

    var vSyncStopWatch: TstopWatch;

    procedure ContextFlip;
    begin
    if eglSwapBuffers(TCustomAndroidContext.SharedDisplay , TCustomAndroidContext.SharedSurface) = 0 then
    glGetError;

    vSyncStopWatch.Stop;
    if vSyncStopWatch.Elapsed.TotalMilliseconds > 16.6 then allog('VSYNC deadline missed', floattostr(vSyncStopWatch.Elapsed.TotalMillisecond s), tallogType.WARN);
    vSyncStopWatch := TstopWatch.StartNew;

    end;
    but what I don't understand, is why I have value like 18ms, 22ms, 24ms, 28ms, 27ms, etc.. instead of only 16.6 or 33.2 or 49.8, etc ? how is it possible ? does eglSwapBuffers really wait for the vsync signal ?

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    Code delphi:
    var vSyncStopWatch: TstopWatch;
    ...
    eglSwapBuffers(...)
    ...
    vSyncStopWatch.Stop;
    if vSyncStopWatch.Elapsed.TotalMilliseconds > 16.6 then allog('VSYNC deadline missed', ... );
    vSyncStopWatch := TstopWatch.StartNew;

    ...what I don't understand, is why I have value like 18ms, 22ms, 24ms, 28ms, 27ms, etc.. instead of only 16.6 or 33.2 or 49.8, etc ? how is it possible ?
    There are several possibilities. But I'd first make sure your rendering load isn't triggering frame overruns (i.e. your rendered frame rate < refresh rate). Try eliminating all of your draw work except the glClear() and eglSwapBuffers() and see what your CPU frame times are then.

    Check this out:
    * Android Performance Patterns

    search down for "Rendering Performance 101", and start playing the videos there. Keep going at least through the one ones on VSync and Profiling GPU Performance. And check out the "Profile GPU Performance: M Update" video.

    Keep in mind CPU != GPU. You're timing on the CPU, but the commands you're submitting on the CPU are executing later on the GPU. Also keep in mind that mobile GPUs have deep pipelines -- often multiple VSync intervals deep. When you call eglSwapBuffers(), there's a good chance the GPU hasn't even rendered a single pixel for that frame you just submitted (by design!). Finally, keep in mind that you're not rendering directly to the display. You're rendering to an off-screen buffer and submitting your results to a compositor, which then later composites your rendered layer with other layers and displays it on-screen. So your CPU draw thread isn't near as close to the VSync processing as you might otherwise think.


    does eglSwapBuffers really wait for the vsync signal ?
    In your CPU draw thread when it calls eglSwapBuffers(), no, not necessarily.

    In the GPU/driver when it actually gets around to processing your eglSwapBuffers() call, yes (...if there's no free buffer available).

    That said, if your rendered frame rate is faster than your refresh rate, the whole pipeline fills up and often times you end up with your CPU draw thread synchronized to the VSync rate. Alternatively, if your rendered frame rate is slower than the refresh rate, then you'll see all sorts of frame times measured on the CPU.
    Last edited by Dark Photon; 09-02-2017 at 07:10 PM.

  3. #3
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12
    thanks Photon!

    Quote Originally Posted by Dark Photon View Post
    There are several possibilities. But I'd first make sure your rendering load isn't triggering frame overruns (i.e. your rendered frame rate < refresh rate). Try eliminating all of your draw work except the glClear() and eglSwapBuffers() and see what your CPU frame times are then.
    i try eliminating everything except glclear, now yes i have number more close to 16 but still i can see number like 15ms, 18ms or 20ms ... this i don't understand how i can have for exemple 15 ms

    Quote Originally Posted by Dark Photon View Post
    search down for "Rendering Performance 101", and start playing the videos there. Keep going at least through the one ones on VSync and Profiling GPU Performance. And check out the "Profile GPU Performance: M Update" video.
    .
    yes i try to enable the android Profile GPU Performance tool, but unfortunatly, my app is not made with android studio, so this tool is not working


    Quote Originally Posted by Dark Photon View Post
    In your CPU draw thread when it calls eglSwapBuffers(), no, not necessarily.

    In the GPU/driver when it actually gets around to processing your eglSwapBuffers() call, yes (...if there's no free buffer available).
    hmm, so how can i efficiently detect a frame drop ?

  4. #4
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12

    Is opengl vsync fixed or it's can fluctuate?

    In OpenGl (under android if it's matter) does vsync signal absolutely fixed at every 16.6 ms interval and can not fluctuate or could it be a little "moveable" in some circumstance ?

    I mean it's must it be absolutely like this:

    16.6ms --- 16.6ms --- 16.6ms --- etc
    or could it be like this?:

    16.6ms -- 18ms --- 16.6ms --- 15ms --- etc ...
    I ask this because between each eglswapBuffers I have strange value like 12ms, 15ms, 18ms, 22ms, etc... and I don't understand why.
    Last edited by loki5100; 09-03-2017 at 12:58 PM.

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    Quote Originally Posted by loki5100 View Post
    i try eliminating everything except glclear, now yes i have number more close to 16 but still i can see number like 15ms, 18ms or 20ms ... this i don't understand how i can have for exemple 15 ms
    I think you're just going to have to dig in and figure out how to profile rendering performance on Android.

    Here's a tree of Android Graphics documents that looks worth a read:

    * Android Graphics

    It could very well be that your app is just not getting full use of the CPU and GPU for some reason, and/or your timing method is insufficient.

    Note that when you start rendering, the buffer chain is empty (meaning there are 2-3 free buffers), so when you call swap your app may very well return quickly or even near immediately, yielding CPU draw thread frame times < the VSync time. The same scenario will likely occur if your app pauses rendering for some reason and then restarts rendering again (on mobile, most apps aren't just blasting frames to the display non-stop; particularly if nothing changed; that's just a waste of CPU/GPU/power/battery).

    yes i try to enable the android Profile GPU Performance tool, but unfortunatly, my app is not made with android studio, so this tool is not working
    I'm no Android guru, but I don't think that's a prerequisite. It's built into Android, and as far as I recall worked with all apps that I tested. See this for details:

    * Profile GPU Rendering Walkthrough

    So if you haven't already, just give it a shot! It's under Settings -> Developer Options.

    hmm, so how can i efficiently detect a frame drop ?
    I'd recommend doing some more reading on how to do this properly on Android.

    Here's one search link I hit that looks promising. I'm sure there are many more:

    * Testing UI Performance

  6. #6
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12
    Quote Originally Posted by Dark Photon View Post
    It could very well be that your app is just not getting full use of the CPU and GPU for some reason, and/or your timing method is insufficient.
    yes but how to find it

    Quote Originally Posted by Dark Photon View Post
    Note that when you start rendering, the buffer chain is empty (meaning there are 2-3 free buffers), so when you call swap your app may very well return quickly or even near immediately, yielding CPU draw thread frame times < the VSync time. The same scenario will likely occur if your app pauses rendering for some reason and then restarts rendering again (on mobile, most apps aren't just blasting frames to the display non-stop; particularly if nothing changed; that's just a waste of CPU/GPU/power/battery).
    yes, so it's mean that eglswapbuffers can return immediatly if buffer chain is empty ? anyway this not explain the exotic number (14 - 18 - 19 - 22 - etc..) i have between each eglswapbuffers :' only maybe like you say, app is just not getting full use of the CPU and GPU for some reason but how to get it out ...

    Quote Originally Posted by Dark Photon View Post
    I'm no Android guru, but I don't think that's a prerequisite. It's built into Android, and as far as I recall worked with all apps that I tested. See this for details:

    * Profile GPU Rendering Walkthrough

    So if you haven't already, just give it a shot! It's under Settings -> Developer Options.
    i already try, on android 6.0, 5, etc, on several phone, didn't work on other app yes it's work!

  7. #7
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12
    Personally i start to think that the vsync is not really "fixed", it's around 16.6 ms but could be sometime less or higher. i have some anim that are not fluid like 60fps but that also are not slow like 30 fps so i can't explain it in different way

  8. #8
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    Quote Originally Posted by loki5100 View Post
    Personally i start to think that the vsync is not really "fixed", it's around 16.6 ms but could be sometime less or higher. i have some anim that are not fluid like 60fps but that also are not slow like 30 fps so i can't explain it in different way
    That seems pretty unlikely. For instance, here's what Android requires of folks implementing an Android graphics stack (the system layers on which your application is built):

    https://source.android.com/devices/g...mplement-vsync

    Implementing VSYNC

    To implement the Android graphics HAL ... You must implement VSYNC with a maximum 1 ms lag (0.5 ms or less is recommended); timestamps returned must be extremely accurate."
    So no, that doesn't explain your results.

    It's more likely that there is a performance problem with your app or a problem (possibly a mistaken assumption) with the way your app is using the system. Like I said, under Android, your app's draw thread isn't really tied that closely to VSync.

  9. #9
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    12
    thanks photon, but i not understand, what the purpose of a function waitForVsync if in some way eglSwapBuffers already look like to wait it. what is very strange is to not have multiple of 16.6 ms between eglSwapBuffers and this why i start to think that vsync is not really fixed

  10. #10
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,124
    Quote Originally Posted by loki5100 View Post
    what is very strange is to not have multiple of 16.6 ms between eglSwapBuffers and this why i start to think that vsync is not really fixed
    Good luck with your research in trying to nail this down. You've reached the limit of my knowledge.

    In a few websearches, I did see references in the android source code to where it is setting up for primary, external, and virtual displays. In one example driver it indicated that VSync was driven by the hardware for the primary display but emulated for external and virtual displays (link -- see "fake_vsync" refs at the bottom; also mentioned in the following presentation on slide 25). Also here's a potentially useful presentation on the Android graphics pipeline (link -- search for vsync references; slide 26 enumerates those display types I mentioned). And on another Android link, I saw a mention that apps always start drawing at a VSync event. So you might try changing your timing from end-of-frame -to- end-of-frame (after Swap) to beginning-of-frame -to- beginning-of-frame. However, it's unclear whether they were talking about app drawing in terms of CPU draw thread queueing up commands or drawing in terms of actual rasterization (fragment work), so they may be referring to a point deeper down in the pipeline.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •