The widget buttons are definitely the problem. I made a basic button class myself and replaced the corona widget buttons with my custom buttons and now the page transitions instantly. Something is going on in the widget button that is causing a big delay…
It’s done. The next CoronaCards version we push out will have a significant speed boost for widget buttons without labels/text. It also significantly improves the performance of display.newText() without text as well… not that you would really do that (it would end up being an invisible display object), but that was the culprit here. Thanks for bringing this issue up.
Sounds great, thanks!
Just wanted to give you an update on my app:
* I’ve replaced all the corona widget buttons on my menu screens with my own. My buttons also support text overlays, but they use a bitmap font now instead of the newText() api so they avoid the performance hit.
* I’ve replaced all my menu screen’s text with bitmap fonts
The app is running very smoothly now! There is pretty much no delay between scene transitions and I am very happy with the results!
I’m hoping to finish making these changes to the main game screens soon. If all goes well it should look and run virtually the same as on iOS and android
P.S. I had a little bit of a time adding a bitmap font to corona since I don’t see any direct corona sdk APIs for them. I searched around and found the bmf.lua file contributed by the community and got that working. It does seem to have some glitches in it though and lacks many features. I think it would be an awesome addition to the corona SDK to provide the APIs for bitmap fonts. That way it would have more features and be better tested/less bugs.
Glad to hear that you’re getting fast performance now.
Regarding bitmap fonts, the reason we don’t have direct support is partly because we know there are 3rd party libraries that do this and we didn’t want to step on any toes. Plus, supporting other languages can actually get quite complex. Such as knowing where to put the word/line-breaks for different languages, supporting Asian languages which have a huge amount of characters, and handling cursive languages such as Arabic. I do agree that we need some kind of solution for WP8, but we’re not sure what that should be at the moment.
Oh, and in case you didn’t know, here are some other 3rd party bitmap font libraries for Corona that I’m aware of.
TextCandy:
http://www.x-pressive.com/TextCandy_Corona/features.html
bmGlyph:
http://www.bmglyph.com/corona-bitmap-font-with-graphics-2-0/
Font-Manager:
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
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.