OpenGL ES 框架詳細解析(七) —— 多任務,高分辨率和其他iOS功能

版本記錄

版本號 時間
V1.0 2017.10.01

前言

OpenGL ES是一個強大的圖形庫,是跨平臺的圖形API,屬于OpenGL的一個簡化版本。iOS系統可以利用OpenGL ES將圖像數據直接送入到GPU進行渲染,這樣避免了從CPU進行計算再送到顯卡渲染帶來的性能的高消耗,能帶來來更好的視頻效果和用戶體驗。接下來幾篇就介紹下iOS 系統的 OpenGL ES框架。感興趣的可以看上面幾篇。
1. OpenGL ES 框架詳細解析(一) —— 基本概覽
2. OpenGL ES 框架詳細解析(二) —— 關于OpenGL ES
3. OpenGL ES 框架詳細解析(三) —— 構建用于iOS的OpenGL ES應用程序的清單
4. OpenGL ES 框架詳細解析(四) —— 配置OpenGL ES的上下文
5. OpenGL ES 框架詳細解析(五) —— 使用OpenGL ES和GLKit進行繪制
6. OpenGL ES 框架詳細解析(六) —— 繪制到其他渲染目的地

Multitasking, High Resolution, and Other iOS Features - 多任務,高分辨率和其他iOS功能

使用OpenGL ES的許多方面是平臺中立的,但是在iOS上使用OpenGL ES的一些細節需要特別考慮。 特別是,使用OpenGL ES的iOS應用程序必須正確處理多任務,或者在移動到后臺時可能會被終止。 在為iOS設備開發OpenGL ES內容時,還應考慮顯示分辨率和其他設備功能。


Implementing a Multitasking-Aware OpenGL ES App - 實現多任務感知OpenGL ES應用程序

當用戶切換到其他應用程序時,您的應用程序可以繼續運行。 有關iOS上多任務的全面討論,請參閱App States and Multitasking

當OpenGL ES應用程序移動到后臺時,它必須執行其他工作。 如果應用程序處理這些任務不正確,則可能會由iOS終止。 此外,一個應用程序可能想要釋放OpenGL ES資源,以便這些資源可用于前臺應用程序。

1. Background Apps May Not Execute Commands on the Graphics Hardware - 后臺應用程序可能無法在圖形硬件上執行命令

如果OpenGL ES應用程序嘗試在圖形硬件上執行OpenGL ES命令,則會終止該應用程序。 iOS防止后臺應用程序訪問圖形處理器,以便最前沿的應用程序始終能夠向用戶呈現出極好的體驗。 您的應用程序不僅可以在后臺進行OpenGL ES調用時被終止,還可以在后臺將先前提交的命令刷新到GPU。 您的應用程序必須確保所有以前提交的命令在移動到后臺之前已完成執行。

如果您使用GLKit視圖并查看控制器,并且僅在繪圖方法中提交OpenGL ES命令,則當應用程序移動到后臺時,您的應用程序會自動正常運行。 默認情況下,GLKViewController類在您的應用程序處于非活動狀態時暫停其動畫定時器,確保您的繪圖方法不被調用。

如果您不使用GLKit視圖或視圖控制器,或者如果您在GLKView繪圖方法之外提交OpenGL ES命令,則必須執行以下步驟以確保您的應用程序未在后臺終止:

  • 在應用程序委托的applicationWillResignActive:方法中,您的應用程序應該停止其動畫定時器(如果有的話),將其置于已知的良好狀態,然后調用glFinish函數。
  • 在您的應用程序委托的applicationDidEnterBackground:方法中,您的應用程序可能需要刪除其一些OpenGL ES對象,以使內存和資源可用于前臺應用程序。 調用glFinish函數以確保資源立即被刪除。
  • 在您的應用程序退出其applicationDidEnterBackground:方法之后,它不能進行任何新的OpenGL ES調用。 如果是OpenGL ES調用,則由iOS終止。
  • 在您的應用程序的應用程序applicationWillEnterForeground:方法中,重新創建任何對象并重新啟動動畫定時器。

總而言之,您的應用程序需要調用glFinish函數,以確保所有以前提交的命令都從命令緩沖區中排出并由OpenGL ES執行。 移動到后臺后,您必須避免使用OpenGL ES,直到它移回到前臺。

2. Delete Easily Re-Created Resources Before Moving to the Background - 在移動到后臺之前刪除容易重新創建的資源

您的應用程序從來不需要在OpenGL ES對象移動到后臺時釋放。 通常,您的應用程序應避免處理其內容。 考慮兩種情況:

  • 用戶正在玩游戲,并短暫退出以檢查他們的日歷。 當玩家返回游戲時,游戲資源仍然在內存中,游戲可以立即恢復。
  • 當用戶啟動另一個OpenGL ES應用程序時,您的OpenGL ES應用程序處于后臺。 如果該應用程序需要比設備上可用的內存更多的內存,系統將自動終止您的應用程序,而不需要執行任何其他工作。

您的目標應該是將您的應用程序設計為一個好的產品:這意味著保持移動到前臺的時間盡可能短,同時在后臺減少其內存占用。

以下是處理這兩種情況的方法:

  • 您的應用程序應將紋理,模型和其他資產保留在內存中; 在您的應用程序移動到后臺時,不應該處理需要很長時間重新創建的資源。
  • 您的應用程序應該處理可以快速,輕松地重新創建的對象。 尋找消耗大量內存的對象。

簡單的目標是您的應用程序分配用于保存呈現結果的幀緩沖區。 當你的應用程序在后臺時,用戶看不到它,可能不會使用OpenGL ES渲染任何新的內容。 這意味著應用程序的幀緩沖區消耗的內存是分配的,但沒有用。 此外,幀緩沖區的內容是暫時的; 大多數應用程序在每次呈現新幀時重新創建幀緩沖區的內容。 這使得renderbuffers成為可以輕松重新創建的內存密集型資源,成為當移動到后臺時可以處理的對象的良好候選。

如果您使用GLKit視圖和視圖控制器,則當應用程序移動到后臺時,GLKViewController類會自動處理其關聯視圖的幀緩沖區。 如果您手動創建用于其他用途的幀緩沖區,則在應用程序移動到后臺時應該處理它們。 在這兩種情況下,您還應該考慮當時應用程序可以處理的其他暫時資源。


Supporting High-Resolution Displays - 支持高分辨率顯示

默認情況下,GLKit視圖的 contentScaleFactor屬性的值與包含它的屏幕的比例匹配,因此其關聯的幀緩沖區配置為以顯示的全分辨率進行渲染。 有關UIKit中支持高分辨率顯示的詳細信息,請參閱 Supporting High-Resolution Screens In Views

如果您使用Core Animation層提供OpenGL ES內容,則其縮放因子默認設置為1.0。 為了繪制Retina顯示屏的完整分辨率,您應該更改CAEAGLLayer對象的比例因子以匹配屏幕的比例因子。

當支持具有高分辨率顯示器的設備時,您應該相應地調整應用程序的模型和紋理資產。 在高分辨率設備上運行時,您可能需要選擇更詳細的模型和紋理來渲染更好的圖像。 相反,在標準分辨率設備上,您可以使用較小的模型和紋理。

重要:許多OpenGL ES API調用以屏幕像素表示維度。 如果使用大于1.0的比例因子,則應在使用glScissor,glBlitFramebuffer,glLineWidthglPointSize函數或gl_PointSize著色器變量時相應調整維度。

確定如何支持高分辨率顯示器的一個重要因素是性能。 Retina顯示屏上的比例因子倍增了像素數量的四倍,導致GPU處理的片斷數量是四倍。 如果您的應用程序執行許多每個片段的計算,像素的增加可能會降低幀速率。 如果您發現您的應用程序在較高比例因子下運行速度顯著較慢,請考慮以下選項之一:

  • 使用本文檔中的性能調整指南優化片段著色器的性能。
  • 在片段著色器中實現更簡單的算法。 通過這樣做,您可以降低單個像素的質量,以更高的分辨率渲染整體圖像。
  • 使用1.0之間的分數比例因子和屏幕的比例因子。 比例因子1.5提供比1.0的比例因子更好的質量,但是需要填充比縮放到2.0的圖像更少的像素。
  • 對您的GLKView對象的drawableColorFormatdrawableDepthFormat屬性使用較低精度的格式。 通過這樣做,可以減少對底層渲染緩沖區進行操作所需的內存帶寬。
  • 使用較小的比例因子并啟用多重采樣。 另外一個優點是,多采樣在不支持高分辨率顯示器的設備上也提供了更高的質量。

要為GLKView對象啟用多重采樣,請更改其drawableMultisample屬性的值。 如果沒有渲染到GLKit視圖,則必須手動設置多采樣緩沖區并在呈現最終圖像之前對其進行解析(請參閱使用多重采樣來提高圖像質量)。

多次采樣不是免費的; 需要額外的內存來存儲附加樣本,并將樣本解析為解析幀緩沖區需要時間。 如果您向應用程序添加多重采樣,請始終測試應用程序的性能,以確保其仍然可以接受。


Supporting Multiple Interface Orientations - 支持多種界面方向

像任何應用程序一樣,OpenGL ES應用程序應該支持適合其內容的用戶界面方向。 您可以在其信息屬性列表中聲明支持的應用程序接口方向,或者使用supportedInterfaceOrientations方法來托管OpenGL ES內容的視圖控制器。 (有關詳細信息,請參閱View Controller Programming Guide for iOS)。

默認情況下,GLKViewControllerGLKView類自動處理方向更改:當用戶將設備旋轉到受支持的方向時,系統會動態定向更改并更改視圖控制器視圖的大小。 當其大小更改時,GLKView對象會相應地調整其幀緩沖區和視口的大小。 如果您需要響應此更改,請在GLKViewController子類中實現viewWillLayoutSubviewsviewDidLayoutSubviews方法,如果使用自定義GLKView子類,則實現layoutSubviews方法。

如果您使用Core Animation層繪制OpenGL ES內容,則應用程序仍應包含一個視圖控制器來管理用戶界面方向。


Presenting OpenGL ES Content on External Displays - 在外部顯示器上呈現OpenGL ES內容

iOS設備可以連接到外部顯示器。 外部顯示器的分辨率及其內容比例因子可能與主屏幕的分辨率和比例因子不同, 您渲染幀的代碼應該進行調整和匹配。

在外部顯示器上繪制的程序與在主屏幕上運行的程序幾乎相同。

  • 按照Multiple Display Programming Guide for iOS中的步驟,在外部顯示器上創建一個窗口。

  • 將適當的視圖或視圖控制器添加到窗口對象的渲染策略。

    • 如果使用GLKit渲染,請設置GLKViewController和GLKView(或您的自定義子類)的實例,并使用其rootViewController屬性將其添加到窗口。
    • 如果渲染到Core Animation圖層,請將包含圖層的視圖添加為window的子視圖。 要使用動畫循環進行渲染,請通過檢索窗口的屏幕屬性并調用其displayLinkWithTarget:selector:方法來創建為外部顯示優化的顯示鏈接對象。

后記

未完,待續~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370

推薦閱讀更多精彩內容