0

Here's my issue: I'm developing a sort of music game where the user can input to android from a midi keyboard (I am using this library: https://github.com/kshoji/USB-MIDI-Driver). For my main game layout, I use a surface view coupled with a game loop. I optimized my onDraw() to be very quick, but for whatever reason, my framerate is much slower when using the external midi keyboard, than when using touches on an on screen keyboard.

At first I though this was due to the overhead from the keyboard driver, but then I noticed that when I touch the screen, the framerate is no longer choppy, even when I am playing from the midi keyboard. Does anyone one know why this might be the case? Does android do some sort of background optimization for ui updates responding to a touch event? Thanks.

EDIT: I have scoped out some more information about my problem. Basically, what my device is doing is setting to CPU speed to low to save power. The policy (as defined by a CPU Governor) is to give the cpu a boost when the user touches the screen, and reduce the cpu clock speed when it doesnt detect any touches. My problem is that since I want to interact via an external device, and not through touch events, the cpu is slow and I get a bad framerate as a result. There are apparently ways to override this if you have root access... but I'd rather not resort to that :/. If anyone has any hacks or ideas, please let me know.

  • Are you calling `postInvalidate()` for your main view from your `onMidiNoteOn` handler? – pelya Aug 29 '15 at 22:34
  • no, but I'm using a game loop to redraw the activity so I shouldn't need to I think? – Thomas Colgrove Aug 30 '15 at 02:40
  • If anyone stops by here in the future, I found the source code regarding cpu governor policies and input boosts: https://android.googlesource.com/kernel/msm/+/android-msm-dory-3.10-kitkat-wear/drivers/cpufreq. Not particularly helpful, but I thought it was interesting to look at and see exactly what was going on under the hood! The file cpu-boost.c contains the code for the "input boosts" in question carried out by the os. – Thomas Colgrove Aug 30 '15 at 06:20
  • The "dory" branch may not be the best example as it's for wearable devices, which are even more paranoid about power than handhelds. – fadden Aug 30 '15 at 17:55

1 Answers1

1

The issue, as you have noted, is aggressive power-saving code. Some notes and a few links are in this answer.

If your app was doing lots of work on the CPU, it wouldn't be throttling down. So one hack / workaround is to have a thread that just sits and spins. This is a really bad idea though, as it will adversely impact the battery life of the device.

If your only issue is with choppy display, and not something more serious like dropping data from an external device, then you can work around the problem by dropping frames when your app falls behind. Quoting the linked answer:

The problem is that the system is aggressively reducing clock speeds to save power when it doesn't detect interaction with the user. (Qualcomm in particular seems fond of this.) The workaround is to drop frames when necessary. See this article on game loops, and a Choreographer-based trick demonstrated in Grafika's "record GL app" activity (in doFrame()).

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166
  • Thank you for the response. The thing is my app isn't supposed to be idle, and the user is technically interacting via the usb device. I only wish there was some way to tell the os that it needs to be responsive! Ah well, I guess I will have to live with my choppy frame rate. Will the grafika solution you mentioned improve smoothness? – Thomas Colgrove Aug 30 '15 at 06:12
  • I recommend you try running Grafika for yourself. On a Nexus 5 the "record GL app" activity would frequently report dropped frames, but I never noticed a glitch unless something else in the system ate up all the CPU time and it had to drop 4 in a row. It's doing a very simple animation at 60fps, so it's not taxing the system, but it has frequently deadlines, which is exactly what the power-saving code is bad at. FWIW, if you run your app under `systrace` on a rooted device you can watch the various clocks adjust and CPU cores spin up/down (see e.g. http://bigflake.com/systrace/). – fadden Aug 30 '15 at 17:50