Metal for animated bitmaps?

Is using Metal or MetalKit an efficient way to get (mutable, animated, CPU generated, 2D RGB) bitmap arrays to the display? If so, would it be more efficient to create a new Metal texture from bitmap for the rendered rectangle every frame? Or to use a mutable texture? Or to use a compute shader to directly pass pixels from a CPU generated buffer to the drawable view without creating an intermediate texture? Or some other sequence?

My current solution uses Core Graphic's CGBitmapContextCreateImage(), and sets the contents of a CALayer with a new image every frame. Would using Metal result in a measurable performance difference on the newest iOS devices?

Replies

Short answer is, that it depends. I mean, using Metal is probably most efficient way of dealing with GPU, but whether it is worth the effort in this case is up to you. Because for example:


1) If "CPU generated" means some kind of procedural graphics, and you have algorithm for generating nth frame of animation (like, say, some fractals or simple bouncing rectangle) then you shouldn't bother with any textures at all. What you'd want to do is write vertex shader/fragment shader taking parameters (like frame number) as uniforms, and generating nth animation frame directly to the rendering target. No data transfer, no data storage, no memory used, about as effective as it gets.


2) If "CPU generated" requires some memory, because for example it is something like 2d cellular automaton or 2d fluid simulation, then you should alloc as many textures as fields your simulation requires, and this times to (for two frames). Then create a) shaders for initializing initial texture values and b) shaders for simulating step from frame n -> to frame n+ 1. Then you just run your simulation on GPU, for example just before rendering or just after that. No CPU-GPU transfer, not that much memory used, and so on.


3) Finally, if animation in question is something that can be done on CPU only (or is impractical to move code to GPU), like raytraced scene, or perhaps motion - capture, or hand-drawn animation, then, and only then I'd consider feeding GPU from CPU. And here devil's in details too, because you'd want different behavior for something like big movie that won't fit in GPU memory, and different for something little and light. I won't use many textures, though. A texture array, or just a big texture + tiling would be a better choice.


Hope that helps

Michal