2011-06-06 111 views
3

我正在開發一款安卓遊戲,並使用SurfaceView。我有一個將被調用每16毫秒(我希望能有60fps的)SurfaceHolder.lockCanvas()爲我的遊戲應用程序花費太長時間

public void myDraw(SurfaceHolder holder) { 
    Canvas c = null; 
    long start = System.currentMillis();  
    try { 
     synchronized(holder) { 
      c = holder.lockCanvas(); 
      if (c != null) { 
       c.drawColor(Color.GREEN); 
      }  
     } 
    } finally { 
     if (c != null) { 
      holder.unlockCanvas(c); 
     } 
    } 
    Log.i(TAG, "total time:" + (System.currentMillis() - start)); 
} 

當我運行我的應用程序的方法,從logcat的輸出是:

total time:30 
total time:23 
total time:6 
total time:39 
total time:17 

爲什麼的鎖定/解鎖畫布需要太多時間?有沒有更好的方法來解決我的問題? (即擁有60 fps的應用程序)

謝謝!

回答

6

我有一個類似的FPS問題與三星截獲低FPS。我只得到12FPS,沒有比空白屏幕更多的東西。我發現這個問題與Android在畫布上進行自動縮放並繪製函數有關。 在AndroidManifest.xml如果添加行

<支持屏安卓anyDensity =「真」 >

那麼Android將不會自動縮放畫布和借鑑作用。默認值是「false」,它將啓用自動縮放。 With android:anyDensity="true"我能夠獲得40+ FPS! 所有這一切的缺點是,你現在必須自己做所有的數學來匹配不同的屏幕尺寸。但這不應該那麼難。 希望這可以幫助任何有類似問題的人。我花了5個多小時才弄出了這個小小的雜物。

0

根據我的理解,lockCanvas()可能非常昂貴,具體取決於基礎硬件實現。

目標是爲您提供一個您可以直接訪問的緩衝區。這個緩衝區可以直接存在於圖形硬件中,也可以是OpenGL紋理或其他東西。

現在,如果調用lockCanvas(),系統必須爲您提供該數據的緩衝區,這可能涉及從GPU到內存的數據傳輸以及圖像格式轉換(例如,yuv到rgb)。

一旦完成編輯數據緩衝區,操作必須以相反方式傳回,回到原始的依賴於HW的格式。

所有這一切都可以是相當昂貴,特別是在移動設備:(

一個好方法,以避免上是使用API​​函數(的drawRect()的代替copyRect修改數據() )但它並不總是可能的。