Reputation: 961
I read many posts about the SurfaceView and how to integrate it in Android game and there is something that almost all the posts ignore.. The reason to use SurfaceView is to export all the graphics logic and screen rendering to different thread (to achieve performances boost). But in all the posts that I read, the SurfaceView thread is also responsible for the logic and the game state updates, thus it seems like it takes the whole point of using SurfaceView. Even in posts that the logic unit is using a different thread, the updates methods and the rendering methods are called synchronically, and again, it's seems like it makes the SurfaceView unnecessary.
Your help (with example if possible) would be appreciated.
Upvotes: 0
Views: 1044
Reputation: 52343
There are similar-ish questions here and here, though your question differs in that it's less "how" and more "why".
Being able to render independently of the main UI thread has some advantages, as there will always be some activity there -- dealing with user input, responding to system queries, managing any View-based UI elements on screen. SurfaceView doesn't require you to use a separate thread, just makes it possible.
Separating the game logic from the rendering has advantages as well, especially when you're using Canvas to do the rendering, as Canvas-based rendering on a SurfaceView is not hardware-accelerated. Since it's all happening on the CPU, there's a major advantage to splitting the work across threads. If you're using OpenGL ES, the advantages are reduced, though there can still be a fair amount of CPU overhead if you're not taking advantage of VBOs and other optimizations.
The trouble with splitting rendering and game logic across threads is that you have to be very careful. You must use appropriate synchronization mechanisms or things can get very weird. It's easier to get it wrong on ARM than x86. There's a long document about the subject here. If you omit synchronization you can have nasty bugs, if your synchronization is too heavy you stifle concurrency and lose the benefits of having multiple threads.
One consequence of this is that example code, which tends to favor simpler approaches, will often do all of the work on a single thread. Unless the example is explicitly trying to show a division of labor, the complexity introduced by splitting the work across threads clouds the example.
A frequently-cited example that divides work between threads is Replica Island. If you look at the way its onDrawFrame() method works, you can see it passing a "draw queue" between threads.
There are other advantages to using SurfaceView. The SurfaceView output is on a completely separate layer from the View-based UI, which means you get a big blank buffer to scribble on. You can put it above or below the View UI, which allows you to obscure the UI or have View UI overlay the game (e.g. a "menu" button or a decorative frame). Nothing you do on the Surface will cause a View invalidate / redraw cycle (which can be very expensive). And, of course, you can render directly with OpenGL ES, which is becoming increasingly important as device screens get denser.
Some other thoughts on game loops can be found in the graphics architecture doc.
Upvotes: 1