【问题标题】:Opengles image texture preloading on iOSiOS上的Opengles图像纹理预加载
【发布时间】:2014-09-09 04:57:36
【问题描述】:

我正在创建一个照片幻灯片,在 iOS 上的图像之间具有复杂的过渡。 Core Animation 不适合这个目的,因为可能的过渡是有限的,所以我求助于 Opengles 2.0。问题是将图像上传到 GPU 并创建纹理是一项耗时的操作,即使对于 960x640 图像也需要大约 200 毫秒,这不适合实时播放场景。预先创建所有纹理是不可行的,因为它们可能有 100 个。我想知道 Core Animation 如何处理这个问题,并且无论您在动画中分配多少 CGImage 都足够流畅以运行? (只要图像在不同时间呈现,而不是一起呈现)。

【问题讨论】:

  • 您希望每秒更换幻灯片超过 5 次?还是只是您担心的延迟?此类问题的常见策略是在您当前显示的内容之前加载一两张幻灯片。因此,一旦您第一次需要幻灯片的图像,它就已经加载了。您可以将其视为幻灯片的缓存,您可以在其中预取您将很快需要的条目。
  • 是的,我担心的是延迟。它应该作为视频在 AVPlayer 上运行,因此延迟要求会很严格。我只需要了解处理它的最佳方法,尤其是当您在视频合成中寻找时,图像会来得太快。

标签: ios core-animation opengl-es-2.0 avfoundation calayer


【解决方案1】:

纹理加载非常耗时,大多数处理大量纹理的应用程序都是在一些初始化时加载它们。这是最简单的方法,但肯定是最消耗资源的。你必须明白,后面发生的事情是读取图像文件,解压缩,在 CPU 上创建原始 RGB(A) 数据,在 GPU 上分配内存并将原始数据发送到 GPU...

处理大量纹理的最佳方法是将它们加载到后台,最好是在您需要它们之前。在评论中已经提到的情况下,您需要为这些纹理创建一些智能缓存。这仍然不够,因为加载本身可能会使您的线程无响应。您需要添加一个后台任务来处理这些图像。

我向您建议的是创建 2 个额外的线程。首先应该将图像数据加载到 CPU,而第二个将数据推送到 GPU。第一个线程非常简单,而第二个线程需要一些额外的 GL 代码来完成。每个线程都需要自己的 openGL 上下文才能与 GPU 通信,因此一旦创建了这个线程,您还需要创建一个额外的上下文。这些上下文不知道彼此的资源,这导致在一个上下文中创建纹理将使其在另一个上下文中无法使用。为此,您将需要一个称为共享组的额外参数。因此,首先您创建共享组,然后使用相同的共享组创建两个上下文,以便可以访问纹理。请注意,最好在您应该使用它的线程上创建上下文(不过,只需将其设置为当前就足够了)。

【讨论】:

  • 感谢您的回答。我正在考虑使用 AVCustomCompositor 创建效果和过渡以在 AVPlayer 上实时运行。用户可以在视频中快速搜索,这意味着图像快速出现和消失。此外,我必须能够预测在接下来的 0.5 秒左右即将播放新图像并开始获取它。但如果用户寻找视频,我必须丢弃旧纹理并获取新纹理。看起来工作量很大,可能 Core Animation 正在按照这些思路做一些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2015-09-18
  • 2018-07-21
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-28
相关资源
最近更新 更多