HeapsIO / heaps

Heaps : Haxe Game Framework
http://heaps.io
MIT License
3.22k stars 340 forks source link

TextureCache does not work well with 2D filters if filtered object frequently changes size #1234

Open Yanrishatum opened 2 months ago

Yanrishatum commented 2 months ago

Purpose of texture is cache is to, well, reduce texture allocations, however the way TextureCache currently is implemented makes it to do a lot of texture allocation in particular corner cases.

If object boundaries are changing frequently, it will cause cache to reallocate the filter texture every time, as it would dispose of old one and not keep it in cache, and even it would - it'd just dispose of it on next frame, which defeats the purpose of texture cache.

Real case example: h2d.Anim with frames of varying size. When frame changes, so does the Bounds of animation, causing assigned filter to request different texture size, and disposing of the old one, and thus causing texture allocs every animation frame change. Issue's brought up @c_l_y_d_e_ from discord, during Into the Necrovale dev.

It may be smart to use something along the lines of hxd.impl.CacheAllocator where textures are not disposed immediately or next frame but rather kept for a fixed amount of time.

Reproduction code:

Repro ```haxe import hxd.Timer; import h2d.filter.Nothing; import h3d.mat.Texture; import h2d.Tile; import h2d.Bitmap; import h2d.Object; import hxd.App; class IssueTexCache extends App { var filtered: Object; var resizing: Bitmap; static function main() { new IssueTexCache(); } override function init() { filtered = new Object(s2d); resizing = new Bitmap(Tile.fromTexture(Texture.genChecker(32)).center(), filtered); filtered.filter = new Nothing(); filtered.setPosition(s2d.width>>1, s2d.height>>1); } override function update(dt:Float) { resizing.setScale(Math.cos(Timer.lastTimeStamp) * 0.5 + 1); super.update(dt); } } ```
csclyde commented 2 months ago

Thank you @Yanrishatum ! Truly helpful, as usual.