是否需要在主线程上绘制到 MTKView 或 CAMetalLayer?
Is drawing to an MTKView or CAMetalLayer required to take place on the main thread?
众所周知,在 AppKit
或 UIKit
中更新用户界面需要在主线程上进行。 Metal 在呈现 drawable
时是否有相同的要求?
在我一直玩弄的层托管 NSView
中,我注意到我可以从 dispatch_queue
调用 [CAMetalLayer nextDrawable]
而不是 main_queue
。然后我可以像往常一样更新该可绘制对象的纹理并呈现它。
这 似乎 可以正常工作,但我觉得这很可疑。除非我忽略了文档中的某些内容,否则我找不到任何提及 Metal 的主线程要求(支持或反对)。
(我正在 macOS 10.13 上进行测试,但我假设 iOS 的主线程要求也相同......?)
在后台线程上绘制是安全的。 docs for -nextDrawable
说:
Calling this method blocks the current CPU thread until a new drawable is available.
(重点加了。)如果只能在主线程调用,那估计就没那么泛化了。此外,Apple 的一般建议是避免阻塞主线程,因此您认为他们会在这里以某种方式指出这一事实,例如建议您不要调用它,除非您非常确定它不会阻塞。
关于可绘制对象的使用方式(而不是获取方式),请注意典型的用例是调用命令缓冲区的 -presentDrawable:
方法。该方法便于添加预定的处理程序块(如通过 -addScheduledHandler:
),该处理程序块随后将在可绘制对象上调用 -present
。未指定处理程序块将在哪个线程或队列上调用,这表明无法保证对可绘制对象的 -present
调用将在主线程上发生。
即使在那之后,可绘制对象在屏幕上的实际呈现在对 -present
的调用中也不是同步的。可绘制对象会等待渲染或写入其纹理的任何命令完成,然后才显示在屏幕上。它没有具体说明异步性是如何实现的,但它进一步表明调用哪个线程 -present
并不重要。
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 中有一些关于多线程的讨论。请注意,这里讨论了由后台线程填充的命令缓冲区,并且没有关于使用可绘制对象的具体警告。同样,这是一种缺乏证据的争论,但我认为这很清楚。他们确实指出,一次只能有一个线程作用于给定的命令缓冲区,因此他们正在考虑线程安全问题。
众所周知,在 AppKit
或 UIKit
中更新用户界面需要在主线程上进行。 Metal 在呈现 drawable
时是否有相同的要求?
在我一直玩弄的层托管 NSView
中,我注意到我可以从 dispatch_queue
调用 [CAMetalLayer nextDrawable]
而不是 main_queue
。然后我可以像往常一样更新该可绘制对象的纹理并呈现它。
这 似乎 可以正常工作,但我觉得这很可疑。除非我忽略了文档中的某些内容,否则我找不到任何提及 Metal 的主线程要求(支持或反对)。
(我正在 macOS 10.13 上进行测试,但我假设 iOS 的主线程要求也相同......?)
在后台线程上绘制是安全的。 docs for -nextDrawable
说:
Calling this method blocks the current CPU thread until a new drawable is available.
(重点加了。)如果只能在主线程调用,那估计就没那么泛化了。此外,Apple 的一般建议是避免阻塞主线程,因此您认为他们会在这里以某种方式指出这一事实,例如建议您不要调用它,除非您非常确定它不会阻塞。
关于可绘制对象的使用方式(而不是获取方式),请注意典型的用例是调用命令缓冲区的 -presentDrawable:
方法。该方法便于添加预定的处理程序块(如通过 -addScheduledHandler:
),该处理程序块随后将在可绘制对象上调用 -present
。未指定处理程序块将在哪个线程或队列上调用,这表明无法保证对可绘制对象的 -present
调用将在主线程上发生。
即使在那之后,可绘制对象在屏幕上的实际呈现在对 -present
的调用中也不是同步的。可绘制对象会等待渲染或写入其纹理的任何命令完成,然后才显示在屏幕上。它没有具体说明异步性是如何实现的,但它进一步表明调用哪个线程 -present
并不重要。
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 中有一些关于多线程的讨论。请注意,这里讨论了由后台线程填充的命令缓冲区,并且没有关于使用可绘制对象的具体警告。同样,这是一种缺乏证据的争论,但我认为这很清楚。他们确实指出,一次只能有一个线程作用于给定的命令缓冲区,因此他们正在考虑线程安全问题。