preventing"闪烁"调用Drawable.draw时() [英] Preventing "flickering" when calling Drawable.draw()

查看:107
本文介绍了preventing"闪烁"调用Drawable.draw时()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小实验应用程序(本质上是一个的非常的的的 LunarLander 演示在Android SDK),与单个 SurfaceView 。我有一个绘制对象精灵,我定期绘制成 SurfaceView 画布对象在不同的​​位置,而不会尝试删除previous图像。因此:

I have a little experimentation app (essentially a very cut-down version of the LunarLander demo in the Android SDK), with a single SurfaceView. I have a Drawable "sprite" which I periodically draw into the SurfaceView's Canvas object in different locations, without attempting to erase the previous image. Thus:

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);
        }
    }
}

运行在模拟器中,我所看到的是,已经出现了一些更新后,图像的几个老拷贝开始闪烁,即出现和消失。我最初以为,也许我是一个误解画布的语义,并且它在某种程度上保持层,而我被颠簸到死亡。但是,我这时才发现,我只得到这样的效果,如果我尝试更新比大约每隔200毫秒快。因此,我的下一个最好的理论是,这也许是对仿真器不能够跟上,撕裂显示器的神器。 (我没有一个物理设备上测试,爱好。)

Running in the emulator, what I'm seeing is that after a few updates have occurred, several old "copies" of the image begin to flicker, i.e. appearing and disappearing. I initially assumed that perhaps I was misunderstanding the semantics of a Canvas, and that it somehow maintains "layers", and that I was thrashing it to death. However, I then discovered that I only get this effect if I try to update faster than roughly every 200 ms. So my next best theory is that this is perhaps an artifact of the emulator not being able to keep up, and tearing the display. (I don't have a physical device to test on, yet.)

要么是这些理论是否正确?

Is either of these theories correct?

注:我真的不希望这样做在实践中(即绘制数百同样的事情叠加副本)。不过,我想知道为什么会这样。

环境:

  • 的Eclipse 3.6.1(太阳神)在Windows 7
  • 在JDK 6
  • 在Android的SDK工具R9
  • 安卓
  • 应用是目标定位2.3.1

切的问题:

我的的run()法实质上是如何LunarLander例子工程(删除所有多余的逻辑)的精简版本。我不明白为什么这是不会饱和的CPU,因为似乎没有什么prevent它运行在满毛皮。任何人都可以澄清这一点?

My run() method is essentially a stripped-down version of how the LunarLander example works (with all the excess logic removed). I don't quite understand why this isn't going to saturate the CPU, as there seems to be nothing to prevent it running at full pelt. Can anyone clarify this?

推荐答案

好吧,我宰了月球着陆器以类似的方式给你,在看到闪烁,我可以告诉你,你所看到的是一个简单的人工制品双缓冲机制,每一个表面有。对

Ok, I've butchered Lunar Lander in a similar way to you, and having seen the flickering I can tell you that what you are seeing is a simple artefact of the double-buffering mechanism that every Surface has.

在画上的任何一个画布附属于表面,要绘制的'回'缓冲区(不可见一个)。而当你 unlockCanvasAndPost()您通过交换缓冲区......你画了什么突然的背缓冲区变成前,反之亦然变得可见。因此绘制你的下一帧做旧的前缓冲......

When you draw anything on a Canvas attached to a Surface, you are drawing to the 'back' buffer (the invisible one). And when you unlockCanvasAndPost() you are swapping the buffers over... what you drew suddenly becomes visible as the "back" buffer becomes the "front", and vice versa. And so your next frame of drawing is done to the old "front" buffer...

的一点是,你总是画上交替帧单独的缓冲区。我想有一个隐含的假设图形架构,你的总是的要被写的每一个像素。

The point is that you always draw to seperate buffers on alternate frames. I guess there's an implicit assumption in graphics architecture that you're always going to be writing every pixel.

已经理解这一点,我认为真正的问题是,为什么没有闪烁的硬件?经多年过去了,工作的图形驱动程序,我可以猜测的原因,但毫不犹豫地猜测太远。希望上面将足以满足这个渲染假象你的好奇心。 : - )

Having understood this, I think the real question is why doesn't it flicker on hardware? Having worked on graphics drivers in years gone by, I can guess at the reasons but hesitate to speculate too far. Hopefully the above will be sufficient to satisfy your curiousity about this rendering artefact. :-)

这篇关于preventing"闪烁"调用Drawable.draw时()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆