mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
Query glX* functions before getting the context to fix GL3 driver
The GL3 context is created using the glXCreateContextAttribs function which is part of the GLX_ARB_create_context extension. However previously the function pointers from GLX extensions were only retrieved once the GL context is created. That meant that the GL3 context creation function would always assume that the extension is not supported so it would always fail. This patch changes it to query the functions when the renderer is set up instead. The base winsys feature flags that are determined while querying the functions are stored in a member of CoglGLXRenderer. These are then copied to the CoglContext when it is initialised. The spec for glXGetProcAddress says that the functions returned are context-independent. That implies that it is safe to call it without binding a context although that is not explicitly stated as far as I can tell. A big of googling finds this DRI documentation which says it can be used without a context: http://dri.freedesktop.org/wiki/glXGetProcAddressNeverReturnsNULL And also this code sample: http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_%28GLX%29 One point that makes me concerned that this might not always work in practice is that the code in SDL2 to create a GL3 context first creates a dummy GL2 context in order to have something bound before it calls glXGetProcAddress. I think this may just be a misunderstanding based on how wglGetProcAddress works however. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 04a7aca9a98e84e43ac5559305a1358112902e30)
This commit is contained in:
parent
1e6ec66330
commit
fe3aa8b8b3
@ -45,61 +45,35 @@ typedef struct _CoglGLXRenderer
|
|||||||
/* GModule pointing to libGL which we use to get glX functions out of */
|
/* GModule pointing to libGL which we use to get glX functions out of */
|
||||||
GModule *libgl_module;
|
GModule *libgl_module;
|
||||||
|
|
||||||
|
/* Copy of the winsys features that are based purely on the
|
||||||
|
* information we can get without using a GL context. We want to
|
||||||
|
* determine this before we have a context so that we can use the
|
||||||
|
* function pointers from the extensions earlier. This is necessary
|
||||||
|
* to use the glXCreateContextAttribs function. */
|
||||||
|
unsigned long base_winsys_features
|
||||||
|
[COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)];
|
||||||
|
|
||||||
|
CoglFeatureFlags legacy_feature_flags;
|
||||||
|
|
||||||
/* Function pointers for core GLX functionality. We can't just link
|
/* Function pointers for core GLX functionality. We can't just link
|
||||||
against these directly because we need to conditionally load
|
against these directly because we need to conditionally load
|
||||||
libGL when we are using GLX so that it won't conflict with a GLES
|
libGL when we are using GLX so that it won't conflict with a GLES
|
||||||
library if we are using EGL + GLES */
|
library if we are using EGL + GLES. These are just the functions
|
||||||
void
|
that we want to use before calling glXGetProcAddress */
|
||||||
(* glXDestroyContext) (Display *dpy, GLXContext ctx);
|
|
||||||
void
|
|
||||||
(* glXSwapBuffers) (Display *dpy, GLXDrawable drawable);
|
|
||||||
Bool
|
Bool
|
||||||
(* glXQueryExtension) (Display *dpy, int *errorb, int *event);
|
(* glXQueryExtension) (Display *dpy, int *errorb, int *event);
|
||||||
const char *
|
const char *
|
||||||
(* glXQueryExtensionsString) (Display *dpy, int screen);
|
(* glXQueryExtensionsString) (Display *dpy, int screen);
|
||||||
Bool
|
Bool
|
||||||
(* glXQueryVersion) (Display *dpy, int *maj, int *min);
|
(* glXQueryVersion) (Display *dpy, int *maj, int *min);
|
||||||
Bool
|
|
||||||
(* glXIsDirect) (Display *dpy, GLXContext ctx);
|
|
||||||
int
|
|
||||||
(* glXGetFBConfigAttrib) (Display *dpy, GLXFBConfig config,
|
|
||||||
int attribute, int *value);
|
|
||||||
GLXWindow
|
|
||||||
(* glXCreateWindow) (Display *dpy, GLXFBConfig config,
|
|
||||||
Window win, const int *attribList);
|
|
||||||
void
|
|
||||||
(* glXDestroyWindow) (Display *dpy, GLXWindow window);
|
|
||||||
GLXPixmap
|
|
||||||
(* glXCreatePixmap) (Display *dpy, GLXFBConfig config,
|
|
||||||
Pixmap pixmap, const int *attribList);
|
|
||||||
void
|
|
||||||
(* glXDestroyPixmap) (Display *dpy, GLXPixmap pixmap);
|
|
||||||
GLXContext
|
|
||||||
(* glXCreateNewContext) (Display *dpy, GLXFBConfig config,
|
|
||||||
int renderType, GLXContext shareList,
|
|
||||||
Bool direct);
|
|
||||||
Bool
|
|
||||||
(* glXMakeContextCurrent) (Display *dpy, GLXDrawable draw,
|
|
||||||
GLXDrawable read, GLXContext ctx);
|
|
||||||
void
|
|
||||||
(* glXSelectEvent) (Display *dpy, GLXDrawable drawable,
|
|
||||||
unsigned long mask);
|
|
||||||
GLXFBConfig *
|
|
||||||
(* glXGetFBConfigs) (Display *dpy, int screen, int *nelements);
|
|
||||||
GLXFBConfig *
|
|
||||||
(* glXChooseFBConfig) (Display *dpy, int screen,
|
|
||||||
const int *attrib_list, int *nelements);
|
|
||||||
XVisualInfo *
|
|
||||||
(* glXGetVisualFromFBConfig) (Display *dpy, GLXFBConfig config);
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
(* glXGetProcAddress) (const GLubyte *procName);
|
(* glXGetProcAddress) (const GLubyte *procName);
|
||||||
|
|
||||||
/* Function pointers for GLX specific extensions */
|
/* Function pointers for GLX specific extensions */
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
|
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g)
|
||||||
|
|
||||||
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
|
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
|
||||||
ret (APIENTRY * pf_ ## name) args;
|
ret (APIENTRY * name) args;
|
||||||
|
|
||||||
#define COGL_WINSYS_FEATURE_END()
|
#define COGL_WINSYS_FEATURE_END()
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Macro prototypes:
|
/* Macro prototypes:
|
||||||
* COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names,
|
* COGL_WINSYS_FEATURE_BEGIN (major_glx_version, minor_glx_version,
|
||||||
|
* name, namespaces, extension_names,
|
||||||
* implied_public_feature_flags,
|
* implied_public_feature_flags,
|
||||||
* implied_private_feature_flags,
|
|
||||||
* implied_winsys_feature)
|
* implied_winsys_feature)
|
||||||
* COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name,
|
* COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name,
|
||||||
* (arguments))
|
* (arguments))
|
||||||
@ -43,11 +43,56 @@
|
|||||||
* XXX: NB: Don't add a trailing semicolon when using these macros
|
* XXX: NB: Don't add a trailing semicolon when using these macros
|
||||||
*/
|
*/
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (texture_from_pixmap,
|
/* Base functions that we assume are always available */
|
||||||
|
COGL_WINSYS_FEATURE_BEGIN (0, 0, /* always available */
|
||||||
|
base_glx_functions,
|
||||||
|
"\0",
|
||||||
|
"\0",
|
||||||
|
0, /* no implied public feature */
|
||||||
|
0 /* no winsys feature */)
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyContext,
|
||||||
|
(Display *dpy, GLXContext ctx))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXSwapBuffers,
|
||||||
|
(Display *dpy, GLXDrawable drawable))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (Bool, glXIsDirect,
|
||||||
|
(Display *dpy, GLXContext ctx))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (int, glXGetFBConfigAttrib,
|
||||||
|
(Display *dpy, GLXFBConfig config,
|
||||||
|
int attribute, int *value))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (GLXWindow, glXCreateWindow,
|
||||||
|
(Display *dpy, GLXFBConfig config,
|
||||||
|
Window win, const int *attribList))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyWindow,
|
||||||
|
(Display *dpy, GLXWindow window))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (GLXPixmap, glXCreatePixmap,
|
||||||
|
(Display *dpy, GLXFBConfig config,
|
||||||
|
Pixmap pixmap, const int *attribList))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyPixmap,
|
||||||
|
(Display *dpy, GLXPixmap pixmap))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateNewContext,
|
||||||
|
(Display *dpy, GLXFBConfig config,
|
||||||
|
int renderType, GLXContext shareList,
|
||||||
|
Bool direct))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (Bool, glXMakeContextCurrent,
|
||||||
|
(Display *dpy, GLXDrawable draw,
|
||||||
|
GLXDrawable read, GLXContext ctx))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXSelectEvent,
|
||||||
|
(Display *dpy, GLXDrawable drawable,
|
||||||
|
unsigned long mask))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXGetFBConfigs,
|
||||||
|
(Display *dpy, int screen, int *nelements))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXChooseFBConfig,
|
||||||
|
(Display *dpy, int screen,
|
||||||
|
const int *attrib_list, int *nelements))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (XVisualInfo *, glXGetVisualFromFBConfig,
|
||||||
|
(Display *dpy, GLXFBConfig config))
|
||||||
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
texture_from_pixmap,
|
||||||
"EXT\0",
|
"EXT\0",
|
||||||
"texture_from_pixmap\0",
|
"texture_from_pixmap\0",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)
|
COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)
|
||||||
COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage,
|
COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage,
|
||||||
(Display *display,
|
(Display *display,
|
||||||
@ -60,11 +105,11 @@ COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage,
|
|||||||
int buffer))
|
int buffer))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (video_sync,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
video_sync,
|
||||||
"SGI\0",
|
"SGI\0",
|
||||||
"video_sync\0",
|
"video_sync\0",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
COGL_WINSYS_FEATURE_VBLANK_COUNTER)
|
COGL_WINSYS_FEATURE_VBLANK_COUNTER)
|
||||||
COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync,
|
COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync,
|
||||||
(unsigned int *count))
|
(unsigned int *count))
|
||||||
@ -74,21 +119,21 @@ COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync,
|
|||||||
unsigned int *count))
|
unsigned int *count))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (swap_control,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
swap_control,
|
||||||
"SGI\0",
|
"SGI\0",
|
||||||
"swap_control\0",
|
"swap_control\0",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
COGL_WINSYS_FEATURE_SWAP_THROTTLE)
|
COGL_WINSYS_FEATURE_SWAP_THROTTLE)
|
||||||
COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval,
|
COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval,
|
||||||
(int interval))
|
(int interval))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (copy_sub_buffer,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
copy_sub_buffer,
|
||||||
"MESA\0",
|
"MESA\0",
|
||||||
"copy_sub_buffer\0",
|
"copy_sub_buffer\0",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
/* We initially assumed that copy_sub_buffer is synchronized on
|
/* We initially assumed that copy_sub_buffer is synchronized on
|
||||||
* which is only the case for a subset of GPUs for example it is not
|
* which is only the case for a subset of GPUs for example it is not
|
||||||
* synchronized on INTEL gen6 and gen7, so we remove this assumption
|
* synchronized on INTEL gen6 and gen7, so we remove this assumption
|
||||||
@ -104,19 +149,19 @@ COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer,
|
|||||||
int x, int y, int width, int height))
|
int x, int y, int width, int height))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (swap_event,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
swap_event,
|
||||||
"INTEL\0",
|
"INTEL\0",
|
||||||
"swap_event\0",
|
"swap_event\0",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)
|
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
COGL_WINSYS_FEATURE_BEGIN (create_context,
|
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||||
|
create_context,
|
||||||
"ARB\0",
|
"ARB\0",
|
||||||
"create_context",
|
"create_context",
|
||||||
0,
|
0,
|
||||||
0,
|
|
||||||
0)
|
0)
|
||||||
COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs,
|
COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs,
|
||||||
(Display *dpy,
|
(Display *dpy,
|
||||||
|
@ -98,13 +98,14 @@ typedef struct _CoglTexturePixmapGLX
|
|||||||
|
|
||||||
/* Define a set of arrays containing the functions required from GL
|
/* Define a set of arrays containing the functions required from GL
|
||||||
for each winsys feature */
|
for each winsys feature */
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
|
#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \
|
||||||
feature_flags, feature_flags_private, \
|
name, namespaces, extension_names, \
|
||||||
|
feature_flags, \
|
||||||
winsys_feature) \
|
winsys_feature) \
|
||||||
static const CoglFeatureFunction \
|
static const CoglFeatureFunction \
|
||||||
cogl_glx_feature_ ## name ## _funcs[] = {
|
cogl_glx_feature_ ## name ## _funcs[] = {
|
||||||
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
|
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
|
||||||
{ G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, pf_ ## name) },
|
{ G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, name) },
|
||||||
#define COGL_WINSYS_FEATURE_END() \
|
#define COGL_WINSYS_FEATURE_END() \
|
||||||
{ NULL, 0 }, \
|
{ NULL, 0 }, \
|
||||||
};
|
};
|
||||||
@ -112,11 +113,14 @@ typedef struct _CoglTexturePixmapGLX
|
|||||||
|
|
||||||
/* Define an array of features */
|
/* Define an array of features */
|
||||||
#undef COGL_WINSYS_FEATURE_BEGIN
|
#undef COGL_WINSYS_FEATURE_BEGIN
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
|
#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \
|
||||||
feature_flags, feature_flags_private, \
|
name, namespaces, extension_names, \
|
||||||
|
feature_flags, \
|
||||||
winsys_feature) \
|
winsys_feature) \
|
||||||
{ 255, 255, 0, namespaces, extension_names, \
|
{ major_version, minor_version, \
|
||||||
feature_flags, feature_flags_private, \
|
0, namespaces, extension_names, \
|
||||||
|
feature_flags, \
|
||||||
|
0, \
|
||||||
winsys_feature, \
|
winsys_feature, \
|
||||||
cogl_glx_feature_ ## name ## _funcs },
|
cogl_glx_feature_ ## name ## _funcs },
|
||||||
#undef COGL_WINSYS_FEATURE_FUNCTION
|
#undef COGL_WINSYS_FEATURE_FUNCTION
|
||||||
@ -268,38 +272,10 @@ resolve_core_glx_functions (CoglRenderer *renderer,
|
|||||||
|
|
||||||
glx_renderer = renderer->winsys;
|
glx_renderer = renderer->winsys;
|
||||||
|
|
||||||
if (!g_module_symbol (glx_renderer->libgl_module, "glXCreatePixmap",
|
if (!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension",
|
||||||
(void **) &glx_renderer->glXCreatePixmap) ||
|
(void **) &glx_renderer->glXQueryExtension) ||
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyPixmap",
|
|
||||||
(void **) &glx_renderer->glXDestroyPixmap) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXChooseFBConfig",
|
|
||||||
(void **) &glx_renderer->glXChooseFBConfig) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXCreateNewContext",
|
|
||||||
(void **) &glx_renderer->glXCreateNewContext) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXGetFBConfigAttrib",
|
|
||||||
(void **) &glx_renderer->glXGetFBConfigAttrib) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion",
|
!g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion",
|
||||||
(void **) &glx_renderer->glXQueryVersion) ||
|
(void **) &glx_renderer->glXQueryVersion) ||
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyContext",
|
|
||||||
(void **) &glx_renderer->glXDestroyContext) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXMakeContextCurrent",
|
|
||||||
(void **) &glx_renderer->glXMakeContextCurrent) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXSwapBuffers",
|
|
||||||
(void **) &glx_renderer->glXSwapBuffers) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension",
|
|
||||||
(void **) &glx_renderer->glXQueryExtension) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXIsDirect",
|
|
||||||
(void **) &glx_renderer->glXIsDirect) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXGetVisualFromFBConfig",
|
|
||||||
(void **) &glx_renderer->glXGetVisualFromFBConfig) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXSelectEvent",
|
|
||||||
(void **) &glx_renderer->glXSelectEvent) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXCreateWindow",
|
|
||||||
(void **) &glx_renderer->glXCreateWindow) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXGetFBConfigs",
|
|
||||||
(void **) &glx_renderer->glXGetFBConfigs) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXDestroyWindow",
|
|
||||||
(void **) &glx_renderer->glXDestroyWindow) ||
|
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString",
|
!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString",
|
||||||
(void **) &glx_renderer->glXQueryExtensionsString) ||
|
(void **) &glx_renderer->glXQueryExtensionsString) ||
|
||||||
(!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress",
|
(!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress",
|
||||||
@ -316,6 +292,66 @@ resolve_core_glx_functions (CoglRenderer *renderer,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_base_winsys_features (CoglRenderer *renderer)
|
||||||
|
{
|
||||||
|
CoglGLXRenderer *glx_renderer = renderer->winsys;
|
||||||
|
CoglXlibRenderer *xlib_renderer =
|
||||||
|
_cogl_xlib_renderer_get_data (renderer);
|
||||||
|
const char *glx_extensions;
|
||||||
|
int default_screen;
|
||||||
|
char **split_extensions;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
default_screen = DefaultScreen (xlib_renderer->xdpy);
|
||||||
|
glx_extensions =
|
||||||
|
glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy,
|
||||||
|
default_screen);
|
||||||
|
|
||||||
|
COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions);
|
||||||
|
|
||||||
|
split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
|
||||||
|
if (_cogl_feature_check (renderer,
|
||||||
|
"GLX", winsys_feature_data + i,
|
||||||
|
glx_renderer->glx_major,
|
||||||
|
glx_renderer->glx_minor,
|
||||||
|
COGL_DRIVER_GL, /* the driver isn't used */
|
||||||
|
split_extensions,
|
||||||
|
glx_renderer))
|
||||||
|
{
|
||||||
|
glx_renderer->legacy_feature_flags |=
|
||||||
|
winsys_feature_data[i].feature_flags;
|
||||||
|
if (winsys_feature_data[i].winsys_feature)
|
||||||
|
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||||
|
winsys_feature_data[i].winsys_feature,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (split_extensions);
|
||||||
|
|
||||||
|
/* Note: the GLX_SGI_video_sync spec explicitly states this extension
|
||||||
|
* only works for direct contexts. */
|
||||||
|
if (!glx_renderer->is_direct)
|
||||||
|
{
|
||||||
|
glx_renderer->glXGetVideoSync = NULL;
|
||||||
|
glx_renderer->glXWaitVideoSync = NULL;
|
||||||
|
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||||
|
COGL_WINSYS_FEATURE_VBLANK_COUNTER,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||||
|
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
if (glx_renderer->glXWaitVideoSync)
|
||||||
|
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||||
|
COGL_WINSYS_FEATURE_VBLANK_WAIT,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
||||||
CoglError **error)
|
CoglError **error)
|
||||||
@ -378,6 +414,8 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_base_winsys_features (renderer);
|
||||||
|
|
||||||
glx_renderer->dri_fd = -1;
|
glx_renderer->dri_fd = -1;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -391,70 +429,24 @@ static CoglBool
|
|||||||
update_winsys_features (CoglContext *context, CoglError **error)
|
update_winsys_features (CoglContext *context, CoglError **error)
|
||||||
{
|
{
|
||||||
CoglGLXDisplay *glx_display = context->display->winsys;
|
CoglGLXDisplay *glx_display = context->display->winsys;
|
||||||
CoglXlibRenderer *xlib_renderer =
|
|
||||||
_cogl_xlib_renderer_get_data (context->display->renderer);
|
|
||||||
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||||
const char *glx_extensions;
|
|
||||||
char **split_extensions;
|
|
||||||
int default_screen;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
_COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE);
|
_COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE);
|
||||||
|
|
||||||
if (!_cogl_context_update_features (context, error))
|
if (!_cogl_context_update_features (context, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memset (context->winsys_features, 0, sizeof (context->winsys_features));
|
memcpy (context->winsys_features,
|
||||||
|
glx_renderer->base_winsys_features,
|
||||||
|
sizeof (context->winsys_features));
|
||||||
|
|
||||||
default_screen = DefaultScreen (xlib_renderer->xdpy);
|
context->feature_flags |= glx_renderer->legacy_feature_flags;
|
||||||
glx_extensions =
|
|
||||||
glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy,
|
|
||||||
default_screen);
|
|
||||||
|
|
||||||
COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions);
|
|
||||||
|
|
||||||
context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
|
context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
|
||||||
COGL_FLAGS_SET (context->features,
|
COGL_FLAGS_SET (context->features,
|
||||||
COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
|
COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
|
||||||
COGL_FLAGS_SET (context->winsys_features,
|
|
||||||
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */);
|
if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer)
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
|
|
||||||
if (_cogl_feature_check (context->display->renderer,
|
|
||||||
"GLX", winsys_feature_data + i, 0, 0,
|
|
||||||
COGL_DRIVER_GL, /* the driver isn't used */
|
|
||||||
split_extensions,
|
|
||||||
glx_renderer))
|
|
||||||
{
|
|
||||||
context->feature_flags |= winsys_feature_data[i].feature_flags;
|
|
||||||
if (winsys_feature_data[i].winsys_feature)
|
|
||||||
COGL_FLAGS_SET (context->winsys_features,
|
|
||||||
winsys_feature_data[i].winsys_feature,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_strfreev (split_extensions);
|
|
||||||
|
|
||||||
/* Note: the GLX_SGI_video_sync spec explicitly states this extension
|
|
||||||
* only works for direct contexts. */
|
|
||||||
if (!glx_renderer->is_direct)
|
|
||||||
{
|
|
||||||
glx_renderer->pf_glXGetVideoSync = NULL;
|
|
||||||
glx_renderer->pf_glXWaitVideoSync = NULL;
|
|
||||||
COGL_FLAGS_SET (context->winsys_features,
|
|
||||||
COGL_WINSYS_FEATURE_VBLANK_COUNTER,
|
|
||||||
FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glx_renderer->pf_glXWaitVideoSync)
|
|
||||||
COGL_FLAGS_SET (context->winsys_features,
|
|
||||||
COGL_WINSYS_FEATURE_VBLANK_WAIT,
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
if (glx_renderer->pf_glXCopySubBuffer || context->glBlitFramebuffer)
|
|
||||||
{
|
{
|
||||||
CoglGpuInfoArchitecture arch;
|
CoglGpuInfoArchitecture arch;
|
||||||
|
|
||||||
@ -633,10 +625,10 @@ create_gl3_context (CoglDisplay *display,
|
|||||||
|
|
||||||
/* Make sure that the display supports the GLX_ARB_create_context
|
/* Make sure that the display supports the GLX_ARB_create_context
|
||||||
extension */
|
extension */
|
||||||
if (glx_renderer->pf_glXCreateContextAttribs == NULL)
|
if (glx_renderer->glXCreateContextAttribs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return glx_renderer->pf_glXCreateContextAttribs (xlib_renderer->xdpy,
|
return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy,
|
||||||
fb_config,
|
fb_config,
|
||||||
NULL /* share_context */,
|
NULL /* share_context */,
|
||||||
True, /* direct */
|
True, /* direct */
|
||||||
@ -1143,13 +1135,13 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
|||||||
* MESA and SGI extensions which should technically be mutually
|
* MESA and SGI extensions which should technically be mutually
|
||||||
* exclusive.
|
* exclusive.
|
||||||
*/
|
*/
|
||||||
if (glx_renderer->pf_glXSwapInterval)
|
if (glx_renderer->glXSwapInterval)
|
||||||
{
|
{
|
||||||
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
||||||
if (fb->config.swap_throttled)
|
if (fb->config.swap_throttled)
|
||||||
glx_renderer->pf_glXSwapInterval (1);
|
glx_renderer->glXSwapInterval (1);
|
||||||
else
|
else
|
||||||
glx_renderer->pf_glXSwapInterval (0);
|
glx_renderer->glXSwapInterval (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
XSync (xlib_renderer->xdpy, False);
|
XSync (xlib_renderer->xdpy, False);
|
||||||
@ -1174,12 +1166,12 @@ _cogl_winsys_wait_for_vblank (CoglContext *ctx)
|
|||||||
|
|
||||||
glx_renderer = ctx->display->renderer->winsys;
|
glx_renderer = ctx->display->renderer->winsys;
|
||||||
|
|
||||||
if (glx_renderer->pf_glXGetVideoSync)
|
if (glx_renderer->glXGetVideoSync)
|
||||||
{
|
{
|
||||||
uint32_t current_count;
|
uint32_t current_count;
|
||||||
|
|
||||||
glx_renderer->pf_glXGetVideoSync (¤t_count);
|
glx_renderer->glXGetVideoSync (¤t_count);
|
||||||
glx_renderer->pf_glXWaitVideoSync (2,
|
glx_renderer->glXWaitVideoSync (2,
|
||||||
(current_count + 1) % 2,
|
(current_count + 1) % 2,
|
||||||
¤t_count);
|
¤t_count);
|
||||||
}
|
}
|
||||||
@ -1193,7 +1185,7 @@ _cogl_winsys_get_vsync_counter (CoglContext *ctx)
|
|||||||
|
|
||||||
glx_renderer = ctx->display->renderer->winsys;
|
glx_renderer = ctx->display->renderer->winsys;
|
||||||
|
|
||||||
glx_renderer->pf_glXGetVideoSync (&video_sync_count);
|
glx_renderer->glXGetVideoSync (&video_sync_count);
|
||||||
|
|
||||||
return video_sync_count;
|
return video_sync_count;
|
||||||
}
|
}
|
||||||
@ -1306,14 +1298,14 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
|||||||
else if (can_wait)
|
else if (can_wait)
|
||||||
_cogl_winsys_wait_for_vblank (context);
|
_cogl_winsys_wait_for_vblank (context);
|
||||||
|
|
||||||
if (glx_renderer->pf_glXCopySubBuffer)
|
if (glx_renderer->glXCopySubBuffer)
|
||||||
{
|
{
|
||||||
Display *xdpy = xlib_renderer->xdpy;
|
Display *xdpy = xlib_renderer->xdpy;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n_rectangles; i++)
|
for (i = 0; i < n_rectangles; i++)
|
||||||
{
|
{
|
||||||
int *rect = &rectangles[4 * i];
|
int *rect = &rectangles[4 * i];
|
||||||
glx_renderer->pf_glXCopySubBuffer (xdpy, drawable,
|
glx_renderer->glXCopySubBuffer (xdpy, drawable,
|
||||||
rect[0], rect[1], rect[2], rect[3]);
|
rect[0], rect[1], rect[2], rect[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1400,7 +1392,7 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
|
|||||||
if (have_counter)
|
if (have_counter)
|
||||||
end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
|
end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
|
||||||
|
|
||||||
if (!glx_renderer->pf_glXSwapInterval)
|
if (!glx_renderer->glXSwapInterval)
|
||||||
{
|
{
|
||||||
CoglBool can_wait =
|
CoglBool can_wait =
|
||||||
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
|
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
|
||||||
@ -1878,7 +1870,7 @@ free_glx_pixmap (CoglContext *context,
|
|||||||
glx_renderer = renderer->winsys;
|
glx_renderer = renderer->winsys;
|
||||||
|
|
||||||
if (glx_tex_pixmap->pixmap_bound)
|
if (glx_tex_pixmap->pixmap_bound)
|
||||||
glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy,
|
glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
|
||||||
glx_tex_pixmap->glx_pixmap,
|
glx_tex_pixmap->glx_pixmap,
|
||||||
GLX_FRONT_LEFT_EXT);
|
GLX_FRONT_LEFT_EXT);
|
||||||
|
|
||||||
@ -2043,11 +2035,11 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
|
|||||||
_cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE);
|
_cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE);
|
||||||
|
|
||||||
if (glx_tex_pixmap->pixmap_bound)
|
if (glx_tex_pixmap->pixmap_bound)
|
||||||
glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy,
|
glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy,
|
||||||
glx_tex_pixmap->glx_pixmap,
|
glx_tex_pixmap->glx_pixmap,
|
||||||
GLX_FRONT_LEFT_EXT);
|
GLX_FRONT_LEFT_EXT);
|
||||||
|
|
||||||
glx_renderer->pf_glXBindTexImage (xlib_renderer->xdpy,
|
glx_renderer->glXBindTexImage (xlib_renderer->xdpy,
|
||||||
glx_tex_pixmap->glx_pixmap,
|
glx_tex_pixmap->glx_pixmap,
|
||||||
GLX_FRONT_LEFT_EXT,
|
GLX_FRONT_LEFT_EXT,
|
||||||
NULL);
|
NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user