diff --git a/cogl/cogl/cogl-mutter.h b/cogl/cogl/cogl-mutter.h index aadbb63eb9fc45b4f673dd64ebf1810bd4a3bb6c..40e6211874fcedb9342f0b1fd5dd814a5c2e67b3 100644 --- a/cogl/cogl/cogl-mutter.h +++ b/cogl/cogl/cogl-mutter.h @@ -38,9 +38,6 @@ #include "cogl/winsys/cogl-onscreen-egl.h" #include "cogl/winsys/cogl-winsys-egl-private.h" #endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-onscreen-glx.h" -#endif #ifdef HAVE_X11 #include "cogl/winsys/cogl-onscreen-xlib.h" #include "cogl/cogl-x11-onscreen.h" diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h index 8fd915527e35d61719a324bae15aaa1b1682c68d..57b0f8dfd949752811315107b7f06962a6b5a555 100644 --- a/cogl/cogl/cogl-renderer-private.h +++ b/cogl/cogl/cogl-renderer-private.h @@ -50,7 +50,6 @@ struct _CoglRenderer const CoglWinsysVtable *winsys_vtable; void *custom_winsys_user_data; CoglCustomWinsysVtableGetter custom_winsys_vtable_getter; - CoglWinsysID winsys_id_override; GList *constraints; GArray *poll_fds; diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index fd4e44166398f752c827456d76010073593f67b8..fe40389c0a42407b4143c25a938d12999c15f4cc 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -49,9 +49,6 @@ #ifdef HAVE_EGL_PLATFORM_XLIB #include "cogl/winsys/cogl-winsys-egl-x11-private.h" #endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-winsys-glx-private.h" -#endif #ifdef HAVE_X11 #include "cogl/cogl-xlib-renderer.h" @@ -119,9 +116,6 @@ static CoglDriverDescription _cogl_drivers[] = static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = { -#ifdef HAVE_GLX - _cogl_winsys_glx_get_vtable, -#endif #ifdef HAVE_EGL_PLATFORM_XLIB _cogl_winsys_egl_xlib_get_vtable, #endif @@ -550,19 +544,6 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) GList *l; gboolean skip_due_to_constraints = FALSE; - if (renderer->winsys_id_override != COGL_WINSYS_ID_ANY) - { - if (renderer->winsys_id_override != winsys->id) - continue; - } - else - { - char *user_choice = getenv ("COGL_RENDERER"); - if (user_choice && - g_ascii_strcasecmp (winsys->name, user_choice) != 0) - continue; - } - for (l = renderer->constraints; l; l = l->next) { CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); @@ -679,23 +660,6 @@ _cogl_renderer_remove_native_filter (CoglRenderer *renderer, } } -void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id) -{ - g_return_if_fail (!renderer->connected); - - renderer->winsys_id_override = winsys_id; -} - -CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->winsys_vtable->id; -} - void * _cogl_renderer_get_proc_address (CoglRenderer *renderer, const char *name) diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index d1b4789ea4c88ee9aa76ced5cb537ffadcb95823..d1721bca454203dc3afac72c2d09ca62f3e24fee 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -126,58 +126,6 @@ cogl_renderer_new (void); /* optional configuration APIs */ -/** - * CoglWinsysID: - * @COGL_WINSYS_ID_ANY: Implies no preference for which backend is used - * @COGL_WINSYS_ID_STUB: Use the no-op stub backend - * @COGL_WINSYS_ID_GLX: Use the GLX window system binding API - * @COGL_WINSYS_ID_EGL_XLIB: Use EGL with the X window system via XLib - * - * Identifies specific window system backends that Cogl supports. - * - * These can be used to query what backend Cogl is using or to try and - * explicitly select a backend to use. - */ -typedef enum -{ - COGL_WINSYS_ID_ANY, - COGL_WINSYS_ID_STUB, - COGL_WINSYS_ID_GLX, - COGL_WINSYS_ID_EGL_XLIB, - COGL_WINSYS_ID_CUSTOM, -} CoglWinsysID; - -/** - * cogl_renderer_set_winsys_id: - * @renderer: A #CoglRenderer - * @winsys_id: An ID of the winsys you explicitly want to use. - * - * This allows you to explicitly select a winsys backend to use instead - * of letting Cogl automatically select a backend. - * - * if you select an unsupported backend then cogl_renderer_connect() - * will fail and report an error. - * - * This may only be called on an un-connected #CoglRenderer. - */ -COGL_EXPORT void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id); - -/** - * cogl_renderer_get_winsys_id: - * @renderer: A #CoglRenderer - * - * Queries which window system backend Cogl has chosen to use. - * - * This may only be called on a connected #CoglRenderer. - * - * Returns: The #CoglWinsysID corresponding to the chosen window - * system backend. - */ -COGL_EXPORT CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer); - /** * cogl_renderer_check_onscreen_template: * @renderer: A #CoglRenderer diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index a49aa4d15ba48597cd58929b79e9e67a1a752b95..9351a3538ccab1a020fd5f33b577f0cd058a8709 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -320,21 +320,6 @@ if have_x11 ] endif -if have_glx - cogl_nonintrospected_headers += [ - 'winsys/cogl-glx.h', - ] - cogl_sources += [ - 'winsys/cogl-glx-display-private.h', - 'winsys/cogl-glx-renderer-private.h', - 'winsys/cogl-onscreen-glx.c', - 'winsys/cogl-onscreen-glx.h', - 'winsys/cogl-winsys-glx-feature-functions.h', - 'winsys/cogl-winsys-glx-private.h', - 'winsys/cogl-winsys-glx.c', - ] -endif - if have_egl cogl_nonintrospected_headers += [ 'cogl-egl.h', @@ -421,7 +406,6 @@ if have_introspection '-D__COGL_H_INSIDE__', '-D__COGL_XLIB_H_INSIDE__', '-D__COGL_EGL_H_INSIDE__', - '-D__COGL_GLX_H_INSIDE__', '-DCOGL_GIR_SCANNING', ], header: 'cogl/cogl.h', diff --git a/cogl/cogl/winsys/cogl-glx-display-private.h b/cogl/cogl/winsys/cogl-glx-display-private.h deleted file mode 100644 index 87767cd45bbc1655bc7f3b7daefde613f37733a8..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-glx-display-private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - - -typedef struct _CoglGLXCachedConfig -{ - /* This will be -1 if there is no cached config in this slot */ - int depth; - gboolean found; - GLXFBConfig fb_config; - gboolean stereo; - gboolean can_mipmap; -} CoglGLXCachedConfig; - -#define COGL_GLX_N_CACHED_CONFIGS 6 - -typedef struct _CoglGLXDisplay -{ - CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - - gboolean found_fbconfig; - gboolean is_direct; - gboolean have_vblank_counter; - gboolean can_vblank_wait; - GLXFBConfig fbconfig; - - /* Single context for all wins */ - GLXContext glx_context; - GLXWindow dummy_glxwin; - Window dummy_xwin; -} CoglGLXDisplay; diff --git a/cogl/cogl/winsys/cogl-glx-renderer-private.h b/cogl/cogl/winsys/cogl-glx-renderer-private.h deleted file mode 100644 index 321bad8214363dba065e164883966c07130b9f36..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-glx-renderer-private.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -#include - -#include "cogl/cogl-xlib-renderer-private.h" - -typedef struct _CoglGLXRenderer -{ - int glx_major; - int glx_minor; - - int glx_error_base; - int glx_event_base; - - /* Vblank stuff */ - int dri_fd; - - /* enumeration with relatioship between OML_sync_control - * UST (unadjusted-system-time) and the system clock */ - enum -{ - COGL_GLX_UST_IS_UNKNOWN, - COGL_GLX_UST_IS_GETTIMEOFDAY, - COGL_GLX_UST_IS_MONOTONIC_TIME, - COGL_GLX_UST_IS_OTHER - } ust_type; - - /* GModule pointing to libGL which we use to get glX functions out of */ - GModule *libgl_module; - - CoglClosure *flush_notifications_idle; - - /* 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)]; - - /* Function pointers for core GLX functionality. We can't just link - against these directly because we need to conditionally load - libGL when we are using GLX so that it won't conflict with a GLES - library if we are using EGL + GLES. These are just the functions - that we want to use before calling glXGetProcAddress */ - Bool - (* glXQueryExtension) (Display *dpy, int *errorb, int *event); - const char * - (* glXQueryExtensionsString) (Display *dpy, int screen); - Bool - (* glXQueryVersion) (Display *dpy, int *maj, int *min); - void * - (* glXGetProcAddress) (const GLubyte *procName); - - int - (* glXQueryDrawable) (Display *dpy, GLXDrawable drawable, - int attribute, unsigned int *value); - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglGLXRenderer; diff --git a/cogl/cogl/winsys/cogl-glx.h b/cogl/cogl/winsys/cogl-glx.h deleted file mode 100644 index 7f6e6523b14f1a89dbdad5837f215ed1ef20d1fa..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-glx.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Cogl - * - * A Low-Level GPU Graphics and Utilities API - * - * Copyright (C) 2014 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_GLX_H_INSIDE__ */ -#ifndef __COGL_GLX_H_INSIDE__ -#define __COGL_GLX_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif - -#endif /* COGL_COMPILATION */ - - -#include - -#include "cogl/cogl-types.h" - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#warning -#undef __COGL_H_INSIDE__ -#undef __COGL_GLX_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c deleted file mode 100644 index 07fad363aa7444923a1227ea5428f61a5203c726..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "config.h" - -#include "cogl/winsys/cogl-onscreen-glx.h" - -#include -#include - -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-x11-onscreen.h" -#include "cogl/cogl-xlib-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -struct _CoglOnscreenGlx -{ - CoglOnscreen parent; - - Window xwin; - int x, y; - CoglOutput *output; - - GLXDrawable glxwin; - uint32_t last_swap_vsync_counter; - uint32_t pending_sync_notify; - uint32_t pending_complete_notify; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL_TYPE_ONSCREEN, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - -static gboolean -cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - Window xwin; - const CoglFramebufferConfig *config; - GLXFBConfig fbconfig; - GError *fbconfig_error = NULL; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - config = cogl_framebuffer_get_config (framebuffer); - if (!cogl_display_glx_find_fbconfig (display, config, - &fbconfig, - &fbconfig_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - /* Update the real number of samples_per_pixel now that we have - * found an fbconfig... */ - if (config->samples_per_pixel) - { - int samples; - int status = glx_renderer->glXGetFBConfigAttrib (xlib_renderer->xdpy, - fbconfig, - GLX_SAMPLES, - &samples); - g_return_val_if_fail (status == Success, TRUE); - cogl_framebuffer_update_samples_per_pixel (framebuffer, samples); - } - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - { - int width; - int height; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - fbconfig); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } - - onscreen_glx->xwin = xwin; - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - onscreen_glx->glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - fbconfig, - onscreen_glx->xwin, - NULL); - } - -#ifdef GLX_INTEL_swap_event - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - GLXDrawable drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - /* similarly to above, we unconditionally select this event - * because we rely on it to advance the master clock, and - * drive redraw/relayout, animations and event handling. - */ - glx_renderer->glXSelectEvent (xlib_renderer->xdpy, - drawable, - GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); - } -#endif /* GLX_INTEL_swap_event */ - - return TRUE; -} - -static void -cogl_onscreen_glx_dispose (GObject *object) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - - G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object); - - g_clear_object (&onscreen_glx->output); - - if (onscreen_glx->glxwin != None || - onscreen_glx->xwin != None) - { - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - drawable = - onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin; - - /* Cogl always needs a valid context bound to something so if we are - * destroying the onscreen that is currently bound we'll switch back - * to the dummy drawable. Although the documentation for - * glXDestroyWindow states that a currently bound window won't - * actually be destroyed until it is unbound, it looks like this - * doesn't work if the X window itself is destroyed */ - if (drawable == cogl_context_glx_get_current_drawable (context)) - { - GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ? - glx_display->dummy_xwin : - glx_display->dummy_glxwin); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - cogl_context_glx_set_current_drawable (context, dummy_drawable); - } - - if (onscreen_glx->glxwin != None) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - onscreen_glx->glxwin); - onscreen_glx->glxwin = None; - } - - if (onscreen_glx->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin); - onscreen_glx->xwin = None; - } - else - { - onscreen_glx->xwin = None; - } - - XSync (xlib_renderer->xdpy, False); - - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - } -} - -static void -cogl_onscreen_glx_bind (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - if (cogl_context_glx_get_current_drawable (context) == drawable) - return; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x, context: %p", - xlib_renderer->xdpy, - (unsigned int) drawable, - glx_display->glx_context); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, - drawable, - glx_display->glx_context); - - /* In case we are using GLX_SGI_swap_control for vblank syncing - * we need call glXSwapIntervalSGI here to make sure that it - * affects the current drawable. - * - * Note: we explicitly set to 0 when we aren't using the swap - * interval to synchronize since some drivers have a default - * swap interval of 1. Sadly some drivers even ignore requests - * to disable the swap interval. - * - * NB: glXSwapIntervalSGI applies to the context not the - * drawable which is why we can't just do this once when the - * framebuffer is allocated. - * - * FIXME: We should check for GLX_EXT_swap_control which allows - * per framebuffer swap intervals. GLX_MESA_swap_control also - * allows per-framebuffer swap intervals but the semantics tend - * to be more muddled since Mesa drivers tend to expose both the - * MESA and SGI extensions which should technically be mutually - * exclusive. - */ - if (glx_renderer->glXSwapInterval) - glx_renderer->glXSwapInterval (1); - - XSync (xlib_renderer->xdpy, False); - - /* FIXME: We should be reporting a GError here */ - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_warning ("X Error received while making drawable 0x%08lX current", - drawable); - return; - } - - cogl_context_glx_set_current_drawable (context, drawable); -} - -static void -ensure_ust_type (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - int64_t ust; - int64_t msc; - int64_t sbc; - struct timeval tv; - int64_t current_system_time; - int64_t current_monotonic_time; - - if (glx_renderer->ust_type != COGL_GLX_UST_IS_UNKNOWN) - return; - - glx_renderer->ust_type = COGL_GLX_UST_IS_OTHER; - - if (glx_renderer->glXGetSyncValues == NULL) - goto out; - - if (!glx_renderer->glXGetSyncValues (xlib_renderer->xdpy, drawable, - &ust, &msc, &sbc)) - goto out; - - /* This is the time source that existing (buggy) linux drm drivers - * use */ - gettimeofday (&tv, NULL); - current_system_time = (tv.tv_sec * G_GINT64_CONSTANT (1000000)) + tv.tv_usec; - - if (current_system_time > ust - 1000000 && - current_system_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_GETTIMEOFDAY; - goto out; - } - - /* This is the time source that the newer (fixed) linux drm - * drivers use (Linux >= 3.8) */ - current_monotonic_time = g_get_monotonic_time (); - - if (current_monotonic_time > ust - 1000000 && - current_monotonic_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_MONOTONIC_TIME; - goto out; - } - - out: - COGL_NOTE (WINSYS, "Classified OML system time as: %s", - glx_renderer->ust_type == COGL_GLX_UST_IS_GETTIMEOFDAY ? "gettimeofday" : - (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME ? "monotonic" : - "other")); - return; -} - -static int64_t -ust_to_microseconds (CoglRenderer *renderer, - GLXDrawable drawable, - int64_t ust) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - switch (glx_renderer->ust_type) - { - case COGL_GLX_UST_IS_UNKNOWN: - g_assert_not_reached (); - break; - case COGL_GLX_UST_IS_GETTIMEOFDAY: - case COGL_GLX_UST_IS_MONOTONIC_TIME: - return ust; - case COGL_GLX_UST_IS_OTHER: - /* In this case the scale of UST is undefined so we can't easily - * scale to microseconds. - * - * For example the driver may be reporting the rdtsc CPU counter - * as UST values and so the scale would need to be determined - * empirically. - * - * Potentially we could block for a known duration within - * ensure_ust_type() to measure the timescale of UST but for now - * we just ignore unknown time sources */ - return 0; - } - - return 0; -} - -static gboolean -is_ust_monotonic (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - return (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME); -} - -static void -_cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXDisplay *glx_display; - - glx_renderer = ctx->display->renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer); - glx_display = ctx->display->winsys; - - if (glx_display->can_vblank_wait) - { - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - if (glx_renderer->glXWaitForMsc) - { - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - Drawable drawable = onscreen_glx->glxwin; - int64_t ust; - int64_t msc; - int64_t sbc; - - glx_renderer->glXWaitForMsc (xlib_renderer->xdpy, drawable, - 0, 1, 0, - &ust, &msc, &sbc); - - if (is_ust_monotonic (ctx->display->renderer, drawable)) - { - info->presentation_time_us = - ust_to_microseconds (ctx->display->renderer, - drawable, - ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - else - { - info->presentation_time_us = g_get_monotonic_time (); - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = msc; - } - else - { - uint32_t current_count; - - glx_renderer->glXGetVideoSync (¤t_count); - glx_renderer->glXWaitVideoSync (2, - (current_count + 1) % 2, - ¤t_count); - - info->presentation_time_us = g_get_monotonic_time (); - } - } -} - -static uint32_t -_cogl_winsys_get_vsync_counter (CoglContext *ctx) -{ - uint32_t video_sync_count; - CoglGLXRenderer *glx_renderer; - - glx_renderer = ctx->display->renderer->winsys; - - glx_renderer->glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -#ifndef GLX_BACK_BUFFER_AGE_EXT -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 -#endif - -static int -cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - unsigned int age = 0; - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - cogl_onscreen_bind (onscreen); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - return age; -} - -static void -set_frame_info_output (CoglOnscreen *onscreen, - CoglOutput *output) -{ - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - - if (output) - { - float refresh_rate = cogl_output_get_refresh_rate (output); - if (refresh_rate != 0.0) - info->refresh_rate = refresh_rate; - } -} - -static void -cogl_onscreen_glx_flush_notification (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - while (onscreen_glx->pending_sync_notify > 0 || - onscreen_glx->pending_complete_notify > 0) - { - if (onscreen_glx->pending_sync_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_peek_head_frame_info (onscreen); - _cogl_onscreen_notify_frame_sync (onscreen, info); - onscreen_glx->pending_sync_notify--; - } - - if (onscreen_glx->pending_complete_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_pop_head_frame_info (onscreen); - _cogl_onscreen_notify_complete (onscreen, info); - g_object_unref (info); - onscreen_glx->pending_complete_notify--; - } - } -} - -static void -flush_pending_notifications_cb (void *data, - void *user_data) -{ - CoglFramebuffer *framebuffer = data; - - if (COGL_IS_ONSCREEN (framebuffer)) - { - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - - cogl_onscreen_glx_flush_notification (onscreen); - } -} - -static void -flush_pending_notifications_idle (void *user_data) -{ - CoglContext *context = user_data; - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* This needs to be disconnected before invoking the callbacks in - * case the callbacks cause it to be queued again */ - _cogl_closure_disconnect (glx_renderer->flush_notifications_idle); - glx_renderer->flush_notifications_idle = NULL; - - g_list_foreach (context->framebuffers, - flush_pending_notifications_cb, - NULL); -} - -static void -set_sync_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to dispatch sync events when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_sync_notify++; -} - -static void -set_complete_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to notify swap completion when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_complete_notify++; -} - -static void -cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen, - const int *user_rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - uint32_t end_frame_vsync_counter = 0; - gboolean have_counter; - gboolean can_wait; - int x_min = 0, x_max = 0, y_min = 0, y_max = 0; - - /* - * We assume that glXCopySubBuffer is synchronized which means it won't prevent multiple - * blits per retrace if they can all be performed in the blanking period. If that's the - * case then we still want to use the vblank sync menchanism but - * we only need it to throttle redraws. - */ - gboolean blit_sub_buffer_is_synchronized = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED); - - int framebuffer_width = cogl_framebuffer_get_width (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - int i; - - /* glXCopySubBuffer expects rectangles relative to the bottom left corner but - * we are given rectangles relative to the top left so we need to flip - * them... */ - memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - - if (i == 0) - { - x_min = rect[0]; - x_max = rect[0] + rect[2]; - y_min = rect[1]; - y_max = rect[1] + rect[3]; - } - else - { - x_min = MIN (x_min, rect[0]); - x_max = MAX (x_max, rect[0] + rect[2]); - y_min = MIN (y_min, rect[1]); - y_max = MAX (y_max, rect[1] + rect[3]); - } - - rect[1] = framebuffer_height - rect[1] - rect[3]; - - } - - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - have_counter = glx_display->have_vblank_counter; - can_wait = glx_display->can_vblank_wait; - - /* We need to ensure that all the rendering is done, otherwise - * redraw operations that are slower than the framerate can - * queue up in the pipeline during a heavy animation, causing a - * larger and larger backlog of rendering visible as lag to the - * user. - * - * For an exaggerated example consider rendering at 60fps (so 16ms - * per frame) and you have a really slow frame that takes 160ms to - * render, even though painting the scene and issuing the commands - * to the GPU takes no time at all. If all we did was use the - * video_sync extension to throttle the painting done by the CPU - * then every 16ms we would have another frame queued up even though - * the GPU has only rendered one tenth of the current frame. By the - * time the GPU would get to the 2nd frame there would be 9 frames - * waiting to be rendered. - * - * The problem is that we don't currently have a good way to throttle - * the GPU, only the CPU so we have to resort to synchronizing the - * GPU with the CPU to throttle it. - * - * Note: calling glFinish() and synchronizing the CPU with the GPU is far - * from ideal. One idea is to use sync objects to track render completion - * so we can throttle the backlog (ideally with an additional extension that - * lets us get notifications in our mainloop instead of having to busy wait - * for the completion). - */ - cogl_framebuffer_finish (framebuffer); - - if (blit_sub_buffer_is_synchronized && have_counter && can_wait) - { - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we have the GLX_SGI_video_sync extension then we can - * be a bit smarter about how we throttle blits by avoiding - * any waits if we can see that the video sync count has - * already progressed. */ - if (onscreen_glx->last_swap_vsync_counter == end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - - if (glx_renderer->glXCopySubBuffer) - { - Display *xdpy = xlib_renderer->xdpy; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - glx_renderer->glXCopySubBuffer (xdpy, drawable, - rect[0], rect[1], rect[2], rect[3]); - } - } - else if (context->glBlitFramebuffer) - { - /* XXX: checkout how this state interacts with the code to use - * glBlitFramebuffer in Neil's texture atlasing branch */ - - /* glBlitFramebuffer is affected by the scissor so we need to - * ensure we have flushed an empty clip stack to get rid of it. - * We also mark that the clip state is dirty so that it will be - * flushed to the correct state the next time something is - * drawn */ - _cogl_clip_stack_flush (NULL, framebuffer); - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - context->glDrawBuffer (GL_FRONT); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - int x2 = rect[0] + rect[2]; - int y2 = rect[1] + rect[3]; - context->glBlitFramebuffer (rect[0], rect[1], x2, y2, - rect[0], rect[1], x2, y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - context->glDrawBuffer (context->current_gl_draw_buffer); - } - - /* NB: unlike glXSwapBuffers, glXCopySubBuffer and - * glBlitFramebuffer don't issue an implicit glFlush() so we - * have to flush ourselves if we want the request to complete in - * a finite amount of time since otherwise the driver can batch - * the command indefinitely. */ - context->glFlush (); - - /* NB: It's important we save the counter we read before acting on - * the swap request since if we are mixing and matching different - * swap methods between frames we don't want to read the timer e.g. - * after calling glFinish() some times and not for others. - * - * In other words; this way we consistently save the time at the end - * of the applications frame such that the counter isn't muddled by - * the varying costs of different swap methods. - */ - if (have_counter) - onscreen_glx->last_swap_vsync_counter = end_frame_vsync_counter; - - { - CoglOutput *output; - - x_min = CLAMP (x_min, 0, framebuffer_width); - x_max = CLAMP (x_max, 0, framebuffer_width); - y_min = CLAMP (y_min, 0, framebuffer_height); - y_max = CLAMP (y_max, 0, framebuffer_height); - - output = - _cogl_xlib_renderer_output_for_rectangle (context->display->renderer, - onscreen_glx->x + x_min, - onscreen_glx->y + y_min, - x_max - x_min, - y_max - y_min); - - set_frame_info_output (onscreen, output); - } - - /* XXX: we don't get SwapComplete events based on how we implement - * the _swap_region() API but if cogl-onscreen.c knows we are - * handling _SYNC and _COMPLETE events in the winsys then we need to - * send fake events in this case. - */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - set_sync_pending (onscreen); - set_complete_pending (onscreen); - } -} - -static void -cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - gboolean have_counter; - GLXDrawable drawable; - - /* XXX: theoretically this shouldn't be necessary but at least with - * the Intel drivers we have see that if we don't call - * glXMakeContextCurrent for the drawable we are swapping then - * we get a BadDrawable error from the X server. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - have_counter = glx_display->have_vblank_counter; - - if (!glx_renderer->glXSwapInterval) - { - gboolean can_wait = have_counter || glx_display->can_vblank_wait; - - uint32_t end_frame_vsync_counter = 0; - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - cogl_framebuffer_finish (framebuffer); - - if (have_counter && can_wait) - { - if (onscreen_glx->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - } - - glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable); - - if (have_counter) - onscreen_glx->last_swap_vsync_counter = - _cogl_winsys_get_vsync_counter (context); - - set_frame_info_output (onscreen, onscreen_glx->output); -} - -static Window -cogl_onscreen_glx_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (x11_onscreen); - - return onscreen_glx->xwin; -} - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - gboolean ust_is_monotonic; - CoglFrameInfo *info; - - /* We only want to notify that the swap is complete when the - application calls cogl_context_dispatch so instead of immediately - notifying we'll set a flag to remember to notify later */ - set_sync_pending (onscreen); - - info = cogl_onscreen_peek_head_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - ust_is_monotonic = is_ust_monotonic (context->display->renderer, - onscreen_glx->glxwin); - - if (swap_event->ust != 0 && ust_is_monotonic) - { - info->presentation_time_us = - ust_to_microseconds (context->display->renderer, - onscreen_glx->glxwin, - swap_event->ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = swap_event->msc; - - set_complete_pending (onscreen); -} - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglOutput *output; - int width, height; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - output = _cogl_xlib_renderer_output_for_rectangle (display->renderer, - onscreen_glx->x, - onscreen_glx->y, - width, height); - if (onscreen_glx->output != output) - { - if (onscreen_glx->output) - g_object_unref (onscreen_glx->output); - - onscreen_glx->output = output; - - if (output) - g_object_ref (onscreen_glx->output); - } -} - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - int x, y; - - - _cogl_framebuffer_winsys_update_size (framebuffer, - configure_event->width, - configure_event->height); - - /* We only want to notify that a resize happened when the - * application calls cogl_context_dispatch so instead of immediately - * notifying we queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - if (configure_event->send_event) - { - x = configure_event->x; - y = configure_event->y; - } - else - { - Window child; - XTranslateCoordinates (configure_event->display, - configure_event->window, - DefaultRootWindow (configure_event->display), - 0, 0, &x, &y, &child); - } - - onscreen_glx->x = x; - onscreen_glx->y = y; - - cogl_onscreen_glx_update_output (onscreen); -} - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - return onscreen_glx->xwin == window; -} - -CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_GLX, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_glx_get_x11_window; -} - -static void -cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); - - object_class->dispose = cogl_onscreen_glx_dispose; - - framebuffer_class->allocate = cogl_onscreen_glx_allocate; - - onscreen_class->bind = cogl_onscreen_glx_bind; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_glx_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_glx_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_glx_get_buffer_age; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.h b/cogl/cogl/winsys/cogl-onscreen-glx.h deleted file mode 100644 index 266595aac4fb6840385624ba806bec3209c46ae9..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include -#include - -#include "cogl/cogl-onscreen.h" - -#define COGL_TYPE_ONSCREEN_GLX (cogl_onscreen_glx_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL, ONSCREEN_GLX, - CoglOnscreen) - -COGL_EXPORT CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height); - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event); - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen); - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event); - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window); diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h index 7633c8c31906011c8eb6970310e3343168949ff0..09160a348193de68ff617f6e73c501bbc94328b7 100644 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h @@ -36,10 +36,6 @@ #include -#ifdef HAVE_GLX -#include -#endif - #include "cogl/cogl-texture-private.h" #include "cogl/winsys/cogl-texture-pixmap-x11.h" diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c index 7a52129c229869a82a329d7634dd4310e758c91d..632270ee96f026ea7f1382cb867c30c3559df41e 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c @@ -610,7 +610,6 @@ _cogl_winsys_egl_xlib_get_vtable (void) vtable = *_cogl_winsys_egl_get_vtable (); - vtable.id = COGL_WINSYS_ID_EGL_XLIB; vtable.name = "EGL_XLIB"; vtable.constraints |= (COGL_RENDERER_CONSTRAINT_USES_X11 | COGL_RENDERER_CONSTRAINT_USES_XLIB); diff --git a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h deleted file mode 100644 index 31e73dbc27894300ef43e7162e219f0da21376fc..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (major_glx_version, minor_glx_version, - * name, namespaces, extension_names, - * implied_legacy_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -/* 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", - "texture_from_pixmap\0", - 0, - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) -COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage, - (Display *display, - GLXDrawable drawable, - int buffer, - int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage, - (Display *display, - GLXDrawable drawable, - int buffer)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - video_sync, - "SGI\0", - "video_sync\0", - 0, - COGL_WINSYS_FEATURE_VBLANK_COUNTER) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync, - (unsigned int *count)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync, - (int divisor, - int remainder, - unsigned int *count)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_control, - "SGI\0", - "swap_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval, - (int interval)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - sync_control, - "OML\0", - "sync_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXGetSyncValues, - (Display* dpy, - GLXDrawable drawable, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXWaitForMsc, - (Display* dpy, - GLXDrawable drawable, - int64_t target_msc, - int64_t divisor, - int64_t remainder, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - copy_sub_buffer, - "MESA\0", - "copy_sub_buffer\0", - 0, -/* 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 - * synchronized on INTEL gen6 and gen7, so we remove this assumption - * for now - */ -#if 0 - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED) -#endif - 0) -COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer, - (Display *dpy, - GLXDrawable drawable, - int x, int y, int width, int height)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_event, - "INTEL\0", - "swap_event\0", - 0, - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) - -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - create_context, - "ARB\0", - "create_context", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs, - (Display *dpy, - GLXFBConfig config, - GLXContext share_context, - Bool direct, - const int *attrib_list)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - buffer_age, - "EXT\0", - "buffer_age\0", - 0, - COGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () diff --git a/cogl/cogl/winsys/cogl-winsys-glx-private.h b/cogl/cogl/winsys/cogl-winsys-glx-private.h deleted file mode 100644 index a6732d984354aa8bf1d744ec69db4aed6c0bd8ee..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#pragma once - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void); - -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error); - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable); - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context); diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c deleted file mode 100644 index 9cab939d3e149ea5b42d58816f3de9a04489214a..0000000000000000000000000000000000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx.c +++ /dev/null @@ -1,1447 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#include "config.h" - -#include "cogl/cogl-i18n-private.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-feature-private.h" -#include "cogl/cogl-context-private.h" -#include "cogl/cogl-framebuffer.h" -#include "cogl/cogl-renderer-private.h" -#include "cogl/cogl-onscreen-template-private.h" -#include "cogl/cogl-private.h" -#include "cogl/cogl-texture-2d-private.h" -#include "cogl/cogl-frame-info-private.h" -#include "cogl/cogl-framebuffer-private.h" -#include "cogl/cogl-onscreen-private.h" -#include "cogl/cogl-xlib-renderer.h" -#include "cogl/cogl-util.h" -#include "cogl/cogl-poll-private.h" -#include "cogl/driver/gl/cogl-pipeline-opengl-private.h" -#include "cogl/winsys/cogl-glx.h" -#include "cogl/winsys/cogl-glx-renderer-private.h" -#include "cogl/winsys/cogl-glx-display-private.h" -#include "cogl/winsys/cogl-onscreen-glx.h" -#include "cogl/winsys/cogl-winsys-private.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include "mtk/mtk-x11.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* This is a relatively new extension */ -#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV -#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 -#endif - -#define MAX_GLX_CONFIG_ATTRIBS 30 - -typedef struct _CoglOnscreenGlx CoglOnscreenGlx; - -typedef struct _CoglContextGLX -{ - GLXDrawable current_drawable; -} CoglContextGLX; - -typedef struct _CoglPixmapTextureEyeGLX -{ - CoglTexture *glx_tex; - gboolean bind_tex_image_queued; - gboolean pixmap_bound; -} CoglPixmapTextureEyeGLX; - -typedef struct _CoglTexturePixmapGLX -{ - GLXPixmap glx_pixmap; - gboolean has_mipmap_space; - gboolean can_mipmap; - - CoglPixmapTextureEyeGLX left; - CoglPixmapTextureEyeGLX right; -} CoglTexturePixmapGLX; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_glx_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - { major_version, minor_version, \ - 0, namespaces, extension_names, \ - 0, \ - winsys_feature, \ - cogl_glx_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl/winsys/cogl-winsys-glx-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - return glx_renderer->glXGetProcAddress ((const GLubyte *) name); -} - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_glx_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event) -{ - CoglOnscreen *onscreen = find_onscreen_for_xid (context, (uint32_t)swap_event->drawable); - - if (!onscreen) - return; - - cogl_onscreen_glx_notify_swap_buffers (onscreen, swap_event); -} - -static void -notify_resize (CoglContext *context, - XConfigureEvent *configure_event) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, configure_event->window); - if (!onscreen) - return; - - cogl_onscreen_glx_resize (onscreen, configure_event); -} - -static CoglFilterReturn -glx_event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; -#ifdef GLX_INTEL_swap_event - CoglGLXRenderer *glx_renderer; -#endif - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - &xevent->xconfigure); - - /* we let ConfigureNotify pass through */ - return COGL_FILTER_CONTINUE; - } - -#ifdef GLX_INTEL_swap_event - glx_renderer = context->display->renderer->winsys; - - if (xevent->type == (glx_renderer->glx_event_base + GLX_BufferSwapComplete)) - { - GLXBufferSwapComplete *swap_event = (GLXBufferSwapComplete *) xevent; - - notify_swap_buffers (context, swap_event); - - /* remove SwapComplete events from the queue */ - return COGL_FILTER_REMOVE; - } -#endif /* GLX_INTEL_swap_event */ - - if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - CoglOnscreenDirtyInfo info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - - return COGL_FILTER_CONTINUE; - } - - return COGL_FILTER_CONTINUE; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - _cogl_xlib_renderer_disconnect (renderer); - - if (glx_renderer->libgl_module) - g_module_close (glx_renderer->libgl_module); - - g_free (renderer->winsys); -} - -static gboolean -update_all_outputs (CoglRenderer *renderer) -{ - GList *l; - - _COGL_GET_CONTEXT (context, FALSE); - - if (context->display == NULL) /* during connection */ - return FALSE; - - if (context->display->renderer != renderer) - return FALSE; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - cogl_onscreen_glx_update_output (COGL_ONSCREEN (framebuffer)); - } - - return TRUE; -} - -static void -_cogl_winsys_renderer_outputs_changed (CoglRenderer *renderer) -{ - update_all_outputs (renderer); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ -} - -static gboolean -resolve_core_glx_functions (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - - glx_renderer = renderer->winsys; - - if (!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension", - (void **) &glx_renderer->glXQueryExtension) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion", - (void **) &glx_renderer->glXQueryVersion) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString", - (void **) &glx_renderer->glXQueryExtensionsString) || - (!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress", - (void **) &glx_renderer->glXGetProcAddress) && - !g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddressARB", - (void **) &glx_renderer->glXGetProcAddress)) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryDrawable", - (void **) &glx_renderer->glXQueryDrawable)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to resolve required GLX symbol"); - return FALSE; - } - - 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_GL3, /* the driver isn't used */ - split_extensions, - glx_renderer)) - { - 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); - - /* The GLX_SGI_video_sync spec explicitly states this extension - * only works for direct contexts; we don't know per-renderer - * if the context is direct or not, so we turn off the feature - * flag; we still use the extension within this file looking - * instead at glx_display->have_vblank_counter. - */ - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - FALSE); - - /* Because of the direct-context dependency, the VBLANK_WAIT feature - * doesn't reflect the presence of GLX_SGI_video_sync. - */ - if (glx_renderer->glXWaitForMsc) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - - renderer->winsys = g_new0 (CoglGLXRenderer, 1); - - glx_renderer = renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - if (renderer->driver != COGL_DRIVER_GL3) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GLX Backend can only be used in conjunction with OpenGL"); - goto error; - } - - glx_renderer->libgl_module = g_module_open (COGL_GL_LIBNAME, - G_MODULE_BIND_LAZY); - - if (glx_renderer->libgl_module == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to dynamically open the OpenGL library"); - goto error; - } - - if (!resolve_core_glx_functions (renderer, error)) - goto error; - - if (!glx_renderer->glXQueryExtension (xlib_renderer->xdpy, - &glx_renderer->glx_error_base, - &glx_renderer->glx_event_base)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); - goto error; - } - - /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting - * extensions specified to require GLX 1.3, but still reporting 1.2 - * via glXQueryVersion. */ - if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy, - &glx_renderer->glx_major, - &glx_renderer->glx_minor) - || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); - goto error; - } - - update_base_winsys_features (renderer); - - glx_renderer->dri_fd = -1; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static gboolean -update_winsys_features (CoglContext *context, GError **error) -{ - CoglGLXDisplay *glx_display = context->display->winsys; - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - memcpy (context->winsys_features, - glx_renderer->base_winsys_features, - sizeof (context->winsys_features)); - - if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer) - COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled - * by the SwapInterval so we have to throttle swap_region requests - * manually... */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) && - (glx_display->have_vblank_counter || glx_display->can_vblank_wait)) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE); - } - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - - return TRUE; -} - -static void -glx_attributes_from_framebuffer_config (CoglDisplay *display, - const CoglFramebufferConfig *config, - int *attributes) -{ - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - int i = 0; - - attributes[i++] = GLX_DRAWABLE_TYPE; - attributes[i++] = GLX_WINDOW_BIT; - - attributes[i++] = GLX_RENDER_TYPE; - attributes[i++] = GLX_RGBA_BIT; - - attributes[i++] = GLX_DOUBLEBUFFER; - attributes[i++] = GL_TRUE; - - attributes[i++] = GLX_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_BLUE_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_ALPHA_SIZE; - attributes[i++] = GLX_DONT_CARE; - attributes[i++] = GLX_DEPTH_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_STENCIL_SIZE; - attributes[i++] = config->need_stencil ? 2 : 0; - if (config->stereo_enabled) - { - attributes[i++] = GLX_STEREO; - attributes[i++] = TRUE; - } - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 && - config->samples_per_pixel) - { - attributes[i++] = GLX_SAMPLE_BUFFERS; - attributes[i++] = 1; - attributes[i++] = GLX_SAMPLES; - attributes[i++] = config->samples_per_pixel; - } - - attributes[i++] = None; - - g_assert (i < MAX_GLX_CONFIG_ATTRIBS); -} - -/* It seems the GLX spec never defined an invalid GLXFBConfig that - * we could overload as an indication of error, so we have to return - * an explicit boolean status. */ -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig *configs = NULL; - int n_configs; - static int attributes[MAX_GLX_CONFIG_ATTRIBS]; - gboolean ret = TRUE; - int xscreen_num = DefaultScreen (xlib_renderer->xdpy); - - glx_attributes_from_framebuffer_config (display, config, attributes); - - configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy, - xscreen_num, - attributes, - &n_configs); - - if (!configs || n_configs == 0) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); - ret = FALSE; - goto done; - } - - COGL_NOTE (WINSYS, "Using the first available FBConfig"); - *config_ret = configs[0]; - -done: - XFree (configs); - return ret; -} - -static GLXContext -create_gl3_context (CoglDisplay *display, - GLXFBConfig fb_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - /* We want a core profile 3.1 context with no deprecated features */ - static const int attrib_list[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - None - }; - /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context - and in part on ARB_robustness. Namely, it needs the notification - strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the - driver exposes the GetGraphicsResetStatusARB function. This means - we don't actually enable robust buffer access. */ - static const int attrib_list_reset_on_purge[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, - GL_TRUE, - GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB, - None - }; - - /* Make sure that the display supports the GLX_ARB_create_context - extension */ - if (glx_renderer->glXCreateContextAttribs == NULL) - return NULL; - - /* We can't check the presence of this extension with the usual - COGL_WINSYS_FEATURE machinery because that only gets initialized - later when the CoglContext is created. */ - if (display->renderer->xlib_want_reset_on_video_memory_purge && - strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)), - "GLX_NV_robustness_video_memory_purge")) - { - GLXContext ctx; - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list_reset_on_purge); - if (!mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) && ctx) - return ctx; - } - - return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list); -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig config; - GError *fbconfig_error = NULL; - XSetWindowAttributes attrs; - XVisualInfo *xvisinfo; - GLXDrawable dummy_drawable; - - g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); - - glx_display->found_fbconfig = - cogl_display_glx_find_fbconfig (display, - &display->onscreen_template->config, - &config, - &fbconfig_error); - if (!glx_display->found_fbconfig) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - glx_display->fbconfig = config; - - COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", - xlib_renderer->xdpy); - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - if (display->renderer->driver == COGL_DRIVER_GL3) - glx_display->glx_context = create_gl3_context (display, config); - else - glx_display->glx_context = - glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, - config, - GLX_RGBA_TYPE, - NULL, - True); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) || - glx_display->glx_context == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); - return FALSE; - } - - glx_display->is_direct = - glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); - glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync; - glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter; - - COGL_NOTE (WINSYS, "Setting %s context", - glx_display->is_direct ? "direct" : "indirect"); - - /* XXX: GLX doesn't let us make a context current without a window - * so we create a dummy window that we can use while no CoglOnscreen - * framebuffer is in use. - */ - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - config); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); - return FALSE; - } - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - glx_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | CWColormap | CWBorderPixel, - &attrs); - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_display->dummy_glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - config, - glx_display->dummy_xwin, - NULL); - } - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = glx_display->dummy_xwin; - - COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", - (unsigned int) dummy_drawable); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - - xlib_renderer->xvisinfo = xvisinfo; - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - g_return_if_fail (glx_display != NULL); - - if (glx_display->glx_context) - { - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - None, None, NULL); - glx_renderer->glXDestroyContext (xlib_renderer->xdpy, - glx_display->glx_context); - glx_display->glx_context = NULL; - } - - if (glx_display->dummy_glxwin) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - glx_display->dummy_glxwin); - glx_display->dummy_glxwin = None; - } - - if (glx_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_xwin); - glx_display->dummy_xwin = None; - } - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglGLXDisplay *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_new0 (CoglGLXDisplay, 1); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextGLX, 1); - - cogl_xlib_renderer_add_filter (context->display->renderer, - glx_event_filter_cb, - context); - return update_winsys_features (context, error); -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - cogl_xlib_renderer_remove_filter (context->display->renderer, - glx_event_filter_cb, - context); - g_free (context->winsys); -} - -static gboolean -get_fbconfig_for_depth (CoglContext *context, - unsigned int depth, - gboolean stereo, - GLXFBConfig *fbconfig_ret, - gboolean *can_mipmap_ret) -{ - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - CoglGLXDisplay *glx_display; - Display *dpy; - GLXFBConfig *fbconfigs; - int n_elements, i; - int db, stencil, alpha, mipmap, rgba, value; - int spare_cache_slot = 0; - gboolean found = FALSE; - - xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - glx_renderer = context->display->renderer->winsys; - glx_display = context->display->winsys; - - /* Check if we've already got a cached config for this depth and stereo */ - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - if (glx_display->glx_cached_configs[i].depth == -1) - spare_cache_slot = i; - else if (glx_display->glx_cached_configs[i].depth == depth && - glx_display->glx_cached_configs[i].stereo == stereo) - { - *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config; - *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap; - return glx_display->glx_cached_configs[i].found; - } - - dpy = xlib_renderer->xdpy; - - fbconfigs = glx_renderer->glXGetFBConfigs (dpy, DefaultScreen (dpy), - &n_elements); - - db = G_MAXSHORT; - stencil = G_MAXSHORT; - mipmap = 0; - rgba = 0; - - for (i = 0; i < n_elements; i++) - { - XVisualInfo *vi; - int visual_depth; - - vi = glx_renderer->glXGetVisualFromFBConfig (dpy, fbconfigs[i]); - if (vi == NULL) - continue; - - visual_depth = vi->depth; - - XFree (vi); - - if (visual_depth != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_ALPHA_SIZE, - &alpha); - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BUFFER_SIZE, - &value); - if (value != depth && (value - alpha) != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STEREO, - &value); - if (!!value != !!stereo) - continue; - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_SAMPLES, - &value); - if (value > 1) - continue; - } - - value = 0; - if (depth == 32) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value); - if (value) - rgba = 1; - } - - if (!value) - { - if (rgba) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGB_EXT, - &value); - if (!value) - continue; - } - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_DOUBLEBUFFER, - &value); - if (value > db) - continue; - - db = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STENCIL_SIZE, - &value); - if (value > stencil) - continue; - - stencil = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); - - if (value < mipmap) - continue; - - mipmap = value; - - *fbconfig_ret = fbconfigs[i]; - *can_mipmap_ret = mipmap; - found = TRUE; - } - - if (n_elements) - XFree (fbconfigs); - - glx_display->glx_cached_configs[spare_cache_slot].depth = depth; - glx_display->glx_cached_configs[spare_cache_slot].found = found; - glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; - glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; - - return found; -} - -static gboolean -try_create_glx_pixmap (CoglContext *context, - CoglTexturePixmapX11 *tex_pixmap, - gboolean mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - Display *dpy; - /* We have to initialize this *opaque* variable because gcc tries to - * be too smart for its own good and warns that the variable may be - * used uninitialized otherwise. */ - GLXFBConfig fb_config = (GLXFBConfig)0; - int attribs[7]; - int i = 0; - - unsigned int depth = tex_pixmap->depth; - Visual* visual = tex_pixmap->visual; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - dpy = xlib_renderer->xdpy; - - if (!get_fbconfig_for_depth (context, depth, - tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO, - &fb_config, - &glx_tex_pixmap->can_mipmap)) - { - COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", - depth); - return FALSE; - } - - if (!glx_tex_pixmap->can_mipmap) - mipmap = FALSE; - - attribs[i++] = GLX_TEXTURE_FORMAT_EXT; - - /* Check whether an alpha channel is used by comparing the total - * number of 1-bits in color masks against the color depth requested - * by the client. - */ - if (_cogl_util_popcountl (visual->red_mask | - visual->green_mask | - visual->blue_mask) == depth) - attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; - else - attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; - - attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; - attribs[i++] = mipmap; - - attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = GLX_TEXTURE_2D_EXT; - - attribs[i++] = None; - - /* We need to trap errors from glXCreatePixmap because it can - * sometimes fail during normal usage. For example on NVidia it gets - * upset if you try to create two GLXPixmaps for the same drawable. - */ - - mtk_x11_error_trap_push (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = - glx_renderer->glXCreatePixmap (dpy, - fb_config, - tex_pixmap->pixmap, - attribs); - glx_tex_pixmap->has_mipmap_space = mipmap; - - XSync (dpy, False); - - if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy)) - { - COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); - XSync (dpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - CoglContext *ctx = cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->can_mipmap = FALSE; - glx_tex_pixmap->has_mipmap_space = FALSE; - - glx_tex_pixmap->left.glx_tex = NULL; - glx_tex_pixmap->right.glx_tex = NULL; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; - - tex_pixmap->winsys = glx_tex_pixmap; - - if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) - { - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); - return FALSE; - } - - return TRUE; -} - -static void -free_glx_pixmap (CoglContext *context, - CoglTexturePixmapGLX *glx_tex_pixmap) -{ - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - - if (glx_tex_pixmap->left.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - if (glx_tex_pixmap->right.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_RIGHT_EXT); - - /* FIXME - we need to trap errors and synchronize here because - * of ordering issues between the XPixmap destruction and the - * GLXPixmap destruction. - * - * If the X pixmap is destroyed, the GLX pixmap is destroyed as - * well immediately, and thus, when Cogl calls glXDestroyPixmap() - * it'll cause a BadDrawable error. - * - * this is technically a bug in the X server, which should not - * destroy either pixmaps until the call to glXDestroyPixmap(); so - * at some point we should revisit this code and remove the - * trap+sync after verifying that the destruction is indeed safe. - * - * for reference, see: - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 - */ - mtk_x11_error_trap_push (xlib_renderer->xdpy); - glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap); - XSync (xlib_renderer->xdpy, False); - mtk_x11_error_trap_pop (xlib_renderer->xdpy); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - if (!tex_pixmap->winsys) - return; - - glx_tex_pixmap = tex_pixmap->winsys; - - free_glx_pixmap (cogl_texture_get_context (COGL_TEXTURE (tex_pixmap)), - glx_tex_pixmap); - - if (glx_tex_pixmap->left.glx_tex) - g_object_unref (glx_tex_pixmap->left.glx_tex); - - if (glx_tex_pixmap->right.glx_tex) - g_object_unref (glx_tex_pixmap->right.glx_tex); - - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = cogl_texture_get_context (tex); - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglPixmapTextureEyeGLX *texture_info; - int buffer; - CoglGLXRenderer *glx_renderer; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - texture_info = &glx_tex_pixmap->right; - buffer = GLX_FRONT_RIGHT_EXT; - } - else - { - texture_info = &glx_tex_pixmap->left; - buffer = GLX_FRONT_LEFT_EXT; - } - - /* If we don't have a GLX pixmap then fallback */ - if (glx_tex_pixmap->glx_pixmap == None) - return FALSE; - - glx_renderer = ctx->display->renderer->winsys; - - /* Lazily create a texture to hold the pixmap */ - if (texture_info->glx_tex == NULL) - { - CoglPixelFormat texture_format; - GError *error = NULL; - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - texture_info->glx_tex = - cogl_texture_2d_new_with_size (ctx, - cogl_texture_get_width (tex), - cogl_texture_get_height (tex)); - - _cogl_texture_set_internal_format (tex, texture_format); - - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created: %s", - tex_pixmap, error->message); - g_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - - if (needs_mipmap) - { - /* If we can't support mipmapping then temporarily fallback */ - if (!glx_tex_pixmap->can_mipmap) - return FALSE; - - /* Recreate the GLXPixmap if it wasn't previously created with a - * mipmap tree */ - if (!glx_tex_pixmap->has_mipmap_space) - { - free_glx_pixmap (ctx, glx_tex_pixmap); - - COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap " - "support for %p", tex_pixmap); - if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE)) - - { - /* If the pixmap failed then we'll permanently fallback - * to using XImage. This shouldn't happen. */ - COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage " - "updates for %p because creating the GLXPixmap " - "with mipmap support failed", tex_pixmap); - - if (texture_info->glx_tex) - g_object_unref (texture_info->glx_tex); - return FALSE; - } - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - } - } - - if (texture_info->bind_tex_image_queued) - { - GLuint gl_handle, gl_target; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (ctx->display->renderer); - - cogl_texture_get_gl_texture (texture_info->glx_tex, - &gl_handle, &gl_target); - - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - if (texture_info->pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer); - - glx_renderer->glXBindTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer, - NULL); - - /* According to the recommended usage in the spec for - * GLX_EXT_texture_pixmap we should release the texture after - * we've finished drawing with it and it is undefined what - * happens if you render to a pixmap that is bound to a texture. - * However that would require the texture backend to know when - * Cogl has finished painting and it may be more expensive to - * keep unbinding the texture. Leaving it bound appears to work - * on Mesa and NVidia drivers and it is also what Compiz does so - * it is probably ok */ - - texture_info->bind_tex_image_queued = FALSE; - texture_info->pixmap_bound = TRUE; - - _cogl_texture_2d_externally_modified (texture_info->glx_tex); - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - return glx_tex_pixmap->right.glx_tex; - else - return glx_tex_pixmap->left.glx_tex; -} - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable) -{ - CoglContextGLX *glx_context = context->winsys; - - glx_context->current_drawable = drawable; -} - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context) -{ - CoglContextGLX *glx_context = context->winsys; - - return glx_context->current_drawable; -} - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .id = COGL_WINSYS_ID_GLX, - .name = "GLX", - .constraints = (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB), - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .renderer_outputs_changed = _cogl_winsys_renderer_outputs_changed, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - .texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create, - .texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free, - .texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update, - .texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify, - .texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture, - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index d627617d6348012c5781f6a575c50d9749fb6a6d..83523a6517de5c4a934dec0a7c593a60cac372b9 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -59,7 +59,6 @@ typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ typedef struct _CoglWinsysVtable { - CoglWinsysID id; CoglRendererConstraint constraints; const char *name; diff --git a/config.h.meson b/config.h.meson index 9919bd4d0430db5ad2ba6b3984b7aa6859e25311..fd704312e4ddbaa18d85b2e7938f2c572a4ab131 100644 --- a/config.h.meson +++ b/config.h.meson @@ -28,9 +28,6 @@ /* Defined if EGLDevice support is enabled */ #mesondefine HAVE_EGL_DEVICE -/* Have GLX for rendering */ -#mesondefine HAVE_GLX - #mesondefine HAVE_EGL_PLATFORM_XLIB /* Have GL for rendering */ diff --git a/meson.build b/meson.build index 817ad1506b243de3c7ae58610013bc04c058a24d..d34ad4dde02cba513c03969e6971fdf0319f844b 100644 --- a/meson.build +++ b/meson.build @@ -193,13 +193,6 @@ if have_egl egl_dep = dependency('egl') endif -have_glx = get_option('glx') and have_x11_client -if have_glx - if not have_gl - error('GLX support requires OpenGL to be enabled') - endif -endif - have_egl_xlib = have_egl and have_x11_client have_gles2 = get_option('gles2') @@ -550,7 +543,6 @@ cdata.set_quoted('PACKAGE_NAME', meson.project_name()) cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) cdata.set('HAVE_EGL', have_egl) -cdata.set('HAVE_GLX', have_glx) cdata.set('HAVE_EGL_PLATFORM_XLIB', have_egl_xlib) cdata.set('HAVE_GL', have_gl) cdata.set('HAVE_GLES2', have_gles2) @@ -733,7 +725,6 @@ summary('debug', get_option('debug'), section: 'Build Configuration') summary('OpenGL', have_gl, section: 'Rendering APIs') summary('GLES2', have_gles2, section: 'Rendering APIs') summary('EGL', have_egl, section: 'Rendering APIs') -summary('GLX', have_glx, section: 'Rendering APIs') summary('Wayland', have_wayland, section: 'Options') summary('Wayland EGLStream', have_wayland_eglstream, section: 'Options') diff --git a/meson_options.txt b/meson_options.txt index 158a3c101e3b61b21360b8f7a27b3792cfdba944..594086114c85c153f3c6097192d471a55b25e5f1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -27,11 +27,6 @@ option('egl', value: true, description: 'Enable EGL support' ) -option('glx', - type: 'boolean', - value: true, - description: 'Enable GLX support' -) option('wayland', type: 'boolean', diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index aa76d018ca29b56271d34d81bf39995e14093884..5fbc6db931888d6a57de8b295b5473d2f72cfd92 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1255,7 +1255,6 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) vtable = *_cogl_winsys_egl_get_vtable (); - vtable.id = COGL_WINSYS_ID_CUSTOM; vtable.name = "EGL_KMS"; vtable.renderer_connect = meta_renderer_native_connect; diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c index 3d714efc21789a39c176ed0a51be43e7af6e3a1c..5e72a82d15dccb7f41ac513e2a72fe9c68795011 100644 --- a/src/backends/x11/meta-renderer-x11.c +++ b/src/backends/x11/meta-renderer-x11.c @@ -40,9 +40,6 @@ #ifdef HAVE_EGL #include "cogl/winsys/cogl-winsys-egl-x11-private.h" #endif -#ifdef HAVE_GLX -#include "cogl/winsys/cogl-winsys-glx-private.h" -#endif G_DEFINE_TYPE (MetaRendererX11, meta_renderer_x11, META_TYPE_RENDERER) @@ -57,16 +54,11 @@ get_x11_cogl_winsys_vtable (CoglRenderer *renderer) switch (renderer->driver) { case COGL_DRIVER_GLES2: + case COGL_DRIVER_GL3: #ifdef HAVE_EGL_PLATFORM_XLIB return _cogl_winsys_egl_xlib_get_vtable (); #else break; -#endif - case COGL_DRIVER_GL3: -#ifdef HAVE_GLX - return _cogl_winsys_glx_get_vtable (); -#else - break; #endif case COGL_DRIVER_ANY: case COGL_DRIVER_NOP: diff --git a/src/backends/x11/meta-stage-x11.c b/src/backends/x11/meta-stage-x11.c index cb6d533da0182e4cc685c373f14b8d69d90f7206..5a5b224300db52d1b22db65c2c74d80614699077 100644 --- a/src/backends/x11/meta-stage-x11.c +++ b/src/backends/x11/meta-stage-x11.c @@ -270,31 +270,12 @@ create_onscreen (CoglContext *cogl_context, int width, int height) { - CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); - CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_display); - - switch (cogl_renderer_get_winsys_id (cogl_renderer)) - { - case COGL_WINSYS_ID_GLX: -#ifdef HAVE_GLX - return COGL_ONSCREEN (cogl_onscreen_glx_new (cogl_context, - width, height)); -#else - g_assert_not_reached (); - break; -#endif - case COGL_WINSYS_ID_EGL_XLIB: #ifdef HAVE_EGL - return COGL_ONSCREEN (cogl_onscreen_xlib_new (cogl_context, - width, height)); + return COGL_ONSCREEN (cogl_onscreen_xlib_new (cogl_context, width, height)); #else - g_assert_not_reached (); - break; + g_assert_not_reached (); + return NULL; #endif - default: - g_assert_not_reached (); - return NULL; - } } static gboolean diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c index 1267dd4f2ca1a574a5eac13e5bc90091dca31b6b..41f0cea1a01e4de0a8008d4f1ee47b5166a36983 100644 --- a/src/compositor/meta-sync-ring.c +++ b/src/compositor/meta-sync-ring.c @@ -34,7 +34,6 @@ #include #include -#include #include #include "clutter/clutter.h" @@ -438,7 +437,7 @@ meta_sync_ring_init (Display *xdisplay) g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); } /* Since the connection we create the X fences on isn't the same as - * the one used for the GLX context, we need to XSync() here to + * the one used for the EGL context, we need to XSync() here to * ensure glImportSync() succeeds. */ XSync (xdisplay, False); for (i = 0; i < NUM_SYNCS; ++i)