New Beta Tester - Corona Cards performance questions

Hi all,

I’m really excited to be able to beta test corona cards for wp8! I’ve got my word game running successfully on my lumia 920! The app is pretty graphically simple so I figured it would be a good candidate to try this out on.

A couple things I’ve noticed:

* It seems to take a long time to load in graphics with display.newImageRect(). Is there anything I need to do different to speed this up? For example, when switching to a new scene there is a significant delay, but only if the scene is loading in some graphics. Also when a user correctly enters a word a circle pops up with a text in it for the score. A rectangle also pops up with some exclamation text in it. There is a delay between the word being entered in and the graphics popping up.

* The overall frame rate of the app seems to be lower, and a bit jerky. For example:

  I use some scroll view controls and when scrolling it isn’t that smooth. I use some transition.to animations to move little letter tiles around when the user touches them. They are a bit jerky now.

Is there anything I need to do different to speed up the app? I’ve tried setting the fps to 60 and 30 in my config.lua but it doesn’t seem to make a difference.

Thanks in advance!

I’m using 2014.2452 and visual studio express 2013

In my experience, the 2 biggest performance killers on WP8 is with display.newText() and print() functions.

The print() function performance hit only happens while you are debugging your app in Visual Studio.  We’ve optimized it quite a bit on our end and is only noticeable when you’re printing a lot of strings at once.

Now, the display.newText() function is by far the biggest performance killer.  Creating text and updating text is an extremely extremely expensive operation on WP8 and unfortunately the performance issue is coming from the operating system’s end.  This means that we can’t make it any faster on our end.  So, if you’re creating or updating text on almost every frame or based on touch events, then that will slaughter the performance.  In these cases, you should use “bitmap fonts” instead, which is Microsoft’s recommended solution.  What this means is that you load all the characters you need in 1 shot via a spritesheet/imagesheet and then assemble the characters into the text.  This is faster because all of the characters are already preloaded as textures in Direct3D.

There are 3rd party bitmap font tools that can help you with this such as TextCandy, bmGlyph, Font-Manager, etc.  In fact, they should improve your text rendering performance on other platforms as well, such as iOS and Android.

That said, the bitmap font technique is only useful for text that is under your control.  That is, it should only be used when you can guarantee that the characters you are using exist in your spritesheet.  The display.newText() function should be used for text that’s out of your control, such as text taken from the Internet like Facebook, Twitter, etc… and this will work fine in this case because you’re not going to be updating this text on every frame.

On more thing…

I have a Lumia 920 as well and unfortunately my framerate caps out between 45-50 FPS.  Not bad, but I wish it was better too.  I’ve found that this particular device has a nasty habit of rendering late on every 4th frame even when I completely strip out Corona from the app.  We can’t squeeze out any more performance out of that device.  But our lower-end Lumia 620 out performs it and renders at a solid 60 FPS.  Not sure what to make of it, but there it is.

I use display.newText() everywhere… I’m getting around 20 fps when moving things around like the letter tiles. The letter tiles are actually corona sdk buttons (which have text in them) so maybe that is why it is running so slow?

I don’t use the enterFrame event at all, everything is user event driven.

I’ll have to look into the bitmap font tools. From what you have said I suspect that this may be the big performance bottle neck.

Is there a performance hit for using the corona widget library? The scroll view isn’t too smooth, but the contents of the scroll view does contain display.newText() so might this be related to that as well?

Joshua, 

I’ve been playing around with things a bit more and this is what I have found:

Even when loading in a scene with a single image to fill the screen and two buttons there is a significant delay in the scene transition (1 - 3 seconds). I see this on my lumia 920 as well as on the windows phone simulators. I am using the storyboard api.

I tried out whammy’s Feed OmNomster app on windows phone and I don’t see these kind of delays in his app.

I must be doing something wrong :frowning:

Would you be able to take a look at my app?

Thanks!

Odds are it’s the display.newText() calls that is your biggest performance hit.  Whammy replaced most of his display.newText() calls in his OmNomster app with calls to a bitmap font library, which is why his app performs so well.  Our image loading and widget loading is actually quite fast on WP8… up until you do text updates.

For example, for the widget TableView, if you do a display.newText() for ever onRowRender() gets called, then that is an huge performance killer right there because that function gets called as you scroll to new rows in the table view.  Note that this is performance killer on Android too and causes scrolling to be not smooth.  There are some optimizations that you can do.  For example, if you know the number of rows will be limited, then you can pre-load the text objects you create via display.newText() and then display them when the onRowRender() gets called.  Or you can use bitmap font (the fastest) solution provided that you have control of the characters that are being displayed.

Also, it might help to understand how display.newText() works.  This function creates an uncompressed 8-bit grayscale bitmap, has the operating system draw text to that bitmap, and then that bitmap is pushed as a texture to the GPU.  This is an extremely expensive thing to do on all platforms and Corona developers usually notice the performance hit when using display.newText() as a visual FPS counter, which will severely impact the framerate on all platforms.  Now, the reason it is more expensive on WP8 is because Microsoft doesn’t have an API to render text to a bitmap on the CPU side.  Instead, Microsoft’s APIs draw text directly to the GPU which is of wrong image format and is not part of Corona’s visual tree.  So, we’re forced to capture that text texture on the GPU, which involves transferring the bitmap from the GPU to the CPU, re-formatting the image to grayscale, and then sending it back to the GPU.  That round trip is very expensive and it is our *only* option on WP8.

But that said, most SDKs don’t offer the ability to have the operating system render text, leveraging the hard work that Apple, Google, and Microsoft put into getting text formatting/layout correct for different languages/locales.  Most SDKs, such as Unity, only offer bitmap font support.  Corona offers the ability to render text both ways, rendered by the OS or via bitmap fonts.  We do so because each text rendering technique has their advantages and disadvantages, allowing you to get the best performance or best layout for other languages.

So, I suggest as a quick text to prove what I’m saying above, try commenting out function that are generating/updating text in your code.  You should see a huge performance difference.  After proving this, from there I recommend that you experiment with bitmap fonts.

Thanks for the detailed description Joshua!

The gotcha here is that I’m not loading any text on these scenes at all, and yet there is still that long delay during scene transitions. I am using two corona widget buttons, but I don’t put any text on them they are just pure image buttons. I’m a bit puzzled about it because it seems like it should load lightning fast since there is only a couple images on each scene. Any other ideas?

Hmm… interesting.

Would you mind do a quick test?  I want you to try adding the widget PNG files directly to your “Assets\Corona” directory to see if it loads any faster.  I have instructions on how to do this here…

   http://forums.coronalabs.com/topic/49277-widgets-in-corona-cards/?p=254947

And sorry to ask you to do this.  I’m tasked to do other things today, but I’ll be happy to play with this later this week if you’re too busy.

I am using my own custom png files for the button widget like this:
 

local backButton = widget.newButton{ defaultFile = "assets/images/tutorialBackButton.png", overFile = "assets/images/tutorialBackButtonOver.png", width=buttonWidth, height=buttonHeight, onRelease = backButton\_onReleaseListener -- event listener function }

I tried copying in the files you suggested but it didn’t have any affect.

There must be something else slowing it down.  Do you see anything getting printed to Visual Studio’s “Output” panel when transitioning between scenes?

There isn’t anything happening in the Output panel… do you think I would get better performance using the composer API? I wonder what it could be. There really isn’t much of anything happening on the scenes… just a couple graphics on most of them. I do use a global table I reference pretty often called GLOBALS, but I can’t really imagine that affecting it.

I’m not sure.  I’ll have to play with it on my end.  I do know that @whammy’s OmNomster app still uses storyboard and it’s working fine for him.  But whammy also initially reported a delay during scene transitions too, but it sounded like he found the cause or perhaps a work-around.  You can see my discussion with him here…

   http://forums.coronalabs.com/topic/49553-timers-issue-in-the-new-coronacards-wp8-build-20142369

I wonder if it has to do with using a fade transition between scenes. I’ll try removing the fade and just straight loading it without a transition effect

No that didn’t make any difference. It appears to just freeze the app for 1 second and then just pops up the new scene.

So I’ve been experimenting with a barebones app.

I’ve found that adding even a single widget button (image only, no text!) adds a noticeable delay for scene transitions (because constructing the new scene takes so much longer). The more widget buttons you add the worse it gets.

Each widget button that I add introduces about 250 - 500 ms of delay when creating the scene. When no buttons are added the scene loads very quickly, even when loading lots of graphics on scene creation.

It appears there is some performance problem in the widget button. Joshua would you be able to look into that? I use corona widget buttons very heavily in my app and I suspect this is the source of my performance issues on wp8. 

Thanks!

I just tested a storyboard app with transition effects and I didn’t see any performance issues.  And each scene would load a new background via the “createScene” event.  But I haven’t tried widget buttons.  That’s interesting.  I’ll have a look at our widget button code, because this doesn’t sound like a “storyboard” issue.

Agreed, I don’t believe this is a storyboard issue. I suspect that widget button very highly :smiley:

Wait.  Hold on.  Are you displaying text in your widget buttons?

I ask because our widget button code internally uses display.newText() to create the text for your button’s “label”.  If your buttons do have labels, then that is the root cause of your performance issue.

Interestingly enough, I’ve noticed that if your button labels are set to an empty string “” or just a space " ", then the performance is considerably worse.

So, how are your buttons set up?

Here is the button I used to test with. There is no text defined, just a two custom images:

local gameModeButton = widget.newButton{ defaultFile = "gameModePuzzle.png", overFile = "gameModePuzzleOver.png", width=100, height=100, onEvent = gameModeButton\_onEvent, x = gameModeX, y = gameModeImageY, }

Okay.  I did notice that there is a much bigger performance hit when the button has no label/text.  I’ll look into resolving that.  Thanks for bringing this up.