Tricks with dialog boxes in fullscreen mode causing permanent framerate drops.

Apprentice
Posts: 15
Joined: 2007.02
Post: #1
I'm doing a bit of a twist on the usual fullscreen mode by allowing dialogs to pop up while in fullscreen. To do this, I have three OpenGL contexts set up, the standard windowed one, the standard fullscreen one, and then a third windowed one that is used by a shield window. When in fullscreen, if a dialog box pops up, the dialog box is set to the shield window level, and the view cuts out the fullscreen context so the shield window is visible but with the dialog in front of it. When the last dialog box is closed, the fullscreen context is set again.

This works perfectly on my development box, a dual G5, but on my wife's G4 iMac, everything works fine until I open a dialog box, and after that, the flushBuffer call for the fullscreen context jumps to a full tenth of a second. Even if I close all dialogs and jump in and out of fullscreen, it never returns to normal.

Here's the code to set up the two fullscreen contexts and the shield window:

Code:
NSOpenGLPixelFormatAttribute    attributes[] = {
    NSOpenGLPFAWindow,
    NSOpenGLPFADoubleBuffer,
    NSOpenGLPFANoRecovery,
    NSOpenGLPFASingleRenderer,
    NSOpenGLPFAScreenMask,
    CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
    0
};
NSOpenGLPixelFormat    *windowedPixelFormat;
NSOpenGLView    *fullscreenWindowView;

windowedPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
fullscreenWindowContext = [[NSOpenGLContext alloc] initWithFormat:windowedPixelFormat
                   shareContext:[self openGLContext]];
[fullscreenWindowContext copyAttributesFromContext:[self openGLContext]  
                     withMask:GL_ALL_ATTRIB_BITS];
fullscreenWindow = [[NSWindow alloc] initWithContentRect:[[[self window] screen] frame]
                styleMask:NSBorderlessWindowMask
                backing:NSBackingStoreBuffered
                defer:NO];
[fullscreenWindow setLevel:CGShieldingWindowLevel()];
fullscreenWindowView = [[NSOpenGLView alloc] initWithFrame:[fullscreenWindow frame]];
[fullscreenWindowView setPixelFormat:windowedPixelFormat];
[fullscreenWindowView setOpenGLContext:fullscreenWindowContext];
[fullscreenWindow setContentView:fullscreenWindowView];
[fullscreenWindow setIgnoresMouseEvents:YES];
attributes[0] = NSOpenGLPFAFullScreen;
fullscreenContext = [[NSOpenGLContext alloc] initWithFormat:[[[NSOpenGLPixelFormat alloc]
        initWithAttributes:attributes] autorelease]
                        shareContext:[self openGLContext]];
[fullscreenContext copyAttributesFromContext:[self openGLContext]  
                withMask:GL_ALL_ATTRIB_BITS];
[fullscreenWindowView release];

The method to toggle fullscreen mode:

Code:
- (void) toggleFullscreen
{
    CGDirectDisplayID    mainDisplay;

    fullscreen = !fullscreen;
    mainDisplay = CGMainDisplayID();
    if(fullscreen) {
        CGDisplayCapture(mainDisplay);
        [fullscreenWindow setFrame:[[[self window] screen] frame] display:YES];
        [fullscreenWindow makeKeyAndOrderFront:self];
        if(openDialogs) {
            [fullscreenWindowContext makeCurrentContext];
            currentContext = fullscreenWindowContext;
            [NSCursor unhide];
        } else {
            [fullscreenContext setFullScreen];
            [fullscreenContext makeCurrentContext];
            currentContext = fullscreenContext;
            [NSCursor hide];
        }
        [self reshape];
    } else {
        [fullscreenWindow orderOut:self];
        [fullscreenContext clearDrawable];
        CGDisplayRelease(mainDisplay);
        [[self window] makeKeyAndOrderFront:self];
        [[self openGLContext] makeCurrentContext];
        currentContext = [self openGLContext];
        [NSCursor unhide];
        [self reshape];
    }
}

And the methods to handle when dialogs open or close.

Code:
- (void) openDialog
{
    openDialogs++;
    if((openDialogs == 1) && fullscreen) {
        [fullscreenWindowContext makeCurrentContext];
        currentContext = fullscreenWindowContext;
        [fullscreenContext clearDrawable];
        [NSCursor unhide];
        [self reshape];
    }
}

- (void) closeDialog
{
    openDialogs--;
    if(openDialogs < 0) openDialogs = 0;
    if((openDialogs == 0) && fullscreen) {
        [fullscreenContext setFullScreen];
        [fullscreenContext makeCurrentContext];
        currentContext = fullscreenContext;
        [NSCursor hide];
        [self reshape];
    }
}

I have no idea what could be causing the fullscreen context to go so choppy -- nothing ever happens to it except the setFullscreen, makeCurrentContext, and clearDrawable calls. Is there some kind of state I'm neglecting to set, or something bleeding over from one of the other contexts? And why would it only affect the iMac?

Thanks in advance.
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #2
Hmm... That sounds like an interesting approach to getting dialogs over full screen. If I understand it right, the dialogs aren't actually over a real full screen but rather a window covering the screen, posing as a full screen context. In that case, you're not actually using a dialog over a full screen context but rather a windowed context, and one of the effects of that which I've seen in the past is that a window over an OpenGL context can slow frame-rate down tremendously -- presumably because of window drawing scheduling (total guess). That doesn't seem to happen on my Intel Mac, but it did last time I checked on my dual G4, but I haven't looked since recent system updates.
Quote this message in a reply
Apprentice
Posts: 15
Joined: 2007.02
Post: #3
AnotherJake Wrote:Hmm... That sounds like an interesting approach to getting dialogs over full screen. If I understand it right, the dialogs aren't actually over a real full screen but rather a window covering the screen, posing as a full screen context. In that case, you're not actually using a dialog over a full screen context but rather a windowed context, and one of the effects of that which I've seen in the past is that a window over an OpenGL context can slow frame-rate down tremendously -- presumably because of window drawing scheduling (total guess). That doesn't seem to happen on my Intel Mac, but it did last time I checked on my dual G4, but I haven't looked since recent system updates.

That's exactly right, the shield window context is there to give the illusion of actual fulllscreen while the dialogs are up. And I'm not concerned at all about any slowdown that might occur on older machines while a dialog is up, since the user should be interacting with the dialog instead of the game, but the problem is that after the dialog is closed, and the fullscreen context is made current again, the framerate stays terrible, no matter what. This is baffling since the fullscreen context isn't the one to have the window in front of it.

All I can think is that there's some behavior of the OpenGL contexts or the window manager that I'm not aware of because this is my first OpenGL project. :P Is there some obvious initialization/destruction call I'm overlooking?
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Mac OS X. Switching between fullscreen and windowed mode. e40pud 2 4,157 Jan 25, 2010 12:01 PM
Last Post: OneSadCookie
  iPhone 3GS OpenGL strange framerate bug airfire 2 3,449 Dec 2, 2009 09:22 AM
Last Post: airfire
  Dialog boxes with SDL + OpenGL IBethune 11 7,513 Feb 4, 2009 06:33 PM
Last Post: FlamingHairball
  GLUT consistant framerate? JeroMiya 2 4,501 Apr 30, 2007 02:25 AM
Last Post: OneSadCookie
  SDL Framerate Control joellevin 10 8,372 Jan 4, 2007 01:26 PM
Last Post: arekkusu