Libgdx multitouch & emulator woes

Today i implemented multitouch support. It was in there for quite a while already, i just didn’t implement the backend. The Input interface has a few new methods.

Note that Input.supportsMultitouch() is a hint at best. For Android version 1.5 and 1.6 this will always report false as there’s no multitouch API support there. For Android 2.0 it will also return false even if there’s multitouch support by the device. A big thank you to the guy who forgot to add PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH to API version 5 (==2.0 the one were multitouch was introduced) and 6 (2.0.1 the bug fix update…). As this is not available in the 2.0 and 2.0.1 APIs i can’t query for multitouch support. I simply assume there is and handle all events accordingly. Everything works as expected on 2.1 and 2.2. Given that 2.0 is dying already it shouldn’t be that much of a problem. Note: this does not mean that multitouch won’t work on 2.0/2.0.1. It will if available, you just don’t now whether it’s there or not by calling Input.supportsMultitouch().

I wrote a very simple test that shows you how to use this stuff. Each finger gets an id, the first finger always has id 0, all subsequent fingers have 1, 2 and so on. If fingers with id 1 and 2 stay on the screen and finger with id 0 is lifted the other two keep their id. If a new finger is put on the screen it will receive the first free id, in this case 0. I especially like how that is totally not documented in the MotionEvent reference or anywhere else. I guess multitouch is a minor feature anyways.

Which brings me to the next item of todays list. Some people reported that all the tests, the hello world app and gdx invaders crash on the emulator. I also got some logcats that told me that the new BufferUtils.copy() method is the culprit. If you remember the earlier post about bulk putting float arrays to direct buffers: It’s slow. So i wrote a simple JNI method which speeds this up tremendously. It worked flawlessly on all devices i have (Samsung Galaxy Leo, HTC Hero, Motorola Droid, Nexus One) as well as on the desktop. The emulator just crashes with a sigseg at address deadd00d, which seems to be Androids variant of deadbeef…

It took me 3 hours to figure out what’s wrong. Here’s the C code that crashed:

Here’s the code that doesn’t crash the emulator:

Yes, it’s a matter of order. It seems that on the emulator you have to call GetPrimitiveArrayCritical before GetDirectBufferAddress. I might be ignorant but i think it shouldn’t really matter. This believe was reinforced by the fact that the code worked on all other platforms and devices, just not on the emulator. I’ll look up all the info i can on the two methods and see whether it’s my fault. If not than i’ll file my first ever Android bug…

From the JNI documentation of GetPrimitiveArrayCritical: “After calling GetPrimitiveArrayCritical, the native code should not run for an extended period of time before it calls ReleasePrimitiveArrayCritical. We must treat the code inside this pair of functions as running in a “critical region.” Inside a critical region, native code must not call other JNI functions, or any system call that may cause the current thread to block and wait for another Java thread. (For example, the current thread must not call read on a stream being written by another Java thread.)”. So, it doesn’t exactly seem like a restriction to me. It only excludes method that might block the current thread. Dunno whether it’s a bug in Dalvik or specified behaviour. The fun part is that it only crashes on the emulator.

2 thoughts on “Libgdx multitouch & emulator woes

Leave a Reply

Your email address will not be published.