From what I've researched online, the iPhone screen refresh rate is 60Hz (not sure if this applies to iPhone 6 as well) - meaning, it can refresh an image up to 60 times a second.
However, I have a project in which I need a very fast blinking animation - to animate a view back-and-forth (from visible to invisible), more than 60 times a second. I thought about using CADisplayLink, so I'll get called every time the screen refreshes, but unfortunately, as stated above, this is not fast enough (gets called 60 times a second only).
Is there something I'm missing here, or is there a way to achieve a higher blinking rate? Do iOS games achieve better rates than this?
Thanks
There's no way to achieve a faster display rate than the screen refresh itself, mainly because the screen can't refresh as fast, so people won't see it anyway.
Hence all iOS games are effectively vsynced at 60 fps.
That said, depending on what you're doing, you might not be getting 60 fps. Have you profiled your app to determine the fps it's running?
If it's not doing 50+, there's probably some optimization that you can do to get it as close to 60 as possible.
Related
In iOS, How many times does RunLoop cycle in one second?
Is it the same as the screen refresh rate, 60 times a second?
No, the run loop frequency is not the same as the screen refresh rate. (It generally exceeds the potential screen refresh rates unless you block the thread.)
When we need to coordinate something with the screen refresh process, we generally use a CADisplayLink, which not only runs with the desired frequency, but also maximizes its timing within the screen refresh cycle.
Note, screen refresh rates can vary from device to device, and, on new devices, they can even vary depending upon the needs of a particular task running on a particular device (faster when you need better performance, slower when not needed and you want to enjoy more energy efficiency). See Optimizing ProMotion Refresh Rates for iPhone 13 Pro and iPad Pro.
I am running a realtime WebGL animation in the Chrome web browser. I am using requestAnimationFrame, which attempts to trigger frame drawing at the monitor's vsync rate (60Hz). However on some lower power machines (Intel graphics laptops), the webGL rendering cannot run at that framerate - running flat out it manages around 20 fps.
A framerate of 20fps would be fine - except for the fact that in this situation, my mouseEvents seem to be quite seriously delayed / lagging. For example, I print out "mouse" to the console in my mouseEvent handler, and it appears around 0.5 seconds after I tap the laptop's touchpad button. This is a serious delay for a realtime application, and results in my 3D scene lagging behind the mouse movement.
So far, the only way I have found to get around this lag is by using a "debounce" i.e. calling the next RequestAnimationFrame from a timed callback of between 50 - 70 milliseconds. This backing off eliminates the delay in mouse events being processed, but obviously results in a reduced fps. (For example a timer of 70 milliseconds reduces my fps from 20 to 10, which is no good, and a smaller delay does not solve the lagging).
I feel like there must be a better way of managing this per-frame synchronisation. My working theory is that RequestAnimationFrames are being queued up ahead of my mouse events, however I am not sure how to solve this. I know that Chrome passes webGL drawing off to another process, and I have tried to wait for drawing to complete by using gl.finish() - however this seems to have no affect.
Many thanks for any help / advice
I used to test my apps using an iPhone 5S - now I switched to a iPhone SE.
Now I am asking myself why the default form slide transitions still stutter on such a fast device - the animation should always appear smooth if the calculated locations are correct relative to the timeline.
Looking into CommonTransitions I saw that there is a CommonTransitions.TYPE_FAST_SLIDE and wondered if this was the key to smooth transitions, is it?
In Theme Constants in the Codename One Designer under FormTransitionOut however there is no option fastSlide - why is that?
I've wondered the same, although I have only a cheap device to test on.
This may only add fuel to the fire, but have you tried Display.setFramerate(int rate). The docs say the default is an (attempted) rate of 10 (redraws per second).
Maybe it would look smoother with 20?
In my app, I have several simple scenes (a single 80 segment sphere with a 500px by 1000px texture, rotating once a minute) displaying at once. When I open the app, everything goes smoothly. I get constant 120fps with less than 50mb of memory usage and around 30% cpu usage.
However, if I minimize the app and come back to it a minute later, or just stop interacting with the app for a while, the scenes all lag terribly and get around 4 fps, despite Xcode reporting 30fps, normal memory usage, and super low (~3%) cpu usage.
I get this behavior when testing on a real iPhone 7 iOS 10.3.1, and I'm not sure if this behavior exists on other devices or the emulator.
Here is a sample project I pulled together to demonstrate this issue. (link here) Am I doing something wrong here? How can I make the scenes wake up and resume using as much cpu as they need to maintain good fps?
I won't probably answer the question you've asked directly, but can give you some points to think about.
I launched you demo app on my iPod 6-th gen (64-bit), iOS 10.3.1 and it lags from the very beginning up to about a minute with FPS 2-3. Then after some time it starts to spin smoothly. The same after going background-foreground. It can be explained with some caching of textures.
I resized one of the SCNView's so that it fits the screen, other views stayed behind. Set v4.showsStatistics = true
And here what I got
as you can see Metal flush takes about 18.3 ms for one frame and its only for one SCNView.
According to this answer on Stackoverflow
So, if my interpretation is correct, that would mean that "Metal
flush" measures the time the CPU spends waiting on video memory to
free up so it can push more data and request operations to the GPU.
So we might suspect that problem is in 4 different SCNViews working with GPU simultaneously.
Let's check it. Comparing to the 2-nd point, I've deleted 3 SCNViews behind and put 3 planets from those views to the front one. So that one SCNView has 4 planets at once. And here is the screenshot
and as you can see Metal flush takes up to 5 ms and its from the beginning and everything goes smoothly. Also you may notice that amount of triangles (top right icon) is four times as many as what we can see on the first screenshot.
To sum up, just try to combine all SCNNodes on one SCNView and possibly you'll get a speed up.
So, I finally figured out a partially functional solution, even though its not what I thought it would be.
The first thing I tried was to keep all the nodes in a single global scene as suggested by Sander's answer and set the delegate on one of the SCNViews as suggested in the second answer to this question. Maybe this used to work or it worked in a different context, but it didn't work for me.
How Sander ended up helping me was the use of the performance statistics, which I didn't know existed. I enabled them for one of my scenes, and something stood out to me about performance:
In the first few seconds of running, before the app gets dramatic frame drops, the performance display read 240fps. "Why was this?", I thought. Who would need 240 fps on a mobile phone with a 60hz display, especially when the SceneKit default is 60. Then it hit me: 60 * 4 = 240.
What I guess was happening is that each update in a single scene triggered a "metal flush", meaning that each scene was being flushed 240 times per second. I would guess that this fills the gpu buffer (or memory? I have no idea) slowly, and eventually SceneKit needs to start clearing it out, and 240 fps across 4 views is simply too much for it to keep up with. (which explains why it initially gets good performance before dropping completely.).
My solution (and this is why I said "partial solution"), was to set the preferedFramesPerSecond for each SceneView to 15, for a total of 60 (I can also get away with 30 on my phone, but I'm not sure if this holds up on weaker devices). Unfortunately 15fps is noticeably choppy, but way better than the terrible performance I was getting originally.
Maybe in the future Apple will enable unique refreshes per SceneView.
TL;DR: set preferredFramesPerSecond to sum to 60 over all of your SceneViews.
I'm having a problem that I'm not sure how to solve.
In cocos2d 2.0 , the second number on the bottom left drops to a low number like 0.002 and causes lag in my game!!
The second number is the 'Frames Per Second's Milliseconds', or the amount of time it takes to go to the next frame. I got this info from a question similar to mine, here is a link to that question:
Cocos2d 2.0 - 3 numbers on the bottom left
The games FPS's Milliseconds usually runs at about 0.016 or 0.021 and there is no lag.
Shouldn't it run smoother at numbers as low as 0.002?
How can I stop this lag?
Is there anybody that knows enough about cocos2d to help me out?
When your app runs really, really slow (around 10 fps or less) the milliseconds display is no longer accurate and will display a very low number.
You need to find out what's causing the drop in framerate. If the number of draw calls is high (100+) then your problem is that you're rendering too much and/or inefficiently (use sprite batching).
If the number of draw calls is reasonably low (no more than 50) then your problem is not the rendering but your own code. Possibly some time consuming (inefficient?) algorithm or frequently loading/unloading objects and/or data (files), those are the most common cases.
How are you observing/measuring this 'lag' ?
If you are reporting this based on running on a simulator, please go check on a device. Simulator numbers are meaningless. Btw, the number does not CAUSE lag, the number is the result (measure) of resource consumption by the app , ie low FPS is caused by laggy software, not the reverse.