SurfaceHolder.lockCanvas()的开销过大

3
每次调用这些方法,处理时间需要14-20毫秒。
Canvas canvas = holder.lockCanvas();
holder.unlockCanvasAndPost(canvas);

这是正常的行为吗? 我应该采取不同的方法吗?
以下是整个代码:
public class Render extends SurfaceView {
    Context c = null;
    SurfaceHolder holder;
    volatile boolean running = true;

    public Render(Context c) {
        super(c);
        this.c = c;
        this.holder = getHolder();
    }

    public void run() {
        if(running) { 
            if(!holder.getSurface().isValid()){
                System.out.println("not valid");
                return;          
            }

            Canvas canvas = holder.lockCanvas();
            holder.unlockCanvasAndPost(canvas);

        }
    }
}

Trace:
01-05 15:49:20.322: I/System.out(4892): 帧时间:0毫秒 帧291
01-05 15:49:20.322: I/System.out(4892): 无效的
01-05 15:49:20.322: I/System.out(4892): 帧时间:0毫秒 帧292
01-05 15:49:20.332: I/System.out(4892): 帧时间:2毫秒 帧293
01-05 15:49:20.357: I/System.out(4892): 帧时间:22毫秒 帧294
01-05 15:49:20.357: I/System.out(4892): 帧时间:1毫秒 帧295
01-05 15:49:20.362: I/System.out(4892): 帧时间:1毫秒 帧296
01-05 15:49:20.367: D/CLIPBOARD(4892): 在输入开始时隐藏剪贴板对话框:由其他人完成...!
01-05 15:49:20.367: I/System.out(4892): 帧时间:8毫秒 帧297
01-05 15:49:20.377: I/System.out(4892): 帧时间:10毫秒 帧298
01-05 15:49:20.397: I/System.out(4892): 帧时间:16毫秒 帧299
01-05 15:49:20.412: I/System.out(4892): 帧时间:16毫秒 帧300
01-05 15:49:20.427: I/System.out(4892): 帧时间:16毫秒 帧301

更新:


当我使用OpenGL时,也会发生同样的事情。

package android.apps.td;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;

public class Render extends GLSurfaceView implements Renderer {

    private final int MILLION = 1000000;
    private long frame;

    public Render(Context context) {
        super(context);
        setRenderer(this);
        // TODO Auto-generated constructor stub
    }

    public void onDrawFrame(GL10 arg0) {
        System.out.println("Frame "+(System.nanoTime()-frame)/MILLION+" ms");
        frame = System.nanoTime();
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        System.out.println("Surface changed w:"+width+" h:"+height);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        System.out.println("Surface created");
    }
}

1
你在它们之间做什么? - dbryson
什么都不做,只是调用这两个方法就会产生延迟。 - jellyfication
2个回答

2

0

我一直在自己调查这个问题。我在Galaxy Tab GT-P7500上发现的是:

  • unlockCanvasAndPost+lockCanvas之间的最小时间间隔为1/60秒或17毫秒。
  • 但是,您可以进行多达6毫秒的工作,帧速率仍将保持在60 fps。
  • 页面翻转(unlockCanvasAndPost+lockCanvas)所需的最小时间约为3毫秒。
  • 超过6毫秒的工作量,lockCanvas()函数可能会引入额外的延迟,将帧速率降至40 fps、30 fps、20 fps或15 fps。在最坏的情况下,页面翻转可能需要超过1/60秒的时间。例如,如果每帧执行48毫秒的工作(当您添加3毫秒用于页面翻转时,这不足以实现20 fps),则页面翻转将浪费19-20毫秒的时间,以将帧速率降至15帧每秒。低于15 fps,页面翻转可能始终需要17毫秒。
  • 这种现象并不总是发生。在观察到此行为后,我创建了一个专用活动进行进一步调查,在该专用活动中,这种现象没有发生。到目前为止,我还没有能够找出原始基准测试和新基准测试之间的区别:它们都在工作线程中的SurfaceView上绘制帧,但在第二个活动中,页面翻转始终需要3毫秒,而在第一个活动中,页面翻转最初需要3毫秒,但在大约半秒钟后突然上升到稳态下的最大值20毫秒。
  • 插入电源没有任何区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接