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.
This commit is contained in:
Gwenole Beauchesne 2014-12-10 19:36:12 +01:00
parent ff0a237458
commit e9f437167f
6 changed files with 51 additions and 25 deletions

View file

@ -68,18 +68,18 @@ static const int x11_event_mask =
* @dpy: an X11 #Display * @dpy: an X11 #Display
* @w: the requested width, in pixels * @w: the requested width, in pixels
* @h: the requested height, in pixels * @h: the requested height, in pixels
* @vis: the request visual * @vid: the requested visual id
* @cmap: the request colormap * @cmap: the requested colormap
* *
* Creates a border-less window with the specified dimensions. If @vis * Creates a border-less window with the specified dimensions. If @vid
* is %NULL, the default visual for @display will be used. If @cmap is * 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 * %None, no specific colormap will be bound to the window. Also note
* the default background color is black. * the default background color is black.
* *
* Return value: the newly created X #Window. * Return value: the newly created X #Window.
*/ */
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; Window rootwin, win;
int screen, depth; int screen, depth;
@ -87,14 +87,13 @@ x11_create_window (Display * dpy, guint w, guint h, Visual * vis, Colormap cmap)
unsigned long xswa_mask; unsigned long xswa_mask;
XWindowAttributes wattr; XWindowAttributes wattr;
unsigned long black_pixel; unsigned long black_pixel;
XVisualInfo visualInfo, *vi;
int num_visuals;
screen = DefaultScreen (dpy); screen = DefaultScreen (dpy);
rootwin = RootWindow (dpy, screen); rootwin = RootWindow (dpy, screen);
black_pixel = BlackPixel (dpy, screen); black_pixel = BlackPixel (dpy, screen);
if (!vis)
vis = DefaultVisual (dpy, screen);
XGetWindowAttributes (dpy, rootwin, &wattr); XGetWindowAttributes (dpy, rootwin, &wattr);
depth = wattr.depth; depth = wattr.depth;
if (depth != 15 && depth != 16 && depth != 24 && depth != 32) 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; xswa.colormap = cmap;
} }
win = XCreateWindow (dpy, rootwin, 0, 0, w, h, 0, depth, InputOutput, vis, if (vid) {
xswa_mask, &xswa); 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) if (!win)
return None; goto error_create_window;
XSelectInput (dpy, win, x11_event_mask); XSelectInput (dpy, win, x11_event_mask);
return win; 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 gboolean

View file

@ -40,8 +40,7 @@ x11_untrap_errors (void);
G_GNUC_INTERNAL G_GNUC_INTERNAL
Window Window
x11_create_window (Display * dpy, guint w, guint h, Visual * vis, x11_create_window (Display * dpy, guint w, guint h, guint vid, Colormap cmap);
Colormap cmap);
G_GNUC_INTERNAL G_GNUC_INTERNAL
gboolean gboolean

View file

@ -206,15 +206,15 @@ gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window,
return TRUE; return TRUE;
} }
static Visual * static guintptr
gst_vaapi_window_glx_get_visual (GstVaapiWindow * window) gst_vaapi_window_glx_get_visual_id (GstVaapiWindow * window)
{ {
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) if (!_gst_vaapi_window_glx_ensure_context (window, NULL))
return NULL; return 0;
return priv->gl_context->visual->visual; return priv->gl_context->visual->visualid;
} }
static void static void
@ -320,7 +320,7 @@ gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass)
klass->parent_resize = window_class->resize; klass->parent_resize = window_class->resize;
klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize; klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize;
window_class->resize = gst_vaapi_window_glx_resize; 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; xwindow_class->get_colormap = gst_vaapi_window_glx_get_colormap;
} }

View file

@ -52,6 +52,7 @@ typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window,
typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window, typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window,
GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * dst_rect); const GstVaapiRectangle * dst_rect);
typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window);
/** /**
* GstVaapiWindow: * GstVaapiWindow:
@ -82,6 +83,8 @@ struct _GstVaapiWindow
* @set_fullscreen: virtual function to change window fullscreen state * @set_fullscreen: virtual function to change window fullscreen state
* @resize: virtual function to resize a window * @resize: virtual function to resize a window
* @render: virtual function to render a #GstVaapiSurface into 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. * Base class for system-dependent windows.
*/ */
@ -99,6 +102,7 @@ struct _GstVaapiWindowClass
GstVaapiWindowResizeFunc resize; GstVaapiWindowResizeFunc resize;
GstVaapiWindowRenderFunc render; GstVaapiWindowRenderFunc render;
GstVaapiWindowRenderPixmapFunc render_pixmap; GstVaapiWindowRenderPixmapFunc render_pixmap;
GstVaapiWindowGetVisualIdFunc get_visual_id;
}; };
GstVaapiWindow * GstVaapiWindow *

View file

@ -214,8 +214,9 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window);
Window xid = GST_VAAPI_OBJECT_ID (window); Window xid = GST_VAAPI_OBJECT_ID (window);
Visual *vis = NULL; guint vid = 0;
Colormap cmap = None; Colormap cmap = None;
const GstVaapiWindowClass *window_class;
const GstVaapiWindowX11Class *klass; const GstVaapiWindowX11Class *klass;
XWindowAttributes wattr; XWindowAttributes wattr;
Atom atoms[2]; Atom atoms[2];
@ -238,10 +239,14 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
return ok; 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); klass = GST_VAAPI_WINDOW_X11_GET_CLASS (window);
if (klass) { if (klass) {
if (klass->get_visual)
vis = klass->get_visual (window);
if (klass->get_colormap) if (klass->get_colormap)
cmap = klass->get_colormap (window); 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 = atoms[0];
priv->atom_NET_WM_STATE_FULLSCREEN = atoms[1]; 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) if (xid)
XRaiseWindow (dpy, xid); XRaiseWindow (dpy, xid);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window);

View file

@ -72,8 +72,6 @@ struct _GstVaapiWindowX11
/** /**
* GstVaapiWindowX11Class: * 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 * @get_colormap: virtual function to get the desired colormap used to
* create the window * create the window
* *
@ -84,7 +82,6 @@ struct _GstVaapiWindowX11Class
/*< private >*/ /*< private >*/
GstVaapiWindowClass parent_class; GstVaapiWindowClass parent_class;
Visual *(*get_visual) (GstVaapiWindow * window);
Colormap (*get_colormap) (GstVaapiWindow * window); Colormap (*get_colormap) (GstVaapiWindow * window);
}; };