Mojo Render Lagging

About Monkey 2 Forums Monkey 2 Programming Help Mojo Render Lagging

This topic contains 21 replies, has 9 voices, and was last updated by  peterigz 1 year, 11 months ago.

Viewing 15 posts - 1 through 15 (of 22 total)
  • Author
    Posts
  • #5869

    arpie
    Participant

    I’m not sure if this is a bug or if I’m misusing RequestRender() or if this is just an unavoidable feature of how mojo and SDL do their thing.

    The code below shows the problem.  Move your mouse over the window and the crosshair lags behind the pointer.  Is it possible to make the crosshair stick to the pointer and move with it?

    #5872

    codifies
    Participant

    I’ve seen that happen with C and just SDL, sadly I can’t off hand remember fixing it either…

    #5873

    AdamStrange
    Participant

    confirmed

    #5875

    Jesse
    Participant

    That happens because of the rate at which the mouse is updating the values. the lag will change depending on the frame rate. The higher the frame rate the smaller the lag. I believe it has to do with not synchronizing to the operating system frame rate. That is common in most if not all computer languages as well. I had that problem in BMax, C and MonkeyX as well as Windows and Mac before. Best thing is to hide the mouse and just display the crosshair.

    Edit
    That lag is almost unavoidable as you can see in programs like Gimp and Paint. they both suffer from the same problem.

    #5876

    peterigz
    Participant

    It’s mainly because of vsync as Jesse says, so the mouse will only be polled at 60hz (or whatever your monitor is). You can disable vsync by adding SwapInterval = 0 in the window constructor which will improve things. I prefer doing this and then using some kind of timing code to separate the rendering and logic to make the game as responsive as possible. Drawback though is the potential for screen tearing as you’re not waiting for a vsync anymore.

    #5881

    arpie
    Participant

    Thank you all for the explanations.  SwapInterval=0 does remove the lag completely… and reports a framerate of 2400 FPS here.  I had no idea that was even possible!

    However, I played with @peterigz suggestion of ‘using some kind of timing code’ and found a curious thing.  The following code still has a slight lag but it is much less noticeable and runs much more smoothly.  Can anybody else confirm the same result?  Can anybody explain why?  The only difference is that RequestRender() is being called from a Timer(), rather than in OnRender().  As far as I understand, that means it is still waiting for a vsync.

    #5882

    arpie
    Participant

    There is definitely something funny going on here.  If I turn the framerate down to 2fps, the problem is obvious.

    Reducing the framerate by setting SwapInterval = 30 and calling RequestRender() in OnRender(), the lag is massive.  Whenever I move the mouse, there is a delay of about 2 seconds before the crosshair moves.  Surely this is a bug?

    If I use a Timer() to call RequestRender, at a rate of 2 per second, the delay before the crosshair moves is about half a second (as I would expect, given the framerate).

    Can anybody confirm they are getting the same results?  It may be an issue with just my OS, I guess.  I’m running Gnome Desktop on Linux.  I don’t have a Windows machine I can test this on, so relying on you guys!

    This first code uses SwapInterval = 30 and has a 2 second lag when I move the mouse :

    This next code uses a Timer() function and shows no unexpected lag :

    #5886

    therevills
    Participant

    What OS are you testing on?

     

    This sounds very similar to the issues we were testing on BlitzMax a few years ago:

    http://www.blitzmax.com/Community/posts.php?topic=94676

    #5887

    arpie
    Participant

    I’m on Arch Linux running Gnome3.  That does look like a similar issue… did you find a fix?

    #5889

    peterigz
    Participant

    SwapInterval means:

    0 = No Vsync wait at all
    1 = 1 Render call per vsync
    2 = 1 render call every 2 vsyncs

    .. and so on. So the higher your swap interval the slower it will render. This is an issue with all games as far as I know. You’ll find that not many FPS players play with vsync on because they want to increase FPS and therefore mouse responsiveness. QuakeLive for example generally caps at 125FPS. But they might also have a way to poll the input at a higher frequency?

    I wonder if you can improve the feel of it by using the mouse speed combined with mouse position to have some kind of predictive movement? Just a theory 🙂

    #5890

    arpie
    Participant

    @peterigz I think I have already understood what SwapInterval means.  In my above post (#5882), I set SwapInterval = 30 and I get 1 OnRender call every 30 vsyncs.  Here, that runs at 2 frames per second (according to the App.FPS variable).  When I move my mouse over the window, there is a 2 second delay before the crosshair moves.  That is 4 times slower than it should be.  Isn’t it?

    I think this is a Monkey2/Mojo bug but would like somebody else to confirm they are seeing the same results and that I am not doing something silly.  Please try running the code I posted above and tell me if you see the same as I do.

    At full speed (60fps), using a Timer() function to call RequestRender actually gives acceptable results here.  There is an expected slight lag but it is not too bad.  Calling RequestRender() in OnRender() is much slower.

    #5891

    Mark Sibly
    Keymaster

    > If I turn the framerate down to 2fps, the problem is obvious.

    With swapinterval=30, I get 2 FPS on emscripten (and mouse lag of about .5 sec) which is correct, but 15 for desktop, which is wrong although mouse lag still looks correct for 15FPS.

    But the SDL docs for SetSwapInterval only mention possible param values of 0, 1 or -1 (-1 is quite interesting…):

    https://wiki.libsdl.org/SDL_GL_SetSwapInterval

    Also, the egl docs mention implementation min/max values:

    https://www.khronos.org/registry/egl/sdk/docs/man/html/eglSwapInterval.xhtml

    So it’s very likely my driver only supports 0,1 or 2 for swapinterval. Yours does seem to be crazily off though if swapinterval 30=2 second lag, but on the other hand if swap interval is outside of supported driver range anything weird could happen.

    I would not depend on SetSwapInterval supporting anything beyond 0 or 1. Even then, graphics drivers can override vsync behavior so it may not work at all.

    #5892

    peterigz
    Participant

    It looks like SwapInterval caps at 4 for me, so the lowest FPS I get is 15fps (on windows 10), so it’s hard to tell if it’s slower than it should be. The timer method seems to work well though, with SwapInterval 0.

    #5898

    Jesse
    Participant

    Apparently on my Macbook SwapInterval for anything other than 0, it does the same thing. I get 60 FPS regardless of what I set it to: -1,1,2,15,30.

    Edit: that’s on desktop.

    #5900

    arpie
    Participant

    So it looks like I didn’t fully understand SwapInterval after all.  Thank you, Mark for linking to the relevant docs.

    And thank you to all of you for taking the time to look at this.

    I am still convinced something odd is going on.  Back at 60fps with SwapInterval = 1, I still get less visible lag if I call Timer(60, RequestRender) instead of calling RequestRender() from OnRender()… but I’ve looked through the mojo source and afaict there is absolutely no reason why it would make any difference!

    I think for now I am just going to hide the pointer and move on to coding something more interesting.  How exactly do I go about hiding the pointer I wonder…?

Viewing 15 posts - 1 through 15 (of 22 total)

You must be logged in to reply to this topic.