flixel icon indicating copy to clipboard operation
flixel copied to clipboard

Black screen on some Android devices

Open giuppe opened this issue 7 years ago • 34 comments

  • Haxe version: 3.4.188
  • Flixel version: 4.5.1
  • OpenFL version: 8.3.0
  • Lime version: 6.4.0
  • Affected targets: android
  • Android NDK: r10e

I built and launched the FlxCaveGenerator sample on an old testing device (Nexus S (crespo), Android 4.4.2) and I get the HaxeFlixel splashscreen (complete with sound) and a black screen afterwards. I stumbled on this while porting a game of mine to the last HaxeFlixel.

The sample works on 4.3.0 (with openfl 3.6.1 and lime 2.9.1 ofc).

OpenFL/Lime samples (tested with openfl 8.4.0 and 8.3.0) do not show the issue, so it seems a regression in HaxeFlixel.

Also, both the sample and my game work on android emulator with a KitKat image (both with shifted colors, but that is an OpenFL issue).

This is the adb logcat on non working device:

V/Zygote ( 3349): Switching descriptor 32 to /dev/null V/Zygote ( 3349): Switching descriptor 9 to /dev/null D/dalvikvm( 3349): Late-enabling CheckJNI I/ActivityManager( 436): Start proc com.example.myapp for activity com.example.myapp/.MainActivity: pid=3349 uid=10061 gids={50061, 3003} I/dalvikvm( 3349): Could not find method org.libsdl.app.SDLActivity.onRequestPermissionsResult, referenced from method org.haxe.lime.GameActivity.onRequestPermissionsResult W/dalvikvm( 3349): VFY: unable to resolve virtual method 422: Lorg/libsdl/app/SDLActivity;.onRequestPermissionsResult (I[Ljava/lang/String;[I)V D/dalvikvm( 3349): VFY: replacing opcode 0x6f at 0x0019 V/SDL ( 3349): Device: crespo V/SDL ( 3349): Model: Nexus S V/SDL ( 3349): onCreate() D/dalvikvm( 3349): Trying to load lib /data/app-lib/com.example.myapp-2/liblime.so 0x41ece3b0 W/SDL ( 3349): Request to get environment variables before JNI is ready D/dalvikvm( 3349): Added shared lib /data/app-lib/com.example.myapp-2/liblime.so 0x41ece3b0 D/dalvikvm( 3349): Trying to load lib /data/app-lib/com.example.myapp-2/libApplicationMain.so 0x41ece3b0 D/dalvikvm( 3349): Added shared lib /data/app-lib/com.example.myapp-2/libApplicationMain.so 0x41ece3b0 D/dalvikvm( 3349): No JNI_OnLoad found in /data/app-lib/com.example.myapp-2/libApplicationMain.so 0x41ece3b0, skipping init V/SDL ( 3349): nativeSetupJNI() V/SDL ( 3349): AUDIO nativeSetupJNI() V/SDL ( 3349): CONTROLLER nativeSetupJNI() V/SDL ( 3349): onResume() D/OpenGLRenderer( 3349): Enabling debug mode 0 V/SDL ( 3349): surfaceCreated() V/SDL ( 3349): surfaceChanged() V/SDL ( 3349): pixel format RGB_565 V/SDL ( 3349): Window size: 800x480 V/SDL ( 3349): nativeResume() V/SDL ( 3349): Running main function hxcpp_main from library libApplicationMain.so V/SDL ( 3349): nativeRunMain() V/SDL ( 3349): onWindowFocusChanged(): true I/ActivityManager( 3349): Timeline: Activity_idle id: android.os.BinderProxy@41ecaf80 time:1064532 I/haxe plugin( 3349): Got Load Proc 56031bac E/libEGL ( 3349): validate_display:254 error 3008 (EGL_BAD_DISPLAY) V/SDL ( 3349): setOrientation() orientation=-1 width=800 height=480 resizable=true hint= D/dalvikvm( 3349): threadid=13: thread exiting, not yet detached (count=0)

For comparison purposes, this is the adb logcat of a working device (Nexus 5, Android 6.0.1):

09-17 18:05:11.983 810 2042 I ActivityManager: Start proc 32231:com.example.myapp/u0a122 for activity com.example.myapp/.MainActivity 09-17 18:05:11.986 32231 32231 I art : Late-enabling -Xcheck:jni 09-17 18:05:12.319 32231 32231 V SDL : Device: hammerhead 09-17 18:05:12.319 32231 32231 V SDL : Model: Nexus 5 09-17 18:05:12.319 32231 32231 V SDL : onCreate() 09-17 18:05:12.344 32231 32231 W SDL : Request to get environment variables before JNI is ready 09-17 18:05:12.352 32231 32231 V SDL : nativeSetupJNI() 09-17 18:05:12.352 32231 32231 V SDL : AUDIO nativeSetupJNI() 09-17 18:05:12.352 32231 32231 V SDL : CONTROLLER nativeSetupJNI() 09-17 18:05:12.451 32231 32231 V SDL : onResume() 09-17 18:05:12.491 32231 32253 D OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 09-17 18:05:13.452 32231 32253 I Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 10/21/15, 369a2ea, I96aee987eb 09-17 18:05:13.461 32231 32253 I OpenGLRenderer: Initialized EGL, version 1.4 09-17 18:05:13.491 32231 32231 V SDL : surfaceCreated() 09-17 18:05:13.491 32231 32231 V SDL : surfaceChanged() 09-17 18:05:13.491 32231 32231 V SDL : pixel format RGB_565 09-17 18:05:13.491 32231 32231 V SDL : Window size: 1920x1080 09-17 18:05:13.504 32231 32231 V SDL : nativeResume() 09-17 18:05:13.504 32231 32275 V SDL : Running main function hxcpp_main from library libApplicationMain.so 09-17 18:05:13.504 32231 32275 V SDL : nativeRunMain() 09-17 18:05:13.522 32231 32275 I haxe plugin: Got Load Proc a195abac 09-17 18:05:13.549 32231 32231 V SDL : onWindowFocusChanged(): true 09-17 18:05:13.609 32231 32275 W AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 1, track 44100 Hz, output 48000 Hz 09-17 18:05:13.780 32231 32275 E libEGL : validate_display:255 error 3008 (EGL_BAD_DISPLAY) 09-17 18:05:13.781 32231 32275 V SDL : setOrientation() orientation=-1 width=1920 height=1080 resizable=true hint= 09-17 18:05:13.920 32231 32283 W art : Native thread exiting without having called DetachCurrentThread (maybe it's going to use a pthread_key_create destructor?): Thread[13,tid=32283,Native,Thread*=0xacb26c00,peer=0x12df80a0,"Thread-1018"]

Update: this is the logcat of the emulator (working):

I/ActivityManager( 401): Start proc com.example.myapp for activity com.example.myapp/.MainActivity: pid=1159 uid=10053 gids={50053, 3003} D/dalvikvm( 1159): Not late-enabling CheckJNI (already on) I/dalvikvm( 1159): Could not find method org.libsdl.app.SDLActivity.onRequestPermissionsResult, referenced from method org.haxe.lime.GameActivity.onRequestPermissionsResult W/dalvikvm( 1159): VFY: unable to resolve virtual method 422: Lorg/libsdl/app/SDLActivity;.onRequestPermissionsResult (I[Ljava/lang/String;[I)V D/dalvikvm( 1159): VFY: replacing opcode 0x6f at 0x0019 V/SDL ( 1159): Device: generic V/SDL ( 1159): Model: sdk V/SDL ( 1159): onCreate() D/dalvikvm( 1159): Trying to load lib /data/app-lib/com.example.myapp-1/liblime.so 0xb0817358 W/SDL ( 1159): Request to get environment variables before JNI is ready D/dalvikvm( 1159): Added shared lib /data/app-lib/com.example.myapp-1/liblime.so 0xb0817358 D/dalvikvm( 1159): Trying to load lib /data/app-lib/com.example.myapp-1/libApplicationMain.so 0xb0817358 D/dalvikvm( 1159): Added shared lib /data/app-lib/com.example.myapp-1/libApplicationMain.so 0xb0817358 D/dalvikvm( 1159): No JNI_OnLoad found in /data/app-lib/com.example.myapp-1/libApplicationMain.so 0xb0817358, skipping init V/SDL ( 1159): nativeSetupJNI() V/SDL ( 1159): AUDIO nativeSetupJNI() V/SDL ( 1159): CONTROLLER nativeSetupJNI() V/SDL ( 1159): onResume() D/ ( 1159): HostConnection::get() New Host Connection established 0xb785f7d0, tid 1159 D/OpenGLRenderer( 1159): Enabling debug mode 0 V/SDL ( 1159): surfaceCreated() V/SDL ( 1159): surfaceChanged() V/SDL ( 1159): pixel format RGB_565 V/SDL ( 1159): Window size: 800x480 V/SDL ( 1159): nativeResume() V/SDL ( 1159): Running main function hxcpp_main from library libApplicationMain.so V/SDL ( 1159): nativeRunMain() V/SDL ( 1159): onWindowFocusChanged(): true I/haxe plugin( 1159): Got Load Proc a670bbac E/libEGL ( 1159): validate_display:254 error 3008 (EGL_BAD_DISPLAY) V/SDL ( 1159): setOrientation() orientation=-1 width=800 height=480 resizable=true hint= D/ ( 1159): HostConnection::get() New Host Connection established 0xb78fb4a0, tid 1174 D/dalvikvm( 1159): threadid=13: thread exiting, not yet detached (count=0)

giuppe avatar Sep 17 '18 16:09 giuppe

My LG G2 also has Android 4.4.2, and the Mode demo was definitely working ok when we initially added OpenFL 8 support. Not sure I've tried with more recent versions, I'll see what happens with current Haxelib versions.

Gama11 avatar Sep 17 '18 17:09 Gama11

Yep, Mode is still working fine with OpenFL 8.4.1 and Lime 7.0.0.

Gama11 avatar Sep 17 '18 18:09 Gama11

I just tested Mode and FlxCaveGenerator on my Ouya (Android 4.4.4) and they work, so it's not a problem with KitKat. However, Mode works on the Nexus S as the screenshot attached: 3D objects show as silohuettes.

Mode on Nexus S

I tested the stage3d openfl sample and it works. I also upgraded to openfl 8.4.0 + lime 7.0.0 with no changes in the tests.

Could it be a GPU problem, like an unsupported texture mode on some devices? Nexus S has a PowerVR SGX540 GPU. What could I try to do to get more info?

giuppe avatar Sep 18 '18 15:09 giuppe

It would be interesting to see the results for an OpenFL sample that actually uses the same rendering API that Flixel uses. That seems to be the case for the BunnyMark sample if use_tilemap isn't defined:

https://github.com/openfl/openfl-samples/blob/6a2c41dd9fdc11b897bc1a0bbc57c81e41d99a34/haxelib/demos/BunnyMark/Source/Main.hx#L193-L199

Also, perhaps @jgranick has some idea.

Gama11 avatar Sep 18 '18 15:09 Gama11

BunnyMark works OK on the Nexus S with and without use_tilemap.

giuppe avatar Sep 18 '18 18:09 giuppe

could you trace(lime.graphics.opengl.GL.getSupportedExtensions()) on this problem phone? I think that some of the used OpenGL functionality isn't supported by device's GPU, and i need to know the list of supported GL extenstions

Beeblerox avatar Sep 18 '18 19:09 Beeblerox

Here is the trace:

I/trace (14325): PlayState.hx:19: [EXT_debug_marker,OES_rgb8_rgba8,OES_depth24,OES_vertex_half_float,OES_texture_float,OES_texture_half_float,OES_element_index_uint,OES_mapbuffer,OES_fragment_precision_high,OES_compressed_ETC1_RGB8_texture,OES_EGL_image,OES_EGL_image_external,OES_required_internalformat,OES_depth_texture,OES_get_program_binary,OES_packed_depth_stencil,OES_standard_derivatives,OES_vertex_array_object,OES_egl_sync,EXT_multi_draw_arrays,EXT_texture_format_BGRA8888,EXT_discard_framebuffer,EXT_shader_texture_lod,IMG_shader_binary,IMG_texture_compression_pvrtc,IMG_texture_npot,IMG_texture_format_BGRA8888,IMG_read_format,IMG_program_binary,IMG_multisampled_render_to_texture]

giuppe avatar Sep 18 '18 19:09 giuppe

maybe your device doesn't support textures with no-power of two sizes? Could you try to just display on the screen 1 FlxSprite with 128 by 128 pixels texture filled with any color (Red of White)?

Beeblerox avatar Sep 18 '18 19:09 Beeblerox

I executed this code:

        var color = new FlxColor();
	color.setRGB(255,0,0,255);
	FlxG.camera.bgColor = color;

	var spr = new FlxSprite();
	spr.loadGraphic(AssetPaths.Sprite0001__png, 128, 128);
	this.add(spr);

Sprite0001.png is a 128x128 png.

This is the result - the HaxeFlixel animated logo and sound, and then: Simple 128x128 sprite on Nexus S

giuppe avatar Sep 18 '18 20:09 giuppe

I changed the loadgraphic line to spr.makeGraphic(128, 128, FlxColor.BLUE); and the result is exactly the same.

giuppe avatar Sep 18 '18 20:09 giuppe

that's very unusual. does regular OpenFL's (not the flixel's one) Bunnymark shows you anything on screen?

Beeblerox avatar Sep 18 '18 20:09 Beeblerox

@Beeblerox yes, this is the OpenFL BunnyMark on the device:

OpenFL's BunnyMark on Nexus S

giuppe avatar Sep 19 '18 09:09 giuppe

Ok, just found: if I force the use of the original OpenFL texture2D(bitmap, coord) shader function instead of flixel_texture2D(bitmap, coord) it works without problems.

 @:glFragmentSource("
            #pragma header

            void main(void)
            {
                    gl_FragColor = texture2D(bitmap, openfl_TextureCoordv);
            }"
    )

In FlxGraphicShader.hx. So the flixel's fragment shader is outputting always black on the device, or doing something that is unsupported.

I'm going to experiment a bit. Is there anything I could test?

giuppe avatar Sep 19 '18 19:09 giuppe

doing so will break color tranformations for sprites

Beeblerox avatar Sep 19 '18 19:09 Beeblerox

Could you trace results of following function calls on the problem device:

import lime.graphics.opengl.GL;

trace(GL.getInteger(GL.MAX_VERTEX_UNIFORM_COMPONENTS));
trace(GL.getInteger(GL.MAX_FRAGMENT_UNIFORM_COMPONENTS));

Beeblerox avatar Sep 19 '18 20:09 Beeblerox

this will give information about number of supported uniforms in vertex and fragment shaders on your device. i suspect that the problem might be that problem device is very low end and doesn't support much of them, but openfl shaders and flixel shaders (which extend them) are using quite some of uniforms

Beeblerox avatar Sep 19 '18 20:09 Beeblerox

Yes, using directly the OpenFL version is not a real fix. I was just pointing that the problem probably lies in that function, somehow.

giuppe avatar Sep 19 '18 20:09 giuppe

trace(GL.getInteger(GL.MAX_VERTEX_UNIFORM_COMPONENTS)); trace(GL.getInteger(GL.MAX_FRAGMENT_UNIFORM_COMPONENTS));

I/trace ( 2157): PlayState.hx:15: 1453942084 I/trace ( 2157): PlayState.hx:16: 1453941972

giuppe avatar Sep 19 '18 21:09 giuppe

New experiment. This works:

            vec4 flixel_texture2D(sampler2D bitmap, vec2 coord)
            {
                  vec4 color = texture2D(bitmap, coord);
                  return color;
            }

This won't work:

            vec4 flixel_texture2D(sampler2D bitmap, vec2 coord)
            {
                    vec4 color = texture2D(bitmap, coord);

                    if (!hasTransform)
                            return color;
                    return color;
            }

giuppe avatar Sep 19 '18 22:09 giuppe

trace(GL.getInteger(GL.MAX_VERTEX_UNIFORM_COMPONENTS)); trace(GL.getInteger(GL.MAX_FRAGMENT_UNIFORM_COMPONENTS));

I/trace ( 2157): PlayState.hx:15: 1453942084 I/trace ( 2157): PlayState.hx:16: 1453941972

These are too big numbers. give me some time and i assemble little sample for tracing further

Beeblerox avatar Sep 20 '18 04:09 Beeblerox

can you tell me what this program traces for you on the problem device:

package;

import lime.graphics.opengl.*;
import openfl.display.OpenGLRenderer;
import openfl.display.Sprite;
import openfl.events.RenderEvent;


#if (lime >= "7.0.0")
import lime.graphics.WebGLRenderContext;
#else
import lime.graphics.opengl.WebGLContext in WebGLRenderContext;
#end


class Main extends Sprite {
	
	
	public function new () {
		
		super ();
		
		addEventListener (RenderEvent.RENDER_OPENGL, renderOpenGL);
		
	}
	
	var traced:Bool = false;
	
	private function renderOpenGL (event:RenderEvent):Void {
		
		var renderer:OpenGLRenderer = cast event.renderer;
		var gl:WebGLRenderContext = renderer.gl;
		
		if (!traced)
		{
			traced = true;
			
			var vertexSource = 
				
				"attribute float openfl_Alpha;
				attribute vec4 openfl_ColorMultiplier;
				attribute vec4 openfl_ColorOffset;
				attribute vec4 openfl_Position;
				attribute vec2 openfl_TextureCoord;
				
				varying float openfl_Alphav;
				varying vec4 openfl_ColorMultiplierv;
				varying vec4 openfl_ColorOffsetv;
				varying vec2 openfl_TextureCoordv;
				
				uniform mat4 openfl_Matrix;
				uniform bool openfl_HasColorTransform;
				uniform vec2 openfl_TextureSize;
				
				attribute float alpha;
				attribute vec4 colorMultiplier;
				attribute vec4 colorOffset;
				uniform bool hasColorTransform;
		
				void main(void) {
					
					openfl_Alphav = openfl_Alpha;
					openfl_TextureCoordv = openfl_TextureCoord;
					
					if (openfl_HasColorTransform) {
						
						openfl_ColorMultiplierv = openfl_ColorMultiplier;
						openfl_ColorOffsetv = openfl_ColorOffset / 255.0;
						
					}
					
					openfl_Alphav = openfl_Alpha * alpha;
			
					if (hasColorTransform)
					{
						openfl_ColorOffsetv = colorOffset / 255.0;
						openfl_ColorMultiplierv = colorMultiplier;
					}
					
					gl_Position = openfl_Matrix * openfl_Position;
					
				}";
			
			var fragmentSource = 
				
				#if !desktop
				"precision mediump float;" +
				#end
				
				"varying float openfl_Alphav;
				varying vec4 openfl_ColorMultiplierv;
				varying vec4 openfl_ColorOffsetv;
				varying vec2 openfl_TextureCoordv;
				
				uniform bool openfl_HasColorTransform;
				uniform vec2 openfl_TextureSize;
				uniform sampler2D bitmap;
				
				uniform bool hasTransform;
				uniform bool hasColorTransform;
				vec4 flixel_texture2D(sampler2D bitmap, vec2 coord)
				{
					vec4 color = texture2D(bitmap, coord);
					if (!hasTransform)
						return color;
					
					if (color.a == 0.0)
					{
						return vec4(0.0, 0.0, 0.0, 0.0);
					}
					else if (hasColorTransform)
					{
						color = vec4(color.rgb / color.a, color.a);
						
						mat4 colorMultiplier = mat4(0);
						colorMultiplier[0][0] = openfl_ColorMultiplierv.x;
						colorMultiplier[1][1] = openfl_ColorMultiplierv.y;
						colorMultiplier[2][2] = openfl_ColorMultiplierv.z;
						colorMultiplier[3][3] = openfl_ColorMultiplierv.w;
						
						color = clamp(openfl_ColorOffsetv + (color * colorMultiplier), 0.0, 1.0);
						
						if (color.a > 0.0)
							return vec4(color.rgb * color.a * openfl_Alphav, color.a * openfl_Alphav);
						else
							return vec4(0.0, 0.0, 0.0, 0.0);
					}
					else
					{
						return color * openfl_Alphav;
					}
				}
				
				void main(void)
				{
					gl_FragColor = flixel_texture2D(bitmap, openfl_TextureCoordv);
				}
				";
			
			var glProgram:GLProgram = #if (lime >= "7.0.0") GLProgram.fromSources (gl, vertexSource, fragmentSource); #else lime.utils.GLUtils.createProgram (vertexSource, fragmentSource); #end
			gl.useProgram (glProgram);
			
			var openfl_Alpha = gl.getAttribLocation(glProgram, "openfl_Alpha");
			var openfl_ColorMultiplier = gl.getAttribLocation(glProgram, "openfl_ColorMultiplier");
			var openfl_ColorOffset = gl.getAttribLocation(glProgram, "openfl_ColorOffset");
			var openfl_Position = gl.getAttribLocation(glProgram, "openfl_Position");
			var openfl_TextureCoord = gl.getAttribLocation(glProgram, "openfl_TextureCoord");
			var alpha = gl.getAttribLocation(glProgram, "alpha");
			var colorMultiplier = gl.getAttribLocation(glProgram, "colorMultiplier");
			var colorOffset = gl.getAttribLocation(glProgram, "colorOffset");
			
			trace("tracing shader attributes");
			trace("openfl_Alpha: " + openfl_Alpha);
			trace("openfl_ColorMultiplier: " + openfl_ColorMultiplier);
			trace("openfl_ColorOffset: " + openfl_ColorOffset);
			trace("openfl_Position: " + openfl_Position);
			trace("openfl_TextureCoord: " + openfl_TextureCoord);
			trace("alpha: " + alpha);
			trace("colorMultiplier: " + colorMultiplier);
			trace("colorOffset: " + colorOffset);
			
			var openfl_Matrix = gl.getUniformLocation(glProgram, "openfl_Matrix");
			var openfl_HasColorTransform = gl.getUniformLocation(glProgram, "openfl_HasColorTransform");
			var openfl_TextureSize = gl.getUniformLocation(glProgram, "openfl_TextureSize");
			var hasColorTransform = gl.getUniformLocation(glProgram, "hasColorTransform");
			var openfl_HasColorTransform = gl.getUniformLocation(glProgram, "openfl_HasColorTransform");
			var openfl_TextureSize = gl.getUniformLocation(glProgram, "openfl_TextureSize");
			var bitmap = gl.getUniformLocation(glProgram, "bitmap");
			var hasTransform = gl.getUniformLocation(glProgram, "hasTransform");
			
			trace("tracing shader uniforms");
			trace("openfl_Matrix: " + openfl_Matrix);
			trace("openfl_HasColorTransform: " + openfl_HasColorTransform);
			trace("openfl_TextureSize: " + openfl_TextureSize);
			trace("hasColorTransform: " + hasColorTransform);
			trace("openfl_HasColorTransform: " + openfl_HasColorTransform);
			trace("openfl_TextureSize: " + openfl_TextureSize);
			trace("bitmap: " + bitmap);
			trace("hasTransform: " + hasTransform);
		}		
	}	
}

Beeblerox avatar Sep 20 '18 05:09 Beeblerox

This is the trace on the problem device:

I/trace ( 4197): Main.hx:152: tracing shader attributes I/trace ( 4197): Main.hx:153: openfl_Alpha: 0 I/trace ( 4197): Main.hx:154: openfl_ColorMultiplier: 2 I/trace ( 4197): Main.hx:155: openfl_ColorOffset: 3 I/trace ( 4197): Main.hx:156: openfl_Position: 7 I/trace ( 4197): Main.hx:157: openfl_TextureCoord: 1 I/trace ( 4197): Main.hx:158: alpha: 4 I/trace ( 4197): Main.hx:159: colorMultiplier: 6 I/trace ( 4197): Main.hx:160: colorOffset: 5 I/trace ( 4197): Main.hx:171: tracing shader uniforms I/trace ( 4197): Main.hx:172: openfl_Matrix: 3 I/trace ( 4197): Main.hx:173: openfl_HasColorTransform: 1 I/trace ( 4197): Main.hx:174: openfl_TextureSize: -1 I/trace ( 4197): Main.hx:175: hasColorTransform: 2 I/trace ( 4197): Main.hx:176: openfl_HasColorTransform: 1 I/trace ( 4197): Main.hx:177: openfl_TextureSize: -1 I/trace ( 4197): Main.hx:178: bitmap: 4 I/trace ( 4197): Main.hx:179: hasTransform: 5

giuppe avatar Sep 20 '18 08:09 giuppe

hmm, all required uniforms are available. let me think about it

Beeblerox avatar Sep 20 '18 09:09 Beeblerox

I don't know if it could be of some help, but I activated the log of GL errors on the device. There is no error with the samples, but this is the result of the previous traces:

trace(GL.getInteger(GL.MAX_VERTEX_UNIFORM_COMPONENTS)); trace(GL.getInteger(GL.MAX_FRAGMENT_UNIFORM_COMPONENTS));

 D/libEGL  ( 5255): [glGetIntegerv] 0x500
 D/glGetError:glGetIntegerv( 5255): #00  pc 0001a820  /system/lib/libEGL.so
 D/glGetError:glGetIntegerv( 5255): #01  pc 000aa444  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #02  pc 009e4fe8  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #03  pc 00969808  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #04  pc 0096a4e0  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #05  pc 0096a9c8  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #06  pc 0096b0f4  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #07  pc 0096b550  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #08  pc 00b52774  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #09  pc 00a59320  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #10  pc 00a3e108  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #11  pc 0021874c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #12  pc 00219260  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #13  pc 00219514  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #14  pc 00b52774  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #15  pc 0059e6bc  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #16  pc 00a6b50c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #17  pc 00a6b95c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #18  pc 00b526a4  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #19  pc 00b08804  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #20  pc 000c0948  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #21  pc 000c0ba0  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #22  pc 000bddd8  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #23  pc 00a6a6ec  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #24  pc 00a5da84  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #25  pc 00101144  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #26  pc 00b053a0  /data/app-lib/com.example.myapp-1/libApplicationMain.so (hxcpp_main+36)
 D/glGetError:glGetIntegerv( 5255): #27  pc 003f4048  /data/app-lib/com.example.myapp-1/liblime.so (Java_org_libsdl_app_SDLActivity_nativeRunMain+508)
 D/glGetError:glGetIntegerv( 5255): #28  pc 0001dd50  /system/lib/libdvm.so (dvmPlatformInvoke+116)
 D/glGetError:glGetIntegerv( 5255): #29  pc 0004ace6  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+393)
 D/glGetError:glGetIntegerv( 5255): #30  pc 0004c5de  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+181)
 I/trace   ( 5255): PlayState.hx:17: 1453942084
 D/libEGL  ( 5255): [glGetIntegerv] 0x500
 D/glGetError:glGetIntegerv( 5255): #00  pc 0001a820  /system/lib/libEGL.so
 D/glGetError:glGetIntegerv( 5255): #01  pc 000aa444  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #02  pc 009e5094  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #03  pc 00969808  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #04  pc 0096a4e0  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #05  pc 0096a9c8  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #06  pc 0096b0f4  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #07  pc 0096b550  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #08  pc 00b52774  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #09  pc 00a59320  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #10  pc 00a3e108  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #11  pc 0021874c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #12  pc 00219260  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #13  pc 00219514  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #14  pc 00b52774  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #15  pc 0059e6bc  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #16  pc 00a6b50c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #17  pc 00a6b95c  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #18  pc 00b526a4  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #19  pc 00b08804  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #20  pc 000c0948  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #21  pc 000c0ba0  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #22  pc 000bddd8  /data/app-lib/com.example.myapp-1/liblime.so
 D/glGetError:glGetIntegerv( 5255): #23  pc 00a6a6ec  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #24  pc 00a5da84  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #25  pc 00101144  /data/app-lib/com.example.myapp-1/libApplicationMain.so
 D/glGetError:glGetIntegerv( 5255): #26  pc 00b053a0  /data/app-lib/com.example.myapp-1/libApplicationMain.so (hxcpp_main+36)
 D/glGetError:glGetIntegerv( 5255): #27  pc 003f4048  /data/app-lib/com.example.myapp-1/liblime.so (Java_org_libsdl_app_SDLActivity_nativeRunMain+508)
 D/glGetError:glGetIntegerv( 5255): #28  pc 0001dd50  /system/lib/libdvm.so (dvmPlatformInvoke+116)
 D/glGetError:glGetIntegerv( 5255): #29  pc 0004ace6  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+393)
 D/glGetError:glGetIntegerv( 5255): #30  pc 0004c5de  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+181)
 I/trace   ( 5255): PlayState.hx:18: 1453941972

giuppe avatar Sep 20 '18 11:09 giuppe

Ok, I made it work. I stumbled upon a similar problem another project had with the same GPU and they had problems when gl_FragColor was assigned and read at the same time, like gl_FragColor *= variable. I thought that maybe the shader compiler was doing something like that, when translating the flixel_texture2D function, and I tried

        @:glFragmentSource("
          #pragma header

          void main(void)
          {
                vec4 flixel_color = texture2D(bitmap, openfl_TextureCoordv);
                gl_FragColor = flixel_color;
          }"
        )

...but this didn't work. I checked the equivalent shader in OpenFL, and saw that they use @:glFragmentBody and #pragma body instead of a "function call".

So I rewrote the flixel_texture2D in the style of OpenFL and everything works. I think the shader compiler is doing something unsupported on this device when translating this particular function call, and maybe in the case of a simple function that does not use uniforms it just inlines it causing no problem.

This is Mode now: Mode with the changes

This is the final shader:

@:glFragmentHeader("
	uniform bool hasTransform;
	uniform bool hasColorTransform;
")
	
@:glFragmentBody("
		vec4 flixel_color = texture2D(bitmap, openfl_TextureCoordv);
		
		if (!hasTransform){
			flixel_color = color;
		}
		else{
			if (color.a == 0.0)
			{
				flixel_color = vec4(0.0, 0.0, 0.0, 0.0);
			}
			else if (hasColorTransform)
			{
				color = vec4(color.rgb / color.a, color.a);
			
				mat4 colorMultiplier = mat4(0);
				colorMultiplier[0][0] = openfl_ColorMultiplierv.x;
				colorMultiplier[1][1] = openfl_ColorMultiplierv.y;
				colorMultiplier[2][2] = openfl_ColorMultiplierv.z;
				colorMultiplier[3][3] = openfl_ColorMultiplierv.w;
			
				color = clamp(openfl_ColorOffsetv + (color * colorMultiplier), 0.0, 1.0);
			
				if (color.a > 0.0)
					flixel_color = vec4(color.rgb * color.a * openfl_Alphav, color.a * openfl_Alphav);
				else
					flixel_color = vec4(0.0, 0.0, 0.0, 0.0);
			}
			else
			{
				flixel_color = color * openfl_Alphav;
			}
		}
"
)

@:glFragmentSource("
	#pragma header
	
	void main(void)
	{
		#pragma body
		gl_FragColor = flixel_color;
	}"
)

I don't know if removing the flixel_texture2D definition could break something else. What do you think?

giuppe avatar Sep 20 '18 18:09 giuppe

Yes, that would break custom shaders using flixel_texture2D():

https://github.com/HaxeFlixel/flixel-demos/search?q=flixel_texture2D&unscoped_q=flixel_texture2D

Some of those need a coordinate other than openfl_TextureCoordv (you might even want to call it multiple times), so flixel_color is not equivalent / less flexible.

Gama11 avatar Sep 20 '18 18:09 Gama11

Update: this works on the device

vec4 flixel_texture2D(vec2 coord){
      vec4 color = texture2D(bitmap, coord);
      // ... everything else unchanged

This could be because sampler2D bitmap is a uniform globally, but it is redefined as a function parameter?

If I do a trace(<sprite>.graphic.shader.glFragmentSource) this is the complete fragment shader:

	varying float openfl_Alphav;
	varying vec4 openfl_ColorMultiplierv;
	varying vec4 openfl_ColorOffsetv;
	varying vec2 openfl_TextureCoordv;

	uniform bool openfl_HasColorTransform;
	uniform vec2 openfl_TextureSize;
	uniform sampler2D bitmap;

	uniform bool hasTransform;
	uniform bool hasColorTransform;


	vec4 flixel_texture2D(sampler2D bitmap, vec2 coord)
	{
		vec4 color = texture2D(bitmap, coord);
		if (!hasTransform)
			return color;
			
		if (color.a == 0.0)
		{
			return vec4(0.0, 0.0, 0.0, 0.0);
		}
		else if (hasColorTransform)
		{
			color = vec4(color.rgb / color.a, color.a);
			
			mat4 colorMultiplier = mat4(0);
			colorMultiplier[0][0] = openfl_ColorMultiplierv.x;
			colorMultiplier[1][1] = openfl_ColorMultiplierv.y;
			colorMultiplier[2][2] = openfl_ColorMultiplierv.z;
			colorMultiplier[3][3] = openfl_ColorMultiplierv.w;
			
			color = clamp(openfl_ColorOffsetv + (color * colorMultiplier), 0.0, 1.0);
			
			if (color.a > 0.0)
				return vec4(color.rgb * color.a * openfl_Alphav, color.a * openfl_Alphav);
			else
				return vec4(0.0, 0.0, 0.0, 0.0);
		}
		else
		{
			return color * openfl_Alphav;
		}
	}
	
	
	void main(void)
	{
		gl_FragColor = flixel_texture2D(bitmap, openfl_TextureCoordv);
	}

giuppe avatar Sep 21 '18 18:09 giuppe

So does simply using a different name for the bitmap parameter work too?

Gama11 avatar Sep 21 '18 18:09 Gama11

Just tried:

        vec4 flixel_texture2D(sampler2D bitmap0, vec2 coord)
	{
		vec4 color = texture2D(bitmap0, coord);
                    //everything else

but it doesn't work...

giuppe avatar Sep 21 '18 18:09 giuppe

Maybe the sampler2D type is managed differently on low end devices, because of its size?

giuppe avatar Sep 21 '18 18:09 giuppe