X11: Further reduce startup time
Use the GLX 1.3 API function to choose the best framebuffer config instead of doing it ourselves. Reduces the number fo getpid() calls by a further ~15K
This commit is contained in:
parent
5c7471910d
commit
9a97f0bced
110
glfw/glx_context.c
vendored
110
glfw/glx_context.c
vendored
@ -47,21 +47,46 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLXFBConfig*
|
||||||
|
choose_fb_config(const _GLFWfbconfig* desired, bool trust_window_bit, int *nelements) {
|
||||||
|
int attrib_list[64];
|
||||||
|
int pos = 0;
|
||||||
|
#define ATTR(x, y) { attrib_list[pos++] = x; attrib_list[pos++] = y; }
|
||||||
|
|
||||||
|
ATTR(GLX_DOUBLEBUFFER, desired->doublebuffer ? True : False);
|
||||||
|
if (desired->stereo > 0) ATTR(GLX_STEREO, desired->stereo ? True : False);
|
||||||
|
if (desired->auxBuffers > 0) ATTR(GLX_AUX_BUFFERS, desired->auxBuffers);
|
||||||
|
if (_glfw.glx.ARB_multisample && desired->samples > 0) ATTR(GLX_SAMPLES, desired->samples);
|
||||||
|
if (desired->depthBits != GLFW_DONT_CARE) ATTR(GLX_DEPTH_SIZE, desired->depthBits);
|
||||||
|
if (desired->stencilBits != GLFW_DONT_CARE) ATTR(GLX_STENCIL_SIZE, desired->stencilBits);
|
||||||
|
if (desired->redBits != GLFW_DONT_CARE) ATTR(GLX_RED_SIZE, desired->redBits);
|
||||||
|
if (desired->greenBits != GLFW_DONT_CARE) ATTR(GLX_GREEN_SIZE, desired->greenBits);
|
||||||
|
if (desired->blueBits != GLFW_DONT_CARE) ATTR(GLX_BLUE_SIZE, desired->blueBits);
|
||||||
|
if (desired->alphaBits != GLFW_DONT_CARE) ATTR(GLX_ALPHA_SIZE, desired->alphaBits);
|
||||||
|
if (desired->accumRedBits != GLFW_DONT_CARE) ATTR(GLX_ACCUM_RED_SIZE, desired->accumRedBits);
|
||||||
|
if (desired->accumGreenBits != GLFW_DONT_CARE) ATTR(GLX_ACCUM_GREEN_SIZE, desired->accumGreenBits);
|
||||||
|
if (desired->accumBlueBits != GLFW_DONT_CARE) ATTR(GLX_ACCUM_BLUE_SIZE, desired->accumBlueBits);
|
||||||
|
if (desired->accumAlphaBits != GLFW_DONT_CARE) ATTR(GLX_ACCUM_ALPHA_SIZE, desired->accumAlphaBits);
|
||||||
|
if (!trust_window_bit) ATTR(GLX_DRAWABLE_TYPE, 0);
|
||||||
|
ATTR(None, None);
|
||||||
|
return glXChooseFBConfig(_glfw.x11.display, _glfw.x11.screen, attrib_list, nelements);
|
||||||
|
#undef ATTR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return the GLXFBConfig most closely matching the specified hints
|
// Return the GLXFBConfig most closely matching the specified hints
|
||||||
//
|
//
|
||||||
static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||||
GLXFBConfig* result)
|
GLXFBConfig* result)
|
||||||
{
|
{
|
||||||
GLXFBConfig* nativeConfigs;
|
GLXFBConfig* nativeConfigs;
|
||||||
_GLFWfbconfig* usableConfigs;
|
int i, nativeCount, ans_idx = 0;
|
||||||
const _GLFWfbconfig* closest;
|
|
||||||
int i, nativeCount, usableCount;
|
|
||||||
const char* vendor;
|
const char* vendor;
|
||||||
bool trustWindowBit = true;
|
bool trustWindowBit = true;
|
||||||
static _GLFWfbconfig prev_desired = {0};
|
static _GLFWfbconfig prev_desired = {0};
|
||||||
static uintptr_t prev_result = 0;
|
static GLXFBConfig prev_result = 0;
|
||||||
if (prev_result != 0 && memcmp(&prev_desired, desired, sizeof(_GLFWfbconfig)) == 0) {
|
if (prev_result != 0 && memcmp(&prev_desired, desired, sizeof(_GLFWfbconfig)) == 0) {
|
||||||
*result = (GLXFBConfig)prev_result;
|
*result = prev_result;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
prev_desired = *desired;
|
prev_desired = *desired;
|
||||||
@ -71,84 +96,38 @@ static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
|||||||
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
||||||
if (vendor && strcmp(vendor, "Chromium") == 0)
|
if (vendor && strcmp(vendor, "Chromium") == 0)
|
||||||
trustWindowBit = false;
|
trustWindowBit = false;
|
||||||
|
nativeConfigs = choose_fb_config(desired, trustWindowBit, &nativeCount);
|
||||||
nativeConfigs =
|
|
||||||
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
|
||||||
if (!nativeConfigs || !nativeCount)
|
if (!nativeConfigs || !nativeCount)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
|
||||||
usableCount = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nativeCount; i++)
|
for (i = 0; i < nativeCount; i++)
|
||||||
{
|
{
|
||||||
const GLXFBConfig n = nativeConfigs[i];
|
const GLXFBConfig n = nativeConfigs[i];
|
||||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
bool transparency_matches = true, srgb_matches = true;
|
||||||
|
if (desired->transparent) {
|
||||||
// Only consider RGBA GLXFBConfigs
|
transparency_matches = false;
|
||||||
if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Only consider window GLXFBConfigs
|
|
||||||
if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
|
|
||||||
{
|
|
||||||
if (trustWindowBit)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desired->transparent)
|
|
||||||
{
|
|
||||||
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
||||||
if (vi)
|
if (vi && _glfwIsVisualTransparentX11(vi->visual)) transparency_matches = true;
|
||||||
{
|
|
||||||
u->transparent = _glfwIsVisualTransparentX11(vi->visual);
|
|
||||||
XFree(vi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
|
if (desired->sRGB && (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)) {
|
||||||
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
|
srgb_matches = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB) ? true : false;
|
||||||
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
|
}
|
||||||
|
|
||||||
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
|
if (transparency_matches && srgb_matches) {
|
||||||
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
|
ans_idx = i; break;
|
||||||
u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
|
}
|
||||||
|
|
||||||
u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
|
|
||||||
u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
|
|
||||||
u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
|
|
||||||
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
|
|
||||||
|
|
||||||
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
|
|
||||||
|
|
||||||
if (getGLXFBConfigAttrib(n, GLX_STEREO))
|
|
||||||
u->stereo = true;
|
|
||||||
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
|
|
||||||
u->doublebuffer = true;
|
|
||||||
|
|
||||||
if (_glfw.glx.ARB_multisample)
|
|
||||||
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
|
|
||||||
|
|
||||||
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
|
|
||||||
u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
|
||||||
|
|
||||||
u->handle = (uintptr_t) n;
|
|
||||||
usableCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
*result = nativeConfigs[ans_idx];
|
||||||
if (closest) {
|
prev_result = nativeConfigs[ans_idx];
|
||||||
*result = (GLXFBConfig) closest->handle;
|
|
||||||
prev_result = (uintptr_t) closest->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(nativeConfigs);
|
XFree(nativeConfigs);
|
||||||
free(usableConfigs);
|
|
||||||
|
|
||||||
return closest != NULL;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL context using legacy API
|
// Create the OpenGL context using legacy API
|
||||||
@ -296,6 +275,7 @@ bool _glfwInitGLX(void)
|
|||||||
|
|
||||||
glfw_dlsym(_glfw.glx.GetFBConfigs, _glfw.glx.handle, "glXGetFBConfigs");
|
glfw_dlsym(_glfw.glx.GetFBConfigs, _glfw.glx.handle, "glXGetFBConfigs");
|
||||||
glfw_dlsym(_glfw.glx.GetFBConfigAttrib, _glfw.glx.handle, "glXGetFBConfigAttrib");
|
glfw_dlsym(_glfw.glx.GetFBConfigAttrib, _glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||||
|
glfw_dlsym(_glfw.glx.ChooseFBConfig, _glfw.glx.handle, "glXChooseFBConfig");
|
||||||
glfw_dlsym(_glfw.glx.GetClientString, _glfw.glx.handle, "glXGetClientString");
|
glfw_dlsym(_glfw.glx.GetClientString, _glfw.glx.handle, "glXGetClientString");
|
||||||
glfw_dlsym(_glfw.glx.QueryExtension, _glfw.glx.handle, "glXQueryExtension");
|
glfw_dlsym(_glfw.glx.QueryExtension, _glfw.glx.handle, "glXQueryExtension");
|
||||||
glfw_dlsym(_glfw.glx.QueryVersion, _glfw.glx.handle, "glXQueryVersion");
|
glfw_dlsym(_glfw.glx.QueryVersion, _glfw.glx.handle, "glXQueryVersion");
|
||||||
|
|||||||
3
glfw/glx_context.h
vendored
3
glfw/glx_context.h
vendored
@ -73,6 +73,7 @@ typedef struct __GLXcontext* GLXContext;
|
|||||||
typedef void (*__GLXextproc)(void);
|
typedef void (*__GLXextproc)(void);
|
||||||
|
|
||||||
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
||||||
|
typedef GLXFBConfig* (*PFNGLXCHOOSEFBCONFIGPROC)(Display*,int,const int*,int*);
|
||||||
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
||||||
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||||
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
|
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
|
||||||
@ -95,6 +96,7 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX
|
|||||||
// libGL.so function pointer typedefs
|
// libGL.so function pointer typedefs
|
||||||
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
||||||
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
||||||
|
#define glXChooseFBConfig _glfw.glx.ChooseFBConfig
|
||||||
#define glXGetClientString _glfw.glx.GetClientString
|
#define glXGetClientString _glfw.glx.GetClientString
|
||||||
#define glXQueryExtension _glfw.glx.QueryExtension
|
#define glXQueryExtension _glfw.glx.QueryExtension
|
||||||
#define glXQueryVersion _glfw.glx.QueryVersion
|
#define glXQueryVersion _glfw.glx.QueryVersion
|
||||||
@ -134,6 +136,7 @@ typedef struct _GLFWlibraryGLX
|
|||||||
// GLX 1.3 functions
|
// GLX 1.3 functions
|
||||||
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
|
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
|
||||||
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
|
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
|
||||||
|
PFNGLXCHOOSEFBCONFIGPROC ChooseFBConfig;
|
||||||
PFNGLXGETCLIENTSTRINGPROC GetClientString;
|
PFNGLXGETCLIENTSTRINGPROC GetClientString;
|
||||||
PFNGLXQUERYEXTENSIONPROC QueryExtension;
|
PFNGLXQUERYEXTENSIONPROC QueryExtension;
|
||||||
PFNGLXQUERYVERSIONPROC QueryVersion;
|
PFNGLXQUERYVERSIONPROC QueryVersion;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user