Framerate drop on iPod Touch 4G when touching and moving

The sample I provided is only an example that simulates a complex hierarchy of display objects. Take a look at my game play footage a few posts earlier. I can’t use “one image”, the scene is built up using a bunch of display objects in parallax layers.

Edit: Changed Trailer to Game Play Footage

You could make a Sprite sheet animation that looks like that

I would also add, that in my game I believe I am really pushing Corona very hard, so I don’t think this scenario has come up in any testing. 

How would a sprite sheet animation help? The scene is gigantic, there are easily 25 layers that scroll in parallax. The trailer doesn’t completely give it away, but trust me, there is a lot going on. The scene is about 10000 pixels wide and is constructed using a single 2048x2048 tilesheet.

If it this complex how you expect older devices to run it. At the end of the day people with modern devices pay the most. It is nice that you want your folks to play but you should get them a new iPad or a good kindle instead. :slight_smile:

I appreciate your help. The problem here is that the framerate is completely acceptable at 30+ fps on even my worst devices, but once the player touches the screen, even without any touch event listeners (and with a single touch listener that returns true) the framerate drops. 

This is not a matter of me needing to change my scene complexity, this is a matter of determining why the touch events cause the frame rate to drop so drastically in a scene that is otherwise perfectly fine, even on my BLU DASH JR which is really the bottom of the barrel.

Did you run the sample application on your iPhone 3GS? Based on the specs of that device, the problem should be obvious.

How does one explain to customers that the game slows down not because of my game, but because of the underlying game engine? I like Corona for it’s simplicity, and I’m really hoping the root cause is something fixable, as I have a lot of time invested in this.

The bug has been assigned to an engineer. I’m not sure where on his schedule it is to look at.

Rob

Hi Rob,

Thanks for the update, even knowing that it may be looked into is good to hear.

I want to emphasize the problem here, there are two constants at the top:

local OBJECT\_COUNT = 2000; -- \<\< I changed this to 1500 in more recent tests of my own local DEMONSTRATE\_BUG = true;

With my finger on the screen making very fast circles:

  • Setting DEMONSTRATE_BUG = false will cause the scene to run very quickly.
  • With local DEMONSTRATE_BUG = true , the scene will run very poorly

The difference between the settings is that TRUE will create a random (and deep) hierarchy of display objects, and FALSE will create a flattened list of display objects in the “global” stage.

I tried the suggestion from @scottrules44, wherein I added this code to the MAIN.lua:

local background = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight); background.alpha = 0.1; background:addEventListener("touch", function () return true end);

This seems to make logical sense, in that since “background” is on top of the display list, it should receive the first touch event, and since it always returns true, propagation to the rest of the display list is canceled.

I’ve even tried adding the listener to the Runtime global, and I’ve tried sending “background” to the back of the list to check if Corona was iterating the list backwards or forewards.

-- In case Corona iterates the Display List back-to-front local background = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight); background.alpha = 0.1; background:addEventListener("touch", function () return true end); background:toBack(); -- In case Corona iterates front-to-back local foreground = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight); foreground.alpha = 0.1; foreground:addEventListener("touch", function () return true end); -- Try to stop it at the system level Runtime:addEventListener("touch", function () return true; end);

In all cases, I receive frame rate drops when DEMONSTRATE_BUG = true.

On my HTC Rezound (http://www.gsmarena.com/htc_rezound-4099.php):

DEMONSTRATE_BUG = true:

–Idle: 30-33 fps

–Touching: 15-18 fps

DEMONSTRATE_BUG = false:

–Idle: 30-33 fps

–Touching: 26-27 fps

On my BLU DASH JR (http://www.gsmarena.com/blu_dash_jr-5662.php)

DEMONSTRATE_BUG = true:

–Idle: 59-60 fps
–Touching: 54-59 fps

DEMONSTRATE_BUG = false:

–Idle: 59-60 fps

–Touching: 45 fps

Thanks again,

Albert

I had a similar problem (with lots of layers) where panning was slow.  I solved it by only updating the screen if the delta change in x,y was > 5.  This greatly reduced the amount of times the full onTouch event processed.  Might help a bit?

Interestingly, I made my Camera system buffer the stage inside a Snapshot object, and touching and moving only affects the changes the frame rate from a steady 30 to 22-24. So it would seem that Corona does some kind of recursive loop on the scene graph for every touch event, maybe looking for touch listeners?

Still, the 6-8 fps drop is a big deal, has anyone experienced this?

Albert

What version of Corona SDK are you using?

Hi Rob,

I’m using the latest daily build, CoronaSDK 2016.2904

Albert

Can you try it with 2830?

Thanks

I just tested with the public release (2830) and I still have the issue. Is there anything else I can look for?

Although the stage is in the buffer, the UI (which is made up of many more display objects) is not in the buffer, so if my suspicion turns out to be true (that Corona is recursively looping through the scene) it may be that there are still too many display objects.

I was looking to see if you found a regression bug. Do you see this on other devices?

Can you make a test case that has the problem?

Hi Rob,

I don’t see this on Android devices, unfortunately my cat destroyed my USB cord for my iPad. I will look into recreating the problem, although last time I checked my code base was something like 70,000 lines so this may be no easy task. If worst comes to worst, I can send you my project files, although I imagine debugging my project would be torture for someone who has never seen it before.

Not to “promote” the game to you or anything, as I haven’t been displaying this publicly yet, but to get an idea of why the code base is so big and why the lag is killing the experience, here is some sample game play.

https://www.youtube.com/watch?v=A58WL3qXJvQ

Again, I’m not trying to promote it here, and if this is a problem, I’ll promptly remove the video, no need to provide feedback on it either.

Thanks for replying,

Albert

We probably would reject  you sending your whole project. We can’t debug it for you. But if you think you have a bug, we do need a test case that demonstrates it. In the absence of that, the only suggestion is to make sure you don’t have a touch listener on your Runtime or on the main stage.  We do loop through all objects that have handlers on them. Your touch handler need to return “true” at the end. If you don’t we are going to look for objects under it to send the event to since your function didn’t say it handled the event.

Rob

Hi,

Thanks. I did make sure there are no touch listeners, as I overwrote the Runtime:add/removeEventListener interface so as to be able to get a count on the number of listeners for any event. When I print out the number of listeners it is zero, and I additionally made sure every reference to the event was “xtouch” instead of “touch”.

I’ll do my best to come up with something to send your way.

Thanks again,

Albert

Hi,

I have narrowed this down and created a simple project that reproduces this problem.

http://www.ionpixel.com/Corona/TouchFpsSlow.zip

If you download and run this project, there is a constant at the top named:

local DEMONSTRATE\_BUG = true;

You can easily search the code to see what the bug does. The project will create 2000 display objects, with the bug enabled, touching and moving on the screen will cause significant frame rate drops on mid to low-end devices. With the bug enabled, the display objects are placed into variable parent DisplayGroups, so as to simulate a very complex hierarchy of display objects.

On my HTC Rezound, the app runs at a steady 25fps. Upon pressing and moving my finger back and forth, the fps drop to 10-11 fps and immediately shoot back up to 25 fps. With the bug demonstration disable, the fps only drops down to 21-22.

On my iPod Tough 4th Gen, the frame rate is at 11 fps, however touching and swiping quickly the screen drops the framerate down to 0, literally the screen freezes.

I understand the display hierarchy may not be a “realistic” app, but it simulates the problem that my real application is having. If you look at my source code, their are absolutely no touch, tap, or mouse event handlers. This bug seems to indicate that for every touch event Corona receives, it crawls the display list hierarchy to determine what object(s) are at the specified position, which it should definitely not do.

This is a critical problem for me, in my production application, framerate on my HTC device is a steady 52, but drops to 20 without a single touch/tap/mouse listener defined.

Case #46695

Thanks,

Albert

Hi Rob,

Is this a problem that can be fixed possibly? Since updating the logic would likely be a huge undertaking and possible not even technically feasible, a feature that can be enabled/disabled at runtime to stop Corona from iterating through the display list for every touch event would be equally awesome. Something like:

system.setTouchListenerEnabled( true/false ); -- Setting this to True would prevent Corona from iterating the display list on all "touch" events.

I’m near release and I’m worried about the performance on older phones. In fact a few of my close friends and relatives have old phones and it would be a huge shame for them to be unable to play my game.

Anything you can help me with would be hugely appreciated.

Albert