gpt4 book ai didi

android - 调用 Drawable.draw() 时防止 "flickering"

转载 作者:太空宇宙 更新时间:2023-11-03 11:38:36 25 4
gpt4 key购买 nike

我有一个小实验应用程序(本质上是 Android SDK 中的 LunarLander 演示的非常精简版),只有一个 SurfaceView。我有一个 Drawable“sprite”,我会定期将其绘制到不同位置的 SurfaceViewCanvas 对象中,而不会尝试删除之前的图像.因此:

private class MyThread extends Thread {
SurfaceHolder holder; // Initialised in ctor (acquired via getHolder())
Drawable sprite; // Initialised in ctor
Rect bounds; // Initialised in ctor

...

@Override
public void run() {
while (true) {
Canvas c = holder.lockCanvas();
synchronized (bounds) {
sprite.setBounds(bounds);
}
sprite.draw(c);
holder.unlockCanvasAndPost(c);
}
}

/**
* Periodically called from activity thread
*/
public void updatePos(int dx, int dy) {
synchronized (bounds) {
bounds.offset(dx, dy);
}
}
}

在模拟器中运行,我看到的是在发生一些更新后,图像的几个旧“副本”开始闪烁,即出现和消失。我最初假设我可能误解了 Canvas 的语义,并且它以某种方式维护“层”,并且我正在将它打死。然而,我随后发现,只有当我试图以比大约每 200 毫秒更快的速度更新时,我才会得到这种效果。所以我的下一个最佳理论是,这可能是模拟器无法跟上并撕裂显示器的产物。 (我还没有可以测试的物理设备。)

这两种理论是否正确?

注意:我实际上并不想在实践中这样做(即绘制同一事物的数百个重叠副本)。但是,我想了解为什么会这样。

环境:

  • Windows 7 上的 Eclipse 3.6.1 (Helios)
  • JDK 6
  • Android SDK 工具 r9
  • 应用的目标是 Android 2.3.1

切题:

我的 run() 方法本质上是 LunarLander 示例工作方式的精简版本(删除了所有多余的逻辑)。我不太明白为什么这不会使 CPU 饱和,因为似乎没有什么可以阻止它全速运行。谁能澄清一下?

最佳答案

好吧,我已经用与你类似的方式对月球着陆器进行了屠杀,并且看到了闪烁我可以告诉你,你所看到的是双缓冲机制的简单 Artifact ,每个 Surface 有。

当您在附加到 SurfaceCanvas 上绘制任何内容时,您正在绘制到“后”缓冲区(不可见的缓冲区)。当您 unlockCanvasAndPost() 时,您正在交换缓冲区……当“后”缓冲区变为“前”缓冲区时,您绘制的内容突然变得可见,反之亦然。所以你的下一帧绘图是对旧的“前”缓冲区完成的......

要点是您总是在交替帧上绘制以分离缓冲区。我想图形架构中有一个隐含的假设,即您总是将要写入每个像素。

理解到这里,我想真正的问题是为什么它在硬件上不闪烁?在过去的几年里从事图形驱动程序方面的工作,我可以猜测原因,但不愿推测得太远。希望以上内容足以满足您对这个渲染 Artifact 的好奇心。 :-)

关于android - 调用 Drawable.draw() 时防止 "flickering",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4985563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com