PDA

View Full Version : core animation, efficiency of making lots of layers




Chirone
May 26, 2009, 10:09 PM
i recently discovered there is a limit to the dimensions of a layer and that it's also somewhat unpredictable.

so i thought that i would split all the objects off into different layers instead.
so then i would have one layer per object

i figure there's no point in drawing the things that aren't on screen at the time, so i thought up of some solutions...

i was wondering if anyone could comment on the efficiency of the following approaches or suggest an efficient approach. the layers that have to change will be really light graphics... nothing too intense... i suppose think fireworks... if i'm drawing 10,000 unique fireworks on screen, not all of them need to be on screen at the same time but they all have to be drawn at some point

the goal is to have the layers appearing on screen at some point with as little lag as possible with the possibility of hardware intense things happening on other processes..

approach one:
hide the layers that aren't on screen by using the hide method.
i found this method in the documentation, i says it can hide the layer, so i figure maybe it doesn't draw the layer at all until it's un-hidden. so it will save on graphics memory?
with this approach i would add all 10,000 layers to a root layer that is drawn on screen. so this might be quite intensive on the RAM because it has to keep an instance of 10,000 layers plus all sorts of other instance variables that are specific to each layer

approach two:
to avoid using too much of the graphics memory and RAM i thought maybe i could just keep a list of some sort that only had an instance of the layers that are on screen.
when something needs to be drawn, the layer is created and the layer is then added to that list, and some other layer might be removed from the list so it's no longer drawn.
could this be too processor intensive? creating layers and adding them to an array list on the fly?


any suggestions would be appreciated.



Spike099
May 27, 2009, 01:21 PM
Take my opinion with a grain of salt, just my two cents here.

1) I remember reading somewhere where that CA is efficient with 1000s of layers... I doubt 10000 will be efficient.

2) If a layer is off the screen, you could remove it from it's parent layer. This way you don't have to have several arrays containing what's on and off the screen.
baseLayer.sublayers will contain everything on screen. When your object makes it's way back on screen, add it as a sublayer.

So... Are you sure CA is the right technology to use? Could this be something solved using custom drawing in a NSView? What are the benefits of using CA?

GorillaPaws
May 27, 2009, 01:33 PM
I'm not sure if you've looked at this but Scott Stevenson wrote a couple of blog posts (http://theocacao.com/document.page/556) awhile back regarding a project called NanoLife that seems to do some similar things to what you're interested in. I don't think it's dealing with the scale you're talking about here though.

HiRez
May 27, 2009, 01:54 PM
You might need to move to OpenGL for something like this. It should be more lightweight than CALayers. It's more work to set up, but the tradeoff is it's more flexible and probably more efficient. I mean you can use CA for stuff like this, but really, it wasn't designed for it, that's what OpenGL is for.

Chirone
May 27, 2009, 04:40 PM
i was using openGL before but CA seemed to solve quite a few problems

Spike099, i see the benefits of CA as being:
-i get smooth transitions (with openGL i got 'swimming' in stuff that would move at a constant speed along the screen)
-i can use core graphics because drawing text with the effects i want is easier to do with core graphics than it is to do with openGL (ok, i think i can use core graphics on normal NSView, but whenever i tried to get a CGContextRef to draw on it would fail and bleed errors)
-i think there were more but i can't remember

with your point 2) how would i tell if the layer is meant to be onscreen? when i hit a button it will play through and i could use the position of other layers to tell if the next one should be added to the base layer's sublayers


GorillaPaws, thanks for the link, i'll take a good look at this

HiRez, thanks for the input. i used openGL before but i couldn't get text to render with anti aliasing (or do you know how to make vector graphics with OpenGL and make text with it? the text needs to be resizeable and not keep the aspect ratio... so it can be way wider than it should be or way taller than it should be. whenever i ask people about drawing text all their solutions never allows for this to happen, and then i found CA and CG which did allow this to happen. )
even though OpenGL was told to antialias the graphics it still didn't, i've given up on that now, because i can't find the solution (which doesn't make sense because it's such a common thing to do):confused:

Spike099
May 30, 2009, 04:44 PM
with your point 2) how would i tell if the layer is meant to be onscreen? when i hit a button it will play through and i could use the position of other layers to tell if the next one should be added to the base layer's sublayers

This will depend on your implementation. Whenever you iterate through all your objects to determine their animation, you can add something like the code snippet below.

NSRect rect1 = NSRectFromCGRect(analyzedLayer.frame);
NSRect rect2 = [self bounds];
if ( !NSIntersectsRect(rect1, rect2) ) {
[analyzedLayer removeFromSuperlayer];
} else {
[[self layer] addSublayer:analyzedLayer];
}

Your object will have a start and end frame, so you'll want to use the delegate method animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag so you can determine after the animation weather or not it needs to be removed.