So multitouch actually works flawlessly on the Galaxy S and Droid Incredible:

Pfuh.. I wished Motorola and HTC would have gotten their act together when they released the Droid/N1/Desire etc. It’s really bad press to claim multitouch capabilities that simply aren’t there. At least when compared to a 2008 IPhone. May this trend continue.

  • Share/Bookmark
 

Back in february iirc i told Robert from Battery Powered Games that multitouch on Android was borked. Not believing me he wrote a nice little app for testing and even put it up on the market. This steered some press with Google responding. It was said that it’s a hardware issue. Today i had a nice e-mail in my inbox thrown at me by the android bug tracker for an update on an issue. In the new comment a link to a newly filed bug report was present pointing to this bug. This bug was filed on June 8th and was accepted on June 9th. It’s about the well known teleporting issue. Looks like at least that problem is going to be solved. We’ll see how that works out, a fix will be backported to Eclair and will be released with the next android version.

It’s still a bummer that Google didn’t specify minimum requirements for multitouch screens. Obviously the low end only has to support some simple gestures and not true multitouch. Makes kitty sad…

On a related note: my (free) Nexus One is fucking up touch every day while i browse and do other things on the phone. It’s really annoying. It manifests as my touch points getting screwed up, e.g. being registered 2-3cm away from where i actually hit the screen. It always happens in landscape mode (i hardly use portrait anyways) but other than that i could not yet figure out how to reproduce it. I have a feeling that it has to do with the system keys which are actually part of the touch screen. Somethings really fishy here. Will record a video next time it happens.

  • Share/Bookmark
 

Update:: Robert started a thread on the platform group and filed a bug.. Please consider visiting both sites and star the issues. It’s the only way to get a little bit of attention.

Yes, touch event floods are still there in Android 2.0.1 and according to Robert from Battery Powered Games also in 2.1. He verified this with a rooted devices on which i run top to see what the CPU usage was like when touching and not touching the screen. A thread on the mailing list is also available.

Seeing how this really bugs the hell out of Robert i wrote a small program with libgdx that sets up a GLSurfaceView and outputs the frames per second along with the CPU usage. I artificially throttle the rendering thread to 5 frames per second so that the average CPU usage without touching the screen is low. I tracked the CPU usage by polling /proc/stat which is directly accessible via a FileInputStream. Here’s the code:

package com.badlogic.touchflood;
 
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class CPULoad 
{
	long total = 0;
	long idle = 0;
 
	float usage = 0;
 
	public CPULoad( )
	{
		readUsage( );
	}
 
	public float getUsage( )
	{
		readUsage( );
		return usage;
	}
 
	private void readUsage( )
	{
		try
		{
			BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( "/proc/stat" ) ), 1000 );
			String load = reader.readLine();
			reader.close();		
 
			String[] toks = load.split(" ");
 
			long currTotal = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4]);
			long currIdle = Long.parseLong(toks[5]);
 
			this.usage = (currTotal - total) * 100.0f / (currTotal - total + currIdle - idle);
			this.total = currTotal;
			this.idle = currIdle;
		}
		catch( IOException ex )
		{
			ex.printStackTrace();			
		}
	}
}

Not to fancy and probably not the best way to do it, however i don’t want to root my phone so that must do :) .

Here’s the results for my Milestone with 2.0.1:

- 8-9% CPU usage without touching
- 22%-55% CPU usage with touching

Robert hunted that behaviour down to the KeyInputQueue, an Android framework class implemented on the Java side of things. The processing of new events, be it keyboard or touch events is implemented without any performance considerations appearantly. No amount of sleeping will be able to solve that problem, so what that guy who did Replica Island said in his Google I/O talk is not correct.

Note that the above results are for Android 2.0.1 on my Milestone. On older chips as well as Android versions this will be a lot worse. I will try it on my Hero tomorrow once i get a hold of it (Stefanie is the proud owner of it at the moment).

For me as a hobbyist it’s just a bit of an annoyance but i don’t know whether there’s a reason that the Android team hasn’t decided yet to fix it. However, for people like Robert that try to make a living of Android game dev it is indeed a big problem. Bad performance is directly reflected by bad user comments which in turn has an impact on your downloads and sales.

On a related note: i tried out Zenonia today, a nice little Zelda clone. The description says it does support multitouch. Coming from a big name (Gamevil) i thought they for sure must have figured out a way around the intrinsic multitouch bug(s) on Android. Well, turns out they didn’t. If you go to the left via the onscreen d-pad and press the action button while holding down the onscree d-pad movement stops. Oh well, at least we small devs aren’t just to stupid :)

You can find an apk of the touch flood test at http://www.file-pasta.com/file/1/touchflood.apk, the Eclipse project can be downloaded from http://www.file-pasta.com/file/0/touchflood.zip

  • Share/Bookmark
 

Multi-Touch is borked!

Yes it really is. Check out this video

This is a simple demo were i register multi-touch events and do polling later on to draw the rectangles at their locations. Here’s the code that handles the multi-touch events:

public boolean onTouch(View v, MotionEvent event)
{
   int action = event.getAction();
   int ptrId = event.getPointerId(0);
   if(event.getPointerCount() > 1)
      ptrId = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
   action = action & MotionEvent.ACTION_MASK;
   if(action < 7 && action > 4)
      action = action - 5;
 
   if( action == MotionEvent.ACTION_DOWN )
   {
      for( int i = 0; i < event.getPointerCount(); i++ )
      {
         float x = event.getX(i);
         float y = event.getY(i);
 
         touchX[event.getPointerId(i)] = (int)x;
         touchY[event.getPointerId(i)] = (int)y;
      }
 
      touched[ptrId] = true;
   }
   if( action == MotionEvent.ACTION_MOVE )
   {
      for( int i = 0; i < event.getPointerCount(); i++ )
      {
         float x = event.getX(i);
         float y = event.getY(i);
 
         touchX[event.getPointerId(i)] = (int)x;
         touchY[event.getPointerId(i)] = (int)y;
      }
   }
   if( action == MotionEvent.ACTION_UP )
   {
      touched[ptrId] = false;
 
      if( event.getPointerCount() == 1 )
         for( int i = 0; i < 10; i++ )
            touched[i] = false;
   }
   if( action == MotionEvent.ACTION_CANCEL )
   {
      touched[ptrId] = false;
      if( event.getPointerCount() == 1 )
         for( int i = 0; i < 10; i++ )
            touched[i] = false;
   }
 
   return true;
}

In the first couple of lines i extract the pointer ID along with the touch event action itself. It’s just some silly bit shifting, you can figure out the details by looking at the MotionEvent class. Next i react to the events and fill the three arrays touchX[], touchY[] and touched[] accordingly. In my rendering thread i poll those three arrays and draw a Rectangle for each entry that has touched[] set. Simple.

Now the problem is pretty easily reproduceable. Touch with the left thumb, hold it and touch with the right thumb, release the left thumb and put it down again. The x-coordinate for the left thumb get’s messed up. In LogCat one can see messages from the class InputDevice saying that a bad pointer was dropped. I had a brief look at that class in the Android sources and it seems to be a bit messy. Lots of magic numbers and so on.

I reported this issue twice on the mailing list here and here and confirmed the issue on the Milestone/Droid. Robert Green from Battery Powered Games told me yesterday that he has the same issues on his Nexus One, so did Markus Junginger from Green Robot. Robert also filled a bug report here.

In this thread Dianne Hackborn, an Android framework developer stated that This is how the sensor hardware works. It is essentially the same sensor as
the G1 and myTouch. Please don’t file a bug about it.
which is quiet interesting considering that the problem must have been obvious in their tests. One of the example codes from the threads above is actually a framework example included in the Android sources and the problem is easily noticeable.

It’s really a bit sad to have such a crippled version of multi-touch on Android. I really can’t blame anyone as the situation is a bit unclear. Is it the drivers or the framework interpreting the driver output? Seeing the comment by Dianne makes me wonder if there’s ever going to be a fix for this.

For now multi-touch enabled games are out of the window :/

  • Share/Bookmark
 

Multitouch Issues

I was fooling around with multitouch the last weekend a bit and arrived at the conclusion that at least my android screen fucks up a lot of the events very often. I searched quite some time for a fix, read all the available documentation very carefully but couldn’t come up with a solution.

The problem is also visible in some android framework tests and all the multitouch games i tried on my droid. You can find a couple of videos here and here. I also found this thread over on the android groups but there’s been no helpful reply yet.

Just for fun i was googling around a bit today and found this nice site. It features a helper class that cleans up the multitouch event stream and should clean up the mess a bit. It’s used in the eclair version of cyanogen’s mod at the moment. I only tested it briefly but so far it seems to work. Cudos to Luke Hutchison who devised this nice little class.

I will report progress on this issue in the near future.

Edit: Luke Hutchison kindly replied to the android group thread over here and confirmed my suspicions. I’d love to get some comments on this from google framework engineers. Thanks Luke for helping us all out on this matter!

Edit2: Well, and he replied here as well. Thanks again! I also wanted to note that the problems Luke mentioned and i experienced are not inherent to only the G1 but also occur on my hero as well as my droid. I don’t know how the Nexus one performs in that regard, let alone other less widely spread devices. I will try to come up with some template code you all can use for your game programming needs in the near future and share it here.

  • Share/Bookmark
Tagged with: