版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.10.01 |
前言
OpenGL ES是一個強大的圖形庫,是跨平臺的圖形API,屬于OpenGL的一個簡化版本。iOS系統(tǒng)可以利用OpenGL ES將圖像數(shù)據(jù)直接送入到GPU進行渲染,這樣避免了從CPU進行計算再送到顯卡渲染帶來的性能的高消耗,能帶來來更好的視頻效果和用戶體驗。接下來幾篇就介紹下iOS 系統(tǒng)的 OpenGL ES框架。感興趣的可以看上面幾篇。
1. OpenGL ES 框架詳細解析(一) —— 基本概覽
2. OpenGL ES 框架詳細解析(二) —— 關(guān)于OpenGL ES
3. OpenGL ES 框架詳細解析(三) —— 構(gòu)建用于iOS的OpenGL ES應(yīng)用程序的清單
4. OpenGL ES 框架詳細解析(四) —— 配置OpenGL ES的上下文
5. OpenGL ES 框架詳細解析(五) —— 使用OpenGL ES和GLKit進行繪制
6. OpenGL ES 框架詳細解析(六) —— 繪制到其他渲染目的地
7. OpenGL ES 框架詳細解析(七) —— 多任務(wù),高分辨率和其他iOS功能
8. OpenGL ES 框架詳細解析(八) —— OpenGL ES 設(shè)計指南
Tuning Your OpenGL ES App - 調(diào)整您的OpenGL ES應(yīng)用程序
iOS中OpenGL ES應(yīng)用程序的性能與OS X或其他桌面操作系統(tǒng)中OpenGL的性能不同。 雖然功能強大的計算設(shè)備,基于iOS設(shè)備的桌面或筆記本電腦不具備內(nèi)存或CPU功能。 嵌入式GPU通過與典型的臺式機或筆記本電腦GPU可能使用的算法不同,優(yōu)化了較低的內(nèi)存和功耗。 低效渲染圖形數(shù)據(jù)可能會導(dǎo)致較差的幀速率,或顯著降低基于iOS設(shè)備的電池壽命。
后面的章節(jié)介紹了許多提高應(yīng)用程序性能的技術(shù); 本章涵蓋整體策略。 除非另有說明,否則本章中的建議涉及OpenGL ES的所有版本。
Debug and Profile Your App with Xcode and Instruments - 使用Xcode和儀器調(diào)試和配置您的應(yīng)用程序
在各種設(shè)備上的各種場景中測試其性能之前,請勿優(yōu)化應(yīng)用程序。 Xcode
和Instruments
包括幫助您確定應(yīng)用程序中的性能和正確性問題的工具。
- 監(jiān)視Xcode調(diào)試量表,以了解性能的一般概述。 當(dāng)您從Xcode運行應(yīng)用程序時,可以看到這些儀表,以便在開發(fā)應(yīng)用程序時輕松發(fā)現(xiàn)性能變化。
- 使用儀器中的OpenGL ES分析和OpenGL ES驅(qū)動程序工具,以更深入地了解運行時性能。 獲取關(guān)于您的應(yīng)用程序的資源使用和符合OpenGL ES最佳做法的詳細信息,并選擇性地禁用部分圖形管道,以便您可以確定哪個部分是您的應(yīng)用程序中的重大瓶頸。 有關(guān)更多信息,請參閱 Instruments User Guide。
- 在Xcode中使用OpenGL ES Frame Debugger和性能分析器工具來精確定位性能和渲染問題。 捕獲用于渲染和呈現(xiàn)單個幀的所有OpenGL ES命令,然后遍歷這些命令,以查看每個對OpenGL ES狀態(tài),綁定的資源和輸出幀緩沖區(qū)的影響。 您還可以查看著色器源代碼,編輯它,并查看更改如何影響渲染的圖像。 在支持OpenGL ES 3.0的設(shè)備上,F(xiàn)rame Debugger還指出哪些繪圖調(diào)用和著色器指令對渲染時間最有貢獻。 有關(guān)這些工具的更多信息,請參閱Xcode OpenGL ES Tools Overview。
1. Watch for OpenGL ES Errors in Xcode and Instruments - 在Xcode和Instruments中觀察OpenGL ES錯誤
當(dāng)您的應(yīng)用程序使用OpenGL ES API
錯誤(例如,通過請求操作底層硬件無法執(zhí)行)時,會出現(xiàn)OpenGL ES錯誤。 即使您的內(nèi)容正確呈現(xiàn),這些錯誤也可能表明性能問題。 檢查OpenGL ES錯誤的傳統(tǒng)方法是調(diào)用glGetError
函數(shù); 但是,重復(fù)調(diào)用此功能可能會顯著降低性能。 應(yīng)該使用上述工具來測試錯誤:
- 在Instruments中分析您的應(yīng)用程序時,請參閱OpenGL ES Analyzer工具的詳細信息窗格,查看錄制時報告的任何OpenGL ES錯誤。
- Xcode中調(diào)試應(yīng)用程序時,捕獲一個幀以檢查用于生成它的繪圖命令,以及執(zhí)行這些命令時遇到的任何錯誤。
當(dāng)遇到OpenGL ES錯誤時,還可以配置Xcode以停止程序執(zhí)行。 (請參閱Adding an OpenGL ES Error Breakpoint
。)
2. Annotate Your OpenGL ES Code for Informative Debugging and Profiling - 注釋您的OpenGL ES代碼進行信息調(diào)試和分析
您可以通過將OpenGL ES命令組織到邏輯組中并為OpenGL ES對象添加有意義的標簽來使調(diào)試和分析更加高效。 這些組和標簽出現(xiàn)在Xcode中的OpenGL ES Frame Debugger
中,如下圖所示,在儀器中的OpenGL ES Analyzer
中。 要添加組和標簽,請使用EXT_debug_marker
和EXT_debug_label
擴展。
當(dāng)您有一系列繪圖命令代表一個有意義的操作 - 例如繪制游戲角色時,您可以使用標記將其分組進行調(diào)試。 下面代碼顯示了如何對紋理,程序,頂點數(shù)組和場景的單個元素繪制調(diào)用。 首先,它調(diào)用glPushGroupMarkerEXT
函數(shù)來提供有意義的名稱,然后發(fā)出一組OpenGL ES命令。 最后,它關(guān)閉組,并調(diào)用glPopGroupMarkerEXT
函數(shù)。
// Using a debug marker to annotate drawing commands
glPushGroupMarkerEXT(0, "Draw Spaceship");
glBindTexture(GL_TEXTURE_2D, _spaceshipTexture);
glUseProgram(_diffuseShading);
glBindVertexArrayOES(_spaceshipMesh);
glDrawElements(GL_TRIANGLE_STRIP, 256, GL_UNSIGNED_SHORT, 0);
glPopGroupMarkerEXT();
您可以使用多個嵌套標記來在復(fù)雜場景中創(chuàng)建有意義的組的層次結(jié)構(gòu)。 當(dāng)您使用GLKView
類繪制OpenGL ES內(nèi)容時,它會自動創(chuàng)建一個“渲染”組,其中包含繪圖方法中的所有命令。 您創(chuàng)建的任何標記都嵌套在此組內(nèi)。
標簽為OpenGL ES對象提供有意義的名稱,例如紋理,著色器程序和頂點數(shù)組對象。 調(diào)用glLabelObjectEXT
函數(shù)為對象提供調(diào)試和分析時要顯示的名稱。 下面代碼說明了使用這個函數(shù)來標記一個頂點數(shù)組對象。 如果您使用GLKTextureLoader類加載紋理數(shù)據(jù),它會自動標記其使用其文件名創(chuàng)建的OpenGL ES紋理對象。
// Using a debug label to annotate an OpenGL ES object
glGenVertexArraysOES(1, &_spaceshipMesh);
glBindVertexArrayOES(_spaceshipMesh);
glLabelObjectEXT(GL_VERTEX_ARRAY_OBJECT_EXT, _spaceshipMesh, 0, "Spaceship");
General Performance Recommendations - 一般性能推薦
使用常識來指導(dǎo)您的性能調(diào)整工作。 例如,如果您的應(yīng)用程序每幀僅繪制幾十個三角形,更改提交頂點數(shù)據(jù)的方式將不太可能提高其性能。 尋找為您的努力提供最佳性能的優(yōu)化。
1. Redraw Scenes Only When the Scene Data Changes - 僅當(dāng)場景數(shù)據(jù)更改時才重畫場景
您的應(yīng)用程序應(yīng)該等待,直到場景中的某些內(nèi)容發(fā)生變化才能渲染新的幀 核心動畫緩存呈現(xiàn)給用戶的最后一張圖像,并繼續(xù)顯示,直到出現(xiàn)新的幀。
即使您的數(shù)據(jù)發(fā)生變化,也不需要以硬件處理命令的速度渲染幀。 對于用戶來說,速度較慢但固定的幀速率通常比快速但可變的幀速率更平滑。 每秒30幀的固定幀速率對于大多數(shù)動畫是足夠的,并且有助于降低功耗。
2. Disable Unused OpenGL ES Features - 禁用未使用的OpenGL ES功能
最好的計算是您的應(yīng)用程序從未執(zhí)行的計算。 例如,如果結(jié)果可以預(yù)先計算并存儲在模型數(shù)據(jù)中,則可以避免在運行時執(zhí)行該計算。
如果您的應(yīng)用程序是針對OpenGL ES 2.0或更高版本編寫的,請勿創(chuàng)建一個具有大量開關(guān)和條件的單一著色器,以執(zhí)行應(yīng)用程序渲染場景所需的每個任務(wù)。 相反,編譯多個著色器程序,每個著色器程序執(zhí)行一個特定的,重點任務(wù)。
如果您的應(yīng)用程序使用OpenGL ES 1.1,請禁用任何不需要渲染場景的固定功能操作。 例如,如果您的應(yīng)用程序不需要照明或混合,請禁用這些功能。 同樣,如果您的應(yīng)用程序僅繪制2D模型,則應(yīng)禁用霧度和深度測試。
3. Simplify Your Lighting Models - 簡化您的照明模型
這些準則既適用于OpenGL ES 1.1中的固定功能照明,又適用于您在OpenGL ES 2.0或更高版本中的自定義著色器中使用的基于著色器的照明計算。
為您的應(yīng)用程序使用最少的燈和最簡單的照明類型。 考慮使用定向燈而不是點光源,點光源這需要更多的計算。 著色器應(yīng)在模型空間中執(zhí)行照明計算; 在更復(fù)雜的照明算法中,考慮在著色器中使用更簡單的照明方程。
預(yù)先計算您的照明,并將顏色值存儲在可通過片段處理進行采樣的紋理中。
Use Tile-Based Deferred Rendering Efficiently - 有效地使用基于平鋪的延遲渲染
iOS設(shè)備中使用的所有GPU都使用基于瓦片的延遲渲染(TBDR)。 當(dāng)您調(diào)用OpenGL ES函數(shù)向硬件提交呈現(xiàn)命令時,這些命令將被緩沖,直到累積了大量命令。 在呈現(xiàn)renderbuffer
或刷新命令緩沖區(qū)之前,硬件不會開始處理頂點和陰影像素。 然后,它們將這些命令作為單個操作,通過將幀緩沖區(qū)劃分為圖塊,然后為每個圖塊繪制一次命令,每個圖塊只渲染其中可見的圖元。 (GLKView類在繪圖方法返回后呈現(xiàn)renderbuffer,如果使用CAEAGLLayer
類創(chuàng)建自己的renderbuffer來顯示,則使用OpenGL ES上下文的presentRenderbuffer:方法來呈現(xiàn)它,glFlush
或glFinish
函數(shù)刷新命令緩沖區(qū)。
由于瓦片內(nèi)存是GPU硬件的一部分,渲染過程的一部分(如深度測試和混合)在時間和能量使用方面比傳統(tǒng)的基于流的GPU架構(gòu)更為高效。 因為這個架構(gòu)一次處理整個場景的所有頂點,GPU可以在片段被處理之前執(zhí)行隱藏的表面去除。 不可見的像素在沒有采樣紋理或執(zhí)行片段處理的情況下被丟棄,大大減少了GPU必須執(zhí)行的渲染圖塊的計算。
在傳統(tǒng)的基于流的渲染器上有用的渲染策略在iOS圖形硬件上具有高性能成本。 遵循以下準則可以幫助您的應(yīng)用在TBDR
硬件上表現(xiàn)良好。
1. Avoid Logical Buffer Loads and Stores - 避免邏輯緩沖區(qū)負載和存儲
當(dāng)TBDR圖形處理器開始渲染圖塊時,必須首先將幀緩沖區(qū)的該部分的內(nèi)容從共享內(nèi)存?zhèn)鬏數(shù)紾PU上的瓦片內(nèi)存。 這種內(nèi)存?zhèn)鬏敚Q為邏輯緩沖區(qū)負載,需要時間和精力。 大多數(shù)情況下,幀緩沖區(qū)的以前內(nèi)容對于繪制下一幀是不必要的。 當(dāng)您開始渲染新的幀時,通過調(diào)用glClear
避免加載先前緩沖區(qū)內(nèi)容帶來的性能成本。
類似地,當(dāng)GPU完成繪制瓦片時,它必須將瓦片的像素數(shù)據(jù)寫回共享存儲器。 這種稱為邏輯緩沖存儲器的傳輸也具有性能成本。 對于每個繪制的畫面,至少需要進行一次這樣的轉(zhuǎn)移,屏幕上顯示的彩色渲染緩沖區(qū)必須被傳送到共享存儲器,以便Core Animation可以呈現(xiàn)。 在渲染算法中使用的其他幀緩沖附件(例如,深度,模板和多采樣緩沖區(qū))不需要保留,因為它們的內(nèi)容將在下一幀繪制后重新創(chuàng)建。 OpenGL ES會自動將這些緩沖區(qū)存儲到共享內(nèi)存中,從而導(dǎo)致性能成本 - 除非您明確使其無效。 要使緩沖區(qū)無效,請使用OpenGL ES 3.0中的glInvalidateFramebuffer
命令或OpenGL ES 1.1或2.0中的glDiscardFramebufferEXT
命令。 (有關(guān)詳細信息,請參閱Discard Unneeded Renderbuffers),當(dāng)您使用GLKView類提供的基本繪圖循環(huán)時,它會自動使任何可繪制的深度,模板或多重采樣緩沖區(qū)無效。
如果切換渲染目的地,也會發(fā)生邏輯緩沖區(qū)存儲和加載操作。 如果渲染到紋理,然后渲染到視圖的幀緩沖區(qū),然后再次渲染到相同的紋理,則紋理的內(nèi)容必須在共享內(nèi)存和GPU之間重復(fù)傳輸。 批量繪制操作,以便將所有繪制到渲染目的地一起完成。 當(dāng)切換幀緩沖區(qū)(使用glBindFramebuffer
或glFramebufferTexture2D
函數(shù)或bindDrawable
方法)時,會使不需要的幀緩沖附件無效,以避免導(dǎo)致邏輯緩沖區(qū)存儲。
2. Use Hidden Surface Removal Effectively - 有效地使用隱藏的表面去除
TBDR
圖形處理器自動使用深度緩沖區(qū)為整個場景執(zhí)行隱藏的表面刪除,確保每個像素只運行一個片段著色器。 用于減少片段處理的傳統(tǒng)技術(shù)不是必需的。 例如,通過深度從前到后排序?qū)ο蠡蛟Z有效地復(fù)制了GPU完成的工作,浪費了CPU時間。
當(dāng)混合或Alpha
測試啟用時,或者片段著色器使用丟棄指令或?qū)懭?code>gl_FragDepth輸出變量時,GPU無法執(zhí)行隱藏的表面刪除。 在這些情況下,GPU無法使用深度緩沖區(qū)來確定片段的可見性,因此必須對覆蓋每個像素的所有圖元運行片段著色器,從而大大增加渲染幀所需的時間和精力。 為了避免這種性能成本,最小化混合使用,丟棄指令和深度寫入。
如果您無法避免混合,Alpha測試或丟棄說明,請考慮以下策略來降低其性能影響:
- 按不透明度排序?qū)ο蟆?先繪制不透明物體。 接下來,使用丟棄操作(或OpenGL ES 1.1中的Alpha測試)繪制需要著色器的對象。 最后,繪制alpha混合對象。
- 修剪需要混合或丟棄指令的對象以減少處理的碎片數(shù)量。 例如,如下圖所示,不是繪制一個正方形來渲染包含大部分空白空間的2D精靈紋理,而是繪制一個更貼近圖像形狀的多邊形。 附加頂點處理的性能成本遠低于運行片段著色器,運行片段著色器的結(jié)果將不被使用。
- 在片段著色器中盡早使用丟棄指令,以避免執(zhí)行結(jié)果未使用的計算。
- 不使用alpha測試或丟棄指令來殺死像素,而是將alpha混合與Alpha設(shè)置為零。 彩色幀緩沖區(qū)未被修改,但圖形硬件仍然可以使用它執(zhí)行的任何Z緩沖區(qū)優(yōu)化。 這樣做會改變存儲在深度緩沖區(qū)中的值,因此可能需要對透明基元進行前后排序。
- 如果您的表現(xiàn)受到不可避免的丟棄操作限制,請考慮“Z-Prepass”渲染策略。 使用簡單的片段著色器渲染場景,只包含丟棄邏輯(避免昂貴的照明計算)來填充深度緩沖區(qū)。 然后,使用
GL_EQUAL
深度測試功能和您的照明著色器再次渲染您的場景。 雖然多次渲染通常會導(dǎo)致性能損失,但是這種方法可以產(chǎn)生比涉及大量丟棄操作的單遍渲染更好的性能。
3. Group OpenGL ES Commands for Efficient Resource Management - OpenGL ES命令用于高效的資源管理
上述內(nèi)存帶寬和計算節(jié)省在處理大型場景時表現(xiàn)最佳。 但是當(dāng)硬件接收到需要渲染較小場景的OpenGL ES命令時,渲染器的效率就大大降低。 例如,如果您的應(yīng)用程序使用紋理渲染批次的三角形,然后修改紋理,則OpenGL ES實現(xiàn)必須立即刷新這些命令,或者重復(fù)紋理,這兩個選項會有效地使用硬件。 類似地,如果它們會改變該幀緩沖區(qū),從幀緩沖區(qū)讀取像素數(shù)據(jù)的任何嘗試都要求處理前面的命令。
為了避免這些性能損失,請組織您的OpenGL ES調(diào)用序列,以便一起執(zhí)行每個渲染目標的所有繪圖命令。
Minimize the Number of Drawing Commands - 最小化繪圖命令的數(shù)量
每當(dāng)您的應(yīng)用程序提交要由OpenGL ES處理的圖元時,CPU將準備圖形硬件的命令。 如果您的應(yīng)用程序使用許多glDrawArrays
或glDrawElements
調(diào)用來渲染場景,則其性能可能受到CPU資源的限制,而不會完全利用GPU。
為了減少這種開銷,尋找將渲染整合到較少繪圖調(diào)用中的方法。 有用的策略包括:
- 將多個基元合并成單個三角形條,如Use Triangle Strips to Batch Vertex Data中所述。 為獲得最佳效果,請合并在緊密的空間附近繪制的圖元。 大量,蔓延的模型更難以有效地剔除當(dāng)他們在幀中不可見時。
- 創(chuàng)建紋理地圖集以使用相同紋理圖像的不同部分繪制多個圖元,如Combine Textures into Texture Atlases中所述。
- 使用實例繪制來渲染許多類似的對象,如下所述。
1. Use Instanced Drawing to Minimize Draw Calls - 使用實例化繪圖來最小化繪制調(diào)用
實例繪制命令允許您使用單個繪圖調(diào)用多次繪制相同的頂點數(shù)據(jù)。 代替使用CPU時間來設(shè)置網(wǎng)格的不同實例(如位置偏移,變換矩陣,顏色或紋理坐標)之間的變化,并為每個實例繪制繪制命令,將實例變體的處理移動到著色器代碼中 在GPU上運行
重復(fù)使用的頂點數(shù)據(jù)是實例繪制的主要候選者。 例如,下面代碼中的代碼在場景中的多個位置繪制一個對象。 然而,許多glUniform
和glDrawArrays
調(diào)用增加了CPU開銷,從而降低了性能。
// Drawing many similar objects without instancing
for (x = 0; x < 10; x++) {
for (y = 0; y < 10; y++) {
glUniform4fv(uniformPositionOffset, 1, positionOffsets[x][y]);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
}
}
采用實例化繪圖需要兩個步驟:首先,如上所述替換循環(huán),單次調(diào)用glDrawArraysInstanced
或glDrawElementsInstanced
。 這些調(diào)用與glDrawArrays
或glDrawElements
相同,但附加參數(shù)指示要繪制的實例數(shù)(上面代碼中的示例為100)。 其次,選擇和實現(xiàn)OpenGL ES為您的頂點著色器使用每個實例信息提供的兩個策略之一。
使用著色器實例ID策略,您的頂點著色器會導(dǎo)出或查找每個實例信息。 每次頂點著色器運行時,其gl_InstanceID
內(nèi)置變量都包含一個標識當(dāng)前正在繪制的實例的數(shù)字。 使用此數(shù)字計算著色器代碼中的位置偏移,顏色或其他每個實例的變化,或者查找統(tǒng)一數(shù)組或其他大容量存儲中的每個實例信息。 例如,下面代碼使用此技術(shù)來繪制位于10 x 10
網(wǎng)格中的100個網(wǎng)格實例。
// OpenGL ES 3.0 vertex shader using gl_InstanceID to compute per-instance information
#version 300 es
in vec4 position;
uniform mat4 modelViewProjectionMatrix;
void main()
{
float xOffset = float(gl_InstanceID % 10) * 0.5 - 2.5;
float yOffset = float(gl_InstanceID / 10) * 0.5 - 2.5;
vec4 offset = vec4(xOffset, yOffset, 0, 0);
gl_Position = modelViewProjectionMatrix * (position + offset);
}
通過實例化的數(shù)組策略,您可以將每個實例信息存儲在頂點數(shù)組屬性中。 您的頂點著色器可以訪問該屬性以使用每個實例信息。 調(diào)用glVertexAttribDivisor
函數(shù)來指定OpenGL ES繪制每個實例時該屬性的進度。 下面兩段代碼的第一段演示了為實例繪制設(shè)置一個頂點數(shù)組,第二段顯示了相應(yīng)的著色器。
// Using a vertex attribute for per-instance information
#define kMyInstanceDataAttrib 5
glGenBuffers(1, &_instBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _instBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(instData), instData, GL_STATIC_DRAW);
glEnableVertexAttribArray(kMyInstanceDataAttrib);
glVertexAttribPointer(kMyInstanceDataAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribDivisor(kMyInstanceDataAttrib, 1);
// OpenGL ES 3.0 vertex shader using instanced arrays
#version 300 es
layout(location = 0) in vec4 position;
layout(location = 5) in vec2 inOffset;
uniform mat4 modelViewProjectionMatrix;
void main()
{
vec4 offset = vec4(inOffset, 0.0, 0.0)
gl_Position = modelViewProjectionMatrix * (position + offset);
}
實例繪圖在核心OpenGL ES 3.0 API
和OpenGL ES 2.0
中通過EXT_draw_instanced
和EXT_instanced_arrays
擴展提供。
Minimize OpenGL ES Memory Usage - 最小化OpenGL ES內(nèi)存使用
您的iOS應(yīng)用程序與系統(tǒng)和其他iOS應(yīng)用程序共享主內(nèi)存。 為OpenGL ES分配的內(nèi)存減少了您的應(yīng)用程序中可用于其他用途的內(nèi)存。 考慮到這一點,只需分配您需要的內(nèi)存,并在應(yīng)用程序不再需要它時立即釋放它。 這里有幾種方法可以節(jié)省內(nèi)存:
- 將圖像加載到OpenGL ES紋理后,釋放原始圖像。
- 只有在您的應(yīng)用程序需要時才分配深度緩沖區(qū)。
- 如果您的應(yīng)用程序不需要一次所有資源,只需加載一部分項目。 例如,一個游戲可能被分為幾個級別; 每個都加載適合更嚴格資源限制的總資源的子集。
iOS中的虛擬內(nèi)存系統(tǒng)不使用交換文件。 當(dāng)檢測到低內(nèi)存條件時,虛擬內(nèi)存不會將易失性頁面寫入磁盤,而是釋放非易失性內(nèi)存,為運行中的應(yīng)用程序提供所需的內(nèi)存。 您的應(yīng)用程序應(yīng)盡可能少地使用內(nèi)存,并準備處理對應(yīng)用程序不是必需的對象。 針對低內(nèi)存條件的響應(yīng)在iOS的App Programming Guide for iOS中有詳細介紹。
Be Aware of Core Animation Compositing Performance - 要注意Core Animation合成性能
Core Animation
將renderbuffers的內(nèi)容與視圖層次結(jié)構(gòu)中的任何其他圖層相結(jié)合,無論這些圖層是用OpenGL ES,Quartz還是其他圖形庫繪制。 這很有幫助,因為這意味著OpenGL ES是核心動畫的first - class citizen
。 然而,將OpenGL ES內(nèi)容與其他內(nèi)容混合需要時間; 當(dāng)使用不當(dāng)時,您的應(yīng)用程序可能執(zhí)行得太慢,無法達到交互式幀速率。
為了獲得最佳性能,您的應(yīng)用程序應(yīng)該僅依靠OpenGL ES來呈現(xiàn)您的內(nèi)容。 將保存OpenGL ES內(nèi)容的視圖設(shè)置為與屏幕匹配,確保其opaque屬性設(shè)置為YES(GLKView對象的默認值),并且不顯示其他視圖或Core Animation圖層。
如果將其渲染為在其他圖層之上合成的Core Animation圖層,則使CAEAGLLayer
對象不透明減少但不會消除性能成本。 如果您的CAEAGLLayer對象在圖層層次結(jié)構(gòu)中的層之下混合在一起,則renderbuffer
的顏色數(shù)據(jù)必須是由Core Animation正確合成的預(yù)乘法alpha
格式。 將OpenGL ES內(nèi)容混合在其他內(nèi)容之上具有嚴重的性能損失。
后記
未完,待續(xù)~~~