2013-03-02 80 views
5

所以,當你調用opengl函數,如glDraw或gLBufferData,它是否會導致程序的線程停止並等待GL完成調用?做opengl函數會導致主線程凍結?

如果沒有,那麼GL如何處理調用像glDraw這樣的重要函數,然後立即改變一個影響繪製調用的設置?

+0

是的,他們通常會阻止功能,即時通訊不確定,因爲我以前沒有做過,但我認爲它會運行在一個循環和更新只是爲了保持幀率。 – PsyKzz 2013-03-02 19:16:27

+0

@MattPsyK:不引入同步點的OpenGL函數不會阻塞。 – datenwolf 2013-03-02 19:23:38

+0

我的不好,做出了一些假設。 – PsyKzz 2013-03-02 20:09:54

回答

6

不,他們(大部分)不。大多數GL函數在使用時會被緩衝,並在以後實際執行。這意味着您不能將CPU和GPU視爲兩個處理器同時工作。通常情況下,CPU會執行一系列緩存的GL函數,並且一旦將它們傳遞給GPU,它就會執行它們。這意味着您無法可靠地控制執行特定GL功能所需的時間,只需比較其執行前後的時間。

如果你想這樣做,你需要先運行一個glFinish(),以便它實際上等待所有先前緩衝的GL調用執行,然後你可以開始計數,執行你想要進行基準測試的調用,再次調用glFinish以確保執行這些調用,然後完成基準測試。

另一方面,我說「主要」。這是因爲閱讀功能實際上需要與GPU同步以顯示真實結果,因此,在這種情況下,他們會等待並凍結主線程。

編輯:我想解釋自己回答你問第二個問題,但以防萬一:所有來電都被緩衝的事實,有可能使一場平局先完成,再後來更改設置爲succesive電話

+0

所以閱讀函數隱式調用glFinish()? – 2013-03-02 19:58:24

+0

@DanWebster:[\ *咳嗽\ *](http://www.opengl.org/wiki/Synchronization) – 2013-03-02 22:52:23

1

它嚴格依賴於有問題的OpenGL調用和OpenGL狀態。當你進行OpenGL調用時,實現首先在內部對它們進行排隊,然後對調用程序的執行進行異步執行。 OpenGL的一個重要概念是同步點。那些工作隊列中的操作需要OpenGL調用阻塞,直到滿足特定條件。 OpenGL對象(紋理,緩衝對象等)純粹是抽象的,並且通過指定客戶端程序中對象的句柄始終對數據進行指定,該對象在調用引用此對象的OpenGL函數時具有該句柄。所以就拿這個序列:

glBindTexture(GL_TEXTURE_2D, texID); 

glTexImage2D(..., image_1); 
draw_textured_quad(); 

glTexImage2D(..., image_2); 
draw_textured_quad(); 

第一draw_textured_quad甚至可能長東西已經繪之前返回。但是,通過調用OpenGL,可以創建一個內部引用,以指向紋理當前擁有的數據。因此,當第二次調用glTexImage2D時,可能會在繪製第一個四元組之前發生,OpenGL必須在內部創建一個輔助紋理對象,該對象將變爲紋理texID並被第二個調用draw_textured_quad使用。如果調用了glTexSubImage2D,則甚至需要對其進行修改。

如果調用的結果修改客戶端內存並取決於先前OpenGL調用生成的數據,則OpenGL調用將僅阻塞。換句話說,在進行OpenGL調用時,OpenGL實現會在內部生成一個依賴關係樹來跟蹤依賴於什麼的依賴關係樹。當一個同步點必須阻塞它時,至少會阻塞,直到滿足所有的依賴關係。