【问题标题】:Custom tile based map is slow基于自定义图块的地图很慢
【发布时间】:2010-12-03 00:16:42
【问题描述】:

我正在为我的公共交通应用程序制作地图。我用的是SurfaceView,它是一个基于tile的地图,除了主线程还有2个线程——绘图线程和位图加载线程。

位图是存储在 SD 卡上的 256x256 PNG,我正在缓存加载的位图,缓存容量为 64 位图。每个缩放级别都有不同的位图集,我的地图有 4 个缩放级别,每个下一个级别都放大 2 倍。

不幸的是,我的 Nexus One 上的滚动和捏缩放不流畅,FPS 为 15 - 20。当没有加载瓷砖时,FPS 为 35 - 40。如果我降低位图加载线程的优先级,它会变得完全平滑,但我经常在地图上看到尚未加载的(白色)图块 - 这比不平滑更糟糕。

那我该怎么办?到目前为止,我有 2 个想法:

  • 尝试使用 OpenGL,但我不想花时间在它上面,然后发现我的 FPS 只增加了 3。我还想在用户单击地图标记后显示弹出窗口(与地图一起滚动),这我不知道如何在 GLSurfaceView 中进行操作。
  • 仅当用户触摸屏幕或正在播放动画时,才将位图加载线程设置为低优先级。我试过了,但由于未知原因,它似乎使问题更加严重,触摸/不触摸屏幕没有任何效果。如果只是我可以修复的一些错误,那么还有另一个问题。如果我使用动能滚动来快速移动地图,我会看到很多未缓存的位图。

【问题讨论】:

    标签: android opengl-es


    【解决方案1】:

    不要在渲染线程上进行任何 I/O。 (顺便说一句,你怎么能使用 GLSurfaceView 而不使用 OpenGL?)

    我编写了一个基于 OpenGL 平铺的地图视图,它在 Nexus One 上像黄油一样流畅(没有测量 fps,但它很容易与 iPhone 4 上的地图应用程序一样流畅)。诀窍是将所有 I/O 移出渲染线程,降低工作线程的优先级,并在当前渲染结束时立即 requestRender() 如果您知道将需要另一个渲染线程(例如在平移或缩放),即不要等待另一个线程发出信号。在市场中寻找 Yell.com 以了解其实际效果(但可能仅限英国)。

    【讨论】:

    • 对不起,应该是 SurfaceView,我编辑了问题。是什么让你认为我在渲染线程中做 IO?我有一个绘图线程和额外的位图加载 (IO) 线程。
    • 解码 .png 怎么样?这也需要在您的加载线程上完成。并且您的加载线程必须具有较低的优先级,否则它仍然会占用您的 UI 线程的 CPU 时间。如果您已经在做所有这些,那可能是您刚刚看到 2D Canvas 绘图 API 有多慢。
    • 你的方法怎么样?您是否在每一帧都绘制每个可见的图块?那会很慢...最好使用离屏位图,只有在新图块可见时才能在该位图上绘制它们。
    • 如果加载线程的优先级较低,则新位图加载速度太慢。到目前为止,最好的折衷方案是对绘制线程和加载线程具有相同的优先级。我认为我不理解您的最后评论-如果有正在进行的动画,我必须绘制每个可见的图块。我现在正在尝试正确实施我的第二个想法(在问题中描述),我希望它会有所帮助......
    • 你的 onDraw(Canvas) 函数是什么样的?它是否遍历可见的图块并分别绘制每个图块?因为这将比保持您滚动的屏幕外位图并且仅在它们变得可见时才绘制新图块要慢。然后,您的 onDraw 就是一个 drawBitmap() 调用。我知道这是因为我写了一个 2D 横向卷轴游戏(市场上的鼹鼠矿工),它必须解决大致相同的问题。要记住的是,一个大 blit 比许多小 blit 快。
    猜你喜欢
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 2017-08-01
    • 2010-12-01
    相关资源
    最近更新 更多