Starling + flattening + flash target + gpu as wmode = different behavior

Sorry for the title, but the conditions to cause this bug are complex.
And superficially it seems to be an ordinary flattening bug related to some incorrectly ported line of our code.
But the dependency of wmode is strange.

What’s it about: A displayobject in starling is not redrawn only if the wmode is ‘gpu’ instead of ‘direct’ wheres the focus is on another swf or another application.

  • the displayobject is a sprite that contains other displayobjects which are tweened
  • browser-embedded swf (tested with and seen in firefox, maxthon, IE)
  • swf is embedded in html with swf-object and wmode “gpu”.
  • embedded swf is not focused, focus is on another swf (on same page) or on another application (outside browser)
  • flattening and unflattening occured in the meantime while focus was elsewhere
  • then a click on a flash-display-list-button is pressed which triggers an animation within the starling displayobject
  • its animation starts but is freezed than shortly after (like it happens sometimes when using flattening the wrong way)
  • the mouse cursor acts as if the sub objects are at the correct place (after anmiation has theoretically ended)
  • it stays freezed until another click onto the starling stage or a second click onto another flash display object.

Unfortunately, I was not able to reproduce it with a simple test application.
We are currently moving from as3 to haxe, starting with our browser applications. Soon we will work on export to html5.
So I actually don’t really have time to investigate this further.

But at least you have some report.
However, if you had some hint, I would still be glad to hear it.
Thanks.

Does wmode="direct" on both SWFs resolve the issue?

I cannot think of any good reason why a Haxe-generated SWF would behave differently than one from the Flex SDK. It should be the same Flash Player, and behave pretty much the same in this regard.

Perhaps flattening uses context3D.drawToBitmapData, which may use gl.readPixels under the hood (or the DirectX equivalent), which may cause some type of more complicated collision in Flash Player’s internal rendering behavior?

Well, I don’t know what under the hood is going on. But yes, wmode=“direct” resolves that specific issue. Just as soon as some swf is embedded with ‘gpu’, the behavior decribed above occurs. And, correction, that issue exists just for FireFox.

Other than that, there is also another related problem that is independent from wmode; it occurs for ‘direct’ and ‘gpu’. The ‘flatten-modified’ displayobject does not update correctly when the flash container has not the focus (by being the last click target). ‘not update correctly’ means: just the first frame of a tween is drawn, then animation freezes. With ‘flatten-modified’ I mean: flattening status changed (over time from false to true to false) while the swf did not have the focus. I have seen this in all browsers I’ve tested (FireFox, Chrome, InternetExplorer, Maxthon).

So it’s actually 2 issues. Probably these are related. Sorry for the confusion, I should have mentioned the latter first, because it is more general.

However, are there maybe some additional rendering optimizations for haxe-starling?
If so, is there a way to turn them off?

Other differences are:

  • starling-version: in haxe we use 1.8.13; in as3 we used 1.8

Okay, I think I found out the reason.

starling.utils.SystemUtil.executeWhenApplicationIsActive() seems to be not called if flash is not focused and executes not earlier until the swf is clicked again (re-focused).

With AS3 loosing swf focus (by clicking onto another swf or some other program) did not deactivate the application.

So the status of “the application being active” is determined somehow differently in haxe-starling. That is not good for us. We use SystemUtil.executeWhenApplicationIsActive to unflatten carefully, mainly for use on mobile devices.

Would it be possible to change that in Starling-codebase? Or is there a way to distinguish between loosing swf-focus and temporarily switching to another app?

Yeah, maybe this is the issue:

Perhaps this should be Lib.current.stage, so it listens for stage ACTIVATE?

Would the original code run in Flash Player? It looks like it is only for AIR. This seems like the only listener made for calling SystemUtil.onActivate which is what makes the pending calls from SystemUtil.executeWhenApplicationIsActive

Oh yes, you’re right. For Flashplayer that code was expected to fail before it was able to add the event listeners. Whereas in Haxe it doesn’t fail. Note: The class NativeApplication does only exist for Air. And the AS3-method getDefinitionByName throws an error if the passed definition does not exist.

And to your suggestion: Unfortunately listening to Lib.current.stage does not work. I tested that. The events are still catched then.

However, I added the as3-logic to the top of that try-block to cause a fail. And it seems to work, at least for browsers. It should also work for Air. But I will test this soon.

my additon:

#if flash
var nativeAppClass:Dynamic = Type.resolveClass("flash.desktop::NativeApplication");
if (nativeAppClass == null)
	throw new Error("Not Air");
#end

original as3-code:
https://github.com/Gamua/Starling-Framework/blob/master/starling/src/starling/utils/SystemUtil.as)

Tested it. This addition also works fine with Air.

Is it possible to include such a fix into the official starling-haxelib?

Absolutely, can you make a pull?

Make it look as similar to format as the ActionScript version as you can :slight_smile:

Thanks, we have created the pull request for this issue now:

Kind regards

Merged, thanks :smile: