Update Bitmap after BitmapData manipulation without new instance

Like in the topic.

I would like to redraw a Bitmap after its BitmapData instance has been updated. It updates if I assign a clone of the old one (the instance changes) it works…

How to do this without a duplication?

Would bitmap.bitmapData = bitmap.bitmapData trigger a redraw?

as the set_bitmapData() function contains the call to the internal __rebuild() function, I would say yes. It should definitively work :wink:

That was the first thing I’ve tried and believe me it did not work…

Try @:privateAccess bitmap.__setRenderDirty().

Only in legacy mode.

Where is changing the BitmapData not working? It should handle dirty flags automatically

So this exact code does not work:

bitmap.bitmapData.setVector(rect, newPixels);
bitmap.bitmapData = bitmap.bitmapData;
@:privateAccess bitmap.__setRenderDirty();

Only cloning does the job, but with unnecessary allocation…

Btw. this library https://github.com/azrafe7/hxPixels manages to do this without the duplication, bu uses some low-level lime magic. See this lines: https://github.com/azrafe7/hxPixels/blob/master/src/hxPixels/Pixels.hx#L295

Ps. This lib also works 5x faster for pixel manipulation than getVector/setVector…

Thanks!

It should be fixed now, also, looks like that method uses setPixels instead of setVector. Try and see that is faster for you?

By the way, the fix was made in Lime, and here’s the sample code that I’m using:

package;


import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.Sprite;
import openfl.events.Event;


class Main extends Sprite {
	
	
	public function new () {
		
		super ();
		
		var bitmapData = new BitmapData (100, 100, false, 0xFFFF0000);
		var bitmap = new Bitmap (bitmapData);
		addChild (bitmap);
		
		addEventListener (Event.ENTER_FRAME, function (_) {
			
			var pixels = bitmapData.getPixels (bitmapData.rect);
			pixels.position = 0;
			
			var length = Std.int (pixels.length / 4);
			
			for (i in 0...length) {
				
				pixels.writeUnsignedInt ((0xFF << 24) | Std.int (Math.random () * 0xFFFFFF));
				
			}
			
			pixels.position = 0;
			bitmapData.setPixels (bitmapData.rect, pixels);
			
		});
		
	}
	
	
}

I’ve been benchmarking various solutions for fast per-pixel manipulation and here are my conclusions (my main target is html5 but I also bechmark cpp target on linux):

  • getPixels/setPixels is much faster than getVector/setVector BUT iteration and modification of ByteArray is much slower (10x) than on typed Array - at least in html5, on linux target there is no significant difference. So in the end it is faster to use getVector/setVector for html5.
  • the fastest and least memory hungry combo for now is to use the hxPixels library in html5
  • the best way to do these kind of stuff is to use a hardware shader - they are going to be merged to openfl soon, but I need a fallback in case of canvas/dom renderer

Perhaps you could use a typed array, then convert to Bytes, then convert that to ByteArray

I want to revisit ByteArray again to make it lighter. It really is a wrapper around a typed array on HTML5, though