這篇“怎么使用Flutter+Metal實現圖像處理”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么使用Flutter+Metal實現圖像處理”文章吧。
Flutter使用CVPixelBuffer和iOS交互,我們可以直接使用CVPixelBuffer創建MTLTexture,然后將MTLTexture設置為渲染目標。這樣Metal框架可以直接將渲染結果寫入CVPixelBuffer,達到更加高效的目的。
主要初始化Device
,PipelineState
,CommandQueue
三個對象。我們需要依賴Device
分配各種Metal資源,PipelineState
管理著渲染流水線的各個環節的配置,比如vertex shader,fragment shader,輸出像素格式等。CommandQueue
用于管理執行的繪制命令。
_device = MTLCreateSystemDefaultDevice(); id<MTLLibrary> lib = [_device newDefaultLibrary]; id<MTLFunction> vertexFunc = [lib newFunctionWithName:vertexFuncName]; id<MTLFunction> fragFunc = [lib newFunctionWithName:fragFuncName]; MTLRenderPipelineDescriptor *renderPipelineDesc = [MTLRenderPipelineDescriptor new]; renderPipelineDesc.vertexFunction = vertexFunc; renderPipelineDesc.fragmentFunction = fragFunc; renderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; _pipelineState = [_device newRenderPipelineStateWithDescriptor:renderPipelineDesc error:nil]; _commandQueue = [_device newCommandQueue];
首先創建一個CVPixelBuffer
對象
NSDictionary *pixelAttributes = @{( id )kCVPixelBufferIOSurfacePropertiesKey : @{}}; CVPixelBufferCreate( kCFAllocatorDefault, imageWidth, imageHeight, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef)pixelAttributes, &_renderTargetPixelBuffer);
利用CVMetalTextureCacheCreateTextureFromImage
從CVPixelBuffer
創建MTLTexture
CVReturn ret = CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, _mtContext.device, nil, &_textureCache); CVMetalTextureRef renderTargetMetalTextureRef; ret = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, _renderTargetPixelBuffer, nil, MTLPixelFormatBGRA8Unorm, imageWidth, imageHeight, 0, &renderTargetMetalTextureRef); id<MTLTexture> mtlTexture = CVMetalTextureGetTexture(renderTargetMetalTextureRef);
CommandQueue
獲得一個CommandBuffer
,用于保存需要執行的繪制命令_activeCmdBuffer = [_commandQueue commandBuffer];
MTLRenderPassDescriptor
設置本次繪制的相關配置,比如繪制到哪里,這里指定通過CVPixelBuffer
創建出來的MTLTexture
,是否清除當前內容,清除的顏色MTLRenderPassDescriptor *renderPassDesc = [MTLRenderPassDescriptor new]; renderPassDesc.colorAttachments[0].texture = target; renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1);
CommandBuffer
和MTLRenderPassDescriptor
創建一個MTLRenderCommandEncoder
_activeEncoder = [_activeCmdBuffer renderCommandEncoderWithDescriptor:renderPassDesc];
MTLRenderCommandEncoder
所在的PipelineState
[_activeEncoder setRenderPipelineState:_pipelineState];
MTLRenderCommandEncoder
綁定Buffer
和Texture
,在Metal里,Uniform和Vertex Buffer 都是通過MTLBuffer綁定到Shader中[_activeEncoder setVertexBuffer:vertexBuffer offset:0 atIndex:0]; [_activeEncoder setFragmentBuffer:uniformBuffer offset:0 atIndex:0]; [_activeEncoder setFragmentBuffer:texture offset:0 atIndex:0];
[_activeEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:vertexCount instanceCount:1];
MTLRenderCommandEncoder
[_activeEncoder endEncoding];
CommandBuffer
[_activeCmdBuffer commit];
[_activeCmdBuffer commit]
之前設置completedHandler
// 同步等待 [_activeCmdBuffer waitUntilCompleted]; // 異步等待 [_activeCmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull buf) { }];
到此繪制的內容就已經在CVPixelBuffer
中了,再將CVPixelBuffer
提交給Flutter顯示即可
以上就是關于“怎么使用Flutter+Metal實現圖像處理”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。