【问题标题】:SurfaceView draw performanceSurfaceView 绘制性能
【发布时间】:2015-01-18 23:03:31
【问题描述】:

我正在使用 Android SurfaceView 编写一个测试应用程序。我想看看它是否是一种可行的 2D 游戏开发方法。目前表现还不算太好。

似乎每 15 秒左右就会出现微小的颠簸和减速。我只在屏幕上绘制了大约 30 个矩形。我希望它能够轻松地做到这一点。

我决定分析性能。我每 10 帧记录一次平均绘制时间。我注意到的是,它有良好的绘制时间,然后它会跳起来。我确定我的代码没有在游戏循环中分配内存,所以我认为这个问题不是 GC。

我注意到性能下降了大约 100 帧,写在一个相当模棱两可的日志语句之后。有谁知道 android 正在打印的内容可能会发生什么。

每次我启动应用程序时,在这个关于删除文件的日志语句之后绘制时间都会下降......

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

【问题讨论】:

  • 你是如何使用 SurfaceView 的?您是使用 Canvas 还是使用 OpenGL ES 进行渲染?您使用的是设备还是模拟器? (深度背景:source.android.com/devices/graphics/architecture.html
  • 我在 Nexus 4 上运行程序。我认为 SurfaceView 不会公开 OpenGL。那就是 GLSurfaceView,它是一种完全不同的动物,如果可以的话,我想避免它。

标签: android surfaceview 2d-games


【解决方案1】:

SurfaceView 有两个部分,Surface 和 View。视图集成到所有其他 UI 元素中,并且可以与标准组件分层。您可以创建一个custom View 并使用 Canvas 在其上绘制。在所有最近的设备上,这将利用硬件加速,尽管实现了not all of the Canvas API

Surface 是一个完全独立的层,它合成在具有渲染视图元素的层之上或之下。您可以在软件中使用 Canvas 或使用 OpenGL ES 在 GPU 上绘制它。 GLSurfaceView 是 SurfaceView 的包装器,它负责 EGL 设置和一些线程问题,但它并没有什么特别之处。有关将 GLES 与普通 SurfaceView 和 TextureView 一起使用的示例,请参阅 Grafika,它有一个方便的库,其中包含所有 EGL 内容。

在 Surface 上渲染的画布不是硬件加速的。随着屏幕变大(以像素为单位),渲染变得越来越昂贵。 Nexus 4 的 CPU+总线速度与像素数的比率相当不错。在 Nexus 4 上流畅的动画在 Nexus 10 上会有点卡顿。(尝试 Grafika“多表面测试”,选择“反弹”,观察日志中的帧速率。)

为了获得良好的性能并为自己节省大量工作,可能值得您花时间研究开源图形或游戏引擎。或者从一个小的现有项目开始,比如Android Breakout

【讨论】:

  • 我注意到,当我将复杂性降低到非常低时,仍然存在口吃。我的绘制时间平均约为 1 毫秒。然而,它仍然每隔几秒钟就会打嗝。画布上的绘图调用是否有可能进行分配并导致垃圾收集器被调用?
  • 如果您不与屏幕交互,某些设备会变慢,从而放大 CPU 开销;参见例如stackoverflow.com/questions/26860156/… 。使用正确的游戏循环结构,它们通常不会引人注意。请记住,您的游戏远非唯一在设备上运行的东西。您可以使用systrace 准确查看运行的时间(例如bigflake.com/systrace)。 GC 事件在日志文件中被调用(至少在 Dalvik 中;不确定 Art)。画布渲染不应导致很多分配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
相关资源
最近更新 更多