Should "getPointer" be Slow?

As chronicled in another thread, I’ve been working on my game’s performance of late. To that end, one of the things that I’ve been doing has been examining the time used by various functions in my code, using a combination of “pstats-python-profiler #t” and the dev-version of PStats.

And doing so today, I noticed something that seemed odd: there was a significant-looking chunk of time being spent in my player-class’s “update” method–and specifically, in the code that gets the current mouse-position. And more specifically, in “GraphicsWindow:getPointer()”.

The exact amount fluctuated, but could rise above 4ms!

Should I… not be using this function? Might I be doing something wrong? Is it a bug? Or a consequence of the profiling? Or is this just a cost to be expected when getting the mouse-position…?

On which OS are you observing this?

Are you calling this method once every frame or many times per frame?

Is this with relative or absolute mouse mode enabled?

Ah, sorry!

Okay:

Ubuntu 22.04.4

Based on a quick test, it looks like I should be calling it just once per frame during gameplay.

(It may be called more often in menus, but I’m less worried about them.)

It should be in “absolute” mode.

It is an unfortunate surprise that getPointer is slow. It’s probably due to the fact that it synchronously requests the current position from the X11 server, to get the lowest possible latency. It’s not immediately obvious to me how we can improve this method’s performance.

That said, what are you using getPointer for, exactly? You should prefer using “relative” mouse mode if you wish to use a mouse-look-style interface, which doesn’t require a round-trip to the X11 server to query the pointer.

For GUI use, or other uses that don’t require the lowest possible latency, I recommend using mouseWatcherNode to get the cursor position instead.

PS. Out of curiosity, are you using a Wayland-based window manager or are you using X.org?

Hmm… Could it be that it’s not truly slow, but that it’s appearing slow due to waiting for sync? That is, that its apparent duration is simply whatever time is “left” in the frame…?

That would explain the fact that its duration seemed to vary…

Ah, I’m actually not making that sort of game!

Specifically, I’m making a top-down game, with the mouse being used to control a cursor for aiming relative to the player-character. I thus want to get the mouse-position in the 2D playfield in order to determine where the player is aiming.

(I think that I switched from “getMouse” to “getPointer” based on this forum post, and never really saw a reason to switch back.)

Hmm… You know, I don’t really know.

Okay, so, having done some quick searching, if “echo $XDG_SESSION_TYPE” is to be believed, I appear to be using x11.

Hmm, perhaps it’s something like that, but I doubt it.

Still, I think I would recommend using getPointer only where a very low latency is important or you’re going to use it with movePointer. In your case, I think using mouseWatcherNode should be fine.

1 Like

Hmm, okay, and thank you! I’ll probably look to switch back to mouseWatcherNode, then!

Regarding the changing duration of “getPointer”, I thought that it might be worth showing the effect in action, and to that end I’ve put together a short gif. This shows a flame-graph produced by the new PStats, with the contribution produced by “getPointer” highlighted.

As shown there, the duration varies significantly, apparently depending on what other things are doing. (Or perhaps on the total frame-time, with the contribution of “getPointer” being inversely proportional to the frame-time?)

Note that the scale at the top is also changing. Rightclick that bar and open a strip chart to see how much it actually varies from frame to frame.

It’s a lot of time, though. Strange.

The scale is changing–but even taking that into account, I see the time used by “getPointer” varying there from about 5ms to about 1ms.

(Specifically, at one point spanning from just past 9.2ms to just past 14ms, and at a later point spanning from a little past 15ms to a little past 16ms.)

Well, here’s an interesting experiment: do something slow, like spawning in twenty more copies of your environment map, just sitting in view somewhere. Does the time disappear?

Okay, so I performed the following test:

I added a test-function, controlled by a key-press event, that spawned a large model into view, then created a “doMethodLater” task that ran a second function that removed the model.

I found that if I spammed the related key-press, the time spent in “getPointer” dropped. When I stopped spamming the key-press, it seemed to climb up again.

Now, the time spent in “getPointer” did seem to fluctuate a lot, and there were times without the key-spamming in which its reported time dropped–but not for as long, nor with the same consistency, I feel.

That does sound like it’s some kind of sychronization point.