異步場景加載基本流程驗證完成。
此方法理論上只需要使用3個Vulkan的指令隊列。
對于移動平臺上的Vulkan,指令隊列數量極少,比如Adreno640只有3個指令隊列可用。所以理論上這一設計也適合目前的移動平臺使用。
(1) graphic_queue:用于完成當前場景的渲染。
(2) load_queue:用于在當前場景異步加載結點,或更新結點資源,比如ui貼圖,文本。
(3) back_load_queue:用于在獨立的線程中異步加載完整場景。
加載場景分別使用load_queue和back_load_queue兩個隊列的原因是,在back_load_queue加載場景時,當前場景可能需要load_queue來異步更新ui之類的資源。
graphic_queue只進行渲染相關或耗時較短的工作,對于耗時可能跨越多幀的操作,比如ui貼圖更新,文本更新,通過異步任務隊列,交由load_queue處理,load_queue處理完成后,通過同步任務通知graphic_queue,完成資源切換。
graphic_queue使用線程池中的多個用于執行單幀任務(Frame Graph)的線程并行記錄渲染指令。
視頻解釋:
(1)
對于異步加載一個完整的場景
通過按鈕廣播點擊消息給腳本管線對象
腳本管線對象調用腳本,通過viewer對象創建新線程加載場景。
新線程加載場景完成后,通過無鎖隊列添加同步任務到同步任務隊列。
在同步任務中反轉場景(反轉場景實際上只是管線對象內部很少幾個變量的交換,耗時極小),進入剛剛加載的場景。(同步任務,確保線程安全,并且如果沒有需要執行的同步任務,幾乎不存在計算代價)
(2)
對于同一場景添加單個或少量結點,載入量較小,沒必要單獨開一個線程,將加載任務放入viewer對象初始化時創建的用于執行跨越多幀的小任務的異步任務隊列,加載結點完成后,通過無鎖隊列添加同步任務到同步任務隊列 ,在同步任務(只是簡單的幾個變量交換,耗時極小)中將結點安全地放入當前場景。
對于類似UI貼圖或文本的更新,通過方法2進行。
