From e9f437167fafeae176f64afd67415da538553c55 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 10 Dec 2014 19:36:12 +0100 Subject: [PATCH] window: add toplevel API to determine a visual id. Add GstVaapiWindowClass::get_visual_id() function hook to help find the best suitable visual id for the supplied window. While doing so, also simplify the process by which an X11 window is created with a desired Visual, i.e. now use a visual id instead of a Visual object. --- gst-libs/gst/vaapi/gstvaapiutils_x11.c | 43 +++++++++++++++----- gst-libs/gst/vaapi/gstvaapiutils_x11.h | 3 +- gst-libs/gst/vaapi/gstvaapiwindow_glx.c | 10 ++--- gst-libs/gst/vaapi/gstvaapiwindow_priv.h | 4 ++ gst-libs/gst/vaapi/gstvaapiwindow_x11.c | 13 ++++-- gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h | 3 -- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.c b/gst-libs/gst/vaapi/gstvaapiutils_x11.c index 0b22aaef43..1f9fd0ba73 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.c @@ -68,18 +68,18 @@ static const int x11_event_mask = * @dpy: an X11 #Display * @w: the requested width, in pixels * @h: the requested height, in pixels - * @vis: the request visual - * @cmap: the request colormap + * @vid: the requested visual id + * @cmap: the requested colormap * - * Creates a border-less window with the specified dimensions. If @vis - * is %NULL, the default visual for @display will be used. If @cmap is + * Creates a border-less window with the specified dimensions. If @vid + * is zero, the default visual for @display will be used. If @cmap is * %None, no specific colormap will be bound to the window. Also note * the default background color is black. * * Return value: the newly created X #Window. */ Window -x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) +x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap) { Window rootwin, win; int screen, depth; @@ -87,14 +87,13 @@ x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) unsigned long xswa_mask; XWindowAttributes wattr; unsigned long black_pixel; + XVisualInfo visualInfo, *vi; + int num_visuals; screen = DefaultScreen (dpy); rootwin = RootWindow (dpy, screen); black_pixel = BlackPixel (dpy, screen); - if (!vis) - vis = DefaultVisual (dpy, screen); - XGetWindowAttributes (dpy, rootwin, &wattr); depth = wattr.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) @@ -109,13 +108,35 @@ x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap) xswa.colormap = cmap; } - win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, vis, - xswa_mask, &xswa); + if (vid) { + visualInfo.visualid = vid; + vi = XGetVisualInfo (dpy, VisualIDMask, &visualInfo, &num_visuals); + if (!vi || num_visuals < 1) + goto error_create_visual; + } else { + vi = &visualInfo; + XMatchVisualInfo (dpy, screen, depth, TrueColor, vi); + } + + win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, + vi->visual, xswa_mask, &xswa); + if (vi != &visualInfo) + XFree (vi); if (!win) - return None; + goto error_create_window; XSelectInput (dpy, win, x11_event_mask); return win; + + /* ERRORS */ +error_create_visual: + GST_ERROR ("failed to create X visual (id:%zu)", (gsize) visualInfo.visualid); + if (vi) + XFree (vi); + return None; +error_create_window: + GST_ERROR ("failed to create X window of size %ux%u", w, h); + return None; } gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiutils_x11.h b/gst-libs/gst/vaapi/gstvaapiutils_x11.h index ebc7380370..500a47fc39 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_x11.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_x11.h @@ -40,8 +40,7 @@ x11_untrap_errors (void); G_GNUC_INTERNAL Window -x11_create_window (Display * dpy, guint w, guint h, Visual * vis, - Colormap cmap); +x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap); G_GNUC_INTERNAL gboolean diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c index 722d522853..4005484bdc 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_glx.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_glx.c @@ -206,15 +206,15 @@ gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window, return TRUE; } -static Visual * -gst_vaapi_window_glx_get_visual (GstVaapiWindow * window) +static guintptr +gst_vaapi_window_glx_get_visual_id (GstVaapiWindow * window) { GstVaapiWindowGLXPrivate *const priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) - return NULL; - return priv->gl_context->visual->visual; + return 0; + return priv->gl_context->visual->visualid; } static void @@ -320,7 +320,7 @@ gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) klass->parent_resize = window_class->resize; klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; window_class->resize = gst_vaapi_window_glx_resize; - xwindow_class->get_visual = gst_vaapi_window_glx_get_visual; + window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id; xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap; } diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h index aac0361db5..36291c44d0 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_priv.h @@ -52,6 +52,7 @@ typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window, typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect); +typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window); /** * GstVaapiWindow: @@ -82,6 +83,8 @@ struct _GstVaapiWindow * @set_fullscreen: virtual function to change window fullscreen state * @resize: virtual function to resize a window * @render: virtual function to render a #GstVaapiSurface into a window + * @get_visual_id: virtual function to get the desired visual id used to + * create the window * * Base class for system-dependent windows. */ @@ -99,6 +102,7 @@ struct _GstVaapiWindowClass GstVaapiWindowResizeFunc resize; GstVaapiWindowRenderFunc render; GstVaapiWindowRenderPixmapFunc render_pixmap; + GstVaapiWindowGetVisualIdFunc get_visual_id; }; GstVaapiWindow * diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 18b361eff7..49fc97ad88 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -214,8 +214,9 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Window xid = GST_VAAPI_OBJECT_ID (window); - Visual *vis = NULL; + guint vid = 0; Colormap cmap = None; + const GstVaapiWindowClass *window_class; const GstVaapiWindowX11Class *klass; XWindowAttributes wattr; Atom atoms[2]; @@ -238,10 +239,14 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, return ok; } + window_class = GST_VAAPI_WINDOW_GET_CLASS (window); + if (window_class) { + if (window_class->get_visual_id) + vid = window_class->get_visual_id (window); + } + klass = GST_VAAPI_WINDOW_X11_GET_CLASS (window); if (klass) { - if (klass->get_visual) - vis = klass->get_visual (window); if (klass->get_colormap) cmap = klass->get_colormap (window); } @@ -252,7 +257,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width, priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; - xid = x11_create_window (dpy, *width, *height, vis, cmap); + xid = x11_create_window (dpy, *width, *height, vid, cmap); if (xid) XRaiseWindow (dpy, xid); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h index c14191f99a..c9d61cbf37 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11_priv.h @@ -72,8 +72,6 @@ struct _GstVaapiWindowX11 /** * GstVaapiWindowX11Class: - * @get_visual: virtual function to get the desired visual used to - * create the window * @get_colormap: virtual function to get the desired colormap used to * create the window * @@ -84,7 +82,6 @@ struct _GstVaapiWindowX11Class /*< private >*/ GstVaapiWindowClass parent_class; - Visual *(*get_visual) (GstVaapiWindow * window); Colormap (*get_colormap) (GstVaapiWindow * window); };