Example #1
0
void StimulusDisplay::stateSystemCallback(const Datum &data, MWorksTime time) {
    unique_lock lock(display_lock);
    
    int newState = data.getInteger();
    
    if ((IDLE == newState) && displayLinksRunning) {
        
        // If another thread is waiting for a display refresh, allow it to complete before stopping
        // the display link
        while (waitingForRefresh) {
            refreshCond.wait(lock);
        }
        
        displayLinksRunning = false;
        currentOutputTimeUS = -1;
        
        // We need to release the lock before calling CVDisplayLinkStop, because
        // StimulusDisplay::displayLinkCallback could be blocked waiting for the lock, and
        // CVDisplayLinkStop won't return until displayLinkCallback exits, leading to deadlock.
        lock.unlock();
        
        // NOTE: As of OS X 10.11, stopping the display links from a non-main thread causes issues
        dispatch_sync(dispatch_get_main_queue(), ^{
            for (auto dl : displayLinks) {
                if (kCVReturnSuccess != CVDisplayLinkStop(dl)) {
                    merror(M_DISPLAY_MESSAGE_DOMAIN,
                           "Unable to stop updates on display %d",
                           CVDisplayLinkGetCurrentCGDisplay(dl));
                }
            }
        });
        
        mprintf(M_DISPLAY_MESSAGE_DOMAIN, "Display updates stopped");
        
    } else if ((RUNNING == newState) && !displayLinksRunning) {
Example #2
0
void StimulusDisplay::stateSystemCallback(const Datum &data, MWorksTime time) {
    unique_lock lock(display_lock);

    int newState = data.getInteger();

    if (IDLE == newState) {
        
        if (CVDisplayLinkIsRunning(displayLink)) {
            // If another thread is waiting for a display refresh, allow it to complete before stopping
            // the display link
            while (waitingForRefresh) {
                refreshCond.wait(lock);
            }

            // We need to release the lock before calling CVDisplayLinkStop, because
            // StimulusDisplay::displayLinkCallback could be blocked waiting for the lock, and
            // CVDisplayLinkStop won't return until displayLinkCallback exits, leading to deadlock.
            lock.unlock();
            
            if (kCVReturnSuccess != CVDisplayLinkStop(displayLink)) {
                merror(M_DISPLAY_MESSAGE_DOMAIN, "Unable to stop display updates");
            } else {
                currentOutputTimeUS = -1;
                mprintf(M_DISPLAY_MESSAGE_DOMAIN, "Display updates stopped");
            }
        }
        
    } else if (RUNNING == newState) {

        if (!CVDisplayLinkIsRunning(displayLink)) {

            lastFrameTime = 0;

            if (kCVReturnSuccess != CVDisplayLinkStart(displayLink)) {
                merror(M_DISPLAY_MESSAGE_DOMAIN, "Unable to start display updates");
            } else {
                // Wait for a refresh to complete, so we know that getCurrentOutputTimeUS() will return a valid time
                ensureRefresh(lock);
                
                mprintf(M_DISPLAY_MESSAGE_DOMAIN,
                        "Display updates started (main = %d, current = %d)",
                        CGMainDisplayID(),
                        CVDisplayLinkGetCurrentCGDisplay(displayLink));
            }

        }
        
    }
}