多任務(wù),高分辨率和其他iOS功能
Implementing a Multitasking-Aware OpenGL ES App使用OpenGL ES的許多方面是平臺中立的,但是在iOS上使用OpenGL ES的一些細(xì)節(jié)特別考慮徒溪。特別是琅关,使用OpenGL ES的iOS應(yīng)用程序必須正確處理多任務(wù),或者在移動到后臺時可能會被終止旦委。在為iOS設(shè)備開發(fā)OpenGL ES內(nèi)容時苇瓣,您還應(yīng)該考慮顯示分辨率和其他設(shè)備功能尉间。
實(shí)現(xiàn)多任務(wù)感知OpenGL ES應(yīng)用程序
當(dāng)用戶切換到其他應(yīng)用程序時,您的應(yīng)用程序可以繼續(xù)運(yùn)行击罪。有關(guān)iOS上多任務(wù)的全面討論哲嘲,請參閱應(yīng)用程序狀態(tài)和多任務(wù)。
當(dāng)OpenGL ES應(yīng)用程序移動到后臺時媳禁,必須執(zhí)行其他工作眠副。如果應(yīng)用程序不正確地處理這些任務(wù),則可能會被iOS終止竣稽。此外囱怕,一個應(yīng)用程序可能想要釋放OpenGL ES資源,以便這些資源可用于前臺應(yīng)用程序毫别。
后臺應(yīng)用程序可能無法在圖形硬件上執(zhí)行命令
如果OpenGL ES應(yīng)用程序嘗試在圖形硬件上執(zhí)行OpenGL ES命令,則會終止該應(yīng)用程序岛宦。 iOS防止后臺應(yīng)用程序訪問圖形處理器,以便最前沿的應(yīng)用程序始終能夠向用戶呈現(xiàn)出極好的體驗(yàn)恋博。您的應(yīng)用程序不僅可以在后臺進(jìn)行OpenGL ES調(diào)用時終止齐佳,還可以在以后提交的命令在后臺刷新GPU私恬。您的應(yīng)用程序必須確保所有以前提交的命令在移動到后臺之前已完成執(zhí)行债沮。
如果您使用GLKit視圖并查看控制器,并且僅在繪圖方法中提交OpenGL ES命令本鸣,則當(dāng)應(yīng)用程序移動到背景時疫衩,您的應(yīng)用程序?qū)⒆詣诱_\(yùn)行。默認(rèn)情況下荣德,GLKViewController類在您的應(yīng)用程序變?yōu)榉腔顒訝顟B(tài)時暫停其動畫定時器闷煤,確保您的繪圖方法不被調(diào)用。
如果您不使用GLKit視圖或查看控制器涮瞻,或者如果您在GLKView繪圖方法之外提交OpenGL ES命令鲤拿,則必須執(zhí)行以下步驟以確保您的應(yīng)用程序未在后臺終止:
- 在應(yīng)用程序委托的ApplicationWillResignActive:方法中,應(yīng)用程序應(yīng)該停止其動畫定時器(如果有的話)署咽,將其置于已知的良好狀態(tài)近顷,然后調(diào)用glFinish函數(shù)生音。
- 在應(yīng)用程序委托的applicationDidEnterBackground:方法中,您的應(yīng)用程序可能需要刪除一些OpenGL ES對象窒升,以使內(nèi)存和資源可用于前臺應(yīng)用程序缀遍。調(diào)用glFinish函數(shù)以確保資源立即被刪除。
- 在您的應(yīng)用程序退出其applicationDidEnterBackground:方法之后饱须,它不能進(jìn)行任何新的OpenGL ES調(diào)用域醇。如果是OpenGL ES呼叫,則由iOS終止蓉媳。
- 在您的應(yīng)用程序的應(yīng)用程序WillEnterForeground:方法中譬挚,重新創(chuàng)建任何對象并重新啟動動畫計(jì)時器。
總而言之酪呻,您的應(yīng)用程序需要調(diào)用glFinish函數(shù)殴瘦,以確保所有以前提交的命令都從命令緩沖區(qū)中排除,并由OpenGL ES執(zhí)行号杠。移動到后臺后蚪腋,您必須避免使用OpenGL ES,直到它回到前臺姨蟋。
在移動到背景之前刪除輕松重新創(chuàng)建的資源
您的應(yīng)用程序不需要在OpenGL ES對象移動到后臺時釋放屉凯。通常,您的應(yīng)用程序應(yīng)避免處理其內(nèi)容眼溶∮蒲猓考慮兩種情況:
- 用戶正在玩游戲,并短暫退出以檢查他們的日歷堂飞。當(dāng)玩家返回游戲時灌旧,游戲的資源仍然在內(nèi)存中,游戲可以立即恢復(fù)
- 當(dāng)用戶啟動另一個OpenGL ES應(yīng)用程序時绰筛,您的OpenGL ES應(yīng)用程序處于后臺。如果該應(yīng)用程序需要比設(shè)備上更多的內(nèi)存铝噩,系統(tǒng)將自動終止您的應(yīng)用程序,而不需要執(zhí)行任何其他工作毛甲。
您的目標(biāo)應(yīng)該是將您的應(yīng)用程序設(shè)計(jì)為一個好的公民:這意味著保持盡可能短的時間移動到前臺具被,同時在后臺減少其內(nèi)存占用。
這是您應(yīng)該如何處理這兩種情況:
- 您的應(yīng)用程序應(yīng)保留內(nèi)存中的紋理七咧,模型和其他資源;在您的應(yīng)用程序移動到后臺時,不應(yīng)該處理需要很長時間重新創(chuàng)建的資源
- 您的應(yīng)用程序應(yīng)該處理可以快速輕松重新創(chuàng)建的對象坑雅。尋找消耗大量內(nèi)存的對象。
容易的目標(biāo)是您的應(yīng)用程序分配來支持呈現(xiàn)結(jié)果的幀緩沖區(qū)终蒂。當(dāng)你的應(yīng)用程序在后臺時遥诉,用戶看不到它,并且可能不會使用OpenGL ES渲染任何新的內(nèi)容矮锈。這意味著應(yīng)用程序的幀緩沖區(qū)消耗的內(nèi)存是分配的,但沒有用债朵。另外瀑凝,幀緩沖區(qū)的內(nèi)容是暫時的;大多數(shù)應(yīng)用程序在每次呈現(xiàn)新幀時重新創(chuàng)建幀緩沖區(qū)的內(nèi)容。這使得renderbuffers成為可以輕松重新創(chuàng)建的內(nèi)存密集型資源粤咪,成為當(dāng)移動到后臺時可以處理的對象的良好候選谚中。
如果您使用GLKit視圖和視圖控制器寥枝,則當(dāng)您的應(yīng)用程序移動到后臺時,GLKViewController類會自動處理其關(guān)聯(lián)視圖的幀緩沖區(qū)某筐。如果您手動創(chuàng)建用于其他用途的幀緩沖區(qū)艾疟,那么當(dāng)應(yīng)用程序移動到后臺時蔽莱,您應(yīng)該處理它們戚长。在這兩種情況下,您還應(yīng)該考慮當(dāng)時應(yīng)用程序可以處理哪些其他臨時資源仪糖。
支持高分辨率顯示
默認(rèn)情況下,GLKit視圖的contentScaleFactor屬性的值與包含它的屏幕的比例匹配攒驰,因此其關(guān)聯(lián)的幀緩沖區(qū)配置為以顯示的完整分辨率呈現(xiàn)故爵。有關(guān)UIKit支持高分辨率顯示的更多信息,請參閱在視圖中支持高分辨率屏幕劲室。
如果您使用Core Animation層提供OpenGL ES內(nèi)容结窘,則默認(rèn)情況下其比例因子設(shè)置為1.0。為了繪制Retina顯示屏的完整分辨率喉磁,您應(yīng)該更改CAEAGLLayer對象的比例因子以符合屏幕的比例因子官脓。
當(dāng)支持具有高分辨率顯示器的設(shè)備時,應(yīng)該相應(yīng)地調(diào)整應(yīng)用的模型和紋理資產(chǎn)斤讥。在高分辨率設(shè)備上運(yùn)行時湾趾,您可能需要選擇更詳細(xì)的模型和紋理來渲染更好的圖像。相反铛楣,在標(biāo)準(zhǔn)分辨率設(shè)備上艺普,您可以使用較小的模型和紋理歧譬。
重要提示:許多OpenGL ES API調(diào)用以屏幕像素表示維度。如果使用大于1.0的比例因子瑰步,則應(yīng)在使用glScissor缩焦,glBlitFramebuffer责静,glLineWidth或glPointSize函數(shù)或gl_PointSize著色器變量時相應(yīng)調(diào)整維度灾螃。
確定如何支持高分辨率顯示器的一個重要因素是性能揩徊。視網(wǎng)膜顯示屏上的比例因子倍增了像素?cái)?shù)量的四倍,導(dǎo)致GPU處理了四倍的片段垃喊。如果您的應(yīng)用程序執(zhí)行許多每個片段的計(jì)算本谜,像素的增加可能會降低幀速率偎窘。如果您發(fā)現(xiàn)您的應(yīng)用程序在較高比例因子下運(yùn)行速度顯著較慢,請考慮以下選項(xiàng)之一
- 使用本文檔中的性能調(diào)整指南優(yōu)化片段著色器的性能他托。
- 在片段著色器中實(shí)現(xiàn)更簡單的算法仆葡。通過這樣做沿盅,您正在降低單個像素的質(zhì)量,以更高的分辨率渲染整體圖像腰涧。
- 使用1.0之間的分?jǐn)?shù)比例因子和屏幕的比例因子窖铡。比例因子1.5提供比1.0的比例因子更好的質(zhì)量,但是需要填充比圖像縮放到2.0的像素少的像素滑臊。
- 對于GLKView對象的drawableColorFormat和drawableDepthFormat屬性使用較低精度的格式简珠。通過這樣做,可以減少在底層渲染緩沖區(qū)上操作所需的內(nèi)存帶寬聋庵。
- 使用較小比例因子并啟用多重采樣祭玉。另外一個優(yōu)點(diǎn)是春畔,多采樣也可以在不支持高分辨率顯示器的設(shè)備上提供更高的質(zhì)量。
要為GLKView對象啟用多重采樣振峻,請更改其drawableMultisample屬性的值择份。如果沒有渲染到GLKit視圖,則必須手動設(shè)置多采樣緩沖區(qū)并在呈現(xiàn)最終圖像之前對其進(jìn)行解析(請參閱使用多重采樣來提高圖像質(zhì)量)凤价。
多次采樣不是免費(fèi)的;需要額外的內(nèi)存來存儲附加樣本拔创,并將樣本解析為解析幀緩沖區(qū)需要時間。如果您向應(yīng)用程序添加多重采樣慢逾,請始終測試應(yīng)用程序的性能灭红,以確保其仍然可以接受。
支持多接口定向
像任何應(yīng)用程序一樣胜卤,OpenGL ES應(yīng)用程序應(yīng)支持與其內(nèi)容相適應(yīng)的用戶界面方向葛躏。您可以在其信息屬性列表中為您的應(yīng)用程序聲明支持的接口方向悠菜,或者使用supportedInterfaceOrientations方法來托管OpenGL ES內(nèi)容的視圖控制器悔醋。 (有關(guān)詳細(xì)信息,請參閱iOS的View Controller編程指南猾愿。)
默認(rèn)情況下,GLKViewController和GLKView類自動處理方向更改:當(dāng)用戶將設(shè)備旋轉(zhuǎn)到受支持的方向時泽本,系統(tǒng)會動態(tài)定向更改并更改視圖控制器視圖的大小规丽。當(dāng)其大小更改時撇贺,GLKView對象會相應(yīng)調(diào)整其幀緩沖區(qū)和視口的大小。如果需要響應(yīng)此更改艘狭,請?jiān)贕LKViewController子類中實(shí)現(xiàn)viewWillLayoutSubviews或viewDidLayoutSubviews方法缓升,如果使用自定義GLKView子類港谊,則實(shí)現(xiàn)layoutSubviews方法橙弱。
如果您使用Core Animation圖層繪制OpenGL ES內(nèi)容,則應(yīng)用程序仍應(yīng)包含一個視圖控制器來管理用戶界面方向斜筐。
在外部顯示器上呈現(xiàn)OpenGL ES內(nèi)容
iOS設(shè)備可以連接到外部顯示器蛀缝。外部顯示器的分辨率及其內(nèi)容比例因子可能與主屏幕的分辨率和比例因子不同;您渲染框架的代碼應(yīng)該調(diào)整為匹配屈梁。
在外部顯示器上繪制的步驟與在主屏幕上運(yùn)行的程序幾乎相同在讶。
- 按照“多顯示器編程指南”中的步驟煞抬,在外部顯示器上創(chuàng)建一個窗口革答。
- 將窗口添加到適當(dāng)?shù)囊晥D或查看控制器對象以用于渲染策略
- 如果使用GLKit渲染残拐,請?jiān)O(shè)置GLKViewController和GLKView(或您的自定義子類)的實(shí)例途茫,并使用其rootViewController屬性將其添加到窗口。
- 如果渲染到Core Animation圖層蹦骑,請將包含圖層的視圖添加為窗口的子視圖慈省。要使用動畫循環(huán)進(jìn)行渲染臀防,請通過檢索窗口的屏幕屬性并調(diào)用其DisplayLinkWithTarget:selector:method來創(chuàng)建為外部顯示優(yōu)化的顯示鏈接對象眠菇。