Application crash (Black screen) on android with openfl legacy

Hi

I have an application that built correctly for the windows target whether I use openfl 3 or openfl legacy. But, when targeting android, only the version compiled with openfl 3 is working, the one compiled with the -Dlegacy tag just render as a black screen. As I want to use openfl legacy (I will use haxeflixel), I am trying to debug this and understand why this code is working fine with openfl 3 or openfl legacy on windows but not with openfl legacy on android… Sadly, the adb logcat do not provide me any understandable error. The only thing I have is a warning related to the problematic app (same process ID) but I don’t even know if this is the reason of the black screen issue or not:

W/Adreno200-ES20(31577): <__load_uniform_int:325>: GL_INVALID_OPERATION 

without any stack trace, it is difficult to say and track the issue back to a function that might be bugged…

So, is there any way to have a stack trace on android like on windows, that would return the line in the code where the error or warning originate from?

Also, when using openfl 3, it appears that the library I use (BabylonHX) actually use lime class for rendering whereas when using openfl legacy, it uses openfl counterparts. Indeed, this library uses compiler specific tags with always the “#if lime” tag before the “#if openfl” tag. And when compiling with the openfl command, if there is no -Dlegacy tag, it appears that the compiler in fact consider this as a lime app. So, if for example I have:

#if lime

	typedef ArrayBufferView = lime.utils.ArrayBufferView;
	
#elseif openfl

	typedef ArrayBufferView = openfl.utils.ArrayBufferView;

it appears that, when compiled with openfl 3, it will use lime.utils.ArrayBufferView while if compiled with the -Dlegacy tag (openf legacy), it would use openfl.utils.ArrayBufferView…
So, is there a way to use lime class (that the compiler enter into “lime” conditional tags) with openfl legacy too?

I use lime 2.6.2 and openfl 3.3.3 and can upload my project if someone is interested in help me understand what the problem is and need to compile it himself.

I’m not really sure I know what is wrong with legacy here, either. Is there anything holding you back from using OpenFL 3 without legacy? I believe HaxeFlixel wants a “-Dnext” flag to not use legacy.

OpenFL 3 leverages Lime as the base layer, but legacy does not use Lime at all, this means that Lime APIs are not available when using legacy, unless you do hybrid, but I’m not sure I would use that

Hi singmajesty
Sadly I can’t use -Dnext to use openfl 3 with haxeflixel here as I tried but it introduced too much bugs in my final application to be considered as a viable option yet (problems with Textfield fonts and position, with sound crash, with bitmapdata colortransform not taken into account and more…).
So, I have an application that works well with haxeflixel and openfl legacy in wich I want to introduce some 3D content using BabylonHx. As a consequence, I tested a simple BabylonHx sample with openfl. The thing is this sample renders correctly when using lime on android but crash when using openfl legacy on android (surpprisingly, it renders correctly on windows, whatever the openfl version). So I think we could say it is kind of an openfl issue (as the app renders well with lime, meaning android openGL is able to render the babylonHx sample correctly) that make some bad call to an openGL function on android and made the app to crash probably. The thing is, I don’t know how to trace back to the function at use when the problem occurs (which might help me fix the problem). Did you know if there is any way to obtain a stack trace on android?

Hey Thomas, I’ve been using HaxeFlixel with -Dnext for several months now without issues (Text fonts and positions, sound, bitmapdata colortransform, etc, all work).

What version of HaxeFlixel are you using?

I use version 3.3.11 (haxeflixel “legacy”, not the developpment version)
Did you used it on android? Because it might depend on the target (on flash, everything is fine, whether I use -Dnext or not. But on android, with -Dnext, this is all bugged)

Do you have issues when using the desktop? Flash has no “legacy” target :slight_smile: (same with HTML5)

Just tested it with windows target and, if I do not have all the issues I have on android with the -Dlegacy flag (Textfield font and position works correctly and sound do not seem to crash), I still have the Bitmapdata related issues…

One example of the kind of issues I have (probably not related to an haxeflixel bug but an openfl one though).

Consider the following code:

var bm:BitmapData = new BitmapData(FlxG.width,120,true,0x00000000);
		
var color:Int = 0xFF6C6C6C;
var hs:Shape = new Shape();
var g:Graphics = hs.graphics;
g.beginFill(0xFF6C6C6C);
g.drawRoundRect(10,10,100,100,25,25);
g.endFill();
bm.draw(hs);
			
var plusbm:BitmapData = Assets.getBitmapData("assets/img/plus.png");
	
		
//color the bitmap with wanted color
//TODO: use an optimised function that do not iterate over each pixel...
color = 0xFF00FF00; //green
for (x in 0...plusbm.width) {
   for (y in 0...plusbm.height) {
	if (plusbm.getPixel(x,y) == 0) {
		plusbm.setPixel(x, y, color);
	}
   }
}
	    
		
//draw it on top of the other bitmap
var transfomatrix:Matrix = new Matrix();
var dim:Int = 80;
var scale:Float = dim / 512;
transfomatrix.scale(scale, scale);
transfomatrix.translate((100 - dim) / 2 + 10, (100 - dim) / 2 + 10);


 bm.draw(plusbm, transfomatrix, null, null, null, true);

   var icon:FlxSprite = new FlxSprite(0,0);
   icon.pixels = bm;

with the asset/img/plus.png picture beeing this 512x512 picture:

with openfl legacy, everything works fine. The bm bitmapdata renders as a green plus over a grey square. With openfl -Dnext though, it renders as a green square over a grey one… So it appears the bitmapdata.setPixel() function probably do not act as expected…

you can test this code by adding the generated flxsprite into an flxstate with haxeflixel but the result is probably the same if you render it into a sprite using openfl only (not tested but I assume it won’t change the result)

EDIT: unlike previously said, I also have sound issues with -Dnext on windows target. My application sometimes crash with the message: “Invalid Wav Data Header!” whereas this never happen when compiled with openfl legacy…

Kinda different topic, but similar problems.
I also can not switch to the latest OpenFL version due to numerous problems.
For example, simple TextField like this doesn’t work on my Android tablets (Nexus 7 and Samsung), virtual keyboard appears, but I can’t enter any text.

var txt:TextField = new TextField();
txt.type = TextFieldType.INPUT;
txt.textColor = 0xffffff;
txt.border = true;
txt.borderColor = 0xffffff;
        
addChild(txt);

Don’t you need to set

txt.selectable = true;

?

With selectable = true; it doesn’t work either.

ok then also try with

txt.needsSoftKeyboard = true;

if it doesn’t work, it is most probably a bug (never tested a textfield with a softkeyboard input though, For now, I have my own virtual keyboard class for mobile targets witch allows me to restrict input to a limited set of characters)

Nope, doesn’t work either.

Another example of issue. With a colortransform issue this time:

var bm:BitmapData = new BitmapData(100, 100, true);
				
var gt:BitmapData = Assets.getBitmapData("assets/img/plastic.png"); 
var wscale:Float = 100 / gt.width;
var hscale:Float = 100 / gt.height;
	
var tmatrix:Matrix = new Matrix();
tmatrix.scale(wscale, hscale);
		
bm.draw(gt, tmatrix, new ColorTransform(1, 1, 1, 1, 255, 0, 0, 0), null, null, true);
		
var icon:FlxSprite = new FlxSprite(0,0);
icon.pixels = bm;

plastic.png beeing this picture:

whith openfl legacy, everything is fine whereas whith openfl 3, the generated flxsprite appears grey (should be red) …

This works for me:

var format = new TextFormat ("Katamotz Ikasi", 30, 0x7A0026);
format.align = TextFormatAlign.LEFT;
format.leading = 0;

var textField = new TextField ();
textField.defaultTextFormat = format;
textField.x = 50;
textField.y = 50;
textField.width = 200;
textField.height = 300;

textField.htmlText = "Yougot<font color='#ff0000'>SSword</font>!";
textField.type = INPUT;

addChild (textField);

All these fields aren’t needed (of course) but it’s what I have from a test I did earlier. Give it a try on the “AddingText” sample (really, just adding type = INPUT should do it) and see again if it works. Can you backspace? Can you tap in the center of the field and type?

Hi!

I just went through the Plus sample, the problem was not bm.draw (like I assumed) but in setPixel

This is a funny case :smile:

getPixel (x, y) == 0 will return true on every pixel – as you might know, transparent pixels are treated as #000000 in Flash (since the data is premultiplied)

setPixel (x, y) then, is the difference between here with legacy. The alpha is supposed to be ignored, we set the alpha to 0xFF, making all your green pixels visible. The fix is in Lime now :success:

getPixel (x, y) == 0 will return true on every pixel – as you might know, transparent pixels are treated as #000000 in Flash (since the data is premultiplied)

True. is getPixel(x,y) supposed to return the alpha value though? in witch case I could test if getPixel(x,y) = 0xFF000000 to differentiate black pixel from transparent ones (that should have the value 0x00000000)

Concerning the fix, does it mean next version of openfl 3/lime would now keep the previous alpha value of the modified pixel with setPixel(x,y,v) or do I misunderstood?

You could do getPixel32 (x, y) == 0xFF000000 to differentiate, sure.

If you knew it was this plus graphic, you could also:

plusbm.floodFill (Math.round (plusbm.width / 2), Math.round (plusbm.height / 2), 0xFF00FF00);

This would fill the matching black pixels from the center :smile:

Your code is fixed now on the GIT repository, so the existing getPixel/setPixel you have behaves like Flash

The color transform is currently ignored in bitmapData.draw, looking into it

1 Like

Thanks for noticing the floodFill function. Unfortunately I can’t use it because this is not always the plus.png icon that I want to transform. Indeed, I have a set of black icons with transparent background and I use getPixel() setPixel() to color my desired icon in whatever color I want. So I basically need a function to transform from a bitmap, all the pixels of a given color into another. There probably exist a method more performant than having to iterate on all the pixels of the bitmap though… Anyway, with the getPixel32 and setPixel32 functions, this is just working well for now (didn’t noticed there was these ARGB counterpart of the RGB getPixel() setPixel() functions). Thanks.