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
* @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

View file

@ -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

View file

@ -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;
}

View file

@ -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 *

View file

@ -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);

View file

@ -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);
};