6
\$\begingroup\$

I will try to keep this question as concise and as readable as I can.

I recently came across an odd problem with my Android game that I'm developing.

It's an openGL ES 2.0 game and initially I was using RENDERMODE_CONTINUOUSLY, my gameloop was running on the OpenGL provided rendering thread and I was basically limiting the logic updates (to say, 30 times per second), while letting the rendering run as fast as the device could handle.

Please note that I'm not using thread.sleep() and do not want to as I've read various articles advising against it

Everything works well, but when I ran the game on an old Galaxy Ace phone it was rendering at 85+ Frames Per Second which got me thinking that it could be using more battery than it needed to (because it was rendering frames which didn't need to be rendered as there were no logic updates in-between them).

So what I did was this:

I set RENDERMODE_WHEN_DIRTY, started another thread myself, put my game loop into that thread and from this loop, called update() (For logic updates) and requestRender() (for drawing). I altered the gameloop so that it would only render when there was an update.

Now, the way it stands, If I limit my loop to say, 30 ticks per seconds, then all is good, both rendering and logic run at a smooth 30 tics per seconds. If things get too much and the device can't handle the rendering, and the frame rate drops (lets say, to 12FPS), then the logic will carry on at 30 times per second which is exactly what I'm after.

Howevever, I've used the CPU Meter in Jellybean and it would appear that the first option (2 threads, rendering flat out) is more CPU (and therefore, I assume battery) efficient that the 2nd method (3 threads, but with rendering limited).

I'm trying to figure out why this would be?

Please note that I can't test the CPU usage on the Galaxy Ace phone as it doesn't run jelly bean, but certainly on my Nexus 10 tablet, the CPU usage is more when using the 3 threaded approach.

I understand that now, my loop still 'loops', even when it has no updates or rendering to do (never sleeping), but this was the case in the first loop too (well, when it had no updates, it would carry on rendering regardless).

So what gives here?

Note: I haven't posted code as it's not really relevant to the question. But if you want to see the loop, please ask and I will post - thanks

With OpenGL, am I best to just leave the device to render as fast as it can? That certainly seems to be the way it's been set up (at least when using RENDERMODE_CONTINUOUSLY)

\$\endgroup\$
5
  • \$\begingroup\$ Maybe your render loop was actually "sleeping" - that is, waiting for render to happen, which tasked GPU but not CPU? Are CPU and GPU even different on Android devices? \$\endgroup\$
    – Nevermind
    Commented May 8, 2013 at 14:05
  • \$\begingroup\$ Hi @Nevermind I don't think the loop was ever sleeping that I know of. (If it was, what would be controling that? And why would the phone be rendering at 85-90 fps?) Yes CPU and GPU are different. \$\endgroup\$ Commented May 8, 2013 at 14:14
  • \$\begingroup\$ It looks like you may have no choice but to sleep on portable devices \$\endgroup\$
    – bobobobo
    Commented May 9, 2013 at 1:58
  • \$\begingroup\$ eglSwapBuffers blocks for the remainder of the frame (waiting for VSYNC). This is good, but as soon as you split into 2 threads (update/draw) it appears you are SOL on slowing down the update thread without calling sleep. \$\endgroup\$
    – bobobobo
    Commented May 9, 2013 at 2:07
  • \$\begingroup\$ That's a shame, the Nexus 10 tablet's vsync is limited to 60fps but an old Galaxy Ace phone just render away to it's heart's content, sometimes at +100 FPS! \$\endgroup\$ Commented May 11, 2013 at 21:12

1 Answer 1

2
\$\begingroup\$

GLES rendering has a CPU cost and a GPU cost. Rendering less often should reduce both of these. I don't believe the CPU meter can show you the GPU cost, and I'm not sure why it would indicate that your CPU usage is greater.

Maybe the (presumably trivial) activity of the third thread is being exaggerated in the accounting? You can get a simple per-thread breakdown with adb shell ps -x -t; the "u" number indicates time spent in user-space, the "s" number is time spent in the kernel.

The systrace tool can show you exactly what's happening on every CPU core, but it's a bit tricky to use and interpret, and you need a recent, rooted device to get some of the interesting bits.

Note the actual battery life will depend on various other factors. For example, if the CPU and GPU aren't all that busy, they can drop to a lower clock frequency.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .