Metal App中有两个问题。
currentPassDescriptor
的呼叫正在暂停。显然,我的绘画太多了。MTKViews
感到困惑。问题(1)
我的应用程序中的currentPassDescriptor
有问题。根据文档,有时会阻塞(1.00秒),原因是没有currentDrawable
可用。
背景:我同时播放4个1920x1080高清视频,并作为调试配置平铺到3840x2160秒的外部显示器上。这些AVPlayer
实例的像素缓冲区由4个独立的CVDIsplayLink
回调捕获,并且从该回调内部有对其分配的MTKView
的绘制调用。总共4个MTKViews
是平铺在单个NSWindow
上的子视图,并配置为手动绘制。
我正在手动使用CVDisplayLink
回调。如果不这样做,例如,当鼠标悬停在应用程序的菜单上时,我会口吃。
在每个draw调用中,我做了一些内核着色器工作,然后尝试获取currentPassDescriptor
。如果成功,我将对片段/顶点着色器进行一次遍历,然后呈现可绘制对象。我的代码流遵循Apple的示例代码以及已发布的示例。
根据金属系统跟踪,大多数绘制调用的时间不到5毫秒。 GPU的利用率约为20-25%,而GPU的可用内存则约为25%。我还可以使主线程进入usleep()
1秒钟而不会打h。
在没有任何用户互动的情况下,视频在第一分钟内停顿的可能性约为5%。如果要进行一些UI工作,那么我将看到windowServer
在Instruments中工作。我还注意到,AVFoundation
似乎每个AVPlayer
都会在GPU上缓存大约15帧视频。
如果抽奖电话的节奏不正常,则大约有10%的可能性事情完全停顿,或者某些视频-有些会完全停顿,有些会因1hz更新而停顿,有些根本不会停顿。运行Metal System Trace时,停顿的可能性也较小。停滞不前的电影似乎是为了获得currentPassDescriptor
而这样做的。
在渲染循环中让currentPassDescriptor
块持续约1s的时间确实是一个糟糕的设计。如此之多,以至于我正在考虑完全避开MTKView
,而自己吸引CAMetalLayer
。但是CAMetalLayer
上的文档似乎表明将发生相同的阻止行为。
我还即时获取了这4个像素缓冲区,并将感兴趣的子尺寸区域渲染到主监视器上的4个较小的MTKViews
上;但是如果删除此代码,仍然会出现卡顿现象。
是每个MTKView
还是每个支持CALayer
的可绘制缓冲区限制? maximumDrawableCount
上CAMetalLayer
的文档说该数字需要是2还是3。这个问题与视图的配置有关。
问题(2)
我当前的设置是具有单个内容视图的3840x2160 NSWindow
。 NSView
的这个子类通过引入NSTrackingRectTag
对鼠标光标进行了一些隐藏/显示。 MTKViews
是此内容视图上的平铺子视图。
这是最好的配置吗?,即,一个NSWindow
铺有瓷砖MTKViews
…还是每个窗口我一个MTKView
?
我也不确定如何最好地配置这些窗口/层-即。通过设置(或清除)wantsLayer
,wantsUpdateLayer
和/或canDrawSubviewsIntoLayer
。我目前仅在单个内容视图上将wantsLayer
设置为YES。 任何暗示都很好。
调整这些属性是否仅将所有可用的可绘制对象折叠到衬里层; MTKView
还有2或3个?
NB:我已经附上了我的Metal应用的示例运行。顶部图表上最长的“工作”时间不到5毫秒。绿色/蓝色的团块正在4个MTKViews上渲染。 “工作”会交替播放,因为其中一个视频是60fps的源;其他的都是30fps。