2012-01-05 113 views
3

每次我调用这些方法时,都需要14-20ms才能继续。SurfaceHolder.lockCanvas()过于昂贵

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

     } 
    } 
} 

跟踪:

01-05 15:49:20.322:I /的System.out(4892):帧时间:0毫秒frame291
01- 05 15:49:20.322:I/System.out(4892):无效
01-05 15:49:20.322:I/System.out(4892):帧时间:0毫秒frame292
01-05 15 :49:20.332:I/System.out(4892):帧时间:2 ms frame293
01-05 15:49:20.357: I/System.out(4892):帧时间:22 ms frame294
01-05 15:49:20.357:I/System.out(4892):帧时间:1 ms frame295
01-05 15:49: 20.362:I/System.out(4892):帧时间:1 ms frame296
01-05 15:49:20.367:D /剪贴板(4892):在开始输入时隐藏剪贴板对话框:由其他人完成......!
01-05 15:49:20.367 I/System.out(4892):Frame time:8 ms frame297
01-05 15:49:20.377:I/System.out(4892):Frame time:10 ms frame298
01-05 15:49:20.397:I/System.out(4892):Frame time:16 ms frame299
01-05 15:49:20.412:I/System.out(4892):Frame time :16毫秒frame300
01-05 15:49:20.427:我/的System.out(4892):帧时间:16毫秒frame301

更新当我使用OpenGL


同样的事情hapens
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 2012-01-05 00:56:21

+0

没有什么,只是调用这两种方法会产生延迟。 – jellyfication 2012-01-05 13:58:51

回答

0

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

  • unlockCanvasAndPost + lockCanvas对之间的最短时间为1/60秒或17毫秒。
  • 但是,您最多可以做6 ms的工作,帧率将保持在60 fps。
  • 翻页(unlockCanvasAndPost + lockCanvas)所用的最短时间约为3毫秒。
  • 6ms以上的工作,lockCanvas()函数可能会引入一个额外的延迟,强制帧率降低到40 fps,30 fps,20 fps或15 fps。在最糟糕的情况下,翻页可能需要超过1/60秒。例如,如果您每帧需要48毫秒的工作量(当您为页面翻转添加3毫秒时,对于20 fps而言不够快),翻页会浪费19-20毫秒,以便将帧率降低到15每秒帧数。低于15 fps,翻页可能会持续17毫秒。
  • 这种现象并不总是会发生。在基准测试中观察到这种行为之后,我创建了一项专门的活动来进一步调查,并在该专项活动中没有发生这种现象。到目前为止,我还没有弄清楚我的原始基准和新基准之间的区别:他们两个都在工作线程中在SurfaceView上绘制帧,但在第二个活动中,页面翻转一直持续3毫秒,而在第一次,页面翻转最初需要3ms,但在大约1/2秒后突然上升,在稳定状态下最多20ms。
  • 插入墙上的力量没有区别。