Wayland: Apply the same framebuffer selection optimisation
Not as much of a win, since EGL only causes approx 1K getpid() calls of which this optimization eliminates only half
This commit is contained in:
parent
9a97f0bced
commit
8a178ebe55
168
glfw/context.c
vendored
168
glfw/context.c
vendored
@ -173,174 +173,6 @@ bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chooses the framebuffer config that best matches the desired one
|
|
||||||
//
|
|
||||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
|
||||||
const _GLFWfbconfig* alternatives,
|
|
||||||
unsigned int count)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
unsigned int missing, leastMissing = UINT_MAX;
|
|
||||||
unsigned int colorDiff, leastColorDiff = UINT_MAX;
|
|
||||||
unsigned int extraDiff, leastExtraDiff = UINT_MAX;
|
|
||||||
const _GLFWfbconfig* current;
|
|
||||||
const _GLFWfbconfig* closest = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
current = alternatives + i;
|
|
||||||
|
|
||||||
if (desired->stereo > 0 && current->stereo == 0)
|
|
||||||
{
|
|
||||||
// Stereo is a hard constraint
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->doublebuffer != current->doublebuffer)
|
|
||||||
{
|
|
||||||
// Double buffering is a hard constraint
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count number of missing buffers
|
|
||||||
{
|
|
||||||
missing = 0;
|
|
||||||
|
|
||||||
if (desired->alphaBits > 0 && current->alphaBits == 0)
|
|
||||||
missing++;
|
|
||||||
|
|
||||||
if (desired->depthBits > 0 && current->depthBits == 0)
|
|
||||||
missing++;
|
|
||||||
|
|
||||||
if (desired->stencilBits > 0 && current->stencilBits == 0)
|
|
||||||
missing++;
|
|
||||||
|
|
||||||
if (desired->auxBuffers > 0 &&
|
|
||||||
current->auxBuffers < desired->auxBuffers)
|
|
||||||
{
|
|
||||||
missing += desired->auxBuffers - current->auxBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->samples > 0 && current->samples == 0)
|
|
||||||
{
|
|
||||||
// Technically, several multisampling buffers could be
|
|
||||||
// involved, but that's a lower level implementation detail and
|
|
||||||
// not important to us here, so we count them as one
|
|
||||||
missing++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->transparent != current->transparent)
|
|
||||||
missing++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These polynomials make many small channel size differences matter
|
|
||||||
// less than one large channel size difference
|
|
||||||
|
|
||||||
// Calculate color channel size difference value
|
|
||||||
{
|
|
||||||
colorDiff = 0;
|
|
||||||
|
|
||||||
if (desired->redBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
colorDiff += (desired->redBits - current->redBits) *
|
|
||||||
(desired->redBits - current->redBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->greenBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
colorDiff += (desired->greenBits - current->greenBits) *
|
|
||||||
(desired->greenBits - current->greenBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->blueBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
colorDiff += (desired->blueBits - current->blueBits) *
|
|
||||||
(desired->blueBits - current->blueBits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate non-color channel size difference value
|
|
||||||
{
|
|
||||||
extraDiff = 0;
|
|
||||||
|
|
||||||
if (desired->alphaBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->alphaBits - current->alphaBits) *
|
|
||||||
(desired->alphaBits - current->alphaBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->depthBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->depthBits - current->depthBits) *
|
|
||||||
(desired->depthBits - current->depthBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->stencilBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->stencilBits - current->stencilBits) *
|
|
||||||
(desired->stencilBits - current->stencilBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->accumRedBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->accumRedBits - current->accumRedBits) *
|
|
||||||
(desired->accumRedBits - current->accumRedBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->accumGreenBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
|
|
||||||
(desired->accumGreenBits - current->accumGreenBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->accumBlueBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
|
|
||||||
(desired->accumBlueBits - current->accumBlueBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->accumAlphaBits != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
|
|
||||||
(desired->accumAlphaBits - current->accumAlphaBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->samples != GLFW_DONT_CARE)
|
|
||||||
{
|
|
||||||
extraDiff += (desired->samples - current->samples) *
|
|
||||||
(desired->samples - current->samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->sRGB && !current->sRGB)
|
|
||||||
extraDiff++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out if the current one is better than the best one found so far
|
|
||||||
// Least number of missing buffers is the most important heuristic,
|
|
||||||
// then color buffer size match and lastly size match for other buffers
|
|
||||||
|
|
||||||
if (missing < leastMissing)
|
|
||||||
closest = current;
|
|
||||||
else if (missing == leastMissing)
|
|
||||||
{
|
|
||||||
if ((colorDiff < leastColorDiff) ||
|
|
||||||
(colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
|
|
||||||
{
|
|
||||||
closest = current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == closest)
|
|
||||||
{
|
|
||||||
leastMissing = missing;
|
|
||||||
leastColorDiff = colorDiff;
|
|
||||||
leastExtraDiff = extraDiff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return closest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieves the attributes of the current context
|
// Retrieves the attributes of the current context
|
||||||
//
|
//
|
||||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||||
|
|||||||
98
glfw/egl_context.c
vendored
98
glfw/egl_context.c
vendored
@ -76,6 +76,7 @@ static const char* getEGLErrorString(EGLint error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _GLFW_X11
|
||||||
// Returns the specified attribute of the specified EGLConfig
|
// Returns the specified attribute of the specified EGLConfig
|
||||||
//
|
//
|
||||||
static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
||||||
@ -84,6 +85,7 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
|||||||
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
|
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return the EGLConfig most closely matching the specified hints
|
// Return the EGLConfig most closely matching the specified hints
|
||||||
//
|
//
|
||||||
@ -91,39 +93,44 @@ static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
const _GLFWfbconfig* desired,
|
const _GLFWfbconfig* desired,
|
||||||
EGLConfig* result)
|
EGLConfig* result)
|
||||||
{
|
{
|
||||||
EGLConfig* nativeConfigs;
|
EGLConfig configs[512];
|
||||||
_GLFWfbconfig* usableConfigs;
|
int i = 0, nativeCount = 0, ans_idx = 0;
|
||||||
const _GLFWfbconfig* closest;
|
EGLint attributes[64];
|
||||||
int i, nativeCount, usableCount;
|
#define ATTR(k, v) { attributes[i++] = k; attributes[i++] = v; }
|
||||||
|
ATTR(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
|
||||||
|
ATTR(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API) {
|
||||||
|
if (ctxconfig->major == 1) ATTR(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT)
|
||||||
|
else ATTR(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->client == GLFW_OPENGL_API) ATTR(EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
|
||||||
|
if (desired->samples > 0) ATTR(EGL_SAMPLES, desired->samples);
|
||||||
|
if (desired->depthBits > 0) ATTR(EGL_DEPTH_SIZE, desired->depthBits);
|
||||||
|
if (desired->stencilBits > 0) ATTR(EGL_STENCIL_SIZE, desired->stencilBits);
|
||||||
|
if (desired->redBits > 0) ATTR(EGL_RED_SIZE, desired->redBits);
|
||||||
|
if (desired->greenBits > 0) ATTR(EGL_GREEN_SIZE, desired->greenBits);
|
||||||
|
if (desired->blueBits > 0) ATTR(EGL_BLUE_SIZE, desired->blueBits);
|
||||||
|
if (desired->alphaBits > 0) ATTR(EGL_ALPHA_SIZE, desired->alphaBits);
|
||||||
|
ATTR(EGL_NONE, EGL_NONE);
|
||||||
|
#undef ATTR
|
||||||
|
if (!eglChooseConfig(_glfw.egl.display, attributes, configs, sizeof(configs)/sizeof(configs[0]), &nativeCount)) {
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: eglChooseConfig failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
|
||||||
if (!nativeCount)
|
if (!nativeCount)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
|
|
||||||
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
|
|
||||||
|
|
||||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
|
||||||
usableCount = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nativeCount; i++)
|
for (i = 0; i < nativeCount; i++)
|
||||||
{
|
{
|
||||||
const EGLConfig n = nativeConfigs[i];
|
|
||||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
|
||||||
|
|
||||||
// Only consider RGB(A) EGLConfigs
|
|
||||||
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Only consider window EGLConfigs
|
|
||||||
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
{
|
{
|
||||||
|
const EGLConfig n = configs[i];
|
||||||
XVisualInfo vi = {0};
|
XVisualInfo vi = {0};
|
||||||
|
|
||||||
// Only consider EGLConfigs with associated Visuals
|
// Only consider EGLConfigs with associated Visuals
|
||||||
@ -138,55 +145,18 @@ static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
|
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
|
||||||
if (vis)
|
if (vis)
|
||||||
{
|
{
|
||||||
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
bool transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
||||||
XFree(vis);
|
XFree(vis);
|
||||||
|
if (!transparent) continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
ans_idx = i;
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
break;
|
||||||
{
|
|
||||||
if (ctxconfig->major == 1)
|
|
||||||
{
|
|
||||||
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
*result = configs[ans_idx];
|
||||||
{
|
return true;
|
||||||
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ctxconfig->client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
|
|
||||||
u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
|
|
||||||
u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
|
|
||||||
|
|
||||||
u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
|
|
||||||
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
|
|
||||||
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
|
|
||||||
|
|
||||||
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
|
|
||||||
u->doublebuffer = true;
|
|
||||||
|
|
||||||
u->handle = (uintptr_t) n;
|
|
||||||
usableCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
|
||||||
if (closest)
|
|
||||||
*result = (EGLConfig) closest->handle;
|
|
||||||
|
|
||||||
free(nativeConfigs);
|
|
||||||
free(usableConfigs);
|
|
||||||
|
|
||||||
return closest != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void makeContextCurrentEGL(_GLFWwindow* window)
|
static void makeContextCurrentEGL(_GLFWwindow* window)
|
||||||
@ -340,6 +310,7 @@ bool _glfwInitEGL(void)
|
|||||||
|
|
||||||
glfw_dlsym(_glfw.egl.GetConfigAttrib, _glfw.egl.handle, "eglGetConfigAttrib");
|
glfw_dlsym(_glfw.egl.GetConfigAttrib, _glfw.egl.handle, "eglGetConfigAttrib");
|
||||||
glfw_dlsym(_glfw.egl.GetConfigs, _glfw.egl.handle, "eglGetConfigs");
|
glfw_dlsym(_glfw.egl.GetConfigs, _glfw.egl.handle, "eglGetConfigs");
|
||||||
|
glfw_dlsym(_glfw.egl.ChooseConfig, _glfw.egl.handle, "eglChooseConfig");
|
||||||
glfw_dlsym(_glfw.egl.GetDisplay, _glfw.egl.handle, "eglGetDisplay");
|
glfw_dlsym(_glfw.egl.GetDisplay, _glfw.egl.handle, "eglGetDisplay");
|
||||||
glfw_dlsym(_glfw.egl.GetError, _glfw.egl.handle, "eglGetError");
|
glfw_dlsym(_glfw.egl.GetError, _glfw.egl.handle, "eglGetError");
|
||||||
glfw_dlsym(_glfw.egl.Initialize, _glfw.egl.handle, "eglInitialize");
|
glfw_dlsym(_glfw.egl.Initialize, _glfw.egl.handle, "eglInitialize");
|
||||||
@ -357,6 +328,7 @@ bool _glfwInitEGL(void)
|
|||||||
|
|
||||||
if (!_glfw.egl.GetConfigAttrib ||
|
if (!_glfw.egl.GetConfigAttrib ||
|
||||||
!_glfw.egl.GetConfigs ||
|
!_glfw.egl.GetConfigs ||
|
||||||
|
!_glfw.egl.ChooseConfig ||
|
||||||
!_glfw.egl.GetDisplay ||
|
!_glfw.egl.GetDisplay ||
|
||||||
!_glfw.egl.GetError ||
|
!_glfw.egl.GetError ||
|
||||||
!_glfw.egl.Initialize ||
|
!_glfw.egl.Initialize ||
|
||||||
|
|||||||
3
glfw/egl_context.h
vendored
3
glfw/egl_context.h
vendored
@ -120,6 +120,7 @@ typedef void* EGLSurface;
|
|||||||
// EGL function pointer typedefs
|
// EGL function pointer typedefs
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGLConfig*,EGLint,EGLint*);
|
||||||
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
|
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
|
||||||
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
|
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
|
||||||
@ -136,6 +137,7 @@ typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
|
|||||||
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
|
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
|
||||||
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
|
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
|
||||||
#define eglGetConfigs _glfw.egl.GetConfigs
|
#define eglGetConfigs _glfw.egl.GetConfigs
|
||||||
|
#define eglChooseConfig _glfw.egl.ChooseConfig
|
||||||
#define eglGetDisplay _glfw.egl.GetDisplay
|
#define eglGetDisplay _glfw.egl.GetDisplay
|
||||||
#define eglGetError _glfw.egl.GetError
|
#define eglGetError _glfw.egl.GetError
|
||||||
#define eglInitialize _glfw.egl.Initialize
|
#define eglInitialize _glfw.egl.Initialize
|
||||||
@ -185,6 +187,7 @@ typedef struct _GLFWlibraryEGL
|
|||||||
|
|
||||||
PFN_eglGetConfigAttrib GetConfigAttrib;
|
PFN_eglGetConfigAttrib GetConfigAttrib;
|
||||||
PFN_eglGetConfigs GetConfigs;
|
PFN_eglGetConfigs GetConfigs;
|
||||||
|
PFN_eglChooseConfig ChooseConfig;
|
||||||
PFN_eglGetDisplay GetDisplay;
|
PFN_eglGetDisplay GetDisplay;
|
||||||
PFN_eglGetError GetError;
|
PFN_eglGetError GetError;
|
||||||
PFN_eglInitialize Initialize;
|
PFN_eglInitialize Initialize;
|
||||||
|
|||||||
3
glfw/internal.h
vendored
3
glfw/internal.h
vendored
@ -794,9 +794,6 @@ void _glfwDebug(const char* format, ...);
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool _glfwStringInExtensionString(const char* string, const char* extensions);
|
bool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
|
||||||
const _GLFWfbconfig* alternatives,
|
|
||||||
unsigned int count);
|
|
||||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig);
|
const _GLFWctxconfig* ctxconfig);
|
||||||
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user