[+] glfwGetPOSIXLoopFds
[-] vulkan and opengl loaders
This commit is contained in:
parent
3f5365a0e8
commit
8480bfc432
@ -4508,6 +4508,13 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwPollEvents(void);
|
GLFWAPI void glfwPollEvents(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param pCount
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
GLFWAPI struct pollfd *glfwGetPOSIXLoopFds(unsigned int *pCount);
|
||||||
|
|
||||||
/*! @brief Waits until events are queued and processes them.
|
/*! @brief Waits until events are queued and processes them.
|
||||||
*
|
*
|
||||||
* This function puts the calling thread to sleep until at least one event is
|
* This function puts the calling thread to sleep until at least one event is
|
||||||
|
@ -120,7 +120,6 @@ static void terminate(void)
|
|||||||
_glfw.mappings = NULL;
|
_glfw.mappings = NULL;
|
||||||
_glfw.mappingCount = 0;
|
_glfw.mappingCount = 0;
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
_glfw.platform.terminateJoysticks();
|
_glfw.platform.terminateJoysticks();
|
||||||
_glfw.platform.terminate();
|
_glfw.platform.terminate();
|
||||||
|
|
||||||
@ -543,7 +542,7 @@ GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
|
|||||||
|
|
||||||
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
|
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
|
||||||
{
|
{
|
||||||
_glfwInitHints.vulkanLoader = loader;
|
_glfw.vk.GetInstanceProcAddr = loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||||
|
@ -784,6 +784,7 @@ struct _GLFWplatform
|
|||||||
void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
|
void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
|
||||||
void (*setWindowOpacity)(_GLFWwindow*,float);
|
void (*setWindowOpacity)(_GLFWwindow*,float);
|
||||||
void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
|
void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
|
||||||
|
struct pollfd *(*getPOSIXLoopFds)(unsigned int *pCount);
|
||||||
void (*pollEvents)(void);
|
void (*pollEvents)(void);
|
||||||
void (*waitEvents)(void);
|
void (*waitEvents)(void);
|
||||||
void (*waitEventsTimeout)(double);
|
void (*waitEventsTimeout)(double);
|
||||||
@ -1043,8 +1044,6 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
GLFWbool _glfwInitVulkan(int mode);
|
|
||||||
void _glfwTerminateVulkan(void);
|
|
||||||
const char* _glfwGetVulkanResultString(VkResult result);
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||||
|
@ -1,380 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.4 macOS - www.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
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// It is fine to use C99 in this file because it will not be built with VS
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#if defined(_GLFW_COCOA)
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
@autoreleasepool {
|
|
||||||
|
|
||||||
if (window)
|
|
||||||
[window->context.nsgl.object makeCurrentContext];
|
|
||||||
else
|
|
||||||
[NSOpenGLContext clearCurrentContext];
|
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
|
||||||
|
|
||||||
} // autoreleasepool
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapBuffersNSGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
@autoreleasepool {
|
|
||||||
|
|
||||||
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
|
||||||
// windows with a non-visible occlusion state
|
|
||||||
if (window->ns.occluded)
|
|
||||||
{
|
|
||||||
int interval = 0;
|
|
||||||
[window->context.nsgl.object getValues:&interval
|
|
||||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
|
||||||
|
|
||||||
if (interval > 0)
|
|
||||||
{
|
|
||||||
const double framerate = 60.0;
|
|
||||||
const uint64_t frequency = _glfwPlatformGetTimerFrequency();
|
|
||||||
const uint64_t value = _glfwPlatformGetTimerValue();
|
|
||||||
|
|
||||||
const double elapsed = value / (double) frequency;
|
|
||||||
const double period = 1.0 / framerate;
|
|
||||||
const double delay = period - fmod(elapsed, period);
|
|
||||||
|
|
||||||
usleep(floorl(delay * 1e6));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[window->context.nsgl.object flushBuffer];
|
|
||||||
|
|
||||||
} // autoreleasepool
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapIntervalNSGL(int interval)
|
|
||||||
{
|
|
||||||
@autoreleasepool {
|
|
||||||
|
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
[window->context.nsgl.object setValues:&interval
|
|
||||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // autoreleasepool
|
|
||||||
}
|
|
||||||
|
|
||||||
static int extensionSupportedNSGL(const char* extension)
|
|
||||||
{
|
|
||||||
// There are no NSGL extensions
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWglproc getProcAddressNSGL(const char* procname)
|
|
||||||
{
|
|
||||||
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
|
|
||||||
procname,
|
|
||||||
kCFStringEncodingASCII);
|
|
||||||
|
|
||||||
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
|
||||||
symbolName);
|
|
||||||
|
|
||||||
CFRelease(symbolName);
|
|
||||||
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyContextNSGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
@autoreleasepool {
|
|
||||||
|
|
||||||
[window->context.nsgl.pixelFormat release];
|
|
||||||
window->context.nsgl.pixelFormat = nil;
|
|
||||||
|
|
||||||
[window->context.nsgl.object release];
|
|
||||||
window->context.nsgl.object = nil;
|
|
||||||
|
|
||||||
} // autoreleasepool
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Initialize OpenGL support
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitNSGL(void)
|
|
||||||
{
|
|
||||||
if (_glfw.nsgl.framework)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
_glfw.nsgl.framework =
|
|
||||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
|
||||||
if (_glfw.nsgl.framework == NULL)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"NSGL: Failed to locate OpenGL framework");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate OpenGL support
|
|
||||||
//
|
|
||||||
void _glfwTerminateNSGL(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the OpenGL context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"NSGL: OpenGL ES is not available on macOS");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->major > 2)
|
|
||||||
{
|
|
||||||
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 by macOS but are not a hard constraint, so ignore and continue
|
|
||||||
|
|
||||||
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
|
|
||||||
// a hard constraint, so ignore and continue
|
|
||||||
|
|
||||||
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
|
||||||
// are not a hard constraint, so ignore and continue
|
|
||||||
|
|
||||||
#define ADD_ATTRIB(a) \
|
|
||||||
{ \
|
|
||||||
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
|
||||||
attribs[index++] = a; \
|
|
||||||
}
|
|
||||||
#define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
|
|
||||||
|
|
||||||
NSOpenGLPixelFormatAttribute attribs[40];
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
ADD_ATTRIB(NSOpenGLPFAAccelerated);
|
|
||||||
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
|
|
||||||
|
|
||||||
if (ctxconfig->nsgl.offline)
|
|
||||||
{
|
|
||||||
ADD_ATTRIB(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
|
|
||||||
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
|
||||||
if (ctxconfig->major >= 4)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
|
||||||
if (ctxconfig->major >= 3)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->major <= 2)
|
|
||||||
{
|
|
||||||
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
|
||||||
SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
|
||||||
|
|
||||||
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
|
||||||
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
|
||||||
fbconfig->accumBlueBits != GLFW_DONT_CARE &&
|
|
||||||
fbconfig->accumAlphaBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
const int accumBits = fbconfig->accumRedBits +
|
|
||||||
fbconfig->accumGreenBits +
|
|
||||||
fbconfig->accumBlueBits +
|
|
||||||
fbconfig->accumAlphaBits;
|
|
||||||
|
|
||||||
SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbconfig->redBits != GLFW_DONT_CARE &&
|
|
||||||
fbconfig->greenBits != GLFW_DONT_CARE &&
|
|
||||||
fbconfig->blueBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
int colorBits = fbconfig->redBits +
|
|
||||||
fbconfig->greenBits +
|
|
||||||
fbconfig->blueBits;
|
|
||||||
|
|
||||||
// macOS needs non-zero color size, so set reasonable values
|
|
||||||
if (colorBits == 0)
|
|
||||||
colorBits = 24;
|
|
||||||
else if (colorBits < 15)
|
|
||||||
colorBits = 15;
|
|
||||||
|
|
||||||
SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
|
||||||
SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
|
||||||
|
|
||||||
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
|
||||||
SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
|
||||||
|
|
||||||
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
|
||||||
SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
|
||||||
|
|
||||||
if (fbconfig->stereo)
|
|
||||||
{
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
||||||
"NSGL: Stereo rendering is deprecated");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
#else
|
|
||||||
ADD_ATTRIB(NSOpenGLPFAStereo);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbconfig->doublebuffer)
|
|
||||||
ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
|
|
||||||
|
|
||||||
if (fbconfig->samples != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
if (fbconfig->samples == 0)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
|
|
||||||
SET_ATTRIB(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_ATTRIB(0);
|
|
||||||
|
|
||||||
#undef ADD_ATTRIB
|
|
||||||
#undef SET_ATTRIB
|
|
||||||
|
|
||||||
window->context.nsgl.pixelFormat =
|
|
||||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
|
||||||
if (window->context.nsgl.pixelFormat == nil)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
||||||
"NSGL: Failed to find a suitable pixel format");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSOpenGLContext* share = nil;
|
|
||||||
|
|
||||||
if (ctxconfig->share)
|
|
||||||
share = ctxconfig->share->context.nsgl.object;
|
|
||||||
|
|
||||||
window->context.nsgl.object =
|
|
||||||
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
|
|
||||||
shareContext:share];
|
|
||||||
if (window->context.nsgl.object == nil)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"NSGL: Failed to create OpenGL context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fbconfig->transparent)
|
|
||||||
{
|
|
||||||
GLint opaque = 0;
|
|
||||||
[window->context.nsgl.object setValues:&opaque
|
|
||||||
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];
|
|
||||||
|
|
||||||
[window->context.nsgl.object setView:window->ns.view];
|
|
||||||
|
|
||||||
window->context.makeCurrent = makeContextCurrentNSGL;
|
|
||||||
window->context.swapBuffers = swapBuffersNSGL;
|
|
||||||
window->context.swapInterval = swapIntervalNSGL;
|
|
||||||
window->context.extensionSupported = extensionSupportedNSGL;
|
|
||||||
window->context.getProcAddress = getProcAddressNSGL;
|
|
||||||
window->context.destroy = destroyContextNSGL;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW native API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
|
|
||||||
|
|
||||||
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
|
|
||||||
"NSGL: Platform not initialized");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return window->context.nsgl.object;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _GLFW_COCOA
|
|
||||||
|
|
@ -1,386 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.4 OSMesa - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2016 Google Inc.
|
|
||||||
// Copyright (c) 2016-2017 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
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// Please use C89 style variable declarations in this file because VS 2010
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
_glfw.platform.getFramebufferSize(window, &width, &height);
|
|
||||||
|
|
||||||
// Check to see if we need to allocate a new buffer
|
|
||||||
if ((window->context.osmesa.buffer == NULL) ||
|
|
||||||
(width != window->context.osmesa.width) ||
|
|
||||||
(height != window->context.osmesa.height))
|
|
||||||
{
|
|
||||||
_glfw_free(window->context.osmesa.buffer);
|
|
||||||
|
|
||||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
|
||||||
window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
|
|
||||||
window->context.osmesa.width = width;
|
|
||||||
window->context.osmesa.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
|
|
||||||
window->context.osmesa.buffer,
|
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
width, height))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"OSMesa: Failed to make context current");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWglproc getProcAddressOSMesa(const char* procname)
|
|
||||||
{
|
|
||||||
return (GLFWglproc) OSMesaGetProcAddress(procname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyContextOSMesa(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (window->context.osmesa.handle)
|
|
||||||
{
|
|
||||||
OSMesaDestroyContext(window->context.osmesa.handle);
|
|
||||||
window->context.osmesa.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.osmesa.buffer)
|
|
||||||
{
|
|
||||||
_glfw_free(window->context.osmesa.buffer);
|
|
||||||
window->context.osmesa.width = 0;
|
|
||||||
window->context.osmesa.height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapBuffersOSMesa(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
// No double buffering on OSMesa
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapIntervalOSMesa(int interval)
|
|
||||||
{
|
|
||||||
// No swap interval on OSMesa
|
|
||||||
}
|
|
||||||
|
|
||||||
static int extensionSupportedOSMesa(const char* extension)
|
|
||||||
{
|
|
||||||
// OSMesa does not have extensions
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWbool _glfwInitOSMesa(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char* sonames[] =
|
|
||||||
{
|
|
||||||
#if defined(_GLFW_OSMESA_LIBRARY)
|
|
||||||
_GLFW_OSMESA_LIBRARY,
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
"libOSMesa.dll",
|
|
||||||
"OSMesa.dll",
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
"libOSMesa.8.dylib",
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
"libOSMesa-8.so",
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
||||||
"libOSMesa.so",
|
|
||||||
#else
|
|
||||||
"libOSMesa.so.8",
|
|
||||||
"libOSMesa.so.6",
|
|
||||||
#endif
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_glfw.osmesa.handle)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
for (i = 0; sonames[i]; i++)
|
|
||||||
{
|
|
||||||
_glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]);
|
|
||||||
if (_glfw.osmesa.handle)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfw.osmesa.handle)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
|
|
||||||
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
|
||||||
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
|
|
||||||
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
|
|
||||||
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
|
||||||
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
|
||||||
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress");
|
|
||||||
|
|
||||||
if (!_glfw.osmesa.CreateContextExt ||
|
|
||||||
!_glfw.osmesa.DestroyContext ||
|
|
||||||
!_glfw.osmesa.MakeCurrent ||
|
|
||||||
!_glfw.osmesa.GetColorBuffer ||
|
|
||||||
!_glfw.osmesa.GetDepthBuffer ||
|
|
||||||
!_glfw.osmesa.GetProcAddress)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"OSMesa: Failed to load required entry points");
|
|
||||||
|
|
||||||
_glfwTerminateOSMesa();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwTerminateOSMesa(void)
|
|
||||||
{
|
|
||||||
if (_glfw.osmesa.handle)
|
|
||||||
{
|
|
||||||
_glfwPlatformFreeModule(_glfw.osmesa.handle);
|
|
||||||
_glfw.osmesa.handle = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_ATTRIB(a, v) \
|
|
||||||
{ \
|
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
|
||||||
attribs[index++] = a; \
|
|
||||||
attribs[index++] = v; \
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
OSMesaContext share = NULL;
|
|
||||||
const int accumBits = fbconfig->accumRedBits +
|
|
||||||
fbconfig->accumGreenBits +
|
|
||||||
fbconfig->accumBlueBits +
|
|
||||||
fbconfig->accumAlphaBits;
|
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"OSMesa: OpenGL ES is not available on OSMesa");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->share)
|
|
||||||
share = ctxconfig->share->context.osmesa.handle;
|
|
||||||
|
|
||||||
if (OSMesaCreateContextAttribs)
|
|
||||||
{
|
|
||||||
int index = 0, attribs[40];
|
|
||||||
|
|
||||||
SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
|
|
||||||
SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
|
|
||||||
SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
|
|
||||||
SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
|
|
||||||
|
|
||||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
|
|
||||||
}
|
|
||||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
|
|
||||||
SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->forward)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"OSMesa: Forward-compatible contexts not supported");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SET_ATTRIB(0, 0);
|
|
||||||
|
|
||||||
window->context.osmesa.handle =
|
|
||||||
OSMesaCreateContextAttribs(attribs, share);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ctxconfig->profile)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"OSMesa: OpenGL profiles unavailable");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->context.osmesa.handle =
|
|
||||||
OSMesaCreateContextExt(OSMESA_RGBA,
|
|
||||||
fbconfig->depthBits,
|
|
||||||
fbconfig->stencilBits,
|
|
||||||
accumBits,
|
|
||||||
share);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.osmesa.handle == NULL)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"OSMesa: Failed to create context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->context.makeCurrent = makeContextCurrentOSMesa;
|
|
||||||
window->context.swapBuffers = swapBuffersOSMesa;
|
|
||||||
window->context.swapInterval = swapIntervalOSMesa;
|
|
||||||
window->context.extensionSupported = extensionSupportedOSMesa;
|
|
||||||
window->context.getProcAddress = getProcAddressOSMesa;
|
|
||||||
window->context.destroy = destroyContextOSMesa;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef SET_ATTRIB
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW native API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
|
||||||
int* height, int* format, void** buffer)
|
|
||||||
{
|
|
||||||
void* mesaBuffer;
|
|
||||||
GLint mesaWidth, mesaHeight, mesaFormat;
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
assert(window != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
|
|
||||||
&mesaWidth, &mesaHeight,
|
|
||||||
&mesaFormat, &mesaBuffer))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"OSMesa: Failed to retrieve color buffer");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width)
|
|
||||||
*width = mesaWidth;
|
|
||||||
if (height)
|
|
||||||
*height = mesaHeight;
|
|
||||||
if (format)
|
|
||||||
*format = mesaFormat;
|
|
||||||
if (buffer)
|
|
||||||
*buffer = mesaBuffer;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
|
||||||
int* width, int* height,
|
|
||||||
int* bytesPerValue,
|
|
||||||
void** buffer)
|
|
||||||
{
|
|
||||||
void* mesaBuffer;
|
|
||||||
GLint mesaWidth, mesaHeight, mesaBytes;
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
assert(window != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
|
|
||||||
&mesaWidth, &mesaHeight,
|
|
||||||
&mesaBytes, &mesaBuffer))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"OSMesa: Failed to retrieve depth buffer");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width)
|
|
||||||
*width = mesaWidth;
|
|
||||||
if (height)
|
|
||||||
*height = mesaHeight;
|
|
||||||
if (bytesPerValue)
|
|
||||||
*bytesPerValue = mesaBytes;
|
|
||||||
if (buffer)
|
|
||||||
*buffer = mesaBuffer;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return window->context.osmesa.handle;
|
|
||||||
}
|
|
||||||
|
|
@ -193,3 +193,15 @@ GLFWAPI const char* glfwGetVersionString(void)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
||||||
|
GLFWwindow* handle,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*)handle;
|
||||||
|
assert(instance != VK_NULL_HANDLE);
|
||||||
|
assert(window != NULL);
|
||||||
|
assert(surface != NULL);
|
||||||
|
*surface = VK_NULL_HANDLE;
|
||||||
|
return _glfw.platform.createWindowSurface(instance, window, allocator, surface);
|
||||||
|
}
|
||||||
|
330
src/vulkan.c
330
src/vulkan.c
@ -1,330 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.4 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2018 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
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// Please use C89 style variable declarations in this file because VS 2010
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define _GLFW_FIND_LOADER 1
|
|
||||||
#define _GLFW_REQUIRE_LOADER 2
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWbool _glfwInitVulkan(int mode)
|
|
||||||
{
|
|
||||||
VkResult err;
|
|
||||||
VkExtensionProperties* ep;
|
|
||||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
|
||||||
uint32_t i, count;
|
|
||||||
|
|
||||||
if (_glfw.vk.available)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
if (_glfw.hints.init.vulkanLoader)
|
|
||||||
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
|
|
||||||
#elif defined(_GLFW_COCOA)
|
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
|
|
||||||
if (!_glfw.vk.handle)
|
|
||||||
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
|
||||||
#else
|
|
||||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
|
|
||||||
#endif
|
|
||||||
if (!_glfw.vk.handle)
|
|
||||||
{
|
|
||||||
if (mode == _GLFW_REQUIRE_LOADER)
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
|
||||||
if (!_glfw.vk.GetInstanceProcAddr)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
|
||||||
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
|
|
||||||
if (!vkEnumerateInstanceExtensionProperties)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
// NOTE: This happens on systems with a loader but without any Vulkan ICD
|
|
||||||
if (mode == _GLFW_REQUIRE_LOADER)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Failed to query instance extension count: %s",
|
|
||||||
_glfwGetVulkanResultString(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ep = _glfw_calloc(count, sizeof(VkExtensionProperties));
|
|
||||||
|
|
||||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Failed to query instance extensions: %s",
|
|
||||||
_glfwGetVulkanResultString(err));
|
|
||||||
|
|
||||||
_glfw_free(ep);
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
|
|
||||||
_glfw.vk.KHR_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
|
||||||
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
|
||||||
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
|
|
||||||
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
|
||||||
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
|
|
||||||
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
|
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
|
||||||
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw_free(ep);
|
|
||||||
|
|
||||||
_glfw.vk.available = GLFW_TRUE;
|
|
||||||
|
|
||||||
_glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwTerminateVulkan(void)
|
|
||||||
{
|
|
||||||
if (_glfw.vk.handle)
|
|
||||||
_glfwPlatformFreeModule(_glfw.vk.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwGetVulkanResultString(VkResult result)
|
|
||||||
{
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case VK_SUCCESS:
|
|
||||||
return "Success";
|
|
||||||
case VK_NOT_READY:
|
|
||||||
return "A fence or query has not yet completed";
|
|
||||||
case VK_TIMEOUT:
|
|
||||||
return "A wait operation has not completed in the specified time";
|
|
||||||
case VK_EVENT_SET:
|
|
||||||
return "An event is signaled";
|
|
||||||
case VK_EVENT_RESET:
|
|
||||||
return "An event is unsignaled";
|
|
||||||
case VK_INCOMPLETE:
|
|
||||||
return "A return array was too small for the result";
|
|
||||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
|
||||||
return "A host memory allocation has failed";
|
|
||||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
|
||||||
return "A device memory allocation has failed";
|
|
||||||
case VK_ERROR_INITIALIZATION_FAILED:
|
|
||||||
return "Initialization of an object could not be completed for implementation-specific reasons";
|
|
||||||
case VK_ERROR_DEVICE_LOST:
|
|
||||||
return "The logical or physical device has been lost";
|
|
||||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
|
||||||
return "Mapping of a memory object has failed";
|
|
||||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
|
||||||
return "A requested layer is not present or could not be loaded";
|
|
||||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
|
||||||
return "A requested extension is not supported";
|
|
||||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
|
||||||
return "A requested feature is not supported";
|
|
||||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
|
||||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
|
||||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
|
||||||
return "Too many objects of the type have already been created";
|
|
||||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
|
||||||
return "A requested format is not supported on this device";
|
|
||||||
case VK_ERROR_SURFACE_LOST_KHR:
|
|
||||||
return "A surface is no longer available";
|
|
||||||
case VK_SUBOPTIMAL_KHR:
|
|
||||||
return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
|
||||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
|
||||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
|
||||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
|
||||||
return "The display used by a swapchain does not use the same presentable image layout";
|
|
||||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
|
||||||
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
|
||||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
|
||||||
return "A validation layer found an error";
|
|
||||||
default:
|
|
||||||
return "ERROR: UNKNOWN VULKAN ERROR";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW public API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI int glfwVulkanSupported(void)
|
|
||||||
{
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
return _glfwInitVulkan(_GLFW_FIND_LOADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
|
||||||
{
|
|
||||||
assert(count != NULL);
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfw.vk.extensions[0])
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*count = 2;
|
|
||||||
return (const char**) _glfw.vk.extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
|
||||||
const char* procname)
|
|
||||||
{
|
|
||||||
GLFWvkproc proc;
|
|
||||||
assert(procname != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
|
|
||||||
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
|
|
||||||
return (GLFWvkproc) vkGetInstanceProcAddr;
|
|
||||||
|
|
||||||
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
|
||||||
if (!proc)
|
|
||||||
{
|
|
||||||
if (_glfw.vk.handle)
|
|
||||||
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|
||||||
VkPhysicalDevice device,
|
|
||||||
uint32_t queuefamily)
|
|
||||||
{
|
|
||||||
assert(instance != VK_NULL_HANDLE);
|
|
||||||
assert(device != VK_NULL_HANDLE);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfw.vk.extensions[0])
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Window surface creation extensions not found");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfw.platform.getPhysicalDevicePresentationSupport(instance,
|
|
||||||
device,
|
|
||||||
queuefamily);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
|
||||||
GLFWwindow* handle,
|
|
||||||
const VkAllocationCallbacks* allocator,
|
|
||||||
VkSurfaceKHR* surface)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
assert(instance != VK_NULL_HANDLE);
|
|
||||||
assert(window != NULL);
|
|
||||||
assert(surface != NULL);
|
|
||||||
|
|
||||||
*surface = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
|
|
||||||
|
|
||||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
|
|
||||||
if (!_glfw.vk.extensions[0])
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Window surface creation extensions not found");
|
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_VALUE,
|
|
||||||
"Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API");
|
|
||||||
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfw.platform.createWindowSurface(instance, window, allocator, surface);
|
|
||||||
}
|
|
||||||
|
|
@ -1,782 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.4 WGL - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-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
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// Please use C89 style variable declarations in this file because VS 2010
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#if defined(_GLFW_WIN32)
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// Return the value corresponding to the specified attribute
|
|
||||||
//
|
|
||||||
static int findPixelFormatAttribValueWGL(const int* attribs,
|
|
||||||
int attribCount,
|
|
||||||
const int* values,
|
|
||||||
int attrib)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < attribCount; i++)
|
|
||||||
{
|
|
||||||
if (attribs[i] == attrib)
|
|
||||||
return values[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Unknown pixel format attribute requested");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ADD_ATTRIB(a) \
|
|
||||||
{ \
|
|
||||||
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
|
|
||||||
attribs[attribCount++] = a; \
|
|
||||||
}
|
|
||||||
#define FIND_ATTRIB_VALUE(a) \
|
|
||||||
findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
|
|
||||||
|
|
||||||
// Return a list of available and usable framebuffer configs
|
|
||||||
//
|
|
||||||
static int choosePixelFormatWGL(_GLFWwindow* window,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
_GLFWfbconfig* usableConfigs;
|
|
||||||
const _GLFWfbconfig* closest;
|
|
||||||
int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0;
|
|
||||||
int attribs[40];
|
|
||||||
int values[sizeof(attribs) / sizeof(attribs[0])];
|
|
||||||
|
|
||||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
|
||||||
1,
|
|
||||||
sizeof(PIXELFORMATDESCRIPTOR),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_pixel_format)
|
|
||||||
{
|
|
||||||
ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB);
|
|
||||||
ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB);
|
|
||||||
ADD_ATTRIB(WGL_PIXEL_TYPE_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCELERATION_ARB);
|
|
||||||
ADD_ATTRIB(WGL_RED_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_RED_SHIFT_ARB);
|
|
||||||
ADD_ATTRIB(WGL_GREEN_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_GREEN_SHIFT_ARB);
|
|
||||||
ADD_ATTRIB(WGL_BLUE_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_BLUE_SHIFT_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ALPHA_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB);
|
|
||||||
ADD_ATTRIB(WGL_DEPTH_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_STENCIL_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCUM_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_AUX_BUFFERS_ARB);
|
|
||||||
ADD_ATTRIB(WGL_STEREO_ARB);
|
|
||||||
ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB);
|
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_multisample)
|
|
||||||
ADD_ATTRIB(WGL_SAMPLES_ARB);
|
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
|
||||||
ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.EXT_colorspace)
|
|
||||||
ADD_ATTRIB(WGL_COLORSPACE_EXT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
|
||||||
|
|
||||||
for (i = 0; i < nativeCount; i++)
|
|
||||||
{
|
|
||||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
|
||||||
pixelFormat = i + 1;
|
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_pixel_format)
|
|
||||||
{
|
|
||||||
// Get pixel format attributes through "modern" extension
|
|
||||||
|
|
||||||
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
|
||||||
pixelFormat, 0,
|
|
||||||
attribCount,
|
|
||||||
attribs, values))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to retrieve pixel format attributes");
|
|
||||||
|
|
||||||
_glfw_free(usableConfigs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) ||
|
|
||||||
!FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB);
|
|
||||||
u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB);
|
|
||||||
u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB);
|
|
||||||
u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB);
|
|
||||||
|
|
||||||
u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB);
|
|
||||||
u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB);
|
|
||||||
|
|
||||||
u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB);
|
|
||||||
u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB);
|
|
||||||
u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB);
|
|
||||||
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
|
|
||||||
|
|
||||||
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
|
|
||||||
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
|
|
||||||
u->stereo = GLFW_TRUE;
|
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_multisample)
|
|
||||||
u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
|
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
|
||||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
|
||||||
{
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
|
||||||
u->sRGB = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.EXT_colorspace)
|
|
||||||
{
|
|
||||||
if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
|
|
||||||
u->sRGB = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get pixel format attributes through legacy PFDs
|
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
|
||||||
pixelFormat,
|
|
||||||
sizeof(PIXELFORMATDESCRIPTOR),
|
|
||||||
&pfd))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to describe pixel format");
|
|
||||||
|
|
||||||
_glfw_free(usableConfigs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
|
|
||||||
!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
|
|
||||||
(pfd.dwFlags & PFD_GENERIC_FORMAT))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfd.iPixelType != PFD_TYPE_RGBA)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!!(pfd.dwFlags & PFD_DOUBLEBUFFER) != fbconfig->doublebuffer)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u->redBits = pfd.cRedBits;
|
|
||||||
u->greenBits = pfd.cGreenBits;
|
|
||||||
u->blueBits = pfd.cBlueBits;
|
|
||||||
u->alphaBits = pfd.cAlphaBits;
|
|
||||||
|
|
||||||
u->depthBits = pfd.cDepthBits;
|
|
||||||
u->stencilBits = pfd.cStencilBits;
|
|
||||||
|
|
||||||
u->accumRedBits = pfd.cAccumRedBits;
|
|
||||||
u->accumGreenBits = pfd.cAccumGreenBits;
|
|
||||||
u->accumBlueBits = pfd.cAccumBlueBits;
|
|
||||||
u->accumAlphaBits = pfd.cAccumAlphaBits;
|
|
||||||
|
|
||||||
u->auxBuffers = pfd.cAuxBuffers;
|
|
||||||
|
|
||||||
if (pfd.dwFlags & PFD_STEREO)
|
|
||||||
u->stereo = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
u->handle = pixelFormat;
|
|
||||||
usableCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!usableCount)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"WGL: The driver does not appear to support OpenGL");
|
|
||||||
|
|
||||||
_glfw_free(usableConfigs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
|
||||||
if (!closest)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
||||||
"WGL: Failed to find a suitable pixel format");
|
|
||||||
|
|
||||||
_glfw_free(usableConfigs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixelFormat = (int) closest->handle;
|
|
||||||
_glfw_free(usableConfigs);
|
|
||||||
|
|
||||||
return pixelFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef ADD_ATTRIB
|
|
||||||
#undef FIND_ATTRIB_VALUE
|
|
||||||
|
|
||||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to make context current");
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!wglMakeCurrent(NULL, NULL))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to clear current context");
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapBuffersWGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (!window->monitor)
|
|
||||||
{
|
|
||||||
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
|
|
||||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
|
||||||
{
|
|
||||||
BOOL enabled = FALSE;
|
|
||||||
|
|
||||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
|
||||||
{
|
|
||||||
int count = abs(window->context.wgl.interval);
|
|
||||||
while (count--)
|
|
||||||
DwmFlush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwapBuffers(window->context.wgl.dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapIntervalWGL(int interval)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
|
||||||
|
|
||||||
window->context.wgl.interval = interval;
|
|
||||||
|
|
||||||
if (!window->monitor)
|
|
||||||
{
|
|
||||||
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
|
|
||||||
// Vista and 7 to avoid interfering with DWM vsync
|
|
||||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
|
||||||
{
|
|
||||||
BOOL enabled = FALSE;
|
|
||||||
|
|
||||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
|
||||||
interval = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wgl.EXT_swap_control)
|
|
||||||
wglSwapIntervalEXT(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int extensionSupportedWGL(const char* extension)
|
|
||||||
{
|
|
||||||
const char* extensions = NULL;
|
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringARB)
|
|
||||||
extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
|
|
||||||
else if (_glfw.wgl.GetExtensionsStringEXT)
|
|
||||||
extensions = wglGetExtensionsStringEXT();
|
|
||||||
|
|
||||||
if (!extensions)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
return _glfwStringInExtensionString(extension, extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWglproc getProcAddressWGL(const char* procname)
|
|
||||||
{
|
|
||||||
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
|
|
||||||
if (proc)
|
|
||||||
return proc;
|
|
||||||
|
|
||||||
return (GLFWglproc) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroyContextWGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (window->context.wgl.handle)
|
|
||||||
{
|
|
||||||
wglDeleteContext(window->context.wgl.handle);
|
|
||||||
window->context.wgl.handle = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize WGL
|
|
||||||
//
|
|
||||||
GLFWbool _glfwInitWGL(void)
|
|
||||||
{
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
HGLRC prc, rc;
|
|
||||||
HDC pdc, dc;
|
|
||||||
|
|
||||||
if (_glfw.wgl.instance)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
_glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll");
|
|
||||||
if (!_glfw.wgl.instance)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to load opengl32.dll");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext");
|
|
||||||
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext");
|
|
||||||
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress");
|
|
||||||
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC");
|
|
||||||
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext");
|
|
||||||
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent");
|
|
||||||
_glfw.wgl.ShareLists = (PFN_wglShareLists)
|
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglShareLists");
|
|
||||||
|
|
||||||
// NOTE: A dummy context has to be created for opengl32.dll to load the
|
|
||||||
// OpenGL ICD, from which we can then query WGL extensions
|
|
||||||
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
|
|
||||||
// creation failure occurs during manual pixel format enumeration
|
|
||||||
|
|
||||||
dc = GetDC(_glfw.win32.helperWindowHandle);
|
|
||||||
|
|
||||||
ZeroMemory(&pfd, sizeof(pfd));
|
|
||||||
pfd.nSize = sizeof(pfd);
|
|
||||||
pfd.nVersion = 1;
|
|
||||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
||||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
||||||
pfd.cColorBits = 24;
|
|
||||||
|
|
||||||
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to set pixel format for dummy context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = wglCreateContext(dc);
|
|
||||||
if (!rc)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to create dummy context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdc = wglGetCurrentDC();
|
|
||||||
prc = wglGetCurrentContext();
|
|
||||||
|
|
||||||
if (!wglMakeCurrent(dc, rc))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to make dummy context current");
|
|
||||||
wglMakeCurrent(pdc, prc);
|
|
||||||
wglDeleteContext(rc);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Functions must be loaded first as they're needed to retrieve the
|
|
||||||
// extension string that tells us whether the functions are supported
|
|
||||||
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
|
||||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
|
||||||
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
|
||||||
wglGetProcAddress("wglGetExtensionsStringARB");
|
|
||||||
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
|
||||||
wglGetProcAddress("wglCreateContextAttribsARB");
|
|
||||||
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
|
||||||
wglGetProcAddress("wglSwapIntervalEXT");
|
|
||||||
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
|
||||||
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
|
||||||
|
|
||||||
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
|
||||||
// checked below as we are already using them
|
|
||||||
_glfw.wgl.ARB_multisample =
|
|
||||||
extensionSupportedWGL("WGL_ARB_multisample");
|
|
||||||
_glfw.wgl.ARB_framebuffer_sRGB =
|
|
||||||
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
|
|
||||||
_glfw.wgl.EXT_framebuffer_sRGB =
|
|
||||||
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
|
|
||||||
_glfw.wgl.ARB_create_context =
|
|
||||||
extensionSupportedWGL("WGL_ARB_create_context");
|
|
||||||
_glfw.wgl.ARB_create_context_profile =
|
|
||||||
extensionSupportedWGL("WGL_ARB_create_context_profile");
|
|
||||||
_glfw.wgl.EXT_create_context_es2_profile =
|
|
||||||
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
|
|
||||||
_glfw.wgl.ARB_create_context_robustness =
|
|
||||||
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
|
||||||
_glfw.wgl.ARB_create_context_no_error =
|
|
||||||
extensionSupportedWGL("WGL_ARB_create_context_no_error");
|
|
||||||
_glfw.wgl.EXT_swap_control =
|
|
||||||
extensionSupportedWGL("WGL_EXT_swap_control");
|
|
||||||
_glfw.wgl.EXT_colorspace =
|
|
||||||
extensionSupportedWGL("WGL_EXT_colorspace");
|
|
||||||
_glfw.wgl.ARB_pixel_format =
|
|
||||||
extensionSupportedWGL("WGL_ARB_pixel_format");
|
|
||||||
_glfw.wgl.ARB_context_flush_control =
|
|
||||||
extensionSupportedWGL("WGL_ARB_context_flush_control");
|
|
||||||
|
|
||||||
wglMakeCurrent(pdc, prc);
|
|
||||||
wglDeleteContext(rc);
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate WGL
|
|
||||||
//
|
|
||||||
void _glfwTerminateWGL(void)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.instance)
|
|
||||||
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_ATTRIB(a, v) \
|
|
||||||
{ \
|
|
||||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
|
||||||
attribs[index++] = a; \
|
|
||||||
attribs[index++] = v; \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
|
||||||
//
|
|
||||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
int attribs[40];
|
|
||||||
int pixelFormat;
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
HGLRC share = NULL;
|
|
||||||
|
|
||||||
if (ctxconfig->share)
|
|
||||||
share = ctxconfig->share->context.wgl.handle;
|
|
||||||
|
|
||||||
window->context.wgl.dc = GetDC(window->win32.handle);
|
|
||||||
if (!window->context.wgl.dc)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to retrieve DC for window");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig);
|
|
||||||
if (!pixelFormat)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
|
||||||
pixelFormat, sizeof(pfd), &pfd))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to set selected pixel format");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->forward)
|
|
||||||
{
|
|
||||||
if (!_glfw.wgl.ARB_create_context)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->profile)
|
|
||||||
{
|
|
||||||
if (!_glfw.wgl.ARB_create_context_profile)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!_glfw.wgl.ARB_create_context ||
|
|
||||||
!_glfw.wgl.ARB_create_context_profile ||
|
|
||||||
!_glfw.wgl.EXT_create_context_es2_profile)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_create_context)
|
|
||||||
{
|
|
||||||
int index = 0, mask = 0, flags = 0;
|
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->forward)
|
|
||||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
|
||||||
|
|
||||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
|
||||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
|
||||||
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
|
|
||||||
|
|
||||||
if (ctxconfig->debug)
|
|
||||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
|
||||||
|
|
||||||
if (ctxconfig->robustness)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_create_context_robustness)
|
|
||||||
{
|
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
|
||||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
|
||||||
}
|
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
|
||||||
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
|
||||||
}
|
|
||||||
|
|
||||||
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->release)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_context_flush_control)
|
|
||||||
{
|
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
|
||||||
}
|
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->noerror)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_create_context_no_error)
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
|
||||||
// explicitly requesting version 1.0 does not always return the
|
|
||||||
// highest version supported by the driver
|
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
|
||||||
{
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags)
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags);
|
|
||||||
|
|
||||||
if (mask)
|
|
||||||
SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
|
||||||
|
|
||||||
SET_ATTRIB(0, 0);
|
|
||||||
|
|
||||||
window->context.wgl.handle =
|
|
||||||
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
|
||||||
if (!window->context.wgl.handle)
|
|
||||||
{
|
|
||||||
const DWORD error = GetLastError();
|
|
||||||
|
|
||||||
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
|
|
||||||
{
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Driver does not support OpenGL version %i.%i",
|
|
||||||
ctxconfig->major,
|
|
||||||
ctxconfig->minor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Driver does not support OpenGL ES version %i.%i",
|
|
||||||
ctxconfig->major,
|
|
||||||
ctxconfig->minor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Driver does not support the requested OpenGL profile");
|
|
||||||
}
|
|
||||||
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_VALUE,
|
|
||||||
"WGL: The share context is not compatible with the requested context");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Failed to create OpenGL context");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Failed to create OpenGL ES context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
|
||||||
if (!window->context.wgl.handle)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"WGL: Failed to create OpenGL context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (share)
|
|
||||||
{
|
|
||||||
if (!wglShareLists(share, window->context.wgl.handle))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to enable sharing with specified OpenGL context");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window->context.makeCurrent = makeContextCurrentWGL;
|
|
||||||
window->context.swapBuffers = swapBuffersWGL;
|
|
||||||
window->context.swapInterval = swapIntervalWGL;
|
|
||||||
window->context.extensionSupported = extensionSupportedWGL;
|
|
||||||
window->context.getProcAddress = getProcAddressWGL;
|
|
||||||
window->context.destroy = destroyContextWGL;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef SET_ATTRIB
|
|
||||||
|
|
||||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
|
|
||||||
"WGL: Platform not initialized");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return window->context.wgl.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _GLFW_WIN32
|
|
||||||
|
|
@ -699,6 +699,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingWin32,
|
_glfwSetWindowFloatingWin32,
|
||||||
_glfwSetWindowOpacityWin32,
|
_glfwSetWindowOpacityWin32,
|
||||||
_glfwSetWindowMousePassthroughWin32,
|
_glfwSetWindowMousePassthroughWin32,
|
||||||
|
_glfwGetPOSIXLoopFdsWin32,
|
||||||
_glfwPollEventsWin32,
|
_glfwPollEventsWin32,
|
||||||
_glfwWaitEventsWin32,
|
_glfwWaitEventsWin32,
|
||||||
_glfwWaitEventsTimeoutWin32,
|
_glfwWaitEventsTimeoutWin32,
|
||||||
@ -758,10 +759,6 @@ void _glfwTerminateWin32(void)
|
|||||||
_glfw_free(_glfw.win32.clipboardString);
|
_glfw_free(_glfw.win32.clipboardString);
|
||||||
_glfw_free(_glfw.win32.rawInput);
|
_glfw_free(_glfw.win32.rawInput);
|
||||||
|
|
||||||
// _glfwTerminateWGL();
|
|
||||||
// _glfwTerminateEGL();
|
|
||||||
// _glfwTerminateOSMesa();
|
|
||||||
|
|
||||||
freeLibraries();
|
freeLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +564,8 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform);
|
|||||||
int _glfwInitWin32(void);
|
int _glfwInitWin32(void);
|
||||||
void _glfwTerminateWin32(void);
|
void _glfwTerminateWin32(void);
|
||||||
|
|
||||||
|
struct pollfd *_glfwGetPOSIXLoopFdsWin32(unsigned int *pCount);
|
||||||
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
||||||
|
@ -38,6 +38,12 @@
|
|||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
struct pollfd* _glfwGetPOSIXLoopFdsWin32(unsigned int* pCount)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Converts utf16 units to Unicode code points (UTF32).
|
// Converts utf16 units to Unicode code points (UTF32).
|
||||||
// Returns GLFW_TRUE when the converting completes and the result is assigned to
|
// Returns GLFW_TRUE when the converting completes and the result is assigned to
|
||||||
// the argument `codepoint`.
|
// the argument `codepoint`.
|
||||||
@ -2874,7 +2880,7 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
|
|||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
|
"Win32: Vulkan instance missing VK_KHR_win32_surface extension");
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sci, 0, sizeof(sci));
|
memset(&sci, 0, sizeof(sci));
|
||||||
@ -2887,10 +2893,10 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
|
|||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create Vulkan surface: %s",
|
"Win32: Failed to create Vulkan surface: %s",
|
||||||
_glfwGetVulkanResultString(err));
|
"unk");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
||||||
|
@ -1133,6 +1133,12 @@ GLFWAPI void glfwPollEvents(void)
|
|||||||
_glfw.platform.pollEvents();
|
_glfw.platform.pollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI struct pollfd* glfwGetPOSIXLoopFds(unsigned int* pCount)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
return _glfw.platform.getPOSIXLoopFds(pCount);
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwWaitEvents(void)
|
GLFWAPI void glfwWaitEvents(void)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
@ -488,6 +488,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingWayland,
|
_glfwSetWindowFloatingWayland,
|
||||||
_glfwSetWindowOpacityWayland,
|
_glfwSetWindowOpacityWayland,
|
||||||
_glfwSetWindowMousePassthroughWayland,
|
_glfwSetWindowMousePassthroughWayland,
|
||||||
|
_glfwGetPOSIXLoopFdsWayland,
|
||||||
_glfwPollEventsWayland,
|
_glfwPollEventsWayland,
|
||||||
_glfwWaitEventsWayland,
|
_glfwWaitEventsWayland,
|
||||||
_glfwWaitEventsTimeoutWayland,
|
_glfwWaitEventsTimeoutWayland,
|
||||||
@ -847,9 +848,6 @@ int _glfwInitWayland(void)
|
|||||||
|
|
||||||
void _glfwTerminateWayland(void)
|
void _glfwTerminateWayland(void)
|
||||||
{
|
{
|
||||||
_glfwTerminateEGL();
|
|
||||||
_glfwTerminateOSMesa();
|
|
||||||
|
|
||||||
if (_glfw.wl.libdecor.context)
|
if (_glfw.wl.libdecor.context)
|
||||||
libdecor_unref(_glfw.wl.libdecor.context);
|
libdecor_unref(_glfw.wl.libdecor.context);
|
||||||
|
|
||||||
|
@ -612,6 +612,8 @@ typedef struct _GLFWcursorWayland
|
|||||||
int currentImage;
|
int currentImage;
|
||||||
} _GLFWcursorWayland;
|
} _GLFWcursorWayland;
|
||||||
|
|
||||||
|
struct pollfd *_glfwGetPOSIXLoopFdsWayland(unsigned int *pCount);
|
||||||
|
|
||||||
GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform);
|
GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform);
|
||||||
int _glfwInitWayland(void);
|
int _glfwInitWayland(void);
|
||||||
void _glfwTerminateWayland(void);
|
void _glfwTerminateWayland(void);
|
||||||
|
@ -1112,14 +1112,14 @@ static void inputText(_GLFWwindow* window, uint32_t scancode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleEvents(double* timeout)
|
static struct pollfd gFds[4];
|
||||||
{
|
|
||||||
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
struct pollfd* _glfwGetPOSIXLoopFdsWayland(unsigned int *pCount)
|
||||||
if (_glfw.joysticksInitialized)
|
{
|
||||||
_glfwDetectJoystickConnectionLinux();
|
if (!pCount) {
|
||||||
#endif
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWbool event = GLFW_FALSE;
|
|
||||||
struct pollfd fds[4] =
|
struct pollfd fds[4] =
|
||||||
{
|
{
|
||||||
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||||
@ -1128,8 +1128,27 @@ static void handleEvents(double* timeout)
|
|||||||
{ -1, POLLIN }
|
{ -1, POLLIN }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_glfw.wl.libdecor.context)
|
*pCount = 3;
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.context) {
|
||||||
fds[3].fd = libdecor_get_fd(_glfw.wl.libdecor.context);
|
fds[3].fd = libdecor_get_fd(_glfw.wl.libdecor.context);
|
||||||
|
*pCount = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(gFds, fds, sizeof(gFds));
|
||||||
|
return gFds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleEvents(double* timeout)
|
||||||
|
{
|
||||||
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
|
if (_glfw.joysticksInitialized)
|
||||||
|
_glfwDetectJoystickConnectionLinux();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLFWbool event = GLFW_FALSE;
|
||||||
|
unsigned int fdCount;
|
||||||
|
struct pollfd* fds = _glfwGetPOSIXLoopFds(&fdCount);
|
||||||
|
|
||||||
while (!event)
|
while (!event)
|
||||||
{
|
{
|
||||||
@ -1152,7 +1171,7 @@ static void handleEvents(double* timeout)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))
|
if (!_glfwPollPOSIX(fds, fdCount, timeout))
|
||||||
{
|
{
|
||||||
wl_display_cancel_read(_glfw.wl.display);
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
return;
|
return;
|
||||||
@ -2406,38 +2425,6 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
if (!createNativeSurface(window, wndconfig, fbconfig))
|
if (!createNativeSurface(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
|
|
||||||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
window->wl.egl.window = wl_egl_window_create(window->wl.surface,
|
|
||||||
wndconfig->width,
|
|
||||||
wndconfig->height);
|
|
||||||
if (!window->wl.egl.window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Wayland: Failed to create EGL window");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wndconfig->mousePassthrough)
|
if (wndconfig->mousePassthrough)
|
||||||
_glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE);
|
_glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE);
|
||||||
|
|
||||||
@ -3581,7 +3568,7 @@ VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance,
|
|||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Failed to create Vulkan surface: %s",
|
"Wayland: Failed to create Vulkan surface: %s",
|
||||||
_glfwGetVulkanResultString(err));
|
"unk");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -1247,6 +1247,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
|||||||
_glfwSetWindowFloatingX11,
|
_glfwSetWindowFloatingX11,
|
||||||
_glfwSetWindowOpacityX11,
|
_glfwSetWindowOpacityX11,
|
||||||
_glfwSetWindowMousePassthroughX11,
|
_glfwSetWindowMousePassthroughX11,
|
||||||
|
_glfwGetPOSIXLoopFdsX11,
|
||||||
_glfwPollEventsX11,
|
_glfwPollEventsX11,
|
||||||
_glfwWaitEventsX11,
|
_glfwWaitEventsX11,
|
||||||
_glfwWaitEventsTimeoutX11,
|
_glfwWaitEventsTimeoutX11,
|
||||||
@ -1650,12 +1651,6 @@ void _glfwTerminateX11(void)
|
|||||||
_glfw.x11.xi.handle = NULL;
|
_glfw.x11.xi.handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwTerminateOSMesa();
|
|
||||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
|
||||||
// cleanup callbacks that get called by that function
|
|
||||||
_glfwTerminateEGL();
|
|
||||||
_glfwTerminateGLX();
|
|
||||||
|
|
||||||
if (_glfw.x11.xlib.handle)
|
if (_glfw.x11.xlib.handle)
|
||||||
{
|
{
|
||||||
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
_glfwPlatformFreeModule(_glfw.x11.xlib.handle);
|
||||||
|
@ -926,6 +926,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform);
|
|||||||
int _glfwInitX11(void);
|
int _glfwInitX11(void);
|
||||||
void _glfwTerminateX11(void);
|
void _glfwTerminateX11(void);
|
||||||
|
|
||||||
|
struct pollfd *_glfwGetPOSIXLoopFdsX11(unsigned int *pCount);
|
||||||
GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
|
GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyWindowX11(_GLFWwindow* window);
|
void _glfwDestroyWindowX11(_GLFWwindow* window);
|
||||||
void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title);
|
void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title);
|
||||||
|
@ -58,6 +58,27 @@
|
|||||||
|
|
||||||
#define _GLFW_XDND_VERSION 5
|
#define _GLFW_XDND_VERSION 5
|
||||||
|
|
||||||
|
static struct pollfd gFds[4];
|
||||||
|
|
||||||
|
struct pollfd* _glfwGetPOSIXLoopFdsX11(unsigned int* pCount)
|
||||||
|
{
|
||||||
|
nfds_t count = 2;
|
||||||
|
struct pollfd fds[3] =
|
||||||
|
{
|
||||||
|
{ ConnectionNumber(_glfw.x11.display), POLLIN },
|
||||||
|
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
|
if (_glfw.joysticksInitialized)
|
||||||
|
fds[count++] = (struct pollfd){ _glfw.linjs.inotify, POLLIN };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pCount = count;
|
||||||
|
memcpy(gFds, fds, sizeof(gFds));
|
||||||
|
return gFds;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for event data to arrive on the X11 display socket
|
// Wait for event data to arrive on the X11 display socket
|
||||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||||
// covers GLX functions
|
// covers GLX functions
|
||||||
@ -81,24 +102,15 @@ static GLFWbool waitForX11Event(double* timeout)
|
|||||||
//
|
//
|
||||||
static GLFWbool waitForAnyEvent(double* timeout)
|
static GLFWbool waitForAnyEvent(double* timeout)
|
||||||
{
|
{
|
||||||
nfds_t count = 2;
|
unsigned int fdCount;
|
||||||
struct pollfd fds[3] =
|
struct pollfd* fds = _glfwGetPOSIXLoopFds(&fdCount);
|
||||||
{
|
|
||||||
{ ConnectionNumber(_glfw.x11.display), POLLIN },
|
|
||||||
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
|
||||||
if (_glfw.joysticksInitialized)
|
|
||||||
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (!XPending(_glfw.x11.display))
|
while (!XPending(_glfw.x11.display))
|
||||||
{
|
{
|
||||||
if (!_glfwPollPOSIX(fds, count, timeout))
|
if (!_glfwPollPOSIX(fds, fdCount, timeout))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
for (int i = 1; i < count; i++)
|
for (int i = 1; i < fdCount; i++)
|
||||||
{
|
{
|
||||||
if (fds[i].revents & POLLIN)
|
if (fds[i].revents & POLLIN)
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -2209,29 +2221,6 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window,
|
|||||||
Visual* visual = NULL;
|
Visual* visual = NULL;
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitGLX())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!visual)
|
if (!visual)
|
||||||
{
|
{
|
||||||
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
||||||
@ -2241,28 +2230,6 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window,
|
|||||||
if (!createNativeWindow(window, wndconfig, visual, depth))
|
if (!createNativeWindow(window, wndconfig, visual, depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
|
||||||
{
|
|
||||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wndconfig->mousePassthrough)
|
if (wndconfig->mousePassthrough)
|
||||||
_glfwSetWindowMousePassthroughX11(window, GLFW_TRUE);
|
_glfwSetWindowMousePassthroughX11(window, GLFW_TRUE);
|
||||||
|
|
||||||
@ -3574,7 +3541,7 @@ VkResult _glfwCreateWindowSurfaceX11(VkInstance instance,
|
|||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: Failed to create Vulkan XCB surface: %s",
|
"X11: Failed to create Vulkan XCB surface: %s",
|
||||||
_glfwGetVulkanResultString(err));
|
"unk");
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -3603,8 +3570,7 @@ VkResult _glfwCreateWindowSurfaceX11(VkInstance instance,
|
|||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: Failed to create Vulkan X11 surface: %s",
|
"X11: Failed to create Vulkan X11 surface: %s", "unk");
|
||||||
_glfwGetVulkanResultString(err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user