Apply changes from latest known public version of bounce dated 2019-11-13

This commit is contained in:
Luke Benstead
2020-01-25 12:31:05 +00:00
parent f87e2a6378
commit a61262407c
431 changed files with 108959 additions and 26372 deletions

View File

@@ -1,7 +1,7 @@
//========================================================================
// GLFW 3.3 OS X - www.glfw.org
// GLFW 3.3 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -26,30 +26,75 @@
#include "internal.h"
// Display link callback for manual swap interval implementation
// This is based on a similar workaround added to SDL2
//
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp* now,
const CVTimeStamp* outputTime,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* userInfo)
{
_GLFWwindow* window = (_GLFWwindow *) userInfo;
const int interval = atomic_load(&window->context.nsgl.swapInterval);
if (interval > 0)
{
[window->context.nsgl.swapIntervalCond lock];
window->context.nsgl.swapIntervalsPassed++;
[window->context.nsgl.swapIntervalCond signal];
[window->context.nsgl.swapIntervalCond unlock];
}
return kCVReturnSuccess;
}
static void makeContextCurrentNSGL(_GLFWwindow* window)
{
@autoreleasepool {
if (window)
[window->context.nsgl.object makeCurrentContext];
else
[NSOpenGLContext clearCurrentContext];
_glfwPlatformSetCurrentContext(window);
_glfwPlatformSetTls(&_glfw.contextSlot, window);
} // autoreleasepool
}
static void swapBuffersNSGL(_GLFWwindow* window)
{
@autoreleasepool {
const int interval = atomic_load(&window->context.nsgl.swapInterval);
if (interval > 0)
{
[window->context.nsgl.swapIntervalCond lock];
do
{
[window->context.nsgl.swapIntervalCond wait];
} while (window->context.nsgl.swapIntervalsPassed % interval != 0);
window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
}
// ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer];
} // autoreleasepool
}
static void swapIntervalNSGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
GLint sync = interval;
[window->context.nsgl.object setValues:&sync
forParameter:NSOpenGLCPSwapInterval];
@autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
atomic_store(&window->context.nsgl.swapInterval, interval);
[window->context.nsgl.swapIntervalCond lock];
window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
} // autoreleasepool
}
static int extensionSupportedNSGL(const char* extension)
@@ -76,11 +121,26 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
//
static void destroyContextNSGL(_GLFWwindow* window)
{
@autoreleasepool {
if (window->context.nsgl.displayLink)
{
if (CVDisplayLinkIsRunning(window->context.nsgl.displayLink))
CVDisplayLinkStop(window->context.nsgl.displayLink);
CVDisplayLinkRelease(window->context.nsgl.displayLink);
}
[window->context.nsgl.swapIntervalCond release];
window->context.nsgl.swapIntervalCond = nil;
[window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil;
[window->context.nsgl.object release];
window->context.nsgl.object = nil;
} // autoreleasepool
}
@@ -119,70 +179,81 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
unsigned int attributeCount = 0;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: OpenGL ES is not available on OS X");
return GLFW_FALSE;
}
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X does not support OpenGL 3.0 or 3.1");
"NSGL: OpenGL ES is not available on macOS");
return GLFW_FALSE;
}
if (ctxconfig->major > 2)
{
if (!ctxconfig->forward)
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X only supports forward-compatible contexts for OpenGL 3.2 and above");
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
return GLFW_FALSE;
}
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of OS X only supports core profile contexts for OpenGL 3.2 and above");
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
return GLFW_FALSE;
}
}
// Context robustness modes (GL_KHR_robustness) are not yet supported on
// OS X but are not a hard constraint, so ignore and continue
// Context robustness modes (GL_KHR_robustness) are not yet supported by
// macOS but are not a hard constraint, so ignore and continue
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported on OS X but are not a hard constraint, so ignore and continue
// supported by macOS but are not a hard constraint, so ignore and continue
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
// a hard constraint, so ignore and continue
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// are not a hard constraint, so ignore and continue
ADD_ATTR(NSOpenGLPFAAccelerated);
ADD_ATTR(NSOpenGLPFAClosestPolicy);
#define addAttrib(a) \
{ \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
}
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
NSOpenGLPixelFormatAttribute attribs[40];
int index = 0;
addAttrib(NSOpenGLPFAAccelerated);
addAttrib(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline)
{
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
// Info.plist for unbundled applications
// HACK: This assumes that NSOpenGLPixelFormat will remain
// a straightforward wrapper of its CGL counterpart
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4)
{
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
}
else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
{
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
if (ctxconfig->major <= 2)
{
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
@@ -194,7 +265,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits);
setAttrib(NSOpenGLPFAAccumSize, accumBits);
}
}
@@ -206,53 +277,61 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
fbconfig->greenBits +
fbconfig->blueBits;
// OS X needs non-zero color size, so set reasonable values
// macOS needs non-zero color size, so set reasonable values
if (colorBits == 0)
colorBits = 24;
else if (colorBits < 15)
colorBits = 15;
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
setAttrib(NSOpenGLPFAColorSize, colorBits);
}
if (fbconfig->alphaBits != GLFW_DONT_CARE)
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE)
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits);
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE)
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo)
ADD_ATTR(NSOpenGLPFAStereo);
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Stereo rendering is deprecated");
return GLFW_FALSE;
#else
addAttrib(NSOpenGLPFAStereo);
#endif
}
if (fbconfig->doublebuffer)
ADD_ATTR(NSOpenGLPFADoubleBuffer);
addAttrib(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE)
{
if (fbconfig->samples == 0)
{
ADD_ATTR2(NSOpenGLPFASampleBuffers, 0);
setAttrib(NSOpenGLPFASampleBuffers, 0);
}
else
{
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
setAttrib(NSOpenGLPFASampleBuffers, 1);
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
}
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it
ADD_ATTR(0);
addAttrib(0);
#undef ADD_ATTR
#undef ADD_ATTR2
#undef addAttrib
#undef setAttrib
window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (window->context.nsgl.pixelFormat == nil)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
@@ -275,8 +354,24 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
return GLFW_FALSE;
}
if (fbconfig->transparent)
{
GLint opaque = 0;
[window->context.nsgl.object setValues:&opaque
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
if (window->ns.retina)
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
GLint interval = 0;
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
[window->context.nsgl.object setView:window->ns.view];
window->context.nsgl.swapIntervalCond = [NSCondition new];
window->context.makeCurrent = makeContextCurrentNSGL;
window->context.swapBuffers = swapBuffersNSGL;
window->context.swapInterval = swapIntervalNSGL;
@@ -284,9 +379,26 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
CVDisplayLinkCreateWithActiveCGDisplays(&window->context.nsgl.displayLink);
CVDisplayLinkSetOutputCallback(window->context.nsgl.displayLink,
&displayLinkCallback,
window);
CVDisplayLinkStart(window->context.nsgl.displayLink);
_glfwUpdateDisplayLinkDisplayNSGL(window);
return GLFW_TRUE;
}
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window)
{
CGDirectDisplayID displayID =
[[[window->ns.object screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
if (!displayID)
return;
CVDisplayLinkSetCurrentCGDisplay(window->context.nsgl.displayLink, displayID);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////