OpenFL and GPU usage

Hi! I have created a similar thread here:

http://community.openfl.org/t/load-images-gpu/?source_topic_id=1379

However, now, with things taking form in my mind, I think I can better state the approach I want to take with my game.

How do I load and use GLTexture objects in an OpenFL project? I want to avoid using Bitmap and BitmapData as I heavily use big PNGs on this project (variuos fullHD spritesheets) and when using these classes, the images are loaded and kept on the RAM while I want them to be loaded only on the GPU.

I am sorry if I am still expressing myself in a rather confusing way, but I would be very grateful if someone could help me with this issue!

There isn’t a native way of just using gl textures in openfl. (Well, there is… you could use openfl.gl and manually render everything… But this is probably overkill)

Bitmaps contain a reference to both BitmapData (stored in the ram) and a GLTexture (stored on the GPU). So you are going to end up with duplication.

This shouldn’t necessarily be a problem, though; Unused ram will just be pushed aside to page.

Is there an existing problem you are trying to solve? Don’t get too caught up on premature optimisation.

Alternatively… if you really wanted to delete the local copy… you could maybe do this…

@:access(openfl.display.BitmapData)
@:access(lime.graphics.Image)
function free_local_bitmap(bitmap:openfl.graphics.Bitmap){
    bitmap.bitmapData.__image.buffer = null;
}

That being said… don’t do this. It will probably just break everything terribly xD

Again - is there an actual current problem you are trying to solve? If so - what is it? there may be better ways of solving it. If not - Let go of the urge to try and prematurely optimise. It’s just a trap.

1 Like

This is hacky too, You could set __image to null after uploading it to GPU, and it will be garbage collected if it’s not cached in somewhere else.
You can no longer call setPixels, getPixels, or any other method that access to raw data of that BitmapDaa, of course.

import openfl.display.BitmapData;
import openfl.display.Bitmap;
import openfl._internal.renderer.RenderSession;
import openfl.display.PixelSnapping;

class HardwareBitmap extends Bitmap
{

	public function new (bitmapData:BitmapData = null, pixelSnapping:PixelSnapping = null, smoothing:Bool = false) {
		
		super (bitmapData, pixelSnapping, smoothing);
		
	}

	@:noCompletion @:dox(hide) public override function __renderGL (renderSession:RenderSession):Void {
		
		super.__renderGL (renderSession);
		@:privateAccess bitmapData.__image = null;
		
	}
    
}
1 Like

Thank you the replies!

I have been bery busy the last couple of days with final touches on the game demo. Today, with all the assets already in the game, it is using 52% of my notebook RAM (4GB). I think the content is being cached somewhere and is not being released or sent to pagination.

Sometimes the application even crashes reporting that it is not being able to allocate any more RAM.

I will try your suggestions and report back!

I tried the HardwareBitmap approach @vroad suggested, but it doesn’t work on legacy mode (that I need due to gradientFill not being implemented in the new version of openfl) and when I run the game, it crashes after a couple of seconds complaining about an Invalid field access in the call:

super.__renderGL (renderSession);

I didn’t follow @ProPuke 's advice because he explicitly asked me to do it, but now you should have an idea of my problem xD. Maybe I should’t load the assets with Asset.getBitmapData?

I should get some memory freed between the stages with Assets.cache.clear() but it is not working =/. I don’t know what is keeping the bitmapdata from being collected.

Have you tried using Assets.getBitmapData with cache set to false, or have you tried going back to Assets and clearing the cache for the files you don’t need anymore?

Wow, I didn’t know that there was an option to load with cache set to false =). I will try to use it!

I call:

Assets.cache.clear();

when a new stage is loaded, but the memory is not freed =/

Found the problem. I was keeping reference of the Bitmaps on an array for debug purposes =/

That would do it! :slight_smile:

You can also try .dispose if you are paranoid, it is supposed to make sure the data is destroyed, even if you still have references to the BitmapData, though in practice, I’ve sometimes seen issues and have found normal garbage collection to be safest

Thanks @singmajesty!

Now that the big problem is solved, I would like to know if there is a way to solve the small one. What can I do to not have these images loaded on the RAM at all? Is there a way to achieve that?

That might not be possible without doing custom GL calls, it’s designed to keep it in memory, and upload to the GPU when necessary (because it isn’t uploaded yet, or it’s changed, etc). The GL context can be lost, so keeping the data let’s us recreate the context without an error, stuff like that :smile:

A GLView would be the other option I can think of

Thank you for the quick reply!

You mean using Stage3D? Is it fully available in all platforms?

Stage3D, or you can use your own GL calls, too, if you don’t need to target Flash

2 Likes