GLSurfaceView queueEvent的作用


使用OpenGL的時候,我們需要一個工作線程來調用OpenGL方法。GLSurfaceView為此創建了一個獨立的渲染線程,這也是所有實現GLSurfaceView.Renderer中的方法(這些方法包裝了調用OpenGL的細節,簡化了開發)的工作線程。所以我們不需要關心線程相關的東西,只需要編寫需要實現的方法即可。

 

基於線程原因,我們不能簡單的在UI線程中調用OpenGL方法,例如,事件分發的方法中我們直接調用Renderer中的方法。除此之外,我們還需要考慮線程安全問題,即同時被UI線程和OpenGL渲染線程讀寫的變量。

 

使用queueEvent(),則完全不必擔心上述問題,因為最終所有方法都是在GLSUrfaceView.Renderer中的方法中調用的,也就是在渲染線程中使用的。

看看源碼中該函數的調用流程:

/**
 * Queue a runnable to be run on the GL rendering thread. This can be used
 * to communicate with the Renderer on the rendering thread.
 * Must not be called before a renderer has been set.
 * @param r the runnable to be run on the GL rendering thread.
 */
public void queueEvent(Runnable r) {
    mGLThread.queueEvent(r);
}

mGLThread即是渲染線程。從注釋中即可知,這個方法是用來和渲染線程進行通信的。

/**
 * Queue an "event" to be run on the GL rendering thread.
 * @param r the runnable to be run on the GL rendering thread.
 */
public void queueEvent(Runnable r) {

    synchronized(sGLThreadManager) {
        mEventQueue.add(r);
        sGLThreadManager.notifyAll();
    }

}

這個函數的核心代碼就上面這兩句。可見,當渲染線程空閑的時候,這個方法可以與渲染線程交互並喚醒渲染線程。

private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();

private void guardedRun() throws InterruptedException {

    Runnable event = null;

    while (true) {
        synchronized (sGLThreadManager) {
            while (true) {
                if (mShouldExit) {
                    return;
                }

                if (! mEventQueue.isEmpty()) {
                    event = mEventQueue.remove(0);
                    break;
                }
                
                ...
                
                if (event != null) {
                    event.run();
                    event = null;
                    continue;
                }    

                ...
                
                view.mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);                
                
                ...
                
                view.mRenderer.onSurfaceChanged(gl, w, h);
                
                ...
                
                view.mRenderer.onDrawFrame(gl);

guardedRun即是渲染線程的工作渲染函數的入口,從上面的函數選摘可知,會在渲染線程的mRenderer方法調用之前調用mEventQueue方法。

queueEvent的典型用法是根據用戶輸入改變mRenderer中的狀態,然后在mRenderer.onDrawFrame中使用新的狀態。

 

參考:http://stackoverflow.com/questions/25388929/android-opengl-queueevent-why

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM