0
votes

I've got my eye upon Metal as an option for performing very performant pixel copies at 60fps.

Let me phrase my question in terms of an existing technology...

I have the attached 1920x1080 NSImage and I want to blit this into an NSView in a "mosaic"-type fashion. Assume this image is a frame of video, so it would more likely be an RGBA32-formatted CVPixelBuffer). Each of these 9 coloured regions could end up in random locations on the screen.

A mosaic of tiles

I could use the drawInRect function from the NSImage API to perform 9 such copy calls from the source of my image to the target NSView. The data model in this case would involve 9 source-target CGRect pairs, and then 9 such calls to perform the copies.

I suspect this is a very slow approach as compared to what could happen in Metal. It could possibly be accelerated if the NSView were Metal-backed.

Can someone enlighten me as to what a very performant Metal version of this would be?

The intent would be to upload the entire texture as-is, once to the GPU and then issue a set of GPU-based calls to (eventually) blit the texture's regions onto screen. Assume that the source pixel format is RGBA32. The intent obviously is for only one CPU->GPU pixel data transfer (no round trips!).

Would such an approach first involve the use of the copyFromBuffer to get the image on the GPU, then a set of 9 calls to copyFromTexture to finalize the texture for presentation? Then mapping that texture onto a quad on-screen. Just surmising. What would this look like?

(The fact that Metal2 now has some one-time argument buffers is appealing to me and may just be a lower-level implementation of the two aforementioned functions from the MTLBlitCommandEncoder. If this is a more performant lower-level implementation, what would that look like instead?)

Any guidance on this would be appreciated.

1

1 Answers

2
votes

I would think that just about any approach that's not overly complicated would be plenty performant. There are very few vertices and only one texture involved.

You could create the initial texture using MTKTextureLoader and its methods to create a texture from a CGImage or even from the original image data source (URL or image asset). Or, since you mentioned Core Video, you can get Metal textures directly from that.

If you want to draw different sectors of that texture to different sectors of the view, I'd draw 9 quads (in a single draw call) and just use the appropriate texture coordinates for each one. No need to copy chunks of the texture from place to place.