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