Is OpenGL on Android a battery killer? - android

I'm currently implementing a software keyboard ( using some sophisticated prediction ), and drawing it using canvas is insufficient in terms of perfomance. I'm getting frame drawing times well above 100ms, which is clearly unacceptable.
The keyboard itself consists of about 33 keys, each of them drawn using drawRoundRect and a simple Text above that. No widgets whatsoever are used, so it's the plain perfomance. Also, almost all of Googles perfomance tips are in use, so thats not the reason for the speed either.
I've now reached a point where switching to opengl actually would make sense, but I'm still sceptical considering the impact an opengl-based keyboard might have on battery life.
As I've found no sufficient documentation on that topic, I hope someone here can point me to the right direction.

Regardless of how much it drains the battery, you probably don't want to do this because most existing devices don't support multiple OpenGL contexts at the same time, so your soft keyboard would be incompatible with any application that is using OpenGL for its own drawing. On these devices the OpenGL context is owned only by the foreground application; it can not be used in secondary parts of the UI like the soft keyboard.
Also as the previous poster said, you would probably be best off looking how to optimize your regular drawing. Drawing vectors is quite slow, so pre-rendering them into a bitmap to just do bitmap blits would help a lot. Also be careful to only draw the parts of the window that have changed. 100ms is a pretty insane amount of time to take to draw the UI, so there are almost certainly significant optimizations you can make. You might want to look at the KeyboardView code in the platform (which is used by the standard soft keyboard and sample IME); this already contains many similar drawing optimizations.

An aside: Have you considered rendering the keys once and then grabbing them as sprites and blitting these? It should be vastly superior to rendering vector graphics.
I cannot give you hard numbers (and as apphacker pointed out, this is device-specific), but even if OpenGL is hardware-accelerated and hence might use more battery, the operation should complete much faster and so use less power in total.
If it is not hardware-accelerated, it seems logical that it should only use more power if it takes longer to complete the operation, as you are only exchanging one drawing API for another.
All in all, as you only have to draw when external events happen it shouldn't matter much in the long run, as people are probably tiping only a few keys per minute.
You'll probably just have to implement it (maybe in a simplified test case) and make measurements.

Related

how to measure and improve battery use in iPhone/iPad game (Android also)

My game uses too much battery. I don't know exactly how much it uses as compared to comparable games, but it uses too much. Players complain that it uses a lot, and a number of them note that it makes their device "run hot". I'm just starting to investigate this and wanted to ask some theoretical and practical questions to narrow the search space. This is mainly about the iOS version of my game, but probably many of the same issues affect the Android version. Sorry to ask many sub-questions, but they all seemed so interrelated I thought it best to keep them together.
Side notes: My game doesn't do network access (called out in several places as a big battery drain) and doesn't consume a lot of battery in the background; it's the foreground running that is the problem.
(1) I know there are APIs to read the battery level, so I can do some automated testing. My question here is: About how long (or perhaps: about how much battery drain) do I need to let the thing run to get a reliable reading? For instance, if it runs for 10 minutes is that reliable? If it drains 10% of the battery, is that reliable? Or is it better to run for more like an hour (or, say, see how long it takes the battery to drain 50%)? What I'm asking here is how sensitive/reliable the battery meter is, so I know how long each test run needs to be.
(2) I'm trying to understand what are the likely causes of the high battery use. Below I list some possible factors. Please help me understand which ones are the most likely culprits:
(2a) As with a lot of games, my game needs to draw the full screen on each frame. It runs at about 30 fps. I know that Apple says to "only refresh the screen as much as you need to", but I pretty much need to draw every frame. Actually, I could put some work into only drawing the parts of the screen that had changed, but in my case that will still be most of the screen. And in any case, even if I can localize the drawing to only part of the screen, I'm still making an OpenGL swap buffers call 30 times per second, so does it really matter that I've worked hard to draw a bit less?
(2b) As I draw the screen elements, there is a certain amount of floating point math that goes on (e.g., in computing texture UV coordinates), and some (less) double precision math that goes on. I don't know how expensive these are, battery-wise, as compared to similar integer operations. I could probably cache a lot of these values to not have to repeatedly compute them, if that was a likely win.
(2c) I do a certain amount of texture switching when rendering the scene. I had previously only been worried about this making the game too slow (it doesn't), but now I also wonder whether reducing texture switching would reduce battery use.
(2d) I'm not sure if this would be practical for me but: I have been reading about shaders and OpenCL, and I want to understand if I were to unload some of the CPU processing to the GPU, whether that would likely save battery (in addition to presumably running faster for vector-type operations). Or would it perhaps use even more battery on the GPU than on the CPU?
I realize that I can narrow down which factors are at play by disabling certain parts of the game and doing iterative battery test runs (hence part (1) of the question). It's just that that disabling is not trivial and there are enough potential culprits that I thought I'd ask for general advice first.
Try reading this article:
Android Documents on optimization
What works well for me, is decreasing the use for garbage collection e.g. when programming for a desktop computer, you're (or i'm) used to defining variables inside loops when they are not needed out side of the loop, this causes a massive use of garbage collection (and i'm not talking about primitive vars, but big objects.
try avoiding things like that.
One little tip that really helped me get Battery usage (and warmth of the device!) down was to throttle FPS in my custom OpenGL Engine.
Especially while the scene is static (e.g. a turn-based game or the user tapped pause) throttle down FPS.
Or throttle if the user isn't responsive for more then 10 seconds, like a screensaver on a desktop pc. In the real world users often get distracted while using mobile devices. Don't let your app drain battery while your user figures out what subway-station he's in ;)
Also on the iPhone, sometimes 60FPS is the default, throttling this manually to 30 FPS is barely visible and safes you about half of the gpu cycles (and therefore a lot of battery!).

Turn based game, which drawing method?

I am going to create a simple turn based 2D game for Android and as far as I know there are basically three methods to do the drawing.
Using a "normal" View, and only drawing when needed (for example on a touch event).
Using a SurfaceView combined with a "game loop" in a separate thread, drawing on each loop iteration.
OpenGL (I have no idea how this works yet).
When I made a small simulation game (a la Farmville) I used the SurfaceView, because it used some simple animation, and if I used a "normal" View, I had to use a Timer to update the graphics at certain intervals. I don't know which one of the two methods was better, but the SurfaceView method seemed to be easier. On the other hand, I figure that using an infinite "game loop" drains the battery very quickly. As for OpenGL, I have no idea how that works or if it is way too complicated for simple games.
So if I have a simple turn based game (think a bit like the fighting parts of Pokémon), which of the above methods would be best? What do other games use (like Angry Birds, DanteInferno, Inotia, Jewels, Robo Defense, Wisp, Zonina, etc)?
I find that the information on the web is very unclear on which to use when.
I had a simple board game which is kind of a turned based game and i used SurfaceView and it came out pretty darn good. You can optimize SurfaceView, but You'll eventually run into problems if you use standard views, specially if you have a scrolling game.
I've use this article and it was very helpful, it has a bunch of different methods of implementing the game loop with their pros and cons: http://www.koonsolo.com/news/dewitters-gameloop/
It's a good starting point.
About the draining of the battery - you can use Thread.sleep() so it will last longer. Didn't do any tests on the battery yet, but you have to face the fact that games drain battery, specially if you play it for hours :)
OpenGL also uses a drawing loop which is called repeatedly, so it will operate in a similar fashion to your SurfaceView approach. OpenGL is praised for its performance capabilities but does carry with it quite a lot of complexity - for a small project it might not be worth the investment, unless you fancy learning about how it works!
As for battery life, the most CPU intensive tasks will be the most draining, meaning the redrawing strategy (time based or event-driven) which is most effecient will be the best choice. Benchmarking a simple prototype should give you an idea of which works best with your game code.
I haven't done game development on Android but I have been creating an application that involves a lot of animated and scrolling UI elements. For this project I've used a mixture of normal extended Views and SurfaceViews, and I've had to borrow lots of techniques traditionally used in game programming. Along the way I've learned how normal Views and SurfaceViews differ, and the pros and cons of using each.
The big difference between the two, which I think is important to grasp, is that with a SurfaceView you're in effect almost directly writing to the screen buffer (not technically correct - but the easiest way to think about it) as soon as you want, and often as you'd like (within limits). It doesn't 'sit' within the normal View hierarchy. Being able to draw in this manner allows for fast animated graphics (particularly by offsetting bitmaps to create scrolling backgrounds and overlaying animated bitmap sprites over the top). Your code does the drawing directly when it wants to. Main disadvantage of a SurfaceView as far as I have been able to tell from my own experience is that you cannot have any other View appear behind it (i.e. no transparency effects).
A normal View on the other hand sits in the normal View hierarchy. Unlike with a SurfaceView you cannot perform a redraw of a normal View as soon as your code wants to. You have to call invalidate() (or postInvalidate() from a non-UI thread) on that View to tell the system that you want to redraw it, and then the system will eventually call that View's onDraw() after some time to do the drawing. There's no guarantee on how quickly that'll be called and this potentially limits the speed at which you can update graphics. The advantage of a normal View however is that it sits within the normal View heirarchy and you can have Views placed on top of each other with transparency and so on.

Tips regarding high performance drawing in Android

Background
I'm writing a graphing library for an android application (yes yes, I know there are plenty out there but none that offer the customizability we need).
I want the graphs to zoomable and pan-able.
Problem
I want the experience to be smooth, leave a small CPU footprint.
Solutions
Use View.onDraw(Canvas)
Use high resolution Bitmap
Use OpenGL
View.onDraw():
Benefits
Some what easy to implement
Drawbacks
Bad performance? (unless it uses OpenGL, does it?)
Bitmap:
Benefits
Really easy to implement
Great performance
Drawbacks
Have to use scaling which is ugly
OpenGL:
Benefits
Probably good performance depending on my implementation
Drawbacks
More work to implement
Final words
OpenGL would probably be the professional solution and would definitely offer more flexibility but it would require more work (how much is unclear).
One thing that is definitely easier in OpenGL is panning/zooming since I can just manipulate the matrix to get it right, the rest should be harder though I think.
I'm not afraid to get my hands dirty but I want to know I'm heading in the right direction before I start digging.
Have I missed any solutions? Are all my solutions sane?
Additional notes:
I can add that when a graph changes I want to animated the changes, this will perhaps be the most demanding task of all.
The problem with using Views is that you inherit from the overhead of the UI toolkit itself. While the toolkit is pretty well optimized, what it does it not necessarily what you want. The biggest drawback when you want to control your drawing is the invalidate/draw loop.
You can work around this "issue" by using a SurfaceView. A SurfaceView lets you render onto a window using your own rendering thread, thus bypassing the UI toolkit's overhead. And you can still use the Canvas 2D rendering API.
Canvas is however using a software rendering pipeline. Your performance will mostly depend on the speed of the CPU and the bandwidth available. In practice, it's rarely as fast as OpenGL. Android 3.0 offer a new hardware pipeline for Canvas but only when rendering through Views. You cannot at this time use the hardware pipeline to render directly onto a SurfaceView.
I would recommend you give SurfaceView a try first. If you write your code correctly (don't draw more than you need it, redraw only what has changed, etc.) you should be able to achieve the performance you seek. If that doesn't work, go with OpenGL.

Simple particle system on Android using OpenGL ES 1.0

I'm trying to put a particle system together in Android, using OpenGL. I want a few thousand particles, most of which will probably be offscreen at any given time. They're fairly simple particles visually, and my world is 2D, but they will be moving, changing colour (not size - they're 2x2), and I need to be able to add and remove then.
I currently have an array which I iterate through, handling velocity changes, managing lifecyling (killing old ones, adding new ones), and plotting them, using glDrawArrays. What OpenGl is pointing at, though, for this call, is a single vertex; I glTranslatex it to the relevant co-ords for each particle I want to plot, one at a time, set the colour with glColor4x then glDrawArrays it. It works, but it's a bit slow and only works for a few hundred particles. I'm handling the clipping myself.
I've written a system to support static particles which I have loaded into a vertex/colourarray and plot using glDrawArrays, but this approach only seems suitable for particles which will never change relative location (ie I move all of them using glTranslate), colour and where I don't need to add/remove particles. A few tests on my phone (HTC Desire) suggest that trying to alter the contents of those arrays (which are ByteBuffers, pointed to by OpenGL) is extremely slow.
Perhaps there's some way of manually writing the screen myself with the CPU. If I'm just plotting 1x1/2x2 dots on the screen, and I'm purely interested in writing and not doing any blending/antialiasing, is this an option? Would it be quicker than whatever OpenGl is doing?
(200 or so particles on a 1ghz machine with megs of ram. This is way slower than I was getting 20 years ago on a 7mhz machine with <500k of ram! I appreciate I'm using Java here, but surely there must be a better solution. Do I have to use the NDK to get the power of C++, or is what I'm after possible)
I've been hoping somebody might answer this definitively, as I'll be needing particles on Android myself. (I'm working in C++, though -- Currently using glDrawArrays(), but haven't pushed particles to the limit yet.)
I found this thread on gamedev.stackexchange.com (not Android-specific), and nobody can agree on the best approach there, but you might want to try a few things out and see for yourself.
I was going to suggest glDrawArrays(GL_POINTS, ...) with glPointSize(), but the guy asking the question there seemed unhappy with it.
Let us know if you find a good solution!

Can I increase performances using glscissor

I'm working on a 2D game for android using OpenGL ES 1.1 and I would like to know if this idea is good/bad/useless.
I have a screen divided in 3 sections, so I used scissors to avoid object overlapping from one view to the other.
I roughly understand the low level implementation of scissor and since my draws take a big part of the computation, I'm looking for ideas to speed it up.
My current idea is as follows:
If I put a glscissor around each object before I draw it, would I increase the speed of my application.
The idea is if I put a GLScissor, (center+/-sizetexture), then the OpenGL pipeline will have less tests to do (since it can discard 90~99% of the surface thanks to the glscissors.
So to all opengl experts, is this good, bad or will have no impact ? And why?
It shouldn't have any impact, IMHO. I'm not an expert, but my thinking is as follows:
Scissor test saves on your GPU's fill rate (the amount of fragments/pixels a hardware can put in the framebuffer per second),
if you put a glScissor around each object, the test won't actually cut off anything - the same number of pixels will be rendered, so no fill rate will be saved.
If you want to have your rendering optimized, a good place to start is to make sure you're doing optimal batching and reduce the number of draw calls or complex state switches (texture switches).
Of course the correct approach to optimizations is to try to diagnose why is your rendering slow, so the above is just my guess which may or may not help in your particular situation.

Categories

Resources