iOS OpenGL Catch-22:OpenGL背景规则和;应用程序快照“;应用程序切换程序

iOS OpenGL Catch-22:OpenGL背景规则和;应用程序快照“;应用程序切换程序,ios,objective-c,ipad,opengl-es,layoutsubviews,Ios,Objective C,Ipad,Opengl Es,Layoutsubviews,像许多开发人员一样,我有一个应用程序,它通过UIView子类使用OpenGL,其layerClass:方法返回[caeaglayer类] 注意:我不是使用GLKit或GLKView或GLKViewController 当我单击Home将应用程序放到后台时,在ApplicationIdentinterBackground之后,iOS调用我的视图的LayoutSubview两次,使用纵向和横向大小,试图生成此处解释的“应用程序快照”(请参阅“准备应用程序快照”): 这怎么可能起作用呢 这里似乎与本

像许多开发人员一样,我有一个应用程序,它通过
UIView
子类使用OpenGL,其
layerClass:
方法返回
[caeaglayer类]

注意:我不是使用
GLKit
GLKView
GLKViewController

当我单击Home将应用程序放到后台时,在
ApplicationIdentinterBackground
之后,iOS调用我的视图的
LayoutSubview
两次,使用纵向和横向大小,试图生成此处解释的“应用程序快照”(请参阅“准备应用程序快照”):

这怎么可能起作用呢

这里似乎与本页上非常明确的建议存在直接矛盾(请参阅“后台应用程序可能无法在图形硬件上执行命令”):

applicationIdentinterbackground

如果不绘制,则无法生成快照。我们必须违反一条或另一条规则

但我们也希望在两个方向都有好的快照,这样当用户双击home并转到App Switcher时,他们可以看到合理的快照图像

即使我通过创建OpenGL曲面和图形(与Apple dox相反,它不会崩溃),临时更改代码以在
ApplicationIdentinterBackground
之后完全实现
LayoutSubview
,然后双击home并从不同方向查看快照,只有我之前所在方向的快照是正确的。另一个是另一个快照的超级丑陋的肮脏的重新缩放。苹果似乎正在经历拍摄快照的过程,但实际上并没有拍摄

我在iPadMini上的iOS9.3.2上看到了这种行为。大多数/所有iPhone设备都不支持这种行为,因为它们不支持横向应用程序切换器

更新:当使用新的iOS 9“滑过”多任务功能并在普通全屏应用程序与滑过另一个应用程序之间切换同一个应用程序时,问题也会发生,情况更糟。iOS似乎只捕获最后一个应用大小的快照,因此在使用640像素宽的应用程序,然后尝试使用应用程序切换器进入应用程序全屏后,我们在应用程序切换器中以及在启动的第一秒钟看到一个奇怪的像素比例失调的快照。一定有办法解决这个问题

更新2:我见过一些iOS应用程序,我知道它们是OpenGL专用的应用程序,如果你在纵向中使用它们,然后返回主页并旋转到横向,然后双击主页,你会看到纵向启动图像,而不是我看到的可怕、扭曲、不相称的图像。虽然我更喜欢渲染快照图像,但我甚至很乐意看到启动图像。但是大家提到的选项,
忽略SnapshotOnnextApplicationLaunch
不起作用,因为它只影响实际应用程序启动时看到的内容,而不影响双击Home时在应用程序切换器中看到的内容,而且对于StackOverflow上的许多人来说,它实际上根本不起作用(甚至在启动时也不起作用)

我们如何摆脱这第二十二条军规

此StackOverflow线程(与我不同,这里的OP使用GLKit,但症状相同):

确认iOS上的某些OpenGL应用程序能够在主双击应用程序切换器中为两个方向提供正确的预览图像。他们是怎么做到的

如何在应用程序切换器中获得两个方向的正确快照

以下是我单击Home按钮退出应用程序时,来自iOS的
AppDelegate
(appdel)、
ViewController
(eaglc)和
View
(eaglv)调用的日志。您可以看到在
dienterbackground
之后出现的快照尝试:

+ 189.57ms appdel appWillResignActive + 0.74ms appdel appWillResignActive between_view_os_callbacks 0 + 4.11ms appdel appWillResignActive between_view_os_callbacks 0 done + 0.82ms appdel appWillResignActive activation_changed + 1.50ms appdel appWillResignActive activation_changed done + 0.47ms appdel appWillResignActive between_view_os_callbacks 1 + 2.68ms drawing rect [(144,1418)+(2,66)] (0 left) + 44.28ms swap_buffers glFlush() + 6.16ms swap_buffers presentRenderBuffer + 9.01ms appdel appWillResignActive between_view_os_callbacks 1 done + 0.61ms appdel save_state ..app saving data, no OpenGL here.. + 0.49ms appdel save_state calling glFinish + 0.34ms appdel save_state done + 0.25ms appdel appWillResignActive done + 492.72ms appdel applicationDidEnterBackground + 0.56ms appdel save_state ..app saving data, no OpenGL here.. + 0.65ms appdel save_state calling glFinish + 0.54ms appdel save_state done + 0.65ms eaglv let_go_of_frame_buffer_render_buffer app drops OpenGL frame_buffer and render_buffer here + 1.10ms appdel applicationDidEnterBackground done Now we are not supposed to do OpenGL, BUT... + 6.30ms eaglc supportedInterfaceOrientations + 5.74ms about_to_sleep between_view_os_callbacks + 1.30ms SKIPPING between_view_os_callbacks cuz app in background + 0.66ms about_to_sleep between_view_os_callbacks done + 135.85ms eaglc willRotateToInterfaceOrientation + 2.49ms appdel willChangeStatusBarFrame new=0,0 768x20 + 3.21ms appdel didChangeStatusBarFrame old=0,0 1024x20 we get a portrait layoutSubviews.... + 1.26ms eaglv layoutSubviews (initted=1, have_fbrb=0) + 1.80ms eaglv assure_frame_buffer_render_buffer + 0.95ms eaglv assure_fbrb scale ios=2 eaglv=2 + 0.90ms eaglv assure_fbrb (frame=1536,2048) + 1.04ms eaglv assure_fbrb (layer frame=1536,2048) + 0.92ms eaglv assure_fbrb in bg: will make fbrb later + 0.96ms eaglv layoutSubviews done + 3.11ms eaglc didRotateFromInterfaceOrientation + 149.07ms eaglc willRotateToInterfaceOrientation + 1.99ms appdel willChangeStatusBarFrame new=0,0 1024x20 + 2.35ms appdel didChangeStatusBarFrame old=0,0 768x20 then a landscape layoutSubviews... + 1.91ms eaglv layoutSubviews (initted=1, have_fbrb=0) + 1.09ms eaglv assure_frame_buffer_render_buffer + 0.91ms eaglv assure_fbrb scale ios=2 eaglv=2 + 1.65ms eaglv assure_fbrb (frame=2048,1536) + 0.92ms eaglv assure_fbrb (layer frame=2048,1536) + 0.93ms eaglv assure_fbrb in bg: will make fbrb later + 0.83ms eaglv layoutSubviews done + 2.79ms eaglc didRotateFromInterfaceOrientation and, adding insult to injury, we get this log message: Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates. +189.57ms appdel appWillResignActive +0.74ms appdel AppWillResignative\u view\u os\u回调之间0 +4.11ms appdel AppWillResignative\u view\u os\u回调0完成 +0.82ms appdel appWillResignActive激活已更改 +1.50ms appdel AppWillResignative激活已完成 +0.47ms appdel AppWillResignative在\u view\u os\u回调之间1 +2.68ms绘图矩形[(1441418)+(2,66)](0左) +44.28ms交换缓冲区glFlush() +6.16ms交换缓冲区前置缓冲区 +9.01ms appdel AppWillResignative\u view\u os\u回调1完成 +0.61ms appdel保存状态 …应用程序正在保存数据,此处没有OpenGL。。 +0.49ms appdel保存状态调用glFinish +0.34ms appdel保存状态完成 +0.25ms appdel appWillResignActive已完成 +492.72ms应用程序标识符背景 +0.56ms appdel保存状态 …应用程序正在保存数据,此处没有OpenGL。。 +0.65ms appdel保存状态调用glFinish +0.54毫秒appdel保存状态完成 +0.65ms eaglv释放帧缓冲区渲染缓冲区 应用程序将OpenGL帧缓冲区和渲染缓冲区放置在此处 +1.10ms应用程序标识符背景完成 现在我们不应该做OpenGL,但是。。。 +6.30ms eaglc支架接口方向 +5.74ms关于查看操作回调之间的睡眠 +1.30毫秒在_view_os_回调之间跳过,因为后台有应用程序 +0.66ms关于\u-to\u在\u-view\u-os\u回调之间睡眠完成 +135.85毫秒eaglc将旋转接口定向 +2.49ms appdel willChangeStatusBarFrame新=0,0 768x20 +3.21ms appdel didChangeStatusBarFrame旧版=0,0 1024x20 我们得到了一个肖像布局子视图。。。。 +1.26ms eaglv布局子视图(初始值=1,具有\u fbrb=0) +1.80ms eaglv保证帧缓冲区渲染缓冲区