在不同的屏幕上绘制可可会失去性能

spu*_*fle 34 cocoa screen nsview core-video cadisplaylink

我有一个基于文档的应用程序,其中每个文档都有一个带有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);
    }
}
Run Code Online (Sandbox Code Playgroud)

渲染代码:

- (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]];
}
Run Code Online (Sandbox Code Playgroud)

这很好用,动画就是黄油......在一个屏幕上.

一旦我将一个文档从主屏幕移动到第二个监视器上,动画就变得像带有方形轮子的汽车一样平滑.当任何一个(或多个)文档在第二个屏幕上时,动画在所有文档中变差.主屏幕上没有文档,辅助屏幕上没有任何文档,动画也会降级.

我已经尝试过多种类型的显示器和多台Mac,总是以这些结果结束.为了确保这不是与CVDisplayLink相关的问题,我还尝试使用NSTimer(最好使用CVDisplayLink)进行渲染,结果相同.

我究竟做错了什么?任何帮助是极大的赞赏.

编辑:我也试过使用基于线程的绘图,再次使用相同的结果.

编辑:我已经取得了一些进展,因为我的基于线程的绘图(基本上是一个while循环)只在一个屏幕上运行良好.(第二个或第一个).

El *_*per 0

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

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