There’s no API to get any kind of performance information from an SCNView
, even as basic as a rolling frame rate. But it’s not hard to add – you can be notified when each frame is drawn by overriding the -draw
method. For example:
NSDate *nextFrameCounterReset;
NSUInteger frameCount;
- (void)draw {
NSDate *now = [NSDate date];
if (nextFrameCounterReset) {
if (NSOrderedDescending == [now compare:nextFrameCounterReset]) {
[frameRateView setLabel:frameCount];
frameCount = 0;
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
} else {
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
++frameCount;
[super draw];
}
Update:
However, if you’re layer-backed the “draw” method isn’t used. Instead you can override:
- (void)drawInBackingLayerWithCGLContext:(CGLContextObj)arg1;
Like so:
NSDate *nextFrameCounterReset;
NSUInteger frameCount;
- (void)drawInBackingLayerWithCGLContext:(CGLContextObj)arg1 {
NSDate *now = [NSDate date];
if (nextFrameCounterReset) {
if (NSOrderedDescending == [now compare:nextFrameCounterReset]) {
[frameRateView setLabel:frameCount];
frameCount = 0;
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
} else {
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
++frameCount;
[super draw];
}
But don’t. Because in actual fact you can get this information via supported API – the SCNSceneRendererDelegate
protocol. You can register your view as its own delegate, or put your frame rate calculation in another object. Either way, your code should look something like:
NSDate *nextFrameCounterReset;
NSUInteger frameCount;
- (void)renderer:(id<SCNSceneRenderer>)aRenderer
didRenderScene:(SCNScene*)scene
atTime:(NSTimeInterval)time {
NSDate *now = [NSDate date];
if (nextFrameCounterReset) {
if (NSOrderedDescending == [now compare:nextFrameCounterReset]) {
[frameRateView setLabel:frameCount];
frameCount = 0;
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
} else {
nextFrameCounterReset = [now dateByAddingTimeInterval:1.0];
}
++frameCount;
[super draw];
}