diff --git a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.h b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.h index eb99c0a6e6..8c10b3210a 100644 --- a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.h +++ b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.h @@ -8,6 +8,8 @@ typedef void *id; #endif +#define CONCURRENT_RENDERING 0 // This seems to crash the computer... + typedef const struct __CFDictionary *CFDictionaryRef; class LowLevelWindow_Cocoa : public LowLevelWindow @@ -16,6 +18,10 @@ class LowLevelWindow_Cocoa : public LowLevelWindow id mWindow; id mWindowContext; id mFullScreenContext; +#if CONCURRENT_RENDERING + id mConcurrentWindowContext; + id mConcurrentFullScreenContext; +#endif bool mSharingContexts; CFDictionaryRef mCurrentDisplayMode; @@ -28,6 +34,12 @@ public: void SwapBuffers(); void Update(); +#if CONCURRENT_RENDERING + bool SupportsThreadedRendering(); + void BeginConcurrentRendering(); + void EndConcurrentRendering(); +#endif + VideoModeParams GetActualVideoModeParams() const { return mCurrentParams; } private: void ShutDownFullScreen(); diff --git a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.mm b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.mm index 3528d3ec6c..d0fa7f3c09 100644 --- a/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.mm +++ b/stepmania/src/arch/LowLevelWindow/LowLevelWindow_Cocoa.mm @@ -72,8 +72,13 @@ public: @end -LowLevelWindow_Cocoa::LowLevelWindow_Cocoa() : mWindowContext(nil), mFullScreenContext(nil), mCurrentDisplayMode(NULL) +LowLevelWindow_Cocoa::LowLevelWindow_Cocoa() : mWindowContext(nil), mFullScreenContext(nil), + mSharingContexts(false), mCurrentDisplayMode(NULL) { +#if CONCURRENT_RENDERING + mConcurrentWindowContext = nil; + mConcurrentFullScreenContext = nil; +#endif POOL; NSRect rect = { {0, 0}, {0, 0} }; SMMainThread *mt = [[SMMainThread alloc] init]; @@ -180,7 +185,7 @@ CString LowLevelWindow_Cocoa::TryVideoMode( const VideoModeParams& p, bool& newD NSOpenGLPixelFormatAttribute(0) }; - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; if( pixelFormat == nil ) { @@ -188,7 +193,7 @@ CString LowLevelWindow_Cocoa::TryVideoMode( const VideoModeParams& p, bool& newD return "Failed to set the windowed pixel format."; } id nextContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - [pixelFormat release]; + if( nextContext == nil ) { [mt performOnMainThread]; @@ -199,6 +204,14 @@ CString LowLevelWindow_Cocoa::TryVideoMode( const VideoModeParams& p, bool& newD [mWindowContext clearDrawable]; [mWindowContext release]; mWindowContext = nextContext; + +#if CONCURRENT_RENDERING + [mConcurrentWindowContext release]; + mConcurrentWindowContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:mWindowContext]; + if( mConcurrentWindowContext ) + SetOGLParameters( mConcurrentWindowContext ); +#endif // We need to recreate the full screen context as well. [mFullScreenContext clearDrawable]; @@ -269,6 +282,14 @@ CString LowLevelWindow_Cocoa::TryVideoMode( const VideoModeParams& p, bool& newD } } SetOGLParameters( mFullScreenContext ); + +#if CONCURRENT_RENDERING + [mConcurrentFullScreenContext release]; + mConcurrentFullScreenContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat + shareContext:mWindowContext]; + if( mConcurrentFullScreenContext ) + SetOGLParameters( mConcurrentFullScreenContext ); +#endif } long swap = p.vsync ? 1 : 0; @@ -289,6 +310,10 @@ void LowLevelWindow_Cocoa::ShutDownFullScreen() ASSERT( mCurrentDisplayMode ); [mFullScreenContext clearDrawable]; +#if CONCURRENT_RENDERING + [mConcurrentFullScreenContext clearDrawable]; +#endif + CGDisplayErr err = CGDisplaySwitchToMode( kCGDirectMainDisplay, mCurrentDisplayMode ); ASSERT( err == kCGErrorSuccess ); @@ -301,6 +326,34 @@ void LowLevelWindow_Cocoa::ShutDownFullScreen() mCurrentParams.windowed = true; } +#if CONCURRENT_RENDERING +bool LowLevelWindow_Cocoa::SupportsThreadedRendering() +{ + return mCurrentParams.windowed ? mConcurrentWindowContext : mConcurrentFullScreenContext; +} + +void LowLevelWindow_Cocoa::BeginConcurrentRendering() +{ + if( mCurrentParams.windowed ) + { + [mConcurrentWindowContext setView:[mWindow contentView]]; + [mConcurrentWindowContext update]; + [mConcurrentWindowContext makeCurrentContext]; + } + else + { + [mConcurrentFullScreenContext setFullScreen]; + [mConcurrentFullScreenContext update]; + [mConcurrentFullScreenContext makeCurrentContext]; + } +} + +void LowLevelWindow_Cocoa::EndConcurrentRendering() +{ + [NSOpenGLContext clearCurrentContext]; +} +#endif + int LowLevelWindow_Cocoa::ChangeDisplayMode( const VideoModeParams& p ) { CFDictionaryRef mode = NULL; @@ -395,12 +448,11 @@ void LowLevelWindow_Cocoa::Update() LockMutex lock( g_ResizeLock ); if( likely(!g_bResized) ) return; - LOG->Trace( "LLW_Cocoa::Update(): %d x %d", mCurrentParams.width, mCurrentParams.height ); + g_bResized = false; if( mCurrentParams.width == g_iWidth && mCurrentParams.height == g_iHeight ) return; mCurrentParams.width = g_iWidth; mCurrentParams.height = g_iHeight; - g_bResized = false; lock.Unlock(); // Unlock before calling ResolutionChanged(). [mWindowContext update]; DISPLAY->ResolutionChanged();