dirkwhoffmann / vAmiga

vAmiga is a user-friendly Amiga 500, 1000, 2000 emulator for macOS
https://dirkwhoffmann.github.io/vAmiga
Other
293 stars 24 forks source link

Add GPU texture support to the screen recorder #765

Closed dirkwhoffmann closed 1 year ago

dirkwhoffmann commented 1 year ago

Right now, the screen recorder can only record the textures that are produced by the emulator. All post-processing stuff such as CRT effects cannot be recorded. It'll be nice if the GPU textures could be recorded, too.

dirkwhoffmann commented 1 year ago

For recording the GPU texture, I've hacked together a small prototype. After a frame has been drawn on the GPU side, the frame buffer is read back and copied into a memory buffer which is accessible by the screen recorder. Instead of feeding FFmpeg the emulator texture, the frame buffer data is used. Function-wise, it works: Now I am able to produce videos containing all post-processing effects applied on the GPU side. E.g., this is a scene from Batman Rises with the CRT video settings enabled (scanlines, dot mask, etc.):

Bildschirm­foto 2022-12-16 um 19 19 10

There is a problem, though. vAmiga is no longer able to process everything in real-time, not even on my MacBook Pro M1. CPU frequency drops from 7 MHz to under 4 MHz ☹️. Yet, I haven't checked where the bottleneck is. Either copying the frame buffer takes too much time or FFmpeg is too slow because the video resolution is much higher now.

dirkwhoffmann commented 1 year ago

More findings:

Copying the framebuffer back from GPU space to CPU space causes the slowdown. Fortunately, it's not due to bandwidth limitations, so the problem can (most likely) be worked around.

I've hacked together another prototype with a modified fragment shader. The new shader creates a copy of the frame buffer in a separate texture. Instead of the frame buffer, the contents of this texture is later copied back into CPU space and handed over to the recorder. I need to do more experiments, but it seems to remove the speed bottleneck.

dirkwhoffmann commented 1 year ago

My workaround seems to work. I've been able to record the framebuffer contents of Batman Rises in real-time:

https://www.youtube.com/watch?v=XEizCj81zVQ

The video was recorded with the default video settings for CRT monitors and a bitrate of 4096 kBits.

There are still issues though. Because the framebuffer texture is written inside the fragment shader, the texture is sometimes written and read at the same time. This results in "mixed frames":

Bildschirm­foto 2022-12-17 um 15 29 07

To work around this issue, double-buffering of the framebuffer texture should be used.

dirkwhoffmann commented 1 year ago

I've run some more experiments and came to the conclusion that bandwidth is indeed a problem. Although it seems like recording is possible in real-time now, there are occasional frame drops. It simply takes too much time to feed back the framebuffer back into the emulator. This makes the planned feature pretty much useless, because the same quality of result can be achieved with an external recording tool. I'll revert to the old screen recording code...

dirkwhoffmann commented 1 year ago

Old code is back. Issue closed.