godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.83k stars 21.14k forks source link

Image function save_png is extremely slow #51868

Open likeich opened 3 years ago

likeich commented 3 years ago

Godot version

3.3.2.stable

System information

Zorin OS 16 (Ubuntu 20.04 LTS) Ryzen 5 2600

Issue description

I need to save the screen as a png every frame for a utility I'm working on. Just the code below is taking 60-100 msecs to run. The first two lines are taking 20-30 msecs to run and saving the png is taking ~50 msecs (timed in GDscript and with the debugger). The performance is poor in Godot on WINE too. Just tested on 4.0 as well and the problem persists there too.

var image: Image = get_viewport().get_texture().get_data()
image.flip_y()
image.save_png(get_full_image_path())

I'm not sure if this is a bug or a limitation, but it seems to me that saving a png shouldn't be this performance-intensive.

Steps to reproduce

Put the code above in the _process function with a valid path.

Minimal reproduction project

Use the above code.

Calinou commented 3 years ago

PNG encoding is relatively slow by nature, and I don't think much can be done to speed it up. You can try using a C++ profiler to see where the bottleneck is. Usually, what's done to speed up PNG saving is to move it to a dedicated thread so you can do other things while the PNG is being saved. It would certainly help a lot in my offline video rendering demo if it was implemented there :slightly_smiling_face:

If you save a decently large PNG in GIMP, you'll also notice that it can take several seconds easily.

Compression is not the only thing that makes saving a PNG viewport slow, but it's certainly a factor. If you modify the source code to disable compression, you may get a 1.2× speedup or so.

See also https://github.com/godotengine/godot-proposals/issues/3083. Just to show that this problem isn't Godot-specific, I gave the same advice to the SHADERed developer and it worked out well there: https://github.com/dfranx/SHADERed/issues/23#issuecomment-540710543