SFML community forums

Help => Window => Topic started by: Brendon on March 16, 2011, 08:48:48 am

Title: Mouse movement causing framerate drop
Post by: Brendon on March 16, 2011, 08:48:48 am
I'm wondering if anyone else has seen this before: a lot of my users are reporting that when they move the mouse around, the game framerate drops to what seems like 1 fps.  If the user doesn't move the mouse, the framerate returns to the expected ~60.

The problem is that this is very inconsistent across machines, making it difficult to debug. I never get it on my dev machine, some others always have it, and for others the problem goes away after restarting the computer.

The input code is very straightforward:
Code: [Select]
public void Update(float elapsedTime)
{
      this.App.DispatchEvents();

      this.mouseX = this.App.Input.GetMouseX();
      this.mouseY = this.App.Input.GetMouseY();
}


I'm using the sfml dotnet 1.6 build.

Anyone have any thoughts on why this is happening?
Title: Mouse movement causing framerate drop
Post by: Laurent on March 16, 2011, 08:50:20 am
I have absolutely no idea, sorry. This is really weird.

Is this happening on Windows only? Have you been able to test it on other platforms?
Title: Mouse movement causing framerate drop
Post by: devlin on March 16, 2011, 08:54:28 am
What does your mainloop look like?

It could be that their computers are "drowning" in events from the mouse movement and thus it's just looping through those events instead of updating your game.
Title: Mouse movement causing framerate drop
Post by: Groogy on March 16, 2011, 09:15:58 am
I'm wondering, wouldn't a high-dps mouse generate more mouse movement events than what a low-dps mouse would generate?

Just thinking on that it varied from different computers.
Title: Mouse movement causing framerate drop
Post by: Brendon on March 16, 2011, 09:49:43 am
@Laurent - my game (http://blendogames.com/atomzombiesmasher) is available on pc, mac, & linux; I've only heard the issue reported on the pc.

@devlin - Can you explain a bit on how one would do that?  I figured DispatchEvents() is what updates all the events, and I'm only calling that once per frame.

@Groogy - that's an interesting idea - I'll ask my users if they have special mice.

I also found these other thread regarding mouse movement & framerate drop, but the issue seemed to have been fixed in his case-
http://www.sfml-dev.org/forum/viewtopic.php?t=2394
Title: Mouse movement causing framerate drop
Post by: devlin on March 16, 2011, 03:35:08 pm
Well - I haven't looked at the DotNet bindings for SFML - but I do know that Application.DoEvents() will suspend the current thread while processing all waiting window messages.
Unless of course the DotNet bindings use PInvoke of the Peek/Translate/DispatchMessage instead of DoEvents to limit the amount of messages processed any one frame.

I bet Groogy is onto something - high dpi mice generate an awful lot of WM_INPUT messages, if any substantial work is done on those messages - it will slow things down.
Title: Mouse movement causing framerate drop
Post by: Laurent on March 16, 2011, 03:44:56 pm
Quote
Well - I haven't looked at the DotNet bindings for SFML - but I do know that Application.DoEvents() will suspend the current thread while processing all waiting window messages.
Unless of course the DotNet bindings use PInvoke of the Peek/Translate/DispatchMessage instead of DoEvents to limit the amount of messages processed any one frame.

SFML.Net's DispatchEvents function calls the GetEvent function imported from SFML, which internally uses Peek/Translate/DispatchMessage. But there's no limit, it processes all messages.

Quote
I bet Groogy is onto something - high dpi mice generate an awful lot of WM_INPUT messages, if any substantial work is done on those messages - it will slow things down.

WM_INPUT is not caught by SFML, so if something happens there it's internal to Windows.
Title: Mouse movement causing framerate drop
Post by: Brendon on March 17, 2011, 02:17:18 am
Some of my users are using high-dps mice - if I were to make a test executable for these people, is there some way I can somehow limit the amount of events received per frame?
Title: Mouse movement causing framerate drop
Post by: Laurent on March 17, 2011, 07:40:06 am
No, you can't.
Title: Mouse movement causing framerate drop
Post by: Tank on March 17, 2011, 09:23:10 am
Actually he can, like this:

Code: [Select]
unsigned int catched_events( 0 );

while( window.IsOpened() ) {
while( catched_events < 10 && window.GetEvent( event ) ) {
// ...
++catched_events;
}

catched_events = 0;

// ...
}


I think those mice really can be the problem. Do you have any idea how many messages they generate per second?
Title: Mouse movement causing framerate drop
Post by: Laurent on March 17, 2011, 09:31:37 am
He can limit the number of mouse events he processes, but not those processed by SFML.

Quote
Do you have any idea how many messages they generate per second?

That should be the first thing to test, before investigating further in this direction ;)
Title: Mouse movement causing framerate drop
Post by: devlin on March 17, 2011, 02:38:26 pm
Movement should generate at least one message * CPI for every inch the player moves the mouse. Some of the newer mice are 5500+ "DPI"... which could easily flood a message loop if they move the mouse more than a few inches at a time - if the eventhandling is non-trivial and their computers slow.
Title: Mouse movement causing framerate drop
Post by: Brendon on March 17, 2011, 07:07:13 pm
Counting how many messages are generated per second sounds like a good place to start.  Here's my test app:

Catch the events when user moves mouse:
Code: [Select]
appWindow.MouseMoved += new EventHandler<MouseMoveEventArgs>(appWindow_MouseMoved);

Increment a counter each time the mouse moves:
Code: [Select]
void appWindow_MouseMoved(object sender, SFML.Window.MouseMoveEventArgs e)
{
       this.mousemoveCounter++;
}

Once per second, display mousemoveCounter's value before resetting it to zero.

Does that sound like how one would count the messages per second?
Title: Mouse movement causing framerate drop
Post by: Brendon on March 17, 2011, 09:04:06 pm
I set up the event-test program.  

My mouse gets ~125 mouse-movement events per second. My user with the problem is getting ~500 events per second.

For those curious, here's a link to the program: http://blendogames.com/dev/windowtest04.zip
Title: Mouse movement causing framerate drop
Post by: Groogy on March 18, 2011, 04:24:31 am
500 still looks like a bit low to actually make the application lag. Though depends on the host machine and what you actually do with the event.

Easy fix for Laurent is to add a bool to mouse moved event that tells the end user if this is the last mouse moved event currently in the queue. Giving us the option to:

Code: [Select]

while( window.GetEvent( event ) == true )
{
        switch( event.Type )
        {
         case sf::Event::MouseMoved:
                if( event.MouseMove.IsLast == false )
                        continue;
        }
}


Unless you depend on precise relative movement, this should help out with the lag as you now instead just ignores all mouse movement that you anyway don't care about.

High DPI mices are a joke. They slow down both the hardware and the software <_< (Clogging up traffic unnecessary)
Why do people buy them?
Title: Mouse movement causing framerate drop
Post by: Laurent on March 18, 2011, 07:57:28 am
Quote
Easy fix for Laurent is to add a bool to mouse moved event that tells the end user if this is the last mouse moved event currently in the queue

I think we should wait for more feedback before writing a fix for this. Let's see if all users that suffer from this problem have a high mouse events rate.
Title: Mouse movement causing framerate drop
Post by: Groogy on March 18, 2011, 02:26:30 pm
Quote from: "Laurent"
Quote
Easy fix for Laurent is to add a bool to mouse moved event that tells the end user if this is the last mouse moved event currently in the queue

I think we should wait for more feedback before writing a fix for this. Let's see if all users that suffer from this problem have a high mouse events rate.


Well just thinking, even though if it is not the problem, isn't it more desirable for most developer to only handle the latest mouse moved event? The other ones aren't interesting anyway.

I'm guessing Brendon does some mediocre/heavy game logic with every mouse moved event. Thus when we face a high DPI mouse, he will do this work several time unnecessary.

Brendon try something like this on:
Code: [Select]

sf::Event lastMoveEvent;
sf::Event event;
while( window.GetEvent( event ) == true )
{
        switch( event.Type )
        {
         case sf::Event::MouseMoved:
                lastMoveEvent = event;
        }
}
HandleMouseMoveEvent( lastMoveEvent );

Though you'll of course have to adapt it to SFML.NET and your framework but I think you get the picture. Sumarization: Only work with the latest MouseMove event in the queue :P
Title: Mouse movement causing framerate drop
Post by: devlin on March 18, 2011, 02:40:35 pm
Quote from: "Groogy"
Well just thinking, even though if it is not the problem, isn't it more desirable for most developer to only handle the latest mouse moved event?

Not really - especially if you use the buffered input for gesture recognition and the like.

What would be useful though is a way to limit the amount of messages processed per frame. I.e. a way to manually loop through the internal messages and save anything that takes too much time to a later frame.

That way you might end up with a serious backlog of events - if the computer playing the game is too slow - but the same computer would choke even with the current system. What it lets you do is smooth out framerate over time instead of having stalls.
Title: Mouse movement causing framerate drop
Post by: Brendon on March 18, 2011, 11:30:53 pm
@Groogy - thanks for the tip.  I'm poking around the sfml.net build, but can't find the equivalent to the "GetEvent(event)" call.

At any rate, the problem is solved - though it introduced a new one.

It turns out I was using sfml v1.5.  I'm using v1.5 because v1.6 has a graphics bug (http://www.sfml-dev.org/forum/viewtopic.php?p=15652) I wasn't able to work around.

I asked my users to copy the v1.6 SFML libraries into the game folder. It worked!  The mouse-event framerate drop is no longer an issue.

But, using the v1.6 libraries introduced the graphics issue mentioned above
v1.5: http://blendogames.com/dev/capture-normal.jpg
v1.6: http://blendogames.com/dev/capture-38.png

So my question now is -
1. Can I use the v1.6 Window component, but retain using the v1.5 Graphics component?
2. Anyone know of a workaround for that v1.6 graphics offset?

I tried running with the v1.6 Window dll and v1.5 Graphics dll, but that seems to disable the mouse input.

Any ideas?
Title: Mouse movement causing framerate drop
Post by: Laurent on March 18, 2011, 11:37:10 pm
Quote
I'm poking around the sfml.net build, but can't find the equivalent to the "GetEvent(event)" call.

There's none, event handling is done the .Net way with DispatchEvent().

Quote
I asked my users to copy the v1.6 SFML libraries into the game folder. It worked! The mouse-event framerate drop was no longer an issue.
:shock:

Quote
1. Can I use the v1.6 Window component, but retain using the v1.5 Graphics component?

I don't know. 1.x versions are not supposed to be binary compatible, but 1.6 was mainly a bug fix release so it might be binary compatible with 1.5.

Quote
2. Anyone know of a workaround for that v1.6 graphics offset?

Don't use scale if you can, or "fix" it in source code and recompile. I can tell you what to do if you want.
Title: Mouse movement causing framerate drop
Post by: Brendon on March 18, 2011, 11:42:17 pm
@Laurent - Sure, I'd absolutely love to know how to make the fix in the source code.
Title: Mouse movement causing framerate drop
Post by: Laurent on March 19, 2011, 10:14:18 am
Remove line 191 in src/SFML/Graphics/Sprite.cpp
Code: [Select]
GLCheck(glTranslatef(0.375f, 0.375f, 0.f));
If your sprites get uglier, there will probably be something to modify in sf::Image as well.

Then recompile SFML, CSFML and SFML.Net ;)
Title: Mouse movement causing framerate drop
Post by: Brendon on March 19, 2011, 11:29:44 pm
You're my hero!  Removing that line and recompiling the libraries fixed it.

Thanks, Laurent.