Metal 开发教程(一)
原文链接: https://developer.apple.com/documentation/metalkit/mtkview?language=objc
MTKView 用于创建,配置,显示metal对象。MTKView提供了一个MTLRenderPassDescriptor对象,该对象指向一个纹理来渲染内容。MTKView 使用CAMetalLayer来管理drawable对象。MTKView 需要一个MTLDevice对象来管理Metal对象。在绘制之前必须设置device相关属性。
MTKView 提供了3种绘制模式:
- Timed updates: view内容的重绘依赖内部的计时器。此时paused 和 enableSetNeedsDisplay 为NO。该模式用于定期更新的游戏和其他动画内容。
- Draw notifications: 当内容无效时view会进行重绘操作。一般由于调用了setNeedsDisplay方法或其他相关的view行为。paused 和 enableSetNeedsDisplay为YES。该模式用于传统的工作流程序,当数据更改时会进行更新。
- Explicit drawing: 当显式调用draw方法时view会进行重绘操作。paused=YES, enableSetNeedsDisplay=NO。该模式用于创建自定义的工作流程。
无论哪种绘图模式,当view需要更新内容时会调用子类的drawRect:方法或者delegate的drawInMTKView:方法。你需要实现MTKView的子类或提供delegate,无需2种都提供。在你的绘制方法中你可以根据view的descriptor获取rander进行绘制。
每个MTKView都有一个CAMetalLayer;通过实现MTKViewDelegate 来和MTKView的交互。调用MTKView的属性currentRenderPassDescriptor配置render.
MTLRenderPassDescriptor* onscreenDescriptor = view.currentRenderPassDescriptor;
读取此属性时,Core Animation隐式获取当前帧的drawable并将其存储在currentDrawable属性中,配置要绘制的render包括必要的 depth, stencil 和 antialiasing textures。你可以在创建MTLRenderCommandEncoder之前调整descriptor功能。建议尽可能晚的获取drawable,最好在渲染之前立即获取。
当内容渲染完成后,您必须呈现drawable以更新view的内容。呈现内容最方便的方法是在命令缓冲区上调用presentDrawable:方法,然后调用commit方法将命令提交给GPU。
// If there's a valid render pass descriptor, use it to render to the current drawable.
if(onscreenDescriptor != nil) {
id<MTLRenderCommandEncoder> onscreenCommandEncoder = [onscreenCommandBuffer renderCommandEncoderWithDescriptor:onscreenDescriptor];
/* Set render state and resources.
...
*/
/* Issue draw calls.
...
*/
[onscreenCommandEncoder endEncoding];
// END encoding your onscreen render pass.
// Register the drawable's presentation.
[onscreenCommandBuffer presentDrawable:view.currentDrawable];
}
// Finalize your onscreen CPU work and commit the command buffer to a GPU.
[onscreenCommandBuffer commit];
当命令队列计划执行命令缓冲区时,drawable将跟踪该命令缓冲区中自身的所有呈现或写入请求。在命令完成执行之前,操作系统不会在屏幕上显示drawable。通过请求命令缓冲区显示drawable,可以确保在命令队列调度了此命令缓冲区之后显示。在注册drawable的之前,无需等待命令缓冲区完成执行。
为了追求更好的性能,当你准备好要渲染内容的时候来获取render的descriptor,并且尽可能减少控制drawable对象。命令一旦完成应立即释放drawable。