多任务,高分辨率和其他iOS特性

Multitasking, High Resolution, and Other iOS Features

多任务的OpenGL ES应用程序

OpenGL ES应用程序移入后台后必须执行其他工作。如果某个应用无法正确处理这些任务,则iOS可能会终止该应用。此外,一个应用可能想要释放OpenGL ES资源,以便使这些资源可用于前置应用。

后台应用程序可能无法在图形硬件上执行命令

iOS阻止后台app访问图形处理器,这样前台应用可以始终为用户提供出色体验。App不仅在后台执行OpenGL ES调用有可能被终止,还会在app后台时先前提交的命令刷新到GPU时被终止。因此,app必须确保之前提交的命令都已经完成执行,才能移交到后台

如果您使用GLKitView或者ViewController,并且仅在绘制方法期间提交运行OpenGL ES命令,则app在移交到后台会自动正常运行。GLKViewController会在App变为非活跃状态时暂停其动画计时器,确保不调用绘图方法

如果不使用GLKView或者GLKViewController,或者在GLKView绘制方法外提交了OpenGL ES命令,则需要采用以下步骤,确保app不会在后台被终止:

  1. applicationWillResignActive:方法中,app停止其动画计时器,将其置于良好状态,然后调用glFinish函数
  2. app的applicationDidEnterBackground方法中,app删除某些OpenGL ES对象,使其内存或资源可用于前台应用。调用glFinish函数确保立即删除函数。
  3. app在结束applicationDidEnterBackground:方法后,不得再进入任何新的OpenGL ES调用。如果调用,则会被iOS终止。
  4. 在app的applicationWillEnterForeground:方法中,重新创建所有对象,然后重启动画计时器

总之,app需要调用glFinish函数 确保之前提交的命令都已从缓冲区删除并由Open GL ES执行,移至后台,必须避免完全使用OpenGL ES,直到移回前台

在移回后台前,请删除较容易创建的资源

在app移交后台时,无需释放OpenGL ES对象,通常app避免销毁其内容。
因为,如果用户启动另外一个Open GLES应用,你的app处于后台则当前台应用使用的内存超过设备可用内存时,则系统将以静默的方式自动终止你的app,而你无需做其它工作

处理以下两种情况的方法:

  • app应该将纹理、模型和其它资源保留在内存中,当应用切换到后台时,切勿浪费大量时间重新创建资源
  • app应该丢弃可以快速创建的对象,

可以丢弃的易于创建的最容易想到的目标是app分配的用于保存渲染结果的帧缓冲区。
因为大多数app每次渲染新帧时,都会重新创建帧缓冲区内容,使渲染缓冲区成为易于占用的内存密集型资源,移入后台可以丢弃对象的理想选择

如果您使用GLKitView和view controller,则当您的应用程序移至后台时,GLKViewController类会自动处理其关联的视图的帧缓冲区。如果您为其他用途手动创建帧缓冲区,则应在应用程序移至后台时将其丢弃。无论哪种情况,您都应考虑当时您的应用可以处置哪些其他临时资源。

支持高分辨率显示

默认情况下,GLKitView的contentScaleFactor属性值和屏幕的scale相匹配,因此其相关联的帧缓冲区配置为以全分辨率显示。参阅Supporting High-Resolution Screens In Views

如果使用Core Animation Layer显示OpenGL ES内容,则默认缩放系数设置为1.0.如果要以Retina屏完整分辨率进行绘制,应改CAEAGLLayer的scale factor为屏幕的scale factor

当在支持高分辨率显示器的设备时,应改调整app的模型和纹理资源。

许多的OpenGL ES的API调用都是以屏幕像素尺寸。此时如果使用大于1.0的比例因子,则在使用glScissor,glBlitFramebuffer,glLineWidth或glPointSize函数或gl_PointSize着色器变量时,应相应地调整尺寸

支持多方向

类似很多app,OpenGL ES app应支持适合其内容的用户界面方向。可以在app的plist文件中声明支持的方向,或者使用supportedInterfaceOrientations方法为OpenGL ES内容的视图控制器声明支持的界面方向。参阅View Controller Programming Guide for iOS

默认,GLKViewControllerGLKView类会自动处理方向更改,当用户将设备旋转到主持的方向时,系统会为方向的更改添加动画效果,并更改视图控制器的View的大小。当其大小更改时,GLKView会相应的调整帧缓冲区和viewport大小。如果需要对此更改做出响应,请在GLKViewController子类中实现viewWillLayoutSubviewsviewDidLayoutSubviews方法,或者在使用自定义GLKView子类时实现layoutSubviews方法。

如果您使用Core Animation图层绘制OpenGL ES内容,则您的应用程序仍应包含视图控制器以管理用户界面方向。

在外部显示器显示

iOS设备可以连接到外部显示器,外部显示器的分辨率和其内容scale factor与主屏幕的不同,因此,渲染一帧的代码应该调整

在外部显示器进行绘制的过程和在主屏幕几乎相同

  1. 在外部显示器创建窗口的步骤遵循 iOS多显示器编程指南
  2. 将适合渲染策略的视图或者视图控制器对象添加到窗口中
    • 如果使用GLKit进行渲染,请设置GLKViewController和GLKView(或您的自定义子类)的实例,并使用其rootViewController属性将其添加到窗口中。
    • 如果渲染到Core Animation图层,请添加包含图层的视图作为窗口的子视图。要使用动画循环进行渲染,请通过获取窗口的screen属性并调用其displayLinkWithTarget:selector:方法来创建针对外部显示优化的显示链接对象。