Skip to content

Loading…

Bitmap font performance too slow #63

Closed
PrimaryFeather opened this Issue · 20 comments

5 participants

@PrimaryFeather

For some reasons, text fields that are backed up by a bitmap font are not as fast as they should be, as described here:

http://forum.starling-framework.org/topic/bitmap-font-composed-textfields-are-much-slower-than-device-rendered-tfs

@jamieowen

Hi,

I think i have spotted something related to this.

If you register a BitmapFont, assign to a TextField and then update the text every frame you get memory/GC problems.
Here's a couple of profiler screenshots:
Build up :
http://dl.dropbox.com/u/6139329/starling-github/buildup.png
Dropoff
http://dl.dropbox.com/u/6139329/starling-github/dropoff.png

It starts off at about 350kb for this simple example, builds up over about 3.5 mins to about 4mb then drops back again when the GC finally kicks in. This process just repeats and would probably be a lot worse with multiple TextFields.

From the look of it the Starling TextField.createComposedContents() / BitmapFont.createDisplayObject() / BitmapChar.createImage() all instantiate new Starling Display Objects every frame.

I've ran into this kind of problem before and usually introducing some sort of Factory Pattern/Object Pool for DisplayObjects would help here!

Cheers,

Jamie

@PrimaryFeather

Thanks for the report, Jamie! Yeah, that makes sense ... I'll have a look at it, too, but I guess some kind of object pool would indeed be the best solution.

@jamieowen

That's ok,
Cheers for the framework!

@Tiago-Ling

Any news regarding this issue?

Is this related to creating new instances when "createRenderedContents" is called or is this something more obscure?

@joshtynjala

I wonder if it would be faster to reuse Image objects, and then set texture and call readjustSize() when characters need to change. That's what I chose to do in my Foxhole Label control, but I didn't actually do any tests to see how it compares to TextField.

@PrimaryFeather

It's the method "createComposedContents", Tiago, I guess that's what you meant.
Josh, exactly, that's one of the reasons. The other might be that all those "addChild" calls lead to many "Event.ADDED" events being dispatched.
I've got a few ideas about optimizing that code -- sorry that I haven't found the time to look into it yet! I'll try to squeeze it in soon.

@Tiago-Ling

Thanks for the reply guys. I'll see what i can do today and report the results here.

As it is now, every time i update a TextField in my game (running in an iPod 4) everything stops for about 100 milliseconds.
Josh, you used readjustSize instead of creating a new BitmapData?

@joshtynjala

@Tiago-Ling When the string changes, I try to reuse the Image for each character by swapping out its texture and calling readjustSize() with the new character. Neither my implementation in Label, nor Daniel's in TextField should be creating new BitmapData anywhere.

@Tiago-Ling

@joshtynjala Sorry, i saw createRenderedContents() instead of createComposedContents().

So, the main problem resides inside BitmapFont and BitmapChar classes?

I'm gonna try to reuse the images as you instructed, and before adding/removing children i'm gonna check to see if the new string has more or fewer chars than the old one, and then just remove/add the difference.

I don't know if this is the best approach, what do you guys think?

@PrimaryFeather

Don't worry about it any more -- I just finished an update that should make this super fast. The text is rendered directly into a QuadBatch now; no more images or events are created.

I just want to do a few more tests before committing it. It should be online tomorrow!

@Tiago-Ling

Thanks Daniel. I tried to reduce instantiation inside the BitmapFont and BitmapChar classes, but in the end my changes didn't have any effect on performance. I saw the need to dig deeper, but without much knowledge about the inner workings of Starling this is much easier said than done.

Well, thanks again, you don't know how much this change is gonna help me!

@PrimaryFeather

I just pushed the updated version into the repository!

To all of you, it would be great if you could test it out and tell me your results -- concerning performance and rendering correctness. Thanks in advance!

@jamikado

One minor change, which I think may be unintentional is that in the old code TextField's mContents was always set to touchable = false, and although the new QuadBatch is now touchable = false by default, I think if you trace the renderedContents path I think the new mImage is ending up touchable = true? Am I missing where this is getting set to touchable = false now?

@jamikado

Daniel, have you tried using some white text bitmap fonts with this latest set of changes with a dark background?
I seem to be seeing all my text always paint behind dark backgrounds.

Even the fr.kouma.starling.utils.Stats class that was ported to Starling and using bitmap fonts doesn't display the text properly now.

Maybe it is something I have locally changed (dont think so) but wasn't sure if the new QuadBatch painting with composed content required new ordering of sprite children....

@PrimaryFeather

You're right, Jeff, I totally forgot to set the bitmap to touchable = false! I did that just now.
As for the rendering problems: I have not encountered that! I'll try it right away.

@PrimaryFeather

embarrassing ... totally forgot to finish the previous quad batch on quad batch rendering.
That caused the issue.

Thanks a lot for the heads-up, Jeff! The tests I made unfortunately did not suffer from that problem, so I did not notice that.

@jamikado

Sweetness! Just added this update and it is all working perfectly! Thanks

What is even more cool is that now that I can see the memory stats in fr.kouma.starling.utils.Stats I can see the it barely moves at all during idle times where the older TextField code would show the constant minor climb... Even more indication these new changes are awesome!

@joshtynjala

Thanks a lot for this enhancement, Daniel. Scrolling in the Starling version of my List component now performs better than the old renderMode gpu version.

@Tiago-Ling

I'd like to thank you as well Daniel. This change made a HUGE difference for me. Using the old textfield class and updating my only textfield at every 0.75 seconds the game was flickering (stopping for about 0.1 seconds, totally perceptible).

Now i can update a textfield at every frame without any difference in the fps. Thank you again for the great framework and for the incredible work at the support forum!

@PrimaryFeather

Thanks for the wonderful feedback, guys! Great to hear that the change was worth it! =)

BTW, I found a small additional optimization that will make it even faster. It's already committed! Bitmap Fonts are now definitely the best font rendering option in Starling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.