2010-09-14 56 views
2

我想要獲得一個相當簡單的openGL ES 1程序,在那裏的兩臺設備上運行平滑穩固的60fps,並且我陷入了HTC的渴望。手機本身速度快,速度快,功能強大,整體使用起來很輕鬆;然而,我似乎無法用OpenGL在60fps全屏顯示任何東西。在與我的應用程序長時間陷入困境後,我決定使用代碼直接從文檔中創建示例代碼來測試應用程序。HTC Desire特定的OpenGL ES 1幀率 - 無法正確對比

這是我在做什麼。使用GLSurfaceView簡單初始化代碼。我有三個版本的onDrawFrame,都很簡單。一個是空的。一個只包含glClear。一個只包含足夠的狀態來繪製一個全屏四元組。跟蹤時間前後。在我的程序中除了我的GLSurfaceView以外沒有任何視圖。我無法解釋我得到的時間。

在所有情況下,onDrawFrame函數本身總是在2ms以下完成。但很多時候,onDrawFrame在30〜40ms之前不會再被調用,我的幀速率一直降到30fps或更低。 我用空的onDrawFrame獲得50fps,用glClear獲得45,用quad獲得35。 相同的代碼在HTC Magic上以60 fps運行,在Samsung Galaxy S上運行在Sharp ISO1上。因爲它的屏幕,索尼Experia X10以30fps的速度上限。我已經在HTC Magic上以60fps的速度完成了更爲複雜的場景,這是與Desire相比動力不足。我沒有Nexus One方便測試。 當然,我除了緩衝區交換阻塞幾毫秒。但它只是一直跳過幀。

試圖找出手機在做什麼外部的onDrawFrame處理程序,我試圖使用Debug.startMethodTracing。我無法通過跟蹤來反映手機花費在循環中的實際時間。 在onDrawFrame結束時,我使用startMethodTracing,然後將當前時間(SystemClock.uptimeMillis)保存在變量中。在下一個函數開始時,我記錄了函數上次退出後的時間差,以及stopMethodTracing。這會一遍又一遍地被調用,所以我安排停止,一旦我得到一個40 + ms暫停迭代的跟蹤。 生成的曲線上的時間標度小於2毫秒,就好像系統在我的程序之外花費了38毫秒。

我嘗試了很多東西。枚舉EGL配置並依次嘗試它們。只是爲了看看它是否改變了任何東西,我在每幀需要重繪的髒方案時切換到渲染。無濟於事。無論我做什麼,交換緩衝區14到16ms的預期差距在一半時間內將花費30 + ms,無論我做什麼,似乎設備都在等待兩次屏幕刷新。設備上的ps顯示我的應用程序約爲10%cPU,而System_server爲35%。當然,我也嘗試了明顯的,殺死其他進程,重新啓動設備......我總是得到相同的確切結果。

我沒有畫布畫的問題。

有誰知道爲什麼慾望(和僅限於慾望)的行爲是這樣的?

僅供參考,這裏是我的測試代碼如下所示:

public class GLTest extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mGLView = new GLSurfaceView(this); 
     mGLView.setRenderer(new ClearRenderer()); 
     setContentView(mGLView); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mGLView.onPause(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mGLView.onResume(); 
    } 

    private GLSurfaceView mGLView; 
} 

class ClearRenderer implements GLSurfaceView.Renderer { 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {} 
    public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } 

    long start; 
    long end; 
    public void onDrawFrame(GL10 gl) 
    { 
    start = System.currentTimeMillis(); 
    if (start - end > 20) 
     Log.e("END TO START", Long.toString(start - end)); 
    //  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    end = System.currentTimeMillis(); 
    if (end - start > 15) 
     Log.e("START TO END", Long.toString(end - start)); 
    } 
} 

回答

0

也許我已經得到了答案:OpenGL驅動程序可以決定做實際呈現的很大一部分在後面的步驟。此步驟默認在之後完成,似乎是離開此方法後設備閒置的原因。好消息是,您可以將此步驟直接納入您的方法中:只需致電gl.glFinish() - 完成最終渲染並返回。之後不應有空閒時間。然而,壞消息是,實際上沒有閒暇時間,所以你將無法得到這段時間(我對幻燈片的渲染速度有一些幻想......現在我必須面對我的真實緩慢執行;))。你應該知道的關於glFinish:似乎有一個os級別的bug會導致某些htc設備出現死鎖(如願望),根據我的理解,它仍然存在於2.2。如果動畫運行幾個小時,似乎就會發生。然而,在網上存在一個修補的opengl表面視圖實現,你可以用它來避免這個問題。不幸的是,我現在沒有鏈接,但你應該能夠通過谷歌找到它(對不起!)。可能有一些方法可以使用在glFinish()中花費的時間:對於某些(全部?)部分,它可能是gpu活動,因此cpu可以自由地執行其他處理。

+1

你可能想考慮使用文本格式來使這個答案更容易閱讀。 – 2012-12-09 16:49:17

1

你應該看看這個http://www.google.com/events/io/2010/sessions/writing-real-time-games-android.html

他建議你保持幀率30幀60fps的不是。

+0

我很抱歉,但建議我完全不理會這個問題,根本不回答這個問題。我不是在寫一款遊戲,雖然30fps對於大多數實時遊戲都是足夠的,但我並沒有可玩性問題,但具有平滑性:我的動畫在30fps時看起來仍然不穩定,而看起來很平滑。30fps顯然不足以滿足我的情況。 – Jean 2010-12-24 04:52:55

+0

感謝這個鏈接 - 我認爲這是真正的答案TBH。第一代手機用於低聚場景的頻率爲60fps,較新的手機似乎停留在30fps最大,但在更大的屏幕上。 – richq 2011-01-14 16:53:01

+0

加上,今天這是一個有點舊的視頻(2010年),所以它不僅僅是可取的,但android編舞者將開始注意到,如果用戶界面運行在低於​​60fps .. – Ewoks 2013-02-20 09:59:47