cogl: Replace xlib error traps with Mtk ones

Replace these with Mtk error traps altogether, and avoid stacking
one API over the other here.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3230>
This commit is contained in:
Carlos Garnacho 2023-08-31 15:09:40 +02:00 committed by Marge Bot
parent 7224bb8a8d
commit 55e3b2e519
7 changed files with 30 additions and 190 deletions

View File

@ -1,45 +0,0 @@
/*
* Cogl
*
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2010,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 <X11/Xlib.h>
typedef struct _CoglXlibTrapState CoglXlibTrapState;
struct _CoglXlibTrapState
{
/* These values are intended to be internal to
* _cogl_xlib_{un,}trap_errors but they need to be in the header so
* that the struct can be allocated on the stack */
int (* old_error_handler) (Display *, XErrorEvent *);
int trapped_error_code;
CoglXlibTrapState *old_state;
};

View File

@ -33,7 +33,6 @@
#include <X11/Xutil.h>
#include "cogl/cogl-object-private.h"
#include "cogl/cogl-xlib-private.h"
#include "cogl/cogl-x11-renderer-private.h"
#include "cogl/cogl-context.h"
#include "cogl/cogl-output.h"
@ -44,10 +43,6 @@ typedef struct _CoglXlibRenderer
Display *xdpy;
/* Current top of the XError trap state stack. The actual memory for
these is expected to be allocated on the stack by the caller */
CoglXlibTrapState *trap_state;
unsigned long outputs_update_serial;
XVisualInfo *xvisinfo;
@ -59,35 +54,6 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error);
void
_cogl_xlib_renderer_disconnect (CoglRenderer *renderer);
/*
* cogl_xlib_renderer_trap_errors:
* @state: A temporary place to store data for the trap.
*
* Traps every X error until _cogl_xlib_renderer_untrap_errors()
* called. You should allocate an uninitialised CoglXlibTrapState
* struct on the stack to pass to this function. The same pointer
* should later be passed to _cogl_xlib_renderer_untrap_errors().
*
* Calls to _cogl_xlib_renderer_trap_errors() can be nested as long as
* _cogl_xlib_renderer_untrap_errors() is called with the
* corresponding state pointers in reverse order.
*/
void
_cogl_xlib_renderer_trap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
/*
* cogl_xlib_renderer_untrap_errors:
* @state: The state that was passed to _cogl_xlib_renderer_trap_errors().
*
* Removes the X error trap and returns the current status.
*
* Return value: the trapped error code, or 0 for success
*/
int
_cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state);
CoglXlibRenderer *
_cogl_xlib_renderer_get_data (CoglRenderer *renderer);

View File

@ -41,6 +41,7 @@
#include "cogl/cogl-x11-renderer-private.h"
#include "cogl/cogl-poll-private.h"
#include "cogl/winsys/cogl-winsys-private.h"
#include "mtk/mtk-x11.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
@ -94,72 +95,6 @@ unregister_xlib_renderer (CoglRenderer *renderer)
_cogl_xlib_renderers = g_list_remove (_cogl_xlib_renderers, renderer);
}
static CoglRenderer *
get_renderer_for_xdisplay (Display *xdpy)
{
GList *l;
for (l = _cogl_xlib_renderers; l; l = l->next)
{
CoglRenderer *renderer = l->data;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
if (xlib_renderer->xdpy == xdpy)
return renderer;
}
return NULL;
}
static int
error_handler (Display *xdpy,
XErrorEvent *error)
{
CoglRenderer *renderer;
CoglXlibRenderer *xlib_renderer;
renderer = get_renderer_for_xdisplay (xdpy);
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
g_assert (xlib_renderer->trap_state);
xlib_renderer->trap_state->trapped_error_code = error->error_code;
return 0;
}
void
_cogl_xlib_renderer_trap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state)
{
CoglXlibRenderer *xlib_renderer;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
state->trapped_error_code = 0;
state->old_error_handler = XSetErrorHandler (error_handler);
state->old_state = xlib_renderer->trap_state;
xlib_renderer->trap_state = state;
}
int
_cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer,
CoglXlibTrapState *state)
{
CoglXlibRenderer *xlib_renderer;
xlib_renderer = _cogl_xlib_renderer_get_data (renderer);
g_assert (state == xlib_renderer->trap_state);
XSetErrorHandler (state->old_error_handler);
xlib_renderer->trap_state = state->old_state;
return state->trapped_error_code;
}
static Display *
assert_xlib_display (CoglRenderer *renderer, GError **error)
{
@ -218,7 +153,6 @@ update_outputs (CoglRenderer *renderer,
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
XRRScreenResources *resources;
CoglXlibTrapState state;
gboolean error = FALSE;
GList *new_outputs = NULL;
GList *l, *m;
@ -230,7 +164,7 @@ update_outputs (CoglRenderer *renderer,
resources = XRRGetScreenResources (xlib_renderer->xdpy,
DefaultRootWindow (xlib_renderer->xdpy));
_cogl_xlib_renderer_trap_errors (renderer, &state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
for (i = 0; resources && i < resources->ncrtc && !error; i++)
{
@ -386,7 +320,7 @@ update_outputs (CoglRenderer *renderer,
}
g_list_free_full (new_outputs, (GDestroyNotify)cogl_object_unref);
_cogl_xlib_renderer_untrap_errors (renderer, &state);
mtk_x11_error_trap_pop (xlib_renderer->xdpy);
if (changed)
{
@ -515,8 +449,6 @@ _cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
&randr_error))
x11_renderer->randr_base = -1;
xlib_renderer->trap_state = NULL;
if (renderer->xlib_enable_event_retrieval)
{
_cogl_poll_renderer_add_fd (renderer,

View File

@ -361,7 +361,6 @@ if have_x11_client
'cogl-x11-onscreen.c',
'cogl-x11-onscreen.h',
'cogl-x11-renderer-private.h',
'cogl-xlib-private.h',
'cogl-xlib-renderer-private.h',
'cogl-xlib-renderer.c',
'winsys/cogl-texture-pixmap-x11-private.h',

View File

@ -38,6 +38,7 @@
#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
{
@ -114,7 +115,6 @@ cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer,
{
int width;
int height;
CoglXlibTrapState state;
XVisualInfo *xvisinfo;
XSetWindowAttributes xattr;
unsigned long mask;
@ -123,7 +123,7 @@ cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer,
width = cogl_framebuffer_get_width (framebuffer);
height = cogl_framebuffer_get_height (framebuffer);
_cogl_xlib_renderer_trap_errors (display->renderer, &state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy,
fbconfig);
@ -162,7 +162,7 @@ cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer,
XFree (xvisinfo);
XSync (xlib_renderer->xdpy, False);
xerror = _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy);
if (xerror)
{
char message[1000];
@ -219,7 +219,6 @@ cogl_onscreen_glx_dispose (GObject *object)
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglXlibTrapState old_state;
GLXDrawable drawable;
G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object);
@ -229,7 +228,7 @@ cogl_onscreen_glx_dispose (GObject *object)
if (onscreen_glx->glxwin != None ||
onscreen_glx->xwin != None)
{
_cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
drawable =
onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin;
@ -272,8 +271,7 @@ cogl_onscreen_glx_dispose (GObject *object)
XSync (xlib_renderer->xdpy, False);
_cogl_xlib_renderer_untrap_errors (context->display->renderer,
&old_state);
mtk_x11_error_trap_pop (xlib_renderer->xdpy);
}
}
@ -287,7 +285,6 @@ cogl_onscreen_glx_bind (CoglOnscreen *onscreen)
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglXlibTrapState old_state;
GLXDrawable drawable;
drawable =
@ -296,7 +293,7 @@ cogl_onscreen_glx_bind (CoglOnscreen *onscreen)
if (cogl_context_glx_get_current_drawable (context) == drawable)
return;
_cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
COGL_NOTE (WINSYS,
"MakeContextCurrent dpy: %p, window: 0x%x, context: %p",
@ -335,8 +332,7 @@ cogl_onscreen_glx_bind (CoglOnscreen *onscreen)
XSync (xlib_renderer->xdpy, False);
/* FIXME: We should be reporting a GError here */
if (_cogl_xlib_renderer_untrap_errors (context->display->renderer,
&old_state))
if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy))
{
g_warning ("X Error received while making drawable 0x%08lX current",
drawable);
@ -539,10 +535,8 @@ 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);
CoglDisplay *display = context->display;
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer);
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
CoglXlibTrapState old_state;
GLXDrawable drawable;
unsigned int age = 0;
@ -550,9 +544,9 @@ cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen)
return 0;
drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin;
_cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age);
_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state);
mtk_x11_error_trap_pop (xlib_renderer->xdpy);
return age;
}

View File

@ -34,6 +34,7 @@
#include "cogl/cogl-xlib-renderer-private.h"
#include "cogl/winsys/cogl-onscreen-egl.h"
#include "cogl/winsys/cogl-winsys-egl-x11-private.h"
#include "mtk/mtk-x11.h"
struct _CoglOnscreenXlib
{
@ -68,7 +69,6 @@ create_xwindow (CoglOnscreenXlib *onscreen_xlib,
Window xwin;
int width;
int height;
CoglXlibTrapState state;
XVisualInfo *xvisinfo;
XSetWindowAttributes xattr;
unsigned long mask;
@ -77,7 +77,7 @@ create_xwindow (CoglOnscreenXlib *onscreen_xlib,
width = cogl_framebuffer_get_width (framebuffer);
height = cogl_framebuffer_get_height (framebuffer);
_cogl_xlib_renderer_trap_errors (display->renderer, &state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config);
if (xvisinfo == NULL)
@ -117,8 +117,7 @@ create_xwindow (CoglOnscreenXlib *onscreen_xlib,
XFree (xvisinfo);
XSync (xlib_renderer->xdpy, False);
xerror =
_cogl_xlib_renderer_untrap_errors (display->renderer, &state);
xerror = mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy);
if (xerror)
{
char message[1000];
@ -184,16 +183,14 @@ cogl_onscreen_xlib_dispose (GObject *object)
CoglRenderer *renderer = context->display->renderer;
CoglXlibRenderer *xlib_renderer =
_cogl_xlib_renderer_get_data (renderer);
CoglXlibTrapState old_state;
_cogl_xlib_renderer_trap_errors (renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
XDestroyWindow (xlib_renderer->xdpy, onscreen_xlib->xwin);
onscreen_xlib->xwin = None;
XSync (xlib_renderer->xdpy, False);
if (_cogl_xlib_renderer_untrap_errors (renderer,
&old_state) != Success)
if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy))
g_warning ("X Error while destroying X window");
onscreen_xlib->xwin = None;

View File

@ -56,6 +56,7 @@
#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 <stdlib.h>
#include <sys/types.h>
@ -642,16 +643,15 @@ create_gl3_context (CoglDisplay *display,
DefaultScreen (xlib_renderer->xdpy)),
"GLX_NV_robustness_video_memory_purge"))
{
CoglXlibTrapState old_state;
GLXContext ctx;
_cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
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 (!_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) && ctx)
if (!mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) && ctx)
return ctx;
}
@ -674,7 +674,6 @@ create_context (CoglDisplay *display, GError **error)
XSetWindowAttributes attrs;
XVisualInfo *xvisinfo;
GLXDrawable dummy_drawable;
CoglXlibTrapState old_state;
g_return_val_if_fail (glx_display->glx_context == NULL, TRUE);
@ -698,7 +697,7 @@ create_context (CoglDisplay *display, GError **error)
COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)",
xlib_renderer->xdpy);
_cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
if (display->renderer->driver == COGL_DRIVER_GL3)
glx_display->glx_context = create_gl3_context (display, config);
@ -710,7 +709,7 @@ create_context (CoglDisplay *display, GError **error)
NULL,
True);
if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) ||
if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy) ||
glx_display->glx_context == NULL)
{
g_set_error_literal (error, COGL_WINSYS_ERROR,
@ -742,7 +741,7 @@ create_context (CoglDisplay *display, GError **error)
return FALSE;
}
_cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
attrs.override_redirect = True;
attrs.colormap = XCreateColormap (xlib_renderer->xdpy,
@ -789,7 +788,7 @@ create_context (CoglDisplay *display, GError **error)
xlib_renderer->xvisinfo = xvisinfo;
if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state))
if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy))
{
g_set_error_literal (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_CONTEXT,
@ -1052,7 +1051,6 @@ try_create_glx_pixmap (CoglContext *context,
GLXFBConfig fb_config = (GLXFBConfig)0;
int attribs[7];
int i = 0;
CoglXlibTrapState trap_state;
unsigned int depth = tex_pixmap->depth;
Visual* visual = tex_pixmap->visual;
@ -1101,7 +1099,7 @@ try_create_glx_pixmap (CoglContext *context,
* upset if you try to create two GLXPixmaps for the same drawable.
*/
_cogl_xlib_renderer_trap_errors (renderer, &trap_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
glx_tex_pixmap->glx_pixmap =
glx_renderer->glXCreatePixmap (dpy,
@ -1112,13 +1110,13 @@ try_create_glx_pixmap (CoglContext *context,
XSync (dpy, False);
if (_cogl_xlib_renderer_untrap_errors (renderer, &trap_state))
if (mtk_x11_error_trap_pop_with_return (xlib_renderer->xdpy))
{
COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap);
_cogl_xlib_renderer_trap_errors (renderer, &trap_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap);
XSync (dpy, False);
_cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
mtk_x11_error_trap_pop (xlib_renderer->xdpy);
glx_tex_pixmap->glx_pixmap = None;
return FALSE;
@ -1169,7 +1167,6 @@ static void
free_glx_pixmap (CoglContext *context,
CoglTexturePixmapGLX *glx_tex_pixmap)
{
CoglXlibTrapState trap_state;
CoglRenderer *renderer;
CoglXlibRenderer *xlib_renderer;
CoglGLXRenderer *glx_renderer;
@ -1203,11 +1200,11 @@ free_glx_pixmap (CoglContext *context,
* for reference, see:
* http://bugzilla.clutter-project.org/show_bug.cgi?id=2324
*/
_cogl_xlib_renderer_trap_errors (renderer, &trap_state);
mtk_x11_error_trap_push (xlib_renderer->xdpy);
glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy,
glx_tex_pixmap->glx_pixmap);
XSync (xlib_renderer->xdpy, False);
_cogl_xlib_renderer_untrap_errors (renderer, &trap_state);
mtk_x11_error_trap_pop (xlib_renderer->xdpy);
glx_tex_pixmap->glx_pixmap = None;
glx_tex_pixmap->left.pixmap_bound = FALSE;