[RESOLVED] Graphics 2.0 - Bad Performance (Image Loading)

Our game is very processor intense, but we were able to optimize until it performed comfortably on iPhone 4 and iPad 2.  That is until graphics 2.0.  We spent days migrating to the new system, excited about the promised performance improvements. Then we built for device.  The game was getting 3-4 second freezes constantly for the first couple minutes of the game, and the overall performance was reduced by at least 30% indefinitely.

What is going on?  We don’t see how this could have anything to do with our code, as it worked perfectly pre-2.0.  We had actually tried 2.0 before, back when the public beta was first released, and experienced the same result. But then we just assumed that it was because it was still in beta, and that all these kinks would be worked out.  But now its publicly released, and theres no way our game can run on it.

The worst part about it is that, as far as we understand, Corona is going to build all future daily builds upon 2.0, thereby entirely excluding our game from them, and putting us in the very unfortunate position of not being able to receive updates.

We have always loved corona because of its excellent performance and how easy it is to use. But with this current revelation we will most likely be moving to Objective C in the very near future if these issues are not resolved. Please tell us this is a common issue and that you are working on it, or that we did something obviously wrong, however we don’t think thats likely as we have looked at every possibility we know of.

Thanks.

That sounds weird. Can you tell us more about what you’re doing in your project that is processor intensive?

During the Beta period, we worked with many developers. The dialogue we had with them allowed us to identify many hot spots and address the performance issues they were seeing. So if you give us more information, we can work together to get to the bottom of this.

I know that there are issues with devices that use the PowerVR SGX535 GPU. The devices include the iPad 1, iPhone 4 and iPod Touch 4th generation. The problem is that the GPU mentioned above is underpowered and Graphics 2.0 pushes the hardware in ways that Graphics 1.0 didn’t.

When I tested on these 3 devices, it looks like the problem lies with the hardware, and not Corona.

In my testing the iPhone 3GS and iPhone 4S have been able to perform as expected though. However my apps are not all that processor intensive. One thing that strikes me is that you mentioned problems on the iPad 2, which I haven’t seen with my projects.

Ok, after noticing that the freezes at the beginning were consistently timed we began to test each part of the code until we discovered what caused it.  

Basically, any time you raise an images alpha from 0 it causes a system-wide delay.  This includes transitioning it from 0 alpha, or just changing it from 0.  The delay is not perceptible until you get into larger images, or images that were loaded from large image sheets.

A 1024 x 1024 image on the iPad 3 had a momentary freeze, while a 1024 x 512 did not have any percievable freeze.  The larger the image, the longer it freezes. In our app we are using several full size images and image sheets, so this causes a serious problem.

Also it seems that this only happens the first time an object is set to 0 alpha.  Subsequent times it can be set to 0 then changed with no issue.

Steps to reproduce:

Load an image at least 1024 square.

Set alpha of image to 0.

Create a circle, 5-10 px radius.

Set circle xy to top left corner.

Transition circle to bottom right corner over 15 seconds.

Delay 5 seconds, then set alpha of image to 1.

Right when the image changes alpha you will see the circle stop for 0.5 - 3 seconds depending on the size of the image.

EDIT:

I believe that Cublah has the same issue here - http://forums.coronalabs.com/topic/40876-transitions-in-graphics-20/

Thanks for the steps to reproduce - we will look into this.

Wow, thought I was crazy. I downloaded the new engine, and there are performance issues. On windows, when I save a project it takes several seconds to load on the simulator. Device performance took a dive too, so I went back to earlier public release. 

I spent quite a bit migrating, so after losing a day or two - I called the ball and went back. In my game, we are doing random generated backgrounds with for loops, and before everything was peachy. But now, it’s like 20 to 40% drop. I went back to previous public release, no issues - I can run on iphone4s and up fine (iphone4, ipod4 are not interesting to me, runs like dog crap on those anyway no matter what I do). 

like XWL, I’m using larger images and a config lua using 800x1200 with 1425x900 images and 2850x1800 (the “modernizing” config lua). 

All I’m saying it seems that the public release isn’t optimal yet. 

-Nick

@nicholasclayg

Not to detract from this thread (I hope Coronalabs gets to the bottom of these G2.0 performance issues), but if you are using images that are natively 1425x900 and 2850x1800 pixels then you wasting a lot of texture memory and bandwidth since textures get up-scaled to the nearest power of two size when loaded into texture memory.   Your 1425x900 will get converted to 2048x1024, and the 2850x1800 will get converted to 4096x2048!  Those are big, honkin’ textures!  

If you downscale your texture images to a power of 2 size in advance you will save a ton of memory/bandwidth at the cost of some minor blurring that you might not even notice.  As an added bonus your app download size will be much smaller.  I’d scale the 1425x900 down to 1024x1024, or even 1024 x 512.  Scale the 2850x1800 down to 2048x2048 or even to 2048x1024.  That would be a 4x reduction in texture memory and you might not need to write off the iPhone/iPod 4 after all.

-Stephen

P.S.  - I should mention that downscaling the textures files to a power of 2 size is all you need to do.  You don’t have to change your config.lua, or mess with any of your existing Corona/lua code, it will all just work.  

From what I understand, you want to scale up if you can and not scale down as that takes more cpu power. At least that’s what I’ve been reading. The images I am using are about 30 to 40 kb a piece (they are hills, background terrain so to speak where the whole image isn’t used).  

For performance, I’ve written my prototype dead simple with system shapes (squares, circles etc) but because it’s randomly generated on the fly based on what the player is doing that generation algorithm just kicks iphone/ipod 4 in the pants and runs at a paltry 40fps. Since the game is based on dragging your finger around QUICK, lower fps = lower accuracy for finger dragging = jumpy dragging = unplayable game. 

Something else to add to that, using config lua settings of 800x1200 vs 480x320 results in MUCH more accurate dragging. The lower res results in skipping jumpy touch. I was forced to go with 800x 1200 for that reason alone, the problem is worse when going to ipad it skips all over the place, unless I use the 800 1200 config lua settings. 

I know fun right? 

But back on point, the performance was FINE before, but now it’s not. It’s ok though, I’m not using any fancy gfx 2.0 features so I’ll still with the older builds for now until it’s sorted :slight_smile:

-NIck

Hi Nick,

Sorry I wasn’t clear, the idea is to pre-scale down the textures in, say, Photoshop, before you use them to build your app, not scale them down in the app.  

Your 2850x1800 texture file might be 40kb on disk (I’m guessing it is has a lot of transparency and solid color fills?) but that is the compressed png file stored on disk.  It still must be uncompressed into full 32 bit glory to be used by a device’s graphics hardware memory, (plus expanded to that pesky power of two size), so it becomes a 4096x2048x32 bits = 24 MB texture!  Also, I think most older devices don’t even support 4096 texture sizes (not sure about iPhone 4).

Sorry if I derailed this thread, but I cleared up a lot of device performance issues in my own projects with this kind of easy optimization so I thought it was worth sharing.  If G 2.0 is a step down in performance (hopefully temporarily) perhaps other optimizations can help boost it back up.

We have a workaround to address the large image load causing a visible stutter. Actually, the performance for loading images on graphics 2.0 and 1.0 is largely the same. What’s different is when the image is loaded:

  • The 2.0 engine lazily loads the image when it’s actually going to be visible on screen (e.g. alpha > 0, etc), which is ideal for applications that want faster start up times by deferring the cost of large image loads. 
  • The 1.0 engine immediately loaded textures on the display.newImage() call regardless of its visibility on screen. This meant you paid the penalty for large image loads immediately.  

The work around to this to force the 2.0 engine to load the texture immediately is to load a tiny display object on start up.

Attached is a sample project, where you will notice that we load a large image (alpha value at 100%) but the height and width is tiny (sub-pixel) so it can’t be seen.  The actual display object (background) that will use this texture however is not visible until 5 seconds into the application.  This causes the engine to load the texture immediately on start up and there is no extra load incurred while the text is transitioning across the display.

Longer term, we are working on a solution to allow a more immediate load for textures in the 2.0 engine but thought this would be useful to explain both the change, and how to immediately load textures on start up.

This is a big change and not one I was aware of. It will cause all sorts of headaches.

OK. That explains why I was getting these temporary hangs after implementing G2.0 every time I started an app.

I didn’t want to modify all the image loading in every module within my apps, so to solve this problem (I hope temporarily) I created a small module with overridden functions that force a load.

-- -- override.lua -- local saved = {}; saved.newImage = display.newImage; display.newImage = function(...) local forceLoad = saved.newImage(select(1, ...)); forceLoad.width, forceLoad.height = 0.1, 0.1; timer.performWithDelay(100, function() forceLoad:removeSelf(); end); local img = saved.newImage(select(1, ...)); return img; end saved.newImageRect = display.newImageRect; display.newImageRect = function(...) local forceLoad = saved.newImageRect(select(1, ...)); forceLoad.width, forceLoad.height = 0.1, 0.1; timer.performWithDelay(100, function() forceLoad:removeSelf(); end); local img = saved.newImageRect(select(1, ...)); return img; end

The only thing that needs to done after this is to put require(“override”) at the top of main.lua.

I tested this on some projects and it seems to work well. The initial lag I saw was gone.

It’s not pretty, but it’s functional…

To take Bryan’s sample app it would become:

-- -- main.lua -- require("override") local imageToLoad = "boxer-1920.jpg" local background = display.newImage( imageToLoad, display.contentCenterX, display.contentCenterY ) background.alpha = 0 -- Without the "override" step the image in background isn't loaded until it becomes visible local myText = display.newText( "Moving text!", 0,0, native.systemFont, 40 ) myText:setFillColor( 1, 255/255, 255/255 ) transition.to( myText, { time=10000, x=320, y=480 } ) local function test() background.alpha = 1 background.x = 0 end timer.performWithDelay( 5000, test)

Similarly, we’ve just converted one of our games to Graphics 2.0 for launch on the GameStick and are seeing a large drop in performance. The version shown has extra particles so is running slower than normal but it shows the drop well:

Previous version:
https://www.dropbox.com/s/jvil9uoo6o0vmvc/Graphics_1-0_h.jpg

With Graphics 2.0:
https://www.dropbox.com/s/fgl7coql6tl9vfr/Graphics_2-0_h.jpg
 

So about 30% slower for us too.

The game needs to run at close to 60fps to be playable and I’m worried that we’re just not going to hit that with Graphics 2.0.

After seeing the demo of 5000 fish at 60 fps we were really hoping for a big boost in performance so this has come as a bit of a shock. Or maybe we’re doing something wrong with our rendering? Tips welcome.

Please can Corona Labs share the 5000 fish demo so we can test the performance of it on a GameStick?

Thanks,
Ian

So it appears that the initial freezing issue has been identified, but as other people have said, there seems to be about a 30% drop in overall performance as well.  It doesn’t seem like these are related, although they could be. It seems that this performance loss is associated with moving/rotating large images.  Does that concur with what you’ve seen spideri and Nick? 

Well our game Finger Hoola is 90% about rotating images so that would be consistent… and annoying if it were true. Hopefully you’ve identified a problem that can be resolved though.

Yep, XWL you nailed it. I’ve stripped down things to barebones and just generally speaking things aren’t as efficient as they were before the g2 upgrade. Luckily, I’m going to continue using build 1260 as it has everything I need for the time being. 

Hopefully, this will get sorted out. I’m not even going to entertain the work around given as that wasn’t needed before, so why start now :)-

-nick

@Bryan01 

So in a future build will there be some sort of flag we can toss in at the top of our lua files

display.FastLoadTextures = true

…or something :slight_smile:

double :slight_smile: :slight_smile:

triple :slight_smile: :) :)

MEGA SMILEYS :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :)  :slight_smile:

What devices are you guys testing on?

LKinx in IRC narrowed down a huge performance hit to rotating a couple of sprites. I don’t recall the specifics, but thought I’d throw it out there as it is something others have noticed as well.

A GameStick still…