34

我有一个基于文档的应用程序,其中每个文档都有一个带有 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循环)仅在一个屏幕上工作得很好。(第二个或第一个)。

4

2 回答 2

1

每次文档进入新屏幕时,您是否尝试过调用 prepareDisplayLink?或许能胜任。您可以从 windowDidMove 函数中检测到这一点。

于 2011-10-20T00:08:01.153 回答
0

你重新绘制框架的速度有多快?问题似乎是卡只能不断地重新绘制一定数量的数据。您是否正在重新绘制彼此独立的每个动画?尝试同时重新绘制所有动画。

问题似乎来自与视频卡的设备驱动程序和您的逻辑的直接交互。祝你好运。

于 2011-09-18T20:48:01.880 回答