Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.85k stars 819 forks source link

Flickering issue with filters #889

Open tconkling opened 8 years ago

tconkling commented 8 years ago

I'm seeing a bizarre problem in my game: under certain circumstances, applying a ColorMatrixFilter to a display object causes other DisplayObjects with custom MeshEffects to flicker between "custom MeshEffect applied" and "custom MeshEffect not applied" states.

This issue only occurs when running in Chrome or on iOS - it doesn't occur in a bundled "captive AIR runtime" version, or when running directly in Flash Player on my (Mac) desktop, or when running in Safari (which uses a different plugin than Chrome for Flash content).

Because it's a hard issue to explain, here's a movie demonstrating the issue: starling_flicker.mov.zip

In this movie, I'm toggling the checkmark button in the bottom-right corner of the screen between its enabled and disabled states. When it's disabled, its grayscale effect is achieved with a ColorMatrixFilter.adjustSaturation(-1) filter applied to it.

The player portraits at the top of the screen, and in the lower left corner, are dynamically recolored with a custom MeshEffect class that implements an overlay blend mode. You can see that, while the checkmark is greyscale, the recolored bits flicker between non-recolored greyscale and properly recolored, MeshEffect-is-being-applied states. When the checkmark's ColorMatrixFilter is removed, the recolored portraits appear as expected.

Again, this only happens when running in Chrome and on iOS, which makes me think I'm exceeding some sort of Context3DProfile-specific threshold, or something of the sort?

I realize this is possibly a game-specific bug that's going to be tough for anyone to reproduce (though I can work on getting a smaller test case). But I'm throwing it out there in case anyone has any ideas?

tconkling commented 8 years ago

A followup: I can fix this issue by calling setRequiresRedraw() on the greyscale checkmark item - which is simply a Sprite containing an image and a ColorMatrixFilter - once per frame. (Calling setRequiresRedraw() on the flickering player portraits doesn't have any effect, even though they're the ones doing the weird flickering.)

And again, only on Chrome/iOS is this even an issue. Very strange!

PrimaryFeather commented 8 years ago

Oh, wow. Just the kind of issue we all love, right? :wink: Not that it would make the reason for this any clearer, but just to maybe isolate the problem a little more; what happens if you disable the render cache?

That's currently only possible via the following hack: In DisplayObjectContainer.as, method render, find the line:

if (child._lastParentOrSelfChangeFrameID != frameID &&

and change it to

if (false && child._lastParentOrSelfChangeFrameID != frameID &&

Does that make any difference?

tconkling commented 8 years ago

Yep - disabling the render cache makes the issue go away!

PrimaryFeather commented 8 years ago

Hmhm ... super odd that this just happens in specific circumstances. I'll keep investigating, perhaps I can come up with something to try. In the meantime, if you find any more curious details, be sure to keep me posted! :wink:

PrimaryFeather commented 7 years ago

While I still don't know what actually caused your problems, could you please try if using the latest head revision changes anything? Earlier this week, I changed the render cache logic slightly, in the hopes of making it more reliable (e.g. this allowed me to remove some other workarounds that were previously necessary). It's a long shot, but maybe it helps in your case, as well?

Thanks in advance!

tconkling commented 7 years ago

Hey Daniel - I'm still seeing the issue with the latest Starling, though things are a bit different now. Specifically, I'm seeing the issue less often, it doesn't seem to be happening in Chrome anymore (only iOS and Android), and it's no longer tied to that greyscale ColorMatrixFilter.

The other major variable is that I'm building with AIR 23 instead of AIR 22. When I have a moment, I'll try dropping back to v22 to get a better sense of whether the SDK itself is responsible for the issue.

PrimaryFeather commented 7 years ago

Thanks for the update! Okay, let's wait for the AIR 22 results, then. I must admit, though, that I have no idea what we could do to find out what exactly is the problem, especially since it's only happening on specific hardware, and not in all frames. We'd need to reproduce the problem in a much simpler project to be able to get to the root of it, I guess.

PrimaryFeather commented 6 years ago

Are there any updates on this — do you still encounter these problems? Otherwise, I'd say we close this issue.

tconkling commented 6 years ago

So I'm not personally seeing this issue on Mac, Windows, or iOS. However, the mobile build of my game is in QA right now and testers are reporting the issue on some devices. Here's an example:

antihero_flicker_ios.mp4.zip

This is on an iPhone 6 running iOS 8.2. (My personal test devices, which don't show the issue, are all on iOS 11 - I haven't seen the issue on iOS 10 either.) I guess this sort of points to it being a driver issue? In the movie I attached, the flicker is occurring only when there is not a GlowFilter attached to another display object. (At the start of the movie, there's a selected character on-screen. Selected characters have a glow filter around them. When the portraits at the top of the screen start flickering, the selected character has disappeared into a building, which removes their display object from the screen. As soon as a new character is selected and has a GlowFilter added, at the end of the clip, the flickering stops.)

(Edited to add - I see in my original description I was able to toggle the flicker on and off by adding a ColorMatrixFilter to a display object. Perhaps my overlay recoloring shader -- the shader that is applied to the flickering character portraits -- is written incorrectly... but it's baffling to me that an unrelated filter on a different display object triggers the glitch.)

(Edit 2: I'm currently building with AIR 26, so this wasn't a regression in AIR 22 that is fixed in later builds.)

PrimaryFeather commented 6 years ago

Thanks a lot for the update, Tim!

Hm, okay. Well, at least the number of affected devices seems to be going down! I'd also say that this may be a driver issue or an incompatibility of Stage3D in combination with iOS 8. There is probably not much we can do about it. But please keep me updated if you run into it on any newer iOS version! We'd definitely need to get this to Adobe's attention then.