Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on old iOS devices when using FlxGraphicsShader for first time #2219

Closed
Tw1ddle opened this issue May 28, 2019 · 7 comments
Closed

Crash on old iOS devices when using FlxGraphicsShader for first time #2219

Tw1ddle opened this issue May 28, 2019 · 7 comments

Comments

@Tw1ddle
Copy link

Tw1ddle commented May 28, 2019

  • Haxe version: N/A
  • Flixel version: Latest git (currently: 5c6ea5b)
  • OpenFL version: 8.8.0 (including up to on latest 8.9.0)
  • Lime version: 7.2.1 (including up to latest 7.5.0)
  • Affected targets: iOS

There is a crash on old iPhones/iPads when the graphics driver tries to compile/run this part of the FlxGraphicsShader fragment shader:

@:glFragmentHeader("
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;
}
}
"
)


Observed behavior: On old iOS devices, Flixel apps always crash as soon as something is rendered. This doesn't repro on the iOS simulator. Testing a range of ~30 devices on a device farm, all the older ones crashed: iPhone 5 iOS 10.1, iPhone 5c iOS 9.1, iPhone 4S iOS 9.2.1, iPhone 5 iOS 10.0.2, iPhone 5c iOS 10.3.1, iPhone 5c 10.0.2. More recent devices seem to run fine, though my testing wasn't exhaustive.

Here's the stack trace. It's always the same, the first time any app renders any sprites:

Thread 0 Crashed:
0   ???                           	0000000000 0 + 0
1   IMGSGX535GLDriver             	0x2dca9df0 ppimgCompileShader + 992
2   IMGSGX535GLDriver             	0x2dc890b6 sgxUpdateCtxSysProgram + 278
3   IMGSGX535GLDriver             	0x2dc8952c glrUpdateCtxSysFragmentProgram + 616
4   IMGSGX535GLDriver             	0x2dd36654 gpusLoadCurrentPipelinePrograms + 1472
5   IMGSGX535GLDriver             	0x2dc8b396 gldUpdateDispatch + 410
6   GLEngine                      	0x31116bcc gleDoDrawDispatchCoreES2 + 588
7   GLEngine                      	0x310f5eee glDrawElements_ACC_ES2Exec + 234
8   OpenGLES                      	0x31178e72 glDrawElements + 38
9   testapp                       	0x006b40d2 lime::_internal::backend::native::NativeOpenGLRenderContext_obj::drawElements+ 6066386 (int, int, int, double) + 38
10  testapp                       	0x0046ff7e openfl::display3D::Context3D_obj::drawTriangles+ 3690366 (hx::ObjectPtr<openfl::display3D::IndexBuffer3D_obj>, hx::Null<int>, hx::Null<int>) + 280
11  testapp                       	0x00511042 openfl::_internal::renderer::context3D::Context3DGraphics_obj::render+ 4350018 (hx::ObjectPtr<openfl::display::Graphics_obj>, hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 4994
12  testapp                       	0x0050ceac openfl::_internal::renderer::context3D::Context3DShape_obj::render+ 4333228 (hx::ObjectPtr<openfl::display::DisplayObject_obj>, hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 112
13  testapp                       	0x00919b48 openfl::display::DisplayObject_obj::_hx___renderGL+ 8579912 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 536
14  testapp                       	0x0091428a openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557194 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 114
15  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
16  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
17  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
18  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
19  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
20  testapp                       	0x009142f4 openfl::display::DisplayObjectContainer_obj::_hx___renderGL+ 8557300 (hx::ObjectPtr<openfl::display::OpenGLRenderer_obj>) + 220
21  testapp                       	0x004ad386 openfl::display::OpenGLRenderer_obj::_hx___render+ 3941254 (Dynamic) + 536
22  testapp                       	0x00481cf4 openfl::display::Stage_obj::render+ 3763444 (hx::ObjectPtr<lime::graphics::RenderContext_obj>) + 634
23  testapp                       	0x00481d7e openfl::display::__Stage_objrender+ 3763582 (hx::Object*, Dynamic const&) + 58
24  testapp                       	0x009ed892 hx::CMemberFunction1::__run+ 9447570 (Dynamic const&) + 14
25  testapp                       	0x0066d8da lime::app::_Event_lime_graphics_RenderContext_Void_obj::dispatch+ 5777626 (hx::ObjectPtr<lime::graphics::RenderContext_obj>) + 78
26  testapp                       	0x009308f6 lime::_internal::backend::native::NativeApplication_obj::handleRenderEvent+ 8673526 () + 344
27  testapp                       	0x00930926 lime::_internal::backend::native::__NativeApplication_objhandleRenderEvent+ 8673574 (hx::Object*) + 12
28  testapp                       	0x009ed718 hx::CMemberFunction0::__run+ 9447192 () + 12
29  testapp                       	0x009b3638 val_call0 + 100
30  testapp                       	0x00136f64 lime::ValuePointer::Call+ 311140 () + 30
31  testapp                       	0x0012be26 lime::SDLApplication::Update+ 265766 () + 90
32  QuartzCore                    	0x313c3df2 CA::Display::DisplayLinkItem::dispatch+ 372210 () + 98
33  QuartzCore                    	0x313c3b9c CA::Display::DisplayLink::dispatch_items+ 371612 (unsigned long long, unsigned long long, unsigned long long) + 344
34  IOMobileFramebuffer           	0x3413c75c IOMobileFramebufferVsyncNotifyFunc + 104
35  IOKit                         	0x2fbc6450 IODispatchCalloutFromCFMessage + 248
36  CoreFoundation                	0x2ee9aea8 __CFMachPortPerform + 136
37  CoreFoundation                	0x2eea5a66 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34
38  CoreFoundation                	0x2eea5a02 __CFRunLoopDoSource1 + 346
39  CoreFoundation                	0x2eea41d6 __CFRunLoopRun + 1398
40  CoreFoundation                	0x2ee0eebe CFRunLoopRunSpecific + 522
41  CoreFoundation                	0x2ee0eca2 CFRunLoopRunInMode + 106
42  GraphicsServices              	0x33d14662 GSEventRunModal + 138
43  UIKit                         	0x3175b14c UIApplicationMain + 1136
44  testapp                       	0x0033747e main + 166
45  libdyld.dylib                 	0x39b98ab6 start + 2

Expected behavior: No more crashing.

I've restructured the fragment shader until it started working on the old devices. Given that the original shader works fine on newer devices (everywhere else), my changes are probably sidestepping some bug in the internals of the graphics driver/shader compiler:

	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);
		}
		
		if(!hasColorTransform)
		{
			return color * openfl_Alphav;
		}
		
		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);
		}
		return vec4(0.0, 0.0, 0.0, 0.0);
	}

I think the bit that makes the difference is changing the if/else if/else block from the original shader into separate if statements.

@Gama11
Copy link
Member

Gama11 commented May 28, 2019

Could this be related to #2173?

@Tw1ddle
Copy link
Author

Tw1ddle commented May 28, 2019

That looks like a different GPU/Android driver-specific issue. As the shader looks OK, I'd say the answer is probably picky/buggy drivers in both cases.

@Gama11
Copy link
Member

Gama11 commented May 28, 2019

Man, shaders are a mess...

@Gama11
Copy link
Member

Gama11 commented May 29, 2019

Are you going to create a pull request with the fix?

@Gama11
Copy link
Member

Gama11 commented Jun 17, 2019

I guess that's a no. :)

@Gama11 Gama11 closed this as completed in 38a8911 Jun 17, 2019
@Tw1ddle
Copy link
Author

Tw1ddle commented Jun 17, 2019

Thanks for doing that, I'll make PRs instead in the future.

FWIW I've shipped with it can confirm this worked on all iOS devices, but didn't try it on Android yet so that isn't as well tested (works on my Motorola G7 Play though).

@Gama11
Copy link
Member

Gama11 commented Jun 17, 2019

I wonder if you'll run into #2173.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants