Why do I get a delay when executing animations first time? - objective-c

I am using imageWithContentsOfFile: to load my .png images into an array. When the IBAction triggers the animation, there is a noticeable delay before the animation starts. Then, each time after that, it executes smoothly. I originally tried to load them with the imageNamed: method but experienced the same delay plus big performance problems on the device.

Load the images in ViewWillLoad instead.
If that doesn't work, use the developer tool Instruments (built into xcode) to find what is causing the performance hit. Choose Open GL ES driver, under the iOS -> graphics menu. Then tick Hide system libraries. Then it will show you which methods are taking a long time, click into those methods to see exactly which lines, then just try and figure out alternative ways to do it.

Related

OpenGL on Cocoa: CGLChoosePixelFormat() is terribly slow?

I've built a small Cocoa app that uses OpenGL to draw some light content. I've used CAOpenGLLayer. While the app itself is very small and works blazingly fast, the launch time of the app is not satisfactory at all. At random times the app would stall for about a second or two upon launch, before showing the content.
I've narrowed down the problem and found that the bottleneck is the CGLChoosePixelFormat() function that is called during OpenGL initialization. It literally takes ~1 second to execute.
For a clean experiment, I created a blank Cocoa app and added an NSOpenGLView to the window. Immediately, the app launch time has grown by 1-2 seconds, for the same reason.
Is there a way to fight this problem? There seems no way to avoid using CGLChoosePixelFormat(), it's essential for getting OpenGL to work on a Mac.
Also, it's said that Core Animation is built upon OpenGL under the hood, but my Core Animation apps do not exhibit this slow startup problem at all. Also, I tried a symbolic breakpoint on CGLChoosePixelFormat in a Core Animation app, but it doesn't trigger. So Core Animation is either not using OpenGL or there is a way to initialize it in a different way. Does anybody has a solution?
P.S. I know Metal is now the way to go for 3D graphics on Macs, but I need to do this particular project on OpenGL for backward compatibility reasons.
I've met the exactly same problem with you. So far I've found that the problem only occurs on MacBook Pro 16" 2019.
Since this problem is hard to reproduce, I can do nothing more than guess. For now I have changed the NSOpenGLPixelFormat initWithAttributes: method to [NSOpenGLView defaultPixelFormat], and hope it will work.

Freezing OS X Screen in Cocoa

I have two methods that modify the display of the screen. Is there a way to freeze the screen until the second method is called?
// I want to freeze the screen here
updateDisplay1(); // Change in display doesn't take effect until screen is unfrozen
updateDisplay2();
// Unfreeze screen here
In Excel VBA this would be something like screenUpdating = FALSE. Is there a similar function in Cocoa?
One possible way is to take screenshot:
// Take screenshot of the screen
// Display the screenshot image in front of the screen
updateDisplay1(); // Change is not visible
updateDisplay2();
// Remove screenshot image
But I'm afraid this is slow and takes up a lot of memory. Is there a more efficient method?
What screen are you talking about?
Standard Cocoa behaviour is:
you update the properties of the various views you are interested in;
each of those will make a call to its own setNeedsDisplayInRect. As a result of those calls, a redraw will be scheduled on the run loop;
once you've finished doing all of your updates, the run loop will be able to move onto its next item;
eventually it'll reach the redraw it scheduled and will make appropriate drawRect calls to appropriate views.
So all view changes that you make in response to an action are automatically atomic. You have to go significantly out of your own way to create a partial update.
taking screenshots with CGWindowListCreateImage takes a few milliseconds and uses roughly any memory. it's usually done directly in the graphic card.
give it a try and measure before doing any performance assumptions:-)

SDL Window shows final frame from the last time the program was run in the background of a new window when I start up a new instance

I'm making a simple game and just messing around with SDL. I have two images currently, and I am practicing making them the background. I make one the background by calling RenderCopy, the DestroyTexture to clear it from memory, and then I present it. I changed the file path from one image to the other to change the background. I ran the program, and now the new image is layered on top of the other. I can fix this problem if I manually do a clean of my computer's memory, and it renders properly. For some reason, SDL is not clearing the image called previously. There is no mention of the old image anywhere else in the code, and all the Destroy functions are called. What is going on?
Edit: I did a little bit of snooping and its not that it even loads the old image; whatever the final render displayed on any program running SDL was before it was run, it will be the background. It is literally like a TV burning an image into the screen; its always there.
The problem was fixed by simply clearing the frame between frames. Didn't have any performance impact.

on view load, start a timer and reveal images at times in iPad app

So in my XIB I have a few graphics that need to reveal in order.. say every one second, the next thing will reveal..
I assume I am going to need something involving viewdidload, starting an NSTimer, then animate the revealing of my graphics with the timer. Can anyone please drop me a few ideas, hints or lines of code to get started?
Thanks!
You could use Quartz Composer to build your image sequence, and then render that to a QCView or OpenGL context.

Jerky/juttery (core-)animation in a screensaver?

I've built a screensaver for Leopard which utilises core-animation. It doesn't do anything overly complicated; uses a tree of CALayers and CATextLayers to produce a "table" of data in the following structure:
- root
› maincontainer
› subcontainer
› row [multiple]
› cell [multiple]
› text layer
At most there are 50 CALayers rendered on the screen at any one time.
Once I've built the "table", I'm adding animating the "subcontainer" into view using CABasicAnimation. Again, I'm not doing anything fancy - just a simple fade-in.
The problem is that while the animation does happen its painful to watch. It's jerky on my development machine which is a 3.06Ghz iMac with 4GB of RAM, and seems to chop the animation into 10 steps rather than showing a gradual change.
It gets worse on the ppc mac-mini the screensaver is targeted for; it refuses to even play the animation, generally "tweening" from the beginning of the animation (0% opacity) to half-way (50%) then completing.
I'm relatively new to ObjectiveC and my experience is based on using garbage-collected environments, but I can't believe I'm leaking enough memory at the point the screensaver starts to cause such problems.
Also, I'm quite sure its not a problem with the hardware. I've tested the built-in screensavers which use core-animation, and downloaded a few free CA-based for comparison, and they run without issue on both machines.
Information is pretty thin on Google with regards to using CA in screensavers, or using CA in general for that matter, and advice/tutorials on profiling/troubling screensavers seems to be non-existant. So any help the community can provide would be well welcomed!
--- UPDATE ---
Seems as though implicit animations help smooth things out a little. Still kinda jerky, but not as bad as trying to animate everything with explicit animations as in my solution.
There isn't much special about a screen saver. I assume you've started with the Core Animation Programming Guide? Running it through Instruments will give you a lot of information about where you're taking too much time.
The code you're using to do the fade-in would be useful. For what you're describing, you don't even need CABasicAnimation; you can just set the animatable properties of the layers, and they by default animate. Make sure you've read up on Implicit Animations. The rest of that page is probably of use as well.
Most of your job in CoreAnimation is getting out of the way. I generally knows what it's doing, and most problems come from second guessing it to trying to tell it too much.