Gamua / Starling-Framework

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

Loading ATFs as PMA textures #823

Open b005t3r opened 8 years ago

b005t3r commented 8 years ago

I know Starling handles only PMA textures properly (when using blend modes, etc.), but when loading ATFs they are loaded as non-PMA. BUT it is possible to create an ATF texture with PMA (I'm using JPEGXR compression and --premultiply-alpha TexturePacker's option).

I changed this bit in Starling's internals and it works :)

public static function fromAtfData(data:ByteArray, scale:Number=1, useMipMaps:Boolean=true,
                                           async:Function=null, repeat:Boolean=false):Texture
(...)
var concreteTexture:ConcreteTexture = new ConcreteTexture(nativeTexture, atfData.format,
    atfData.width, atfData.height, useMipMaps && atfData.numTextures > 1,
    true, false, scale, repeat);

My idea is this: add PMA property to TextureOptions and use it when loadign ATFs. This way everybody can specify if their ATFs are premultiplied or not.

PrimaryFeather commented 8 years ago

Makes sense! You're right, it must be possible to load ATF textures with PMA. I'll add that!

b005t3r commented 8 years ago

BTW, I tested it on PC and JPEGXR only at the moment, but will try this on Android, Mac and iOS as well later today (but I can't see why it wouldn't work).

b005t3r commented 8 years ago

I tested this a bit and everything seems to work just fine, but I noticed one really strange thing - when using ATFs with JXR compression (so they are loaded as BGRA) they consume a lot more GPU memory than PNGs, which doesn't make any sense. With PNG Scout was showing ~26 MB, with ATFs it went up to ~61MB. Do you have any idea what's going on?

b005t3r commented 8 years ago

OK, I did more test and the excess memory usage is because generated textures have to be POT, so they are bigger in general, BUT they also seem to have space for mipmaps allocated, even though I disabled mipmaps generation (and I double checked it when debugging - false is passed everywhere as mipmaps param). So maybe there's a bug and mipmaps are always created, regardles of the TextureOptions passed?

PrimaryFeather commented 8 years ago

Ah, that makes sense! Well, at least kind of. One of the disadvantages of POT-texture (flash.display3D.textures:Texture) is that they always allocate memory for mipmaps — whether you need them, or not. There are a few bugbase issues about that, with the gist being: that's as designed, and won't be changed in the future. :-(

That's also one of the reasons for Starling defaulting to RectangleTextures whenever possible, BTW.

b005t3r commented 8 years ago

Yes, I understand that, but do ATFs have to allocate even more space for mipmaps, even where there are none?

PrimaryFeather commented 8 years ago

The problem is that you can only upload ATF data to the class flash.display3D.textures:Texture — and that's the one that allocates the memory. :disappointed:

PrimaryFeather commented 8 years ago

However, going up from 26 to 61 MB really seems a lot. Much more than one could make mipmaps responsible for, right?

b005t3r commented 8 years ago

Yes, but all of this added up - textures were bigger plus they allocated 1.5x more space (because of mipmaps).

So OK, problem solved - it makes no sense to use ATFs with JXR compression only. But it's still possible to have PMA with any ATFs, so it would be useful if you added a property for this in TextureOptions.

PrimaryFeather commented 8 years ago

Yes, I'll do that, promised! :smile:

PrimaryFeather commented 8 years ago

I just added an according parameter to the Texture.fromAtfData method. However, I don't know yet how best to teach the AssetManager about this setting.

Right now, it uses the TextureOptions class to decide the settings for each texture. However, the premultipliedAlpha setting is currently ignored — up until now, it has been true for Bitmaps and false for ATF files. (That setting is only used in Texture.fromTextureBase().)

If I now let the AssetManager decide on the PMA setting via the options, it's quite non-intuitive that it's only used for ATF files. I'd also have to change the default to false. I don't see a really clean solution for this — except maybe a new option like forcePmaForAtfData or something like that.

Ideally, I'd love to have this information stored in the ATF file header. Then any tool creating the ATF files could decide on the setting, and you wouldn't have to care about this at runtime.

I'm actually considering to undo this change, because it's probably not much use to you, anyway — without AssetManager support.

You can still load your textures: you just have to let them load by the AssetManager (as you're doing now), and then pass the texture.base to Texture.fromTextureBase(), supplying your PMA-enabled options.

At the same time, I try to get Adobe and Andreas Löw to write this information into the ATF header. What's your opinion on this?

b005t3r commented 8 years ago

I guess you could add something like forcePMA to options. If this is false, default values are used (false for ATFs and true for bitmaps), if set to true, PMA is always on for the texture.

Currently I don'y need it - I checked my options with ATFs and nothing lokks good enough, so I'm using PNGs only, BUT I've seen many different posts about problems people are having with lack of PMA support for ATFs (some posts are even left unanswered, because nobody knows what the problem is), so I guess this should be a thing in Starling.

Also, I think you could add a warning message to be traced to console when somebody creates a non-PMA texture, just to let people know they might run into troubles when using different blend modes with such textures.

PrimaryFeather commented 8 years ago

I guess you could add something like forcePMA to options. If this is false, default values are used (false for ATFs and true for bitmaps), if set to true, PMA is always on for the texture.

Mhm, that's probably the way to go.

I've seen many different posts about problems people are having with lack of PMA support for ATFs.

Damn, it seems I overlooked those. Thanks for the heads-up! BTW, do you know of any other tools besides TexturePacker that would have that option?

[...] just to let people know they might run into troubles when using different blend modes with such textures.

At least in Starling 2, this is thankfully no longer an issue. The only downside of ATF textures is now one additional operation in the fragment shader.

Thanks a lot for the feedback, Łukasz!

b005t3r commented 8 years ago

Damn, it seems I overlooked those. Thanks for the heads-up! BTW, do you know of any other tools besides TexturePacker that would have that option?

No, I only use TexturePacker. With Adobe png2atf this could be possible when using PMA PNGs, but I didn't test that.

At least in Starling 2, this is thankfully no longer an issue. The only downside of ATF textures is now one additional operation in the fragment shader.

Oh, good to know :)

Thanks a lot for the feedback, Łukasz!

Anytime! :)

PrimaryFeather commented 8 years ago

Another quick question — I must be completely blind, but I can't find the "pma" switch in TexturePacker when choosing ATF textures. It's there for "PNG" and some other formats, but not when I select "ATF". Or is this only available in the command line interface?

b005t3r commented 8 years ago

Ah, yes, there's no PMA checkbox for ATFs when using JXR compression BUT you can use --premultiply-alpha in command-line tool (I contacted Andreas Löw about it) and it works. There are however PMA checkboxes for other formats (you probably need to switch the advanced options to use it). I tested with JXR and DXT and it worked.

PrimaryFeather commented 8 years ago

Okay, that explains that. Thanks! :smile: