Drawdle with the backgrounds on |
Why was this happening? Drawdle plays great, background and all, on my friend's HTC Evo 4G, a device that is similar to the HTC Thunderbolt only a year older and by any measure not as powerful. The story was the same for the Droid Incredible line of phones: Drawdle plays fine on the original and plays horribly on the newer model. Something was very wrong.
The culprit, as I was able to verify, was the background. Users who turned the Drawdle background off on their Thunderbolts reported markedly improved performance, in line with devices that were known to be OK. Unfortunately, this was not enough to go on: the code responsible for the background in Drawdle wasn't that different from the rest of the codebase. Creating the background required the physics engine, line rendering and buffer updating, nothing that that wasn't being done all the time anyway.
I didn't have access to an affected device to profile on (an a la carte Thunderbolt costs $700 retail), so tracking this down would not be quick. I started by converting my vertex arrays to VBOs, confident that there was a bug in the glDrawArrays implementation on these devices. A quick trip to the Verizon Store to test my fix showed that my optimism was misplaced, as there was no improvement. This pattern repeated itself when I tried disabling the physics engine and updates to the color buffers for the background objects (look closely and you can see the objects periodically change their colors). Nothing that I tried helped.
My only hint was this post discussing a similar problem on a weather application: some users were reporting that the app ran fine on their devices until they turned on county lines. I had an epiphany that night while thinking about that post: it was line drawing that was slowing my app on these devices, sprite rendering, which was implemented the same way, using glDrawArrays, worked fine.
I set about converting my line drawing calls to their equivalent triangle strip calls. This wasn't trivial or cheap (a triangle strip requires twice as many vertices as an equivalent line, line strip or line loop), but it was worth the effort. On my next round of testing (thank you Verizon Store) my app performed flawlessly.
Long story short, you should avoid drawing calls with GL_LINES, GL_LINE_STRIP and GL_LINE_LOOP when developing for Android. This goes for both vertex arrays and VBOs. This problem appears to affect only some phones with Adreno 205 GPUs, but that isn't proven at this point. More research is needed; if you have anything to share, please drop me a line or leave a comment here.
No comments:
Post a Comment