|
|
|
@@ -59,7 +59,8 @@ GHOST_ContextCGL::GHOST_ContextCGL(
|
|
|
|
|
int contextResetNotificationStrategy)
|
|
|
|
|
: GHOST_Context(stereoVisual, numOfAASamples),
|
|
|
|
|
m_openGLView(openGLView),
|
|
|
|
|
m_openGLContext(nil)
|
|
|
|
|
m_openGLContext(nil),
|
|
|
|
|
m_debug(contextFlags)
|
|
|
|
|
{
|
|
|
|
|
assert(openGLView != nil);
|
|
|
|
|
}
|
|
|
|
@@ -172,20 +173,21 @@ static void makeAttribList(
|
|
|
|
|
bool stereoVisual,
|
|
|
|
|
int numOfAASamples,
|
|
|
|
|
bool needAlpha,
|
|
|
|
|
bool needStencil)
|
|
|
|
|
bool needStencil,
|
|
|
|
|
bool softwareGL)
|
|
|
|
|
{
|
|
|
|
|
attribs.clear();
|
|
|
|
|
|
|
|
|
|
// Pixel Format Attributes for the windowed NSOpenGLContext
|
|
|
|
|
attribs.push_back(NSOpenGLPFADoubleBuffer);
|
|
|
|
|
|
|
|
|
|
// Force software OpenGL, for debugging
|
|
|
|
|
/* XXX jwilkins: fixed this to work on Intel macs? useful feature for Windows and Linux too?
|
|
|
|
|
* Maybe a command line flag is better... */
|
|
|
|
|
if (getenv("BLENDER_SOFTWAREGL")) {
|
|
|
|
|
if (softwareGL) {
|
|
|
|
|
attribs.push_back(NSOpenGLPFARendererID);
|
|
|
|
|
attribs.push_back(kCGLRendererGenericFloatID);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
attribs.push_back(NSOpenGLPFAAccelerated);
|
|
|
|
|
attribs.push_back(NSOpenGLPFANoRecovery);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway */
|
|
|
|
@@ -219,13 +221,21 @@ static void makeAttribList(
|
|
|
|
|
|
|
|
|
|
attribs.push_back(NSOpenGLPFASamples);
|
|
|
|
|
attribs.push_back((NSOpenGLPixelFormatAttribute) numOfAASamples);
|
|
|
|
|
|
|
|
|
|
attribs.push_back(NSOpenGLPFANoRecovery);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attribs.push_back((NSOpenGLPixelFormatAttribute) 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(merwin): make this available to all platforms
|
|
|
|
|
static void getVersion(int *major, int *minor)
|
|
|
|
|
{
|
|
|
|
|
#if 1 // legacy GL
|
|
|
|
|
sscanf((const char*)glGetString(GL_VERSION), "%d.%d", major, minor);
|
|
|
|
|
#else // 3.0+
|
|
|
|
|
glGetIntegerv(GL_MAJOR_VERSION, major);
|
|
|
|
|
glGetIntegerv(GL_MINOR_VERSION, minor);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
|
|
|
|
{
|
|
|
|
@@ -248,9 +258,12 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
|
|
|
|
static const bool needStencil = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil);
|
|
|
|
|
|
|
|
|
|
static bool softwareGL = getenv("BLENDER_SOFTWAREGL"); // command-line argument would be better
|
|
|
|
|
GLint major = 0, minor = 0;
|
|
|
|
|
NSOpenGLPixelFormat *pixelFormat;
|
|
|
|
|
// TODO: keep pixel format for subsequent windows/contexts instead of recreating each time
|
|
|
|
|
|
|
|
|
|
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
|
|
|
|
|
|
|
|
|
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
|
|
|
|
|
|
|
|
@@ -261,7 +274,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
|
|
|
|
// (Now that I think about it, does WGL really require the code that it has for finding a lesser match?)
|
|
|
|
|
|
|
|
|
|
attribs.clear();
|
|
|
|
|
makeAttribList(attribs, m_stereoVisual, 0, needAlpha, needStencil);
|
|
|
|
|
makeAttribList(attribs, m_stereoVisual, 0, needAlpha, needStencil, softwareGL);
|
|
|
|
|
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -282,25 +295,47 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[m_openGLView setPixelFormat:pixelFormat];
|
|
|
|
|
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
|
|
|
|
|
[pixelFormat release];
|
|
|
|
|
|
|
|
|
|
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext]; // +1 refCount to pixelFormat
|
|
|
|
|
[m_openGLContext makeCurrentContext];
|
|
|
|
|
|
|
|
|
|
if (m_openGLContext == nil)
|
|
|
|
|
goto error;
|
|
|
|
|
getVersion(&major, &minor);
|
|
|
|
|
if (m_debug) {
|
|
|
|
|
fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
|
|
|
|
|
fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s_sharedCount == 0)
|
|
|
|
|
s_sharedOpenGLContext = m_openGLContext;
|
|
|
|
|
|
|
|
|
|
[pixelFormat release]; // -1 refCount to pixelFormat
|
|
|
|
|
|
|
|
|
|
s_sharedCount++;
|
|
|
|
|
if (major < 2 || (major == 2 && minor < 1)) {
|
|
|
|
|
// fall back to software renderer if GL < 2.1
|
|
|
|
|
fprintf(stderr, "OpenGL 2.1 is not supported on your hardware, falling back to software");
|
|
|
|
|
softwareGL = true;
|
|
|
|
|
|
|
|
|
|
// discard hardware GL context
|
|
|
|
|
[NSOpenGLContext clearCurrentContext];
|
|
|
|
|
[m_openGLContext release];
|
|
|
|
|
|
|
|
|
|
// create software GL context
|
|
|
|
|
makeAttribList(attribs, m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, softwareGL);
|
|
|
|
|
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
|
|
|
|
|
m_openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:s_sharedOpenGLContext];
|
|
|
|
|
[pixelFormat release];
|
|
|
|
|
|
|
|
|
|
[m_openGLContext makeCurrentContext];
|
|
|
|
|
|
|
|
|
|
getVersion(&major, &minor);
|
|
|
|
|
if (m_debug) {
|
|
|
|
|
fprintf(stderr, "OpenGL version %d.%d%s\n", major, minor, softwareGL ? " (software)" : "");
|
|
|
|
|
fprintf(stderr, "Renderer: %s\n", glGetString(GL_RENDERER));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef GHOST_MULTITHREADED_OPENGL
|
|
|
|
|
//Switch openGL to multhreaded mode
|
|
|
|
|
CGLContextObj cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj];
|
|
|
|
|
if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError)
|
|
|
|
|
printf("\nSwitched openGL to multithreaded mode\n");
|
|
|
|
|
if (m_debug)
|
|
|
|
|
fprintf(stderr, "\nSwitched OpenGL to multithreaded mode\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef GHOST_WAIT_FOR_VSYNC
|
|
|
|
@@ -311,10 +346,16 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext()
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
initContextGLEW();
|
|
|
|
|
|
|
|
|
|
[m_openGLView setOpenGLContext:m_openGLContext];
|
|
|
|
|
[m_openGLContext setView:m_openGLView];
|
|
|
|
|
|
|
|
|
|
initContextGLEW();
|
|
|
|
|
if (s_sharedCount == 0)
|
|
|
|
|
s_sharedOpenGLContext = m_openGLContext;
|
|
|
|
|
|
|
|
|
|
s_sharedCount++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
initClearGL();
|
|
|
|
|
[m_openGLContext flushBuffer];
|
|
|
|
|