2012-01-05 112 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。
  • 插入牆上的力量沒有區別。