HaxeFlixel / flixel

Free, cross-platform 2D game engine powered by Haxe and OpenFL
https://haxeflixel.com/
MIT License
2k stars 444 forks source link

[ENHANCEMENT] Support FlxGraphic.dump() to allow for GPU-only textures #3034

Open EliteMasterEric opened 9 months ago

EliteMasterEric commented 9 months ago

OpenFL has functionality available which flags image data as dumped and removes the contents of BitmapData from RAM (while still holding a reference to the texture that has been uploaded to VRAM). This GREATLY reduces memory usage at the expense of being unable to draw on the graphic, which is still fine in a wide variety of use cases. Depending on the type of graphic I think this should probably even be the default in many cases, requiring the graphic to be explicitly "undumped" to be drawn on.

Doing this would involve calling disposeBitmap() on the underlying BitmapData. The next time the BitmapData is rendered, BitmapData.getTexture() is called; when this happens, OpenFL instantiates the hardware texture (__texture) and calls __uploadFromImage to populate it. Once this is done, OpenFL will use __texture when rendering and the BitmapData.image is no longer necessary. If disposeBitmap() has been called, image is set to null after the texture is instantiated so the array can be garbage collected.

The above functionality only works on a hardware renderer (such as a native build supporting OpenGL). When using a software renderer (i.e. Flash Player, or desktop targets without OpenGL), OpenFL is not capable of uploading the texture to VRAM this way; disposeImage() will not cause image to dispose and thus nothing should break.

I do not know what happens when disposeImage() is used on the HTML5 target, it could use a texture provided by WebGL or it could use the software rendering functionality.

The above functionality has been experimented with somewhat in FNF mod projects (resulting in massive decreases in memory), but having it available in the main branch would be a major improvement and at this point in time it is probably the most important change I want to see come to Flixel 6.

Note also that disposeImage() is flagged as Beta in the documentation but has existed for about 8 years so I assume it's mostly fine.

DigiEggz commented 6 months ago

The above functionality has been experimented with somewhat in FNF mod projects (resulting in massive decreases in memory), but having it available in the main branch would be a major improvement and at this point in time it is probably the most important change I want to see come to Flixel 6.

Can you link to a project that features this change? I'd like to take a look at implementing and testing whatever they have done, as there have also been some PRs in OpenFL that claim to improve performance when using disposed image bitmaps.

EliteMasterEric commented 6 months ago

It appears Psych Engine has it: https://github.com/ShadowMario/FNF-PsychEngine/blob/65494a3375fbceb5d74cfd2231ba668790842a4f/source/backend/Paths.hx#L273

DigiEggz commented 6 months ago

@EliteMasterEric Thanks for the quick reply. Do you have any starting point suggestions for how we could begin to test disposing bitmaps? I've been looking through the HaxeFlixel graphics code and am not sure how it compares to Psyche Engine's approach.

EliteMasterEric commented 6 months ago

Currently, Flixel loads Bitmaps into RAM automatically. This is done to enable functionality to draw onto sprites. Simply overriding the default behavior would cause any applications using this to cease functioning.

I think the ideal implementation is one in which one can set a flag (similar to DEFAULT_PERSIST) which defines whether graphics are automatically disposed once uploaded to the GPU; you could then override the behavior on a case-by-case basis.

DigiEggz commented 6 months ago

Can you point to toward any core locations or starting points where I could test out disposing of bitmaps, despite the immediate problems it will cause? I'm hunting for a good jumping off point but there are quite a few moving parts to the drawing system.