使用 NSOpenGLLayer 从单独的线程中绘制

2023-12-28

我正在开发一个应用程序,它需要使用 OpenGL 进行绘制,刷新率至少等于显示器的刷新率。我需要在单独的线程中执行绘图,以便绘图永远不会被激烈的 UI 操作锁定。

实际上我正在使用NSOpenGLView结合CVDisplayLink我可以毫无问题地达到 60-80FPS。

因为我还需要在这个视图之上显示一些可可控件,所以我尝试子类化NSOpenGLView并使其成为分层支持的,如下图层支持的OpenGL视图 https://developer.apple.com/library/mac/#samplecode/LayerBackedOpenGLView/Introduction/Intro.html苹果的例子。

结果并不令人满意,我得到了很多伪影。

因此我使用单独的方法解决了这个问题NSWindow托管可可控件并将此窗口添加为包含以下内容的主窗口的子窗口NSOpenGLView。 它运行良好,我能够获得与初始实现完全相同的 FPS。

因为我认为这个解决方案很像一个肮脏的黑客,所以我正在寻找一种替代的、更干净的方法来实现我所需要的。

前几天我遇到了NSOpenGLLayer我认为它可以作为解决我的问题的可行解决方案。

最后,在所有的序言之后,我的问题是: 是否有可能绘制到NSOpenGLLayer从一个单独的线程使用CVDisplayLink打回来?。

到目前为止,我已经尝试实现这一点,但我无法从中提取CVDisplayLink打回来。我只能-setNeedsDisplay:TRUE on the NSOpenGLLayer来自CVDisplayLink回调然后执行绘图-drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:当它被可可自动调用时。但我想这样我是从主线程中绘制的,不是吗?

谷歌搜索后我什至发现this http://youfaqs.com/201127316/mailing-list/help-needed-for-the-nsopengllayer-behavior-under-lion.html帖子中用户声称狮子下的绘图只能发生在内部-drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:.

我目前使用的是 Snow Leopard,但该应用程序即使在 Lion 上也应该可以完美运行。

我错过了什么吗?


是的,这是可能的,但不推荐。称呼display在 CVDisplayLink 内的图层上。这会导致canDrawInContext:...被调用,如果返回 YES,drawInContext:...将被调用,所有这些都在调用的任何线程上display。要使渲染的图像在屏幕上可见,您必须调用[CATransaction flush]。 Apple 邮件列表中已建议使用此方法,但它并非完全没有问题(其他视图的显示方法也可能在后台线程上调用,并且并非所有视图都支持从后台线程渲染)。

推荐的方法是使图层异步并在主线程上渲染 OpenGL 上下文。如果您无法以这种方式实现良好的帧速率,因为您的主线程在其他地方很忙,建议将其他所有内容(几乎整个应用程序逻辑)移动到其他线程(例如使用 Grand Central Dispatch),并且仅保留用户输入和在主线程上绘制代码。如果您的窗口非常大,您可能仍然无法获得比 30 FPS(每两次屏幕刷新一帧)更好的东西,但这是因为 CALayer 合成似乎是一个相当昂贵的过程,并且它已经或多或少地进行了优化静态图层(例如包含图片的图层),不适用于以 60 FPS 自行更新的图层。

例如。如果您正在编写 3D 游戏,建议您根本不要将 CALayers 与 OpenGL 内容混合。如果您需要 Cocoa UI 元素,请将它们与 OpenGL 内容分开(例如,将窗口水平分成仅显示 OpenGL 的部分和仅显示控件的部分),或者自己绘制所有控件(这对于游戏来说很常见)。

最后但并非最不重要的一点是,两个窗口方法并不像您想象的那么奇特,这就是 VLC(视频播放器)在视频图像上绘制控件的方式(在 Mac 上也由 OpenGL 渲染)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 NSOpenGLLayer 从单独的线程中绘制 的相关文章

  • 访问 Linux 线程(pthreads)的本地堆栈

    我目前正在实现一个使用多线程但对总内存消耗有要求的应用程序 我希望有一个主线程执行 I O 并有几个工作线程执行计算 目前 我在主堆栈上有几个可供工作人员访问的数据结构 我使用 OpenMP 进行工作分配 由于主 工作者模式不能很好地与 O
  • 跨线程操作无效 VB.NET

    我浏览了该网站 发现与该主题相关的问题是针对 C 的 我正在维护的应用程序是用 VB NET 编写的 因此 如果我忽略了一个问题 我深表歉意 这是我调用我的线程的地方 Private Sub saveBtn Click ByVal send
  • 从单个应用程序中的多个线程调用 dll 函数是否安全?

    我正在 Delphi 2009 中编写一个服务器应用程序 它实现了多种类型的身份验证 每种身份验证方法都存储在单独的 dll 中 第一次使用身份验证方法时 会加载适当的 dll 仅当应用程序关闭时 DLL 才会被释放 在服务器线程 连接 之
  • 如何创建无法创建新文档的基于文档的应用程序?

    我有一个基于文档的应用程序 旨在处理现有文档 而不是创建新文档 如何防止应用程序在通过 Finder 打开应用程序时创建新的空白文档 您可以实现一个 NSApplication 委托协议方法 BOOL applicationShouldOp
  • 如何使用 Handler.Post() 通知工作线程 UI 被修改?

    我有一个工作线程 偶尔我会使用以下命令向 UI 线程发送更新Handler Post 在某些情况下 我需要工作线程等待Handler Post 在 UI 线程上执行and视图被修改并且afterUI线程被修改 通知worker线程继续 这是
  • Lockfree 标准集合和教程或文章

    有人知道用于无锁常用数据类型的实现 即源代码 的好资源吗 我正在考虑列表 队列等 锁定实现非常容易找到 但我找不到无锁算法的示例以及 CAS 的工作原理以及如何使用它来实现这些结构 查看 Julian M Bucknall 的博客 他 详细
  • 没有公平性的DelayQueue有问题吗?

    在 Java 7 中 DelayQueue 的实现使用没有公平策略的 ReentrantLock 从长远来看 这是一个问题吗 线程会因此而饿死吗 Thanks 如果您考虑ScheduledThreadPoolExecutor 或任何其他生产
  • 摆脱潜在的僵局

    我遇到了看似僵局 死锁听起来是不是有点像 无法关闭窗口 如果 IDE 上没有终止按钮 则无法终止 空白 什么也没有发生 没有任何异常或错误 如果这些是在僵局中发生的事情 那么我可能已经解决了一半的问题 我知道有两个线程正在运行 AWT Ev
  • 使用 pyobjc 将元数据写入 pdf

    我正在尝试使用以下 python 代码将元数据写入 pdf 文件 from Foundation import from Quartz import url NSURL fileURLWithPath test pdf pdfdoc PDF
  • 我可以在 R 中并行读取 1 个大 CSV 文件吗? [复制]

    这个问题在这里已经有答案了 我有一个很大的 csv 文件 需要很长时间才能阅读 我可以使用 parallel 或相关的包在 R 中并行读取此内容吗 我尝试过使用 mclapply 但它不起作用 根据OP的评论 fread来自data tab
  • 块执行后变量返回 null

    我正在调度一个队列来在单独的线程上下载一些 flickr 照片 在 viewWillAppear 中 当我记录块内数组的内容时 它完美地显示了所有内容 dispatch queue t photoDowonload dispatch que
  • .NET 中的线程中止

    我有一个线程正在分析文件并对数据库进行事务调用 每个事务都有一个审计条目作为其事务的一部分 调用 Thread Abort 来停止文件的处理有什么大问题吗 而不是到处散布丑陋的安全点 文件将在 Abort 调用后关闭 明显的问题是放弃交易的
  • 低级键盘钩子不在 UI 线程上

    我想为键盘挂钩创建一个好的库 我使用 SetWindowsHookEx 方法 我注意到如果我的应用程序的主线程繁忙 则应在任何系统 KeyDown 事件中调用的方法 hookProc 不会执行 我认为钩子应该这样制作 以便另一个线程负责它
  • BlockingCollection.TakeFromAny 方法是否适合构建阻塞优先级队列?

    我需要建立一个阻塞优先级队列 我的预感是TakeFromAny https learn microsoft com en us dotnet api system collections concurrent blockingcollect
  • Objective-C 字符串文字的预处理器宏值

    我在构建设置中定义了一个预处理器宏 FOO BAR 我想将该值转换为可以传递给方法的 Objective C 字符串文字 以下 define 不起作用 但它应该展示我想要实现的目标 define FOOLITERAL FOO want FO
  • 在特定线程上运行工作

    我想要一个特定的线程 任务队列并在该单独的线程中处理任务 应用程序将根据用户的使用情况创建任务并将其排队到任务队列中 然后单独的线程处理任务 即使队列为空 保持线程活动并使用它来处理排队任务也至关重要 我尝试过几种实现TaskSchedul
  • Cocoa - 在另一个 xib 上显示 xib

    谁能告诉我如何 或指导我有关信息 在另一个 xib 笔尖 上显示 xib 笔尖 我希望如何放置它 以便我可以以编程方式将它移动到主笔尖 就像这样 这显然不起作用 void drawRect NSRect dirtyRect NSRect c
  • 代码编译期间遇到警告消息“使用或覆盖已弃用的 API”

    我编译了我的程序并收到以下错误 我该如何解决呢 Note ClientThreadClients java uses or overrides a deprecated API Note Recompile with Xlint depre
  • Unity3d 中的多线程脚本调用

    我试图在Unity3d中实现多线程脚本执行 但是Unity库似乎没有提供方法 我们必须使用Mono提供的System Threading 但他们提到 Unity Scripting 不是线程安全的 我可以使用 System threadin
  • 为什么 WebView 中的 dataWithPDFInsideRect 不能在 Mavericks 上创建高质量的 PDF?

    Run 示例项目 https github com tvarghese TestWebView并观察桌面上生成的输出 PDF 名为保存网页 pdf 粘贴感兴趣的代码片段 NSURL url NSBundle mainBundle URLFo

随机推荐