Multitouch slowdown

Hi.

I noticed a slowdown in the responsiveness of my application when I use a touchscreen and make contact with more than one finger. The idea is to equate a two fingers drag to a right click mouse drag to rotate the scene.

When I use the mouse, the scene moves and rotates smoothly and without delays. When I use a single finger on the touch screen the scene moves (pan operation) a little slower but still quite smoothly. But as soon as a second finger makes contact with the screen the scene rotation gets very choppy and unresponsive. It feels like the draw loop is blocked for some reason on the SDL events processing.

I handle events exclusively in SdlEventProc.

I initially used this code to render:

SDL_AddEventWatch(SdlEventProc, NULL);
...
while (!g_quitting)
{
    ... render ...
    SDL_GL_SwapWindow(mainSdlWnd);

    SDL_Event event;
    while (SDL_PollEvent(&event)) {};
}

But with this code I could have up to 5s delay between a two finger touch screen interaction and the scene getting rendered. Log file shows that the SdlEventProc gets called in real time as events happen but the render loop is stuck. Then about 5s later the SDL_PollEvent gets called in a loop providing a block of SDL_FINGERMOTION and SDL_MULTIGESTURE interleaved events. And after the fingers stop moving across the touchscreen the event queue is emptied the rendering continues.

If I had to guess is that the rendering is blocked while SDL is trying to figure out if a gesture is being drawn.

And another interesting thing is that if I use this code the rendering seems more responsive:

SDL_AddEventWatch(SdlEventProc, NULL);
...
while (!g_quitting)
{
    ... render ...
    SDL_GL_SwapWindow(mainSdlWnd);
    SDL_PumpEvents();
}

But from what I understand the event queue will fill up this way. Is that correct?

Since I don’t care about events in the rendering loop… Would it be OK to just flush the Event queue?
I assume SDL_FlushEvents might do the trick. But I don’t want to cause any events not getting pushed to SdlEventProc.

Since I also do not care about gesture detection… Can I somehow disable (not just filter) the gesture detection and if so - how?

I also checked if the touch screen driver is perhaps consuming all the CPU while touch operations are performed and that does not seem to be the case. The CPU load does get a bit higher (by 20-30%) but with 2 cores / 4 threads the application should remain responsive. Also hard to say what caused the CPU load to go higher and if it was indeed the touchscreen driver. The touchscreen in general is very responsive in Windows.

I am using SDL 2.0.9 at the moment. Would a newer version resolve this issue?

The problem seems to affect my Windows tablet a lot more than it affects my RaspberryPi 3.

Any ideas how to make the touch screen related lag go away?

Thank you for your time.

It’s too bad that Raspberry Pi OS ships with such a ridiculously outdated version of SDL

Uhm, that responsibility cannot be placed on RasPi folks… It’s my fault. I am afraid I may have neglected to update… cough… for a while…? :innocent:

I will update the RasPi SDL version and I just build a latest version of SDL (2.0.14) on my Windows machine and report if I SDL behaves differently.

Nah, I have a Raspberry Pi as well, and Raspbian (which is even still 32-bit unless you manually install the 64-bit beta) ships SDL 2.0.9 even when fully updated.

Meanwhile, Ubuntu for the Raspberry Pi is 64-bit and ships with SDL 2.0.14.

edit: to be fair to the Raspberry Pi people, it’s because Raspbian/Raspberry Pi OS tracks Debian Stable, which only ships “stable” packages, aka software that’s 5 years old. SDL’s auto-batching would probably greatly benefit Raspberry Pis, but it wasn’t added until SDL ~2.0.12

Batching was first enabled in 2.0.10 according to this; it’s also the version in which the float-coordinate rendering functions were added (SDL_RenderCopyF etc). Sadly there have been regressions in some recent releases of SDL2 (e.g. the SDL_RenderDrawLine endpoint anomaly) so it’s not always desirable to use the very latest ‘stable’ version.

Ah, I see what you mean. I felt I never had much use for the Raspian image. Sure it’s convenient… But I just use ArchLinux.

The SDL build I am using came from their repos. Didn’t manage to verify which version is deployed but it is probably two years old or so.

It may be best that I build the latest release myself and poke it with debug symbols and all. See what comes out.

Honestly the Windows version is more concerning as the latest version still feels unresponsive.

Good to know. Thank you.

I mostly use SDL to just provide the window / video mode init part and the hook into the window events and here come the touch/mouse events into play as well.

I traced some of the performance issues to the debugger session being active. I didn’t suspect the debugger initially because the app is (usually) very responsive when using a mouse.

My findings are still incomplete but I managed to comment out of the gesture handler from SDL and it looks like that is not causing any issues.

I hope to know more tomorrow or this evening.

Thank you for getting back to me.

I did some further testing and what looks like that the slowdown is not SDL version related. What does seem to make the slowdown occur is CPU load. When the systems had a background process running that consumed 25-40% of the CPU, multitouch events seem not to arrive in my SDL2 based app. Single touch events seem to arrive fine as well as mouse events.

I made a video capture of the issue. Here I am using my build of SDL2-2.0.14 where I disabled SDL2 Gesture detection by commenting out the call to SDL_GestureProcessEvent(event) in SDL_events.c:848. I did this in an attempt to isolate the issue and this is the only change.

Windows touchscreen driver tracks all touchscreen interaction in (near) real time as can be seen in the recording - the circles on the screen move smoothly and show the contact of my fingers with the screen. So the driver is not Windows driver related.

The background is changed every time a frame is drawn so it is possible to “track” redraws. That is why the background is cycling through shades of gray.

See: SDL multitouch issue - YouTube

Could it be related to some kind of event handler thread priority in SDL2?

Any ideas on how to resolve this issue?