我有一个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。 在许多屏幕绘制中,我认为,这样可以减少View交换期间的帧丢失,但是我想要一个万无一失的万能解决方案。基本上,我需要的是仅在strokeUIView准备显示后才清除strokeViewMetal。任何指针将不胜感激
答案 0 :(得分:0)
presentsWithTransaction
属性设置为true时,99%的测试都解决了MTKView和UIView之间的同步问题。根据Apple的文档:
将此值设置为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
这样做是为了防止Core活动在我们准备展示MTKView的drawable之前结束。
所有这些设置之后,我可以简单地做到:
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
话虽如此,我确实时不时地看到视图的重叠,但是频率要低得多