绘制到 MTKView 或 CAMetalLayer 是否需要在主线程上进行? [英] Is drawing to an MTKView or CAMetalLayer required to take place on the main thread?

查看:32
本文介绍了绘制到 MTKView 或 CAMetalLayer 是否需要在主线程上进行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,更新AppKitUIKit 中的用户界面需要在主线程上进行.Metal 在呈现 drawable 时是否有相同的要求?

It's well known that updating the user interface in AppKit or UIKit is required to take place on the main thread. Does Metal have the same requirement when it comes to presenting a drawable?

在我一直在玩的层托管 NSView 中,我注意到我可以从 dispatch_queue 调用 [CAMetalLayer nextDrawable] 不是 main_queue.然后我可以像往常一样更新该 drawable 的纹理并呈现它.

In a layer-hosted NSView that I've been playing around with, I've noticed that I can call [CAMetalLayer nextDrawable] from a dispatch_queue that is not the main_queue. I can then update that drawable's texture as usual and present it.

看起来工作正常,但我觉得这很可疑.除非我忽略了文档中的某些内容,否则我找不到提到 Metal 的主线程要求(支持或反对).

This appears to work properly, but I find that rather suspicious. Unless I've overlooked something in the documentation, I can find no mention of Metal's main thread requirements (either for, or against).

(我正在 macOS 10.13 上进行测试,但我认为 iOS 的主线程要求也相同......?)

推荐答案

在后台线程上绘图是安全的.-nextDrawable 的文档说:

It is safe to draw on background threads. The docs for -nextDrawable say:

调用此方法会阻塞当前 CPU 线程,直到有新的可绘制对象可用.

Calling this method blocks the current CPU thread until a new drawable is available.

(强调.)如果它只能在主线程上调用,那可能不会如此普遍.此外,Apple 的一般建议是避免阻塞主线程,因此您会认为他们会在这里以某种方式指出这一事实,例如建议您不要调用它,除非您非常确定它不会阻塞.

(Emphasis added.) If it could only be called on the main thread, that would probably not be so generalized. Also, Apple's general advice is to avoid blocking the main thread, so you'd think they would call out that fact in some way here, such as advising you not to call it unless you're pretty sure it won't block.

关于如何使用 drawable(而不是获取),请注意一个典型的用例是调用命令缓冲区的 -presentDrawable: 方法.该方法可以方便地添加调度处理程序块(如通过 -addScheduledHandler:),然后在可绘制对象上调用 -present.未指定将在哪个线程或队列上调用处理程序块,这表明无法保证可绘制对象上的 -present 调用将在主线程上发生.

For how the drawable is used (rather than obtained), note that a typical use case is to call the command buffer's -presentDrawable: method. That method is a convenience for adding a scheduled handler block (as via -addScheduledHandler:) which will then call -present on the drawable. It is unspecified what thread or queue the handler blocks will be called on, which suggests that there's no promise that the -present call on the drawable will happen on the main thread.

即使在那之后,可绘制对象在屏幕上的实际呈现在对 -present 的调用中也不是同步的.drawable 会等待任何渲染或写入其纹理的命令完成,然后才呈现给屏幕.没有具体说明如何实现异步性,但它进一步表明调用 -present 线程无关紧要.

And even after that, the actual presentation of the drawable to the screen is not synchronous within the call to -present. The drawable waits until any commands that render or write to its texture are completed and only then presents to the screen. It's not specified how that asynchronicity is achieved, but it further suggests that it doesn't matter what thread -present is called on.

Metal 编程指南,虽然它并不像人们希望的那样直接.特别参见 有关多线程、命令缓冲区和命令编码器的部分.请注意,这里讨论了由后台线程填充的命令缓冲区,并且没有关于使用可绘制对象的具体警告.同样,这是缺乏证据的争论,但我认为这很清楚.他们确实指出一次只能有一个线程作用于给定的命令缓冲区,因此他们正在考虑线程安全问题.

There's a bit of discussion about multi-threading in the Metal Programming Guide, although it's not quite as direct as one might hope. See especially the section on Multiple Threads, Command Buffers, and Command Encoders. Note that there's a discussion of command buffers being filled by background threads and no specific warning about working with drawables. Again, it's sort of argument by lack of evidence, but I think it's clear. They do call out that only a single thread may act on a given command buffer at a time, so they are considering thread safety questions.

这篇关于绘制到 MTKView 或 CAMetalLayer 是否需要在主线程上进行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆