Рисование какао на разных экранах теряет производительность

У меня есть приложение на основе документов, где каждый документ имеет одно окно с 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 ) очень хорошо работает только на одном экране. (Либо второй, либо первый).

34
задан spudwaffle 6 July 2011 в 23:15
поделиться