2016-11-20 63 views
0

我是新來的蘋果金屬API和圖形編程的一般。我正在慢慢構建一個遊戲引擎,從UI開始。我的用戶界面基於每個都有自己的子節點列表的節點。因此,如果我有一個帶有三個「按鈕」的子菜單的「菜單」節點,調用render(:MTLDrawable:CommandQueue),菜單將通過向隊列提交一個命令緩衝區將自身呈現給drawable,然後使用相同的方法爲其所有子節點調用相同的方法繪製和隊列,直到整個節點樹已經從上到下渲染。我希望生成一個單獨的子線程來渲染樹中的每個節點 - 我是否可以將每個渲染函數包裝在調度異步調用中?命令隊列本質上是線程安全的嗎?在使用Metal呈現多個對象之前,同時將多個對象渲染爲單個紋理的解決方案是什麼?到目前爲止,在任何Metal教程中看到的所有內容都是一個線程,它使用每個幀的單個命令緩衝區按順序渲染所有內容,在每個幀的末尾調用presentDrawable(),然後調用commit()多線程與金屬

編輯 當我說我想用多線程,它僅適用於命令編碼,而不是執行本身。我不想結束繪製理論菜單中的按鈕,然後由於執行順序錯誤而被菜單背景覆蓋。我只是希望每個對象的渲染操作都被編碼到一個單獨的線程上,然後交給命令隊列。

回答

1

即使您想使用CPU端併發來執行渲染,對每個UI元素使用單獨的命令緩衝區和渲染過程也是極端矯枉過正。我認爲你應該從寫作最簡單的東西開始,然後從那裏進行優化。在CPU成爲瓶頸之前,您可以設置很多狀態併發出大量繪製調用,這就是爲什麼人們以簡單的單線程方法開始的原因。

將工作分派給線程不是免費的。它引入了開銷,而且這種開銷可能會主宰您爲發佈用於繪製任何給定元素的命令所做的工作,尤其是一旦您考慮重複加載和存儲渲染目標所需的帶寬。

一旦你確定你是CPU綁定的(可能一旦你發出數以千計的繪製調用每幀),你可以看看跨線程分裂編碼與MTLParallelRenderCommandEncoder,或多路徑解決方案。但是,在你到達點之前,你可能應該引入某種批處理系統,它可以消除你的UI元素髮出繪製調用的責任,因爲儘管從OOP的角度來看這看起來很整潔,但它可能是一個很大的建築失誤如果你關心性能的規模。

舉一個例子,您可以看看流行的dear imgui項目的後端渲染器的this Metal implementation,以瞭解如何構建在UI渲染上下文中繪製調用批處理的系統。