如何从MTKView无缝切换到UIView显示



我有一个MTKView,我将其内容绘制到UIView中。我想在没有明显变化的情况下将显示从MTKView切换到UIView。如何实现?

目前,我有

let strokeCIImage = CIImage(mtlTexture: metalTextureComposite...) // get MTLTexture
let imageCropCG = cicontext.createCGImage(strokeCIImage...) // convert to CGImage
let layerStroke = CALayer() // create layer
layerStroke.contents = imageCropCG // populate with CGImage
strokeUIView.layer.addSublayer(layerStroke)  // add to view
strokeUIView.layerWillDraw(layerStroke) //heads up to strokeUIView

以及layerWillDraw((中清除MTKView的委托方法。

strokeViewMetal.metalClearDisplay()

结果是,我每隔一段时间就会看到一个帧下降,其中什么都没有显示。

为了将这两项任务干净地分开,我还尝试了以下方法:

let dispatchWorkItem = DispatchWorkItem{
print("lyr add start")
self.pageCanvasImage.layer.addSublayer(sublayer)
print("lyr add end")
}
let dg = DispatchGroup()
DispatchQueue.main.async(group: dg, execute: dispatchWorkItem)
//print message when all blocks in the group finish
dg.notify(queue: DispatchQueue.main) {
print("dispatch mtl clear")
self.strokeCanvasMetal.setNeedsDisplay()  // clear MTKView
}

想法是将新的CALayer添加到UIImageView,然后清除MTKView。在许多屏幕绘制中,我认为这会减少视图交换过程中的丢帧次数,但我想要一个没有丢帧的万无一失的解决方案。基本上,我所追求的是只有在strokeUIView准备好显示后才清除strokeViewMetal。任何指针都将受到赞赏

当我将MTKView的presentsWithTransaction属性设置为true时,MTKView和UIView之间的同步性问题在99%的测试中都得到了解决。根据苹果的文件:

将此值设置为true将更改此默认行为,以便MTKView同步显示其可绘制内容,使用核心动画事务在可绘制的present((方法被调用。

完成后,绘制循环必须修改为:

commandEncoder.endEncoding()  
commandBuffer.present(drawable)  
commandBuffer.commit()

至:

commandEncoder.endEncoding()  
commandBuffer.commit()  
commandBuffer.waitUntilScheduled()  // synchronously wait until the drawable is ready
drawable.present() // call the drawable’s present() method directly

这样做是为了防止核心活动在我们准备好展示MTKView的绘图之前结束。

有了所有这些设置,我可以简单地:

let strokeCIImage = CIImage(mtlTexture: metalTextureComposite...) // get MTLTexture
let imageCropCG = cicontext.createCGImage(strokeCIImage...) // convert to CGImage
let layerStroke = CALayer() // create layer
layerStroke.contents = imageCropCG // populate with CGImage
// the last two events will happen synchronously
strokeUIView.layer.addSublayer(layerStroke)  // add to view
strokeViewMetal.metalClearDisplay() // empty out MTKView

尽管如此,我确实不时看到观点的重叠,但的频率要低得多

最新更新