mirror of
				https://github.com/tiagovignatti/intel-gpu-tools.git
				synced 2025-11-04 12:07:12 +00:00 
			
		
		
		
	overlay: Add a X11 window backend
Useful for remote hosts. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
		
							parent
							
								
									1c1a279806
								
							
						
					
					
						commit
						34e4780c8e
					
				
							
								
								
									
										13
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								configure.ac
									
									
									
									
									
								
							@ -72,9 +72,18 @@ AC_SUBST(ASSEMBLER_WARN_CFLAGS)
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(DRM, [libdrm_intel >= 2.4.45 libdrm])
 | 
			
		||||
PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
 | 
			
		||||
PKG_CHECK_MODULES(OVERLAY, [xv x11 xext], enable_overlay=yes, enable_overlay=no)
 | 
			
		||||
PKG_CHECK_MODULES(OVERLAY_XVLIB, [xv x11 xext], enable_overlay_xvlib=yes, enable_overlay_xvlib=no)
 | 
			
		||||
PKG_CHECK_MODULES(OVERLAY_XLIB, [cairo-xlib], enable_overlay_xlib=yes, enable_overlay_xlib=no)
 | 
			
		||||
 | 
			
		||||
AM_CONDITIONAL(BUILD_OVERLAY, [test "x$enable_overlay" = xyes])
 | 
			
		||||
AM_CONDITIONAL(BUILD_OVERLAY_XVLIB, [test "x$enable_overlay_xvlib" = xyes])
 | 
			
		||||
AM_CONDITIONAL(BUILD_OVERLAY_XLIB, [test "x$enable_overlay_xlib" = xyes])
 | 
			
		||||
AM_CONDITIONAL(BUILD_OVERLAY, [test "x$enable_overlay_xlib" = xyes -o "x$enable_overlay_xvlib"])
 | 
			
		||||
if test x$enable_overlay_xvlib = xyes; then
 | 
			
		||||
	AC_DEFINE(HAVE_OVERLAY_XVLIB, 1, [Enable XV backend])
 | 
			
		||||
fi
 | 
			
		||||
if test x$enable_overlay_xlib = xyes; then
 | 
			
		||||
	AC_DEFINE(HAVE_OVERLAY_XLIB, 1, [Enable X backend])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# for testdisplay
 | 
			
		||||
PKG_CHECK_MODULES(CAIRO, [cairo >= 1.12.0])
 | 
			
		||||
 | 
			
		||||
@ -23,11 +23,26 @@ intel_gpu_overlay_SOURCES = \
 | 
			
		||||
	gpu-freq.c \
 | 
			
		||||
	igfx.h \
 | 
			
		||||
	igfx.c \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if BUILD_OVERLAY_XLIB
 | 
			
		||||
AM_CFLAGS += $(OVERLAY_XLIB_CFLAGS)
 | 
			
		||||
LDADD += $(OVERLAY_XLIB_LIBS)
 | 
			
		||||
intel_gpu_overlay_SOURCES += \
 | 
			
		||||
	x11/x11-window.c \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if BUILD_OVERLAY_XVLIB
 | 
			
		||||
AM_CFLAGS += $(OVERLAY_XVLIB_CFLAGS)
 | 
			
		||||
LDADD += $(OVERLAY_XVLIB_LIBS)
 | 
			
		||||
intel_gpu_overlay_SOURCES += \
 | 
			
		||||
	x11/dri2.c \
 | 
			
		||||
	x11/dri2.h \
 | 
			
		||||
	x11/rgb2yuv.c \
 | 
			
		||||
	x11/rgb2yuv.h \
 | 
			
		||||
	x11/x11-overlay.c \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST=README
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,8 @@ static void overlay_show(cairo_surface_t *surface)
 | 
			
		||||
{
 | 
			
		||||
	struct overlay *overlay;
 | 
			
		||||
 | 
			
		||||
	cairo_surface_flush(surface);
 | 
			
		||||
 | 
			
		||||
	overlay = cairo_surface_get_user_data(surface, &overlay_key);
 | 
			
		||||
	if (overlay == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
@ -510,6 +512,8 @@ int main(int argc, char **argv)
 | 
			
		||||
	ctx.width = 640;
 | 
			
		||||
	ctx.height = 236;
 | 
			
		||||
	ctx.surface = x11_overlay_create(POS_TOP_RIGHT, &ctx.width, &ctx.height);
 | 
			
		||||
	if (ctx.surface == NULL)
 | 
			
		||||
		ctx.surface = x11_window_create(POS_TOP_RIGHT, &ctx.width, &ctx.height);
 | 
			
		||||
	if (ctx.surface == NULL)
 | 
			
		||||
		return ENOMEM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,7 @@
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include"config.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
 | 
			
		||||
enum position {
 | 
			
		||||
@ -33,5 +37,16 @@ struct overlay {
 | 
			
		||||
 | 
			
		||||
extern const cairo_user_data_key_t overlay_key;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_OVERLAY_XVLIB
 | 
			
		||||
cairo_surface_t *x11_overlay_create(enum position pos, int *width, int *height);
 | 
			
		||||
void x11_overlay_stop(void);
 | 
			
		||||
#else
 | 
			
		||||
static inline cairo_surface_t *x11_overlay_create(enum position pos, int *width, int *height) { return NULL; }
 | 
			
		||||
static inline void x11_overlay_stop(void) { }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_OVERLAY_XLIB
 | 
			
		||||
cairo_surface_t *x11_window_create(enum position pos, int *width, int *height);
 | 
			
		||||
#else
 | 
			
		||||
static inline cairo_surface_t *x11_window_create(enum position pos, int *width, int *height) { return NULL; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										186
									
								
								overlay/x11/x11-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								overlay/x11/x11-window.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <cairo-xlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "../overlay.h"
 | 
			
		||||
 | 
			
		||||
struct x11_window {
 | 
			
		||||
	struct overlay base;
 | 
			
		||||
	Display *dpy;
 | 
			
		||||
	Window win;
 | 
			
		||||
	int width, height;
 | 
			
		||||
	int visible;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline struct x11_window *to_x11_window(struct overlay *o)
 | 
			
		||||
{
 | 
			
		||||
	return (struct x11_window *)o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int noop(Display *dpy, XErrorEvent *event)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void x11_window_show(struct overlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
	struct x11_window *priv = to_x11_window(overlay);
 | 
			
		||||
 | 
			
		||||
	if (!priv->visible) {
 | 
			
		||||
		XMapWindow(priv->dpy, priv->win);
 | 
			
		||||
		priv->visible = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	XFlush(priv->dpy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void x11_window_position(struct overlay *overlay,
 | 
			
		||||
				enum position p)
 | 
			
		||||
{
 | 
			
		||||
	struct x11_window *priv = to_x11_window(overlay);
 | 
			
		||||
	Screen *scr = ScreenOfDisplay(priv->dpy, DefaultScreen(priv->dpy));
 | 
			
		||||
	int x, y;
 | 
			
		||||
 | 
			
		||||
	switch (p & 7) {
 | 
			
		||||
	default:
 | 
			
		||||
	case 0: x = 0; break;
 | 
			
		||||
	case 1: x = (scr->width - priv->width)/2; break;
 | 
			
		||||
	case 2: x = scr->width - priv->width; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch ((p >> 4) & 7) {
 | 
			
		||||
	default:
 | 
			
		||||
	case 0: y = 0; break;
 | 
			
		||||
	case 1: y = (scr->height - priv->height)/2; break;
 | 
			
		||||
	case 2: y = scr->height - priv->height; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (priv->visible) {
 | 
			
		||||
		XMoveWindow(priv->dpy, priv->win, x, y);
 | 
			
		||||
		XFlush(priv->dpy);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void x11_window_hide(struct overlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
	struct x11_window *priv = to_x11_window(overlay);
 | 
			
		||||
	if (priv->visible) {
 | 
			
		||||
		XUnmapWindow(priv->dpy, priv->win);
 | 
			
		||||
		XFlush(priv->dpy);
 | 
			
		||||
		priv->visible = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void x11_window_destroy(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct x11_window *priv = data;
 | 
			
		||||
	XDestroyWindow(priv->dpy, priv->win);
 | 
			
		||||
	XCloseDisplay(priv->dpy);
 | 
			
		||||
	free(priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cairo_surface_t *
 | 
			
		||||
x11_window_create(enum position position, int *width, int *height)
 | 
			
		||||
{
 | 
			
		||||
	Display *dpy;
 | 
			
		||||
	Screen *scr;
 | 
			
		||||
	Window win;
 | 
			
		||||
	int screen;
 | 
			
		||||
	cairo_surface_t *surface;
 | 
			
		||||
	XSetWindowAttributes attr;
 | 
			
		||||
	struct x11_window *priv;
 | 
			
		||||
	int x, y, w, h;
 | 
			
		||||
 | 
			
		||||
	dpy = XOpenDisplay(NULL);
 | 
			
		||||
	if (dpy == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	screen = DefaultScreen(dpy);
 | 
			
		||||
	scr = XScreenOfDisplay(dpy, screen);
 | 
			
		||||
 | 
			
		||||
	XSetErrorHandler(noop);
 | 
			
		||||
 | 
			
		||||
	if (*width == -1) {
 | 
			
		||||
		w = scr->width;
 | 
			
		||||
		switch (position & 7) {
 | 
			
		||||
		default:
 | 
			
		||||
		case 0:
 | 
			
		||||
		case 2: w >>= 1; break;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (*width > scr->width) {
 | 
			
		||||
		w = scr->width;
 | 
			
		||||
	} else
 | 
			
		||||
		w = *width;
 | 
			
		||||
 | 
			
		||||
	if (*height == -1) {
 | 
			
		||||
		h = scr->height;
 | 
			
		||||
		switch ((position >> 4) & 7) {
 | 
			
		||||
		default:
 | 
			
		||||
		case 0:
 | 
			
		||||
		case 2: h >>= 1; break;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (*height > scr->height)
 | 
			
		||||
		h = scr->height;
 | 
			
		||||
	else
 | 
			
		||||
		h = *height;
 | 
			
		||||
 | 
			
		||||
	switch (position & 7) {
 | 
			
		||||
	default:
 | 
			
		||||
	case 0: x = 0; break;
 | 
			
		||||
	case 1: x = (scr->width - w)/2; break;
 | 
			
		||||
	case 2: x = scr->width - w; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch ((position >> 4) & 7) {
 | 
			
		||||
	default:
 | 
			
		||||
	case 0: y = 0; break;
 | 
			
		||||
	case 1: y = (scr->height - h)/2; break;
 | 
			
		||||
	case 2: y = scr->height - h; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attr.override_redirect = True;
 | 
			
		||||
	win = XCreateWindow(dpy, DefaultRootWindow(dpy),
 | 
			
		||||
			   x, y, w, h, 0,
 | 
			
		||||
			   DefaultDepth(dpy, screen),
 | 
			
		||||
			   InputOutput,
 | 
			
		||||
			   DefaultVisual(dpy, screen),
 | 
			
		||||
			   CWOverrideRedirect, &attr);
 | 
			
		||||
 | 
			
		||||
	surface = cairo_xlib_surface_create(dpy, win, DefaultVisual (dpy, screen), w, h);
 | 
			
		||||
	if (cairo_surface_status(surface))
 | 
			
		||||
		goto err_win;
 | 
			
		||||
 | 
			
		||||
	priv = malloc(sizeof(*priv));
 | 
			
		||||
	if (priv == NULL)
 | 
			
		||||
		goto err_surface;
 | 
			
		||||
 | 
			
		||||
	priv->base.surface = surface;
 | 
			
		||||
	priv->base.show = x11_window_show;
 | 
			
		||||
	priv->base.position = x11_window_position;
 | 
			
		||||
	priv->base.hide = x11_window_hide;
 | 
			
		||||
 | 
			
		||||
	priv->dpy = dpy;
 | 
			
		||||
	priv->win = win;
 | 
			
		||||
	priv->visible = false;
 | 
			
		||||
 | 
			
		||||
	priv->width = w;
 | 
			
		||||
	priv->height = h;
 | 
			
		||||
 | 
			
		||||
	cairo_surface_set_user_data(surface, &overlay_key, priv, x11_window_destroy);
 | 
			
		||||
 | 
			
		||||
	*width = w;
 | 
			
		||||
	*height = h;
 | 
			
		||||
	return surface;
 | 
			
		||||
 | 
			
		||||
err_surface:
 | 
			
		||||
	cairo_surface_destroy(surface);
 | 
			
		||||
err_win:
 | 
			
		||||
	XDestroyWindow(dpy, win);
 | 
			
		||||
	XCloseDisplay(dpy);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user