/* Method to prepare change one visual state to another: */ virtual bool prepareChange(UIVisualStateType previousVisualStateType) { m_pMachineLogic = UIMachineLogic::create(this, m_pSession, visualStateType()); bool fResult = m_pMachineLogic->checkAvailability(); #ifdef Q_WS_MAC /* If the new is or the old type was fullscreen we add the blending * transition between the mode switches. * TODO: make this more general. */ if ( fResult && ( visualStateType() == UIVisualStateType_Fullscreen || previousVisualStateType == UIVisualStateType_Fullscreen)) { /* Fade to black */ CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &m_fadeToken); CGDisplayFade(m_fadeToken, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true); } #else /* Q_WS_MAC */ Q_UNUSED(previousVisualStateType); #endif /* !Q_WS_MAC */ return fResult; }
//-------------------------------------------------------------------------------------------------// void OSXWindow::createCGLFullscreen(unsigned int width, unsigned int height, unsigned int depth, unsigned int fsaa, CGLContextObj sharedContext) { // Find the best match to what was requested boolean_t exactMatch = 0; int reqWidth, reqHeight, reqDepth; #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // Get a copy of the current display mode CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); // Loop through all display modes to determine the closest match. // CGDisplayBestModeForParameters is deprecated on 10.6 so we will emulate it's behavior // Try to find a mode with the requested depth and equal or greater dimensions first. // If no match is found, try to find a mode with greater depth and same or greater dimensions. // If still no match is found, just use the current mode. CFArrayRef allModes = CGDisplayCopyAllDisplayModes(kCGDirectMainDisplay, NULL); for(int i = 0; i < CFArrayGetCount(allModes); i++) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); String modeString = StringConverter::toString(CGDisplayModeGetWidth(mode)) + String(" x ") + StringConverter::toString(CGDisplayModeGetHeight(mode)) + String(" @ ") + StringConverter::toString(bitDepthFromDisplayMode(mode)) + "bpp."; LogManager::getSingleton().logMessage(modeString); if(bitDepthFromDisplayMode(mode) != depth) continue; if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height)) { displayMode = mode; exactMatch = 1; break; } } // No depth match was found if(!exactMatch) { for(int i = 0; i < CFArrayGetCount(allModes); i++) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); if(bitDepthFromDisplayMode(mode) >= depth) continue; if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height)) { displayMode = mode; exactMatch = 1; break; } } } reqWidth = CGDisplayModeGetWidth(displayMode); reqHeight = CGDisplayModeGetHeight(displayMode); reqDepth = bitDepthFromDisplayMode(displayMode); #else CFDictionaryRef displayMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, depth, width, height, &exactMatch); const void *value = NULL; value = CFDictionaryGetValue(displayMode, kCGDisplayWidth); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqWidth); value = CFDictionaryGetValue(displayMode, kCGDisplayHeight); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqHeight); value = CFDictionaryGetValue(displayMode, kCGDisplayBitsPerPixel); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqDepth); #endif if(!exactMatch) { // TODO: Report the size difference // That mode is not available, using the closest match String request = StringConverter::toString(width) + String(" x ") + StringConverter::toString(height) + String(" @ ") + StringConverter::toString(depth) + "bpp. "; String received = StringConverter::toString(reqWidth) + String(" x ") + StringConverter::toString(reqHeight) + String(" @ ") + StringConverter::toString(reqDepth) + "bpp. "; LogManager::getSingleton().logMessage(String("RenderSystem Warning: You requested a fullscreen mode of ") + request + String(" This mode is not available and you will receive the closest match. The best display mode for the parameters requested is: ") + received); } // Do the fancy display fading CGDisplayFadeReservationToken reservationToken; CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &reservationToken); CGDisplayFade(reservationToken, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true); // Grab the main display and save it for later. // You could render to any display, but picking what display // to render to could be interesting. CGDisplayCapture(kCGDirectMainDisplay); // Switch to the correct resolution #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 CGDisplaySetDisplayMode(kCGDirectMainDisplay, displayMode, NULL); #else CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); #endif // Get a pixel format that best matches what we are looking for CGLPixelFormatAttribute attribs[] = { kCGLPFADoubleBuffer, kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8, kCGLPFADepthSize, (CGLPixelFormatAttribute)reqDepth, kCGLPFAStencilSize, (CGLPixelFormatAttribute)8, kCGLPFASampleBuffers, (CGLPixelFormatAttribute)0, kCGLPFASamples, (CGLPixelFormatAttribute)0, kCGLPFAFullScreen, kCGLPFASingleRenderer, kCGLPFAAccelerated, kCGLPFADisplayMask, (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), (CGLPixelFormatAttribute)0 }; // Set up FSAA if it was requested if(fsaa > 1) { // turn on kCGLPFASampleBuffers attribs[8] = (CGLPixelFormatAttribute)1; // set the samples for kCGLPFASamples attribs[10] = (CGLPixelFormatAttribute)fsaa; } CGLError err; CGLPixelFormatObj pixelFormatObj; #if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4) GLint numPixelFormats = 0; err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); #else long numPixelFormats = 0; err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); #endif if(err != 0) { CGReleaseAllDisplays(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen"); } // Create the CGLcontext from our pixel format, share it with the sharedContext passed in err = CGLCreateContext(pixelFormatObj, sharedContext, &mCGLContext); if(err != 0) { CGReleaseAllDisplays(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen"); } // Once we have the context we can destroy the pixel format // In order to share contexts you must keep a pointer to the context object around // Our context class will now manage the life of the pixelFormatObj //CGLDestroyPixelFormat(pixelFormatObj); // Set the context to full screen #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 CGLSetFullScreenOnDisplay(mCGLContext, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay)); #else CGLSetFullScreen(mCGLContext); #endif // Set the context as current CGLSetCurrentContext(mCGLContext); // This synchronizes CGL with the vertical retrace // Apple docs suggest that OpenGL blocks rendering calls when waiting for // a vertical retrace anyhow. #if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4) GLint swapInterval = 1; CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval); #else long swapInterval = 1; CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval); #endif // Give a copy of our context to the rendersystem mContext = new OSXCGLContext(mCGLContext, pixelFormatObj); // Let everyone know we are fullscreen now mIsFullScreen = true; // Set some other variables. Just in case we got a different value from CGDisplayBestModeForParameters than we requested mWidth = reqWidth; mHeight = reqHeight; mColourDepth = reqDepth; CGDisplayFade(reservationToken, 2.0, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false); CGReleaseDisplayFadeReservation(reservationToken); }
//void doFadeOperation(int operation, float time, bool sync) // from SMFL void doFadeOperation(int operation, float time, bool sync) { static CGDisplayFadeReservationToken prevToken = kCGDisplayFadeReservationInvalidToken; CGDisplayFadeReservationToken token = prevToken; CGError result = 0, capture = 0; if (operation == FillScreen) { // Get access for the fade operation result = CGAcquireDisplayFadeReservation((int)(3 + time), &token); if (!result) { // Capture display but do not fill the screen with black // so that we can see the fade operation capture = CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoFill); if (!capture) { // Do the increasing fade operation CGDisplayFade(token, time, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0f, 0.0f, 0.0f, sync); // Now, release the non black-filling capture CGDisplayRelease(kCGDirectMainDisplay); // And capture with filling // so that we don't see the switching in the meantime CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoOptions); } prevToken = token; } } else if (operation == CleanScreen) { // Get access for the fade operation if (token == kCGDisplayFadeReservationInvalidToken) result = CGAcquireDisplayFadeReservation((int)(3 + time), &token); if (!result) { if (!capture) { // Release the black-filling capture CGDisplayRelease(kCGDirectMainDisplay); // Capture the display but do not fill with black (still for the fade operation) CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoFill); // Do the decreasing fading CGDisplayFade(token, time, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0f, 0.0f, 0.0f, sync); // Release the fade operation token CGReleaseDisplayFadeReservation(token); // Invalidate the given token prevToken = kCGDisplayFadeReservationInvalidToken; } // Release the captured display CGDisplayRelease(kCGDirectMainDisplay); } } }