2

I am writing a test application using Android SurfaceView. I want to see if it is a viable approach to 2D game development. At the moment performance is not too great.

There seems to be tiny little jerks and slowdowns every 15 or so seconds. I am only drawing about 30 rectangles on screen. I would hope it would be able to do this with ease.

I decided to profile performance. I log the average draw time every 10 frames. What I have noticed is that it goes periods with good draw times, and then it jumps up. I am certain my code does not allocate memory in the game loop, so I think this problem is not the GC.

Something I have noticed is that the performance drops about 100 frames in, write after a rather ambiguous log statement. Does anyone have any idea what might be happening with what android is printing.

Everytime I start app, the draw time drops after this log statement about removing file....

01-18 16:53:20.221 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 14 01-18 16:53:20.589 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 18 01-18 16:53:20.919 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:21.250 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:21.581 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:21.911 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:22.241 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:22.572 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 13 01-18 16:53:22.906 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 18 01-18 16:53:23.277 552-650/? D/TaskPersister﹕ removeObsoleteFile: deleting file=5725_task.xml 01-18 16:53:23.278 552-650/? D/TaskPersister﹕ removeObsoleteFile: deleting file=5725_task_thumbnail.png 01-18 16:53:23.330 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 32 01-18 16:53:23.680 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 18 01-18 16:53:24.032 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 20 01-18 16:53:24.399 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 31 01-18 16:53:24.777 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 26 01-18 16:53:25.148 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 23 01-18 16:53:25.473 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 12 01-18 16:53:25.804 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 14 01-18 16:53:26.142 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 14 01-18 16:53:26.467 19296-19370/com.example.scott.coloursquares I/game_screen﹕ draw time = 14

fadden
  • 51,356
  • 5
  • 116
  • 166
Scorb
  • 1,654
  • 13
  • 70
  • 144
  • How are you using SurfaceView? Are you rendering with a Canvas or with OpenGL ES? Are you using a device or an emulator? (Deep background: https://source.android.com/devices/graphics/architecture.html ) – fadden Jan 18 '15 at 23:53
  • I am running program on a Nexus 4. SurfaceView does not expose OpenGL I thought. That is GLSurfaceView, which is a whole different animal, that I would like to avoid if I could. – Scorb Jan 19 '15 at 00:21

1 Answers1

3

SurfaceView has two parts, the Surface and the View. The View integrates into all the other UI elements, and can be layered with standard components. You can create a custom View and draw on it with a Canvas. On all recent devices, that will take advantage of hardware acceleration, though not all of the Canvas API is implemented.

The Surface is a completely independent layer that is composited above or below the layer that has the rendered View elements. You can draw on it in software, using Canvas, or with the GPU by using OpenGL ES. GLSurfaceView is a wrapper around SurfaceView that takes care of EGL setup and some threading issues, but there's nothing special about it. For examples of using GLES with plain SurfaceView and TextureView, see Grafika, which has a handy library with all the EGL stuff taken care of.

Canvas rendering onto a Surface is not hardware accelerated. As screens get larger (pixel-wise), rendering becomes increasingly expensive. The Nexus 4 has a pretty good ratio of CPU+bus speed to pixel count. Animation that would be smooth on the Nexus 4 would choke a bit on the Nexus 10. (Try the Grafika "multi-surface test", select "bounce", watch the frame rate in the log.)

To get good performance, and save yourself a lot of work, it might be worth your while to investigate an open-source graphics or game engine. Or start with a small existing project like Android Breakout.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • I have noticed that as I reduce complexity to very low, there are still stutters. My draw times are about 1 ms average. Yet it still hiccups a little bit every few seconds. Is it possible that the drawing calls on canvas are making allocations and causing the garbage collector to be called? – Scorb Jan 21 '15 at 03:42
  • Some devices will slow down if you're not interacting with the screen, magnifying CPU overhead; see e.g. http://stackoverflow.com/questions/26860156/animation-glitches-while-rendering-on-surfaceview/26870239#26870239 . With the right game loop structure they generally won't be noticeable. Remember that your game is far from the only thing running on the device. You can use `systrace` to see exactly what's running when (e.g. http://bigflake.com/systrace/). GC events are called out in the log file (at least in Dalvik; not sure about Art). Canvas rendering should not cause many allocs. – fadden Jan 21 '15 at 17:01