为什么 lockCanvas() 很慢?

发布于 2024-11-07 03:01:36 字数 1107 浏览 3 评论 0原文

我正在实现一个 SurfaceView 子类,在其中运行一个单独的线程来绘制 SurfaceHolders Canvas。 我正在测量调用 lockCanvas() 之前和之后的时间,结果从大约 70 毫秒到 100 毫秒不等。 有谁能指出我为什么得到这么高的时间吗? 这里是代码的相关部分:

public class TestView extends SurfaceView implements SurfaceHolder.Callback {

....

boolean created;
public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

   mThread = new DrawingThread(mHolder, true);
   mThread.onWindowResize(width, height);
   mThread.start();
}

public void surfaceCreated(SurfaceHolder holder) {

    created = true;
}

public void surfaceDestroyed(SurfaceHolder holder) {
    created = false;

}
class DrawingThread extends Thread {
public void run() {
while(created) {



            Canvas canvas = null;
            try {
                            long t0 = System.currentTimeMillis();
            canvas = holder.lockCanvas(null);
            long t1 = System.currentTimeMillis();
                            Log.i(TAG, "Timing: " + ( t1 - t0) );
            } finally {
                holder.unlockCanvasAndPost(canvas);
            }
}

I'm implementing a SurfaceView subclass, where I run a separate thread to draw onto a SurfaceHolders Canvas.
I'm measuring time before and after call to lockCanvas(), and I'm getting from about 70ms to 100ms.
Does anyone could point me why i'm getting such high timings?
Here the relevant part of the code:

public class TestView extends SurfaceView implements SurfaceHolder.Callback {

....

boolean created;
public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

   mThread = new DrawingThread(mHolder, true);
   mThread.onWindowResize(width, height);
   mThread.start();
}

public void surfaceCreated(SurfaceHolder holder) {

    created = true;
}

public void surfaceDestroyed(SurfaceHolder holder) {
    created = false;

}
class DrawingThread extends Thread {
public void run() {
while(created) {



            Canvas canvas = null;
            try {
                            long t0 = System.currentTimeMillis();
            canvas = holder.lockCanvas(null);
            long t1 = System.currentTimeMillis();
                            Log.i(TAG, "Timing: " + ( t1 - t0) );
            } finally {
                holder.unlockCanvasAndPost(canvas);
            }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

飘落散花 2024-11-14 03:01:36

每次更改表面时都会创建一个线程。您应该在 surfaceCreated 中启动线程并在 surfaceDestroyed 中终止它。 surfaceChanged 适用于表面尺寸发生变化的情况。

来自 SurfaceView。surfaceCreated 文档:

首次创建表面后立即调用此函数。其实现应该启动他们想要的任何渲染代码。请注意,只有一个线程可以绘制到 Surface,因此如果您的正常渲染将在另一个线程中进行,则不应在此处绘制到 Surface。

多线程可能会让你受到限制。来自 SurfaceHolder。lockCanvas 文档:

如果在 Surface 未准备好时(在 Callback.surfaceCreated 之前或 Callback.surfaceDestroyed 之后)重复调用此函数,您的调用将被限制至较慢的速率,以避免消耗 CPU。< /p>

但是,我不相信这是唯一的问题。 surfaceChanged 实际上是否被多次调用?

You're creating a thread every time the surface is changed. You should start your thread in surfaceCreated and kill it in surfaceDestroyed. surfaceChanged is for when the dimensions of your surface changes.

From SurfaceView.surfaceCreated docs:

This is called immediately after the surface is first created. Implementations of this should start up whatever rendering code they desire. Note that only one thread can ever draw into a Surface, so you should not draw into the Surface here if your normal rendering will be in another thread.

The multiple threads are probably getting you throttled. From SurfaceHolder.lockCanvas docs:

If you call this repeatedly when the Surface is not ready (before Callback.surfaceCreated or after Callback.surfaceDestroyed), your calls will be throttled to a slow rate in order to avoid consuming CPU.

However, I'm not convinced this is the only problem. Does surfaceChanged actually get called multiple times?

西瓜 2024-11-14 03:01:36

这与lockCanvas在android图形框架中的实际实现方式有关。

您可能应该已经知道 lockCanvas 将返回您将用于绘制的空闲内存块。 空闲意味着该内存未用于合成,也未用于显示。在内部,简单来说,一个SurfaceView是由双缓冲区备份的,一个用于绘制,一个用于合成/显示。这个双缓冲区由 BufferQueque 管理。 如果合成/显示比绘图慢,我们必须等到有可用的可用缓冲区。

This is related to how lockCanvas is actually implemented in the android graphic framework.

You should probably already know that lockCanvas will return you an free piece of memory that you will be used to draw to. By free, it means this memory has not be used for composition and not for display. Internally, simply speaking, an SurfaceView is backed up by double buffer, one is for drawing , one is for composition/display. This double buffer is managed by BufferQueque. If composition/display is slow than drawing, we have to wait until we have free buffer available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文