我有一个基于文档的应用程序,其中每个文档都有一个带有 NSScrollView 的窗口,该窗口仅使用 Cocoa 进行一些(相当连续的)绘图。
为了调用绘图,我使用了 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
循环)仅在一个屏幕上工作得很好。(第二个或第一个)。