0
votes

Our applications need double buffering semantics e.g. when drawing a line in one paint operation the line should still be there the next time around (no wipe, use same buffer). This works very well for us with SurfaceView, lock etc.

However those cannot be hardware accelerated and we feel we might be missing out on some performance on some Android devices.

When running on iOS we use OpenGL and retained backing mode which prevents the OS from wiping the display on every redraw. I was hoping Android has something similar that will prevent an invalidate call from wiping the elements previously drawn on the screen but I could find no such option other than creating a Bitmap.

Drawing to a Bitmap would also be an option (that's what we do today), but then how do we leverage the hardware acceleration here?

3
OpenGLES is the safest way in the search for hardware acceleration. And I may be horribly wrong, but I think double buffering is enabled by default and it has nothing to do with what you describe. To preserve drawn shapes among frames, not calling glClear() in onDrawFrame should be enough(?) - foibs
Thanks but I'm not interested in porting the code to OpenGL, there is a lot of code and OGL isn't the best fit for this type of code (a lot of text etc.). We use OGL on iOS so I'm well aware of the pain I would be facing. - Shai Almog
Double buffering is all about preventing screen flicker caused by applications that do need to clear the screen and draw every frame from scratch. You are asking for the screen not to be wiped, but on the other hand you say you "need double buffering". That sounds contradictory; I'd say disable double buffering altogether and you should be good. Did I misunderstand the question, or am I missing something about Android that's different from the mobile platform that I used to work on years ago? - Ruud Helderman
Keyword in my question above: semantics... We need the semantics not the double buffering itself. - Shai Almog

3 Answers

1
votes

We had a similar challenge with the Androidplot library as we ruled out SurfaceView as a legitimate solution due to issues with displaying 2 or more SurfaceViews at once. We ended up creating our own BufferedCanvas implementation which is really nothing more than a ping pong buffer that uses Bitmaps.

As far as hardware acceleration goes, it should be enabled by default and from (what I understand) code should "just work" as long as you aren't using any unsupported drawing operations. You'll notice that the code linked above has to explicitly disable acceleration for this reason.

1
votes

Don't draw to a Bitmap, stick with OpenGL and use a framebuffer object (FBO).

0
votes

It seems that this isn't doable in quite the same way as a double buffering approach.

What I ended up doing is use the postInvalidate(int, int, int, int) method and build a task queue to draw the elements that have changed. The thing that was really problematic for me was the fact that Android kept deleting the screen, this was actually because we didn't invoke activity.getWindow().setBackgroundDrawable(null); which we didn't feel with software rendering but causes screen wipes in hardware accelerated rendering.