У меня есть приложение на основе документов, где у каждого документа есть одно окно с NSScrollView, которое делает некоторые (довольно непрерывные) рисунки, используя только какао.
Чтобы вызвать рисунок, я использую схему CVDisplayLink, выделеннуюв коде ниже:
- (void)windowControllerDidLoadNib:(NSWindowController *) aController {
//other stuff...
[self prepareDisplayLink]; //For some reason putting this in awakeFromNib crashes
}
//Prep the display link.
- (void)prepareDisplayLink {
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetCurrentCGDisplay(displayLink, ((CGDirectDisplayID)[[[[[self windowForSheet]screen]deviceDescription]objectForKey:@"NSScreenNumber"]intValue]));
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
}
//Callback to draw frame
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc]init];
CVReturn result = [(ScrollView*)displayLinkContext getFrameForTime:outputTime];
[pool drain];
return result;
}
//Drawing function:
- (CVReturn)getFrameForTime:(const CVTimeStamp*)outputTime
{
[scrollView lockFocusIfCanDraw];
[self addToCurrentPostion:(dist/time)*CVDisplayLinkGetActualOutputVideoRefreshPeriod(displayLink)]; //Redraws the scrollview];
[scrollView unlockFocus];
return kCVReturnSuccess;
}
//Set the display when the window moves:
- (void)windowDidMove:(NSNotification *)notification {
if ([notification object] == [self windowForSheet]) {
CVDisplayLinkSetCurrentCGDisplay(displayLink, ((CGDirectDisplayID)[[[[[self windowForSheet]screen]deviceDescription]objectForKey:@"NSScreenNumber"]intValue]));
}
}
//Start or stop the animation:
- (IBAction)toggleAnim:(id)sender {
if (CVDisplayLinkIsRunning(displayLink)) {
CVDisplayLinkStop(displayLink);
}
else {
CVDisplayLinkStart(displayLink);
}
}
Код рендеринга:
- (void)addToCurrentPostion:(float)amnt {
fCurrentPosition += amnt; //fCurrentPositon is a float ivar
if (scrollView) [[scrollView contentView]scrollToPoint:NSMakePoint(0,(int)fCurrentPosition)];
if (scrollView) [scrollView reflectScrolledClipView:[scrollView contentView]];
}
Это прекрасно работает, и анимация маслянистая ..... на одном экране.
Как только я перемещаю один документ с основного экрана на второй монитор, анимация становится примерно такой же плавной, как у машины с квадратными колесами.Анимация становится плохой во всех документах, когда один или несколько документов находятся на втором экране.На главном экране не может быть никаких документов, а на дополнительном экране никаких документов, и анимация также будет ухудшаться.
Я пробовал это на нескольких типах мониторов и на нескольких компьютерах Mac, всегда заканчиваясь этими результатами.Чтобы убедиться, что это не проблема, связанная с CVDisplayLink, я также попытался выполнить рендеринг с использованием NSTimer (для которого CVDisplayLink предпочтительнее) с теми же результатами.
Что я делаю неправильно?Любая помощь очень ценится.
РЕДАКТИРОВАТЬ: Я также пытался использовать на основе потоков, опять же с теми же результатами.
РЕДАКТИРОВАТЬ: Я добился определенного прогресса в том, что мое основанное на потоках рисование (в основном цикл while
) очень хорошо работает только на одном экране.(Либо второе, либо первое).