@ Andrea3000 - Номинально они должны иметь одинаковые характеристики производительности. Я смог обновить CAOpenGLLayer со скоростью 60 FPS без проблем, но проблема, с которой я столкнулся, заключалась в том, что стандартный механизм обновления для этого слоя работает в основном потоке. Это может привести к приостановке подачи моего видео при выполнении таких действий, как взаимодействие с меню. CAOpenGLLayer вполне может быть быстро обновлен.
я есть приложение, которое отображает содержимое OpenGL в Mac OS X. Первоначально оно отображалось в NSOpenGLView, затем я изменил его для отображения в подкласс CAOpenGLLayer.
Когда я это сделал, я увидел огромную потерю производительности: вдвое уменьшил частоту кадров, снизил чувствительность мыши, заикание (время от времени останавливается, до секунды, в течение которого активность профилировщика сообщает об ожидании мьютекса для загрузки данных на ОЗУ GPU) и удвоение Использование процессора.
Я исследую эту проблему и у меня есть несколько вопросов:
Был ли подобный удар по производительности замечен кем-то другим?Я делаю что-то не так с моей настройкой CAOpenGLLayer?Как реализованы CAOpenGLLayer и платформа Core Animation, т. Е. По какому пути мой контент OpenGL проходит от моих вызовов glDrawElements до моего экрана, и как я должен действовать на своей стороне, чтобы оптимизировать производительность с такой настройкой?Вот мой код для установки CAOpenGLLayer:
// my application's entry point (can't be easily changed):
void AppUpdateLogic(); //update application logic. Will load textures
void AppRender(); //executes drawing
void AppEventSink(NSEvent* ev); //handle mouse and keyboard events.
//Will do pick renderings
@interface MyCAOpenGLLayer: CAOpenGLLayer
{
CGLPixelFormatObj pixelFormat;
CGLContextObj glContext;
}
@end
@implementation MyCAOpenGLLayer
- (id)init {
self = [super init];
CGLPixelFormatAttribute attributes[] =
{
kCGLPFAAccelerated,
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)16,
(CGLPixelFormatAttribute)0
};
GLint numPixelFormats = 0;
CGLChoosePixelFormat(attributes, &pixelFormat, &numPixelFormats);
glContext = [super copyCGLContextForPixelFormat:mPixelFormat];
return self;
}
- (void)drawInCGLContext:(CGLContextObj)inGlContext
pixelFormat:(CGLPixelFormatObj)inPixelFormat
forLayerTime:(CFTimeInterval)timeInterval
displayTime:(const CVTimeStamp *)timeStamp
{
AppRender();
[super drawInCGLContext:inGlContext
pixelFormat:inPixelFormat
forLayerTime:timeInterval
displayTime:timeStamp ]
}
- (void)releaseCGLPixelFormat:(CGLPixelFormatObj)pixelFormat {
[self release];
}
- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
[self retain];
return pixelFormat;
}
- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
[self retain];
return glContext;
}
- (void)releaseCGLContext:(CGLContextObj)glContext {
[self release];
}
@end
@interface MyMainViewController: NSViewController {
CGLContextObj glContext;
CALayer* myOpenGLLayer;
}
-(void)timerTriggered:(NSTimer*)timer;
@end
@implementation MyMainViewController
-(void)viewDidLoad:(NSView*)view {
myOpenGLLayer = [[MyCAOpenGLLayer alloc] init];
[view setLayer:myOpenGLLayer];
[view setWantsLayer:YES];
glContext = [myOpenGLLayer copyCGLContextForPixelFormat:nil];
[NSTimer scheduledTimerWithTimeInterval:1/30.0
target:self
selector:@selector(timerTriggered:)
userInfo:nil
repeats:YES ];
}
- (void)timerTriggered:(NSTimer*)timer {
CGLContextObj oldContext = CGLContextGetCurrent();
CGLContextSetCurrent(glContext);
CGLContextLock(glContext);
AppUpdateLogic();
[myOpenGLLayer setNeedsDisplay:YES];
CGLContextUnlock(glContext);
CGLContextSetCurrent(oldContext);
}
- (void)mouseDown:(NSEvent*)event {
CGLContextObj oldContext = CGLContextGetCurrent();
CGLContextSetCurrent(glContext);
CGLContextLock(glContext);
AppEventSink(event);
CGLContextUnlock(glContext);
CGLContextSetCurrent(oldContext);
}
@end
Может быть полезно знать, что моя видеокарта не очень мощная (Intel GMA с 64 МБ общей памяти).