xf86-video-intel: 7 commits - tools/virtual.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Sep 2 16:11:15 PDT 2013


 tools/virtual.c |  160 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 126 insertions(+), 34 deletions(-)

New commits:
commit 6f090044d1de4160777963910df3586bdf0186dc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 23:52:52 2013 +0100

    intel-virtual-output: Remember to mark the timer as active when moving the mouse
    
    Otherwise we throttle mouse updates to the next display update...
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index d26a768..43146dc 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -1061,6 +1061,8 @@ static void display_load_visible_cursor(struct display *display, XFixesCursorIma
 	DBG(("%s marking cursor changed\n", DisplayString(display->dpy)));
 	display->cursor_moved++;
 	display->cursor_visible += display->cursor != display->invisible_cursor;
+
+	context_enable_timer(display->ctx);
 }
 
 static void display_cursor_move(struct display *display, int x, int y, int visible)
@@ -1073,6 +1075,8 @@ static void display_cursor_move(struct display *display, int x, int y, int visib
 		display->cursor_x = x;
 		display->cursor_y = y;
 	}
+
+	context_enable_timer(display->ctx);
 }
 
 static void display_flush_cursor(struct display *display)
commit 91aca61c83f0905d1f6446dba56c5f67d91efb6f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 23:27:27 2013 +0100

    intel-virtual-output: Don't clobber the XID inside the ShmSegmentInfo
    
    As there is an XID inside the ShmSegmentInfo we cannot share one between
    both endpoints, or else it gets clobbered and rendering is lost (unless
    by happy coincidence the last XID is available in both Xservers).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index c30d9a6..d26a768 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -107,7 +107,6 @@ struct output {
 	char *name;
 	RROutput rr_output;
 	RRCrtc rr_crtc;
-	XShmSegmentInfo shm;
 	Window window;
 	Picture win_picture;
 	Picture pix_picture;
@@ -117,6 +116,7 @@ struct output {
 	long serial;
 	int use_shm;
 	int use_shm_pixmap;
+	XShmSegmentInfo shm;
 
 	XRenderPictFormat *use_render;
 
@@ -212,7 +212,7 @@ can_use_shm(Display *dpy,
 		return 0;
 
 	shm.readOnly = 0;
-	shm.shmaddr = shmat (shm.shmid, NULL, 0);
+	shm.shmaddr = shmat(shm.shmid, NULL, 0);
 	if (shm.shmaddr == (char *) -1) {
 		shmctl(shm.shmid, IPC_RMID, NULL);
 		return 0;
@@ -665,7 +665,6 @@ static void init_image(struct clone *clone)
 		image->bits_per_pixel = 16;
 		break;
 	}
-	image->obdata = (char *)&clone->shm;
 
 	ret = XInitImage(image);
 	assert(ret);
@@ -678,7 +677,7 @@ static void output_init_xfer(struct clone *clone, struct output *output)
 		if (output->pixmap)
 			XFreePixmap(output->dpy, output->pixmap);
 		output->pixmap = XShmCreatePixmap(output->dpy, output->window,
-						  clone->shm.shmaddr, &clone->shm,
+						  clone->shm.shmaddr, &output->shm,
 						  clone->width, clone->height, clone->depth);
 		if (output->pix_picture) {
 			XRenderFreePicture(output->dpy, output->pix_picture);
@@ -718,9 +717,9 @@ static int clone_init_xfer(struct clone *clone)
 		clone->height = 0;
 
 		if (clone->src.use_shm)
-			XShmDetach(clone->src.dpy, &clone->shm);
+			XShmDetach(clone->src.dpy, &clone->src.shm);
 		if (clone->dst.use_shm)
-			XShmDetach(clone->dst.dpy, &clone->shm);
+			XShmDetach(clone->dst.dpy, &clone->dst.shm);
 
 		if (clone->shm.shmaddr) {
 			shmdt(clone->shm.shmaddr);
@@ -755,16 +754,18 @@ static int clone_init_xfer(struct clone *clone)
 		return ENOMEM;
 	}
 
-	clone->shm.readOnly = 0;
-
 	init_image(clone);
 
 	if (clone->src.use_shm) {
-		XShmAttach(clone->src.dpy, &clone->shm);
+		clone->src.shm = clone->shm;
+		clone->dst.shm.readOnly = False;
+		XShmAttach(clone->src.dpy, &clone->src.shm);
 		XSync(clone->src.dpy, False);
 	}
 	if (clone->dst.use_shm) {
-		XShmAttach(clone->dst.dpy, &clone->shm);
+		clone->dst.shm = clone->shm;
+		clone->dst.shm.readOnly = True;
+		XShmAttach(clone->dst.dpy, &clone->dst.shm);
 		XSync(clone->dst.dpy, False);
 	}
 
@@ -1159,7 +1160,7 @@ static int clone_output_init(struct clone *clone, struct output *output,
 	return 0;
 }
 
-static void ximage_set_size(XImage *image, int width, int height)
+static void ximage_prepare(XImage *image, int width, int height)
 {
 	image->width = width;
 	image->height = height;
@@ -1170,6 +1171,9 @@ static void get_src(struct clone *c, const XRectangle *clip)
 {
 	DBG(("%s-%s get_src(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name,
 	     clip->x, clip->y, clip->width, clip->height));
+
+	c->image.obdata = (char *)&c->src.shm;
+
 	if (c->src.use_render) {
 		XRenderComposite(c->src.dpy, PictOpSrc,
 				 c->src.win_picture, 0, c->src.pix_picture,
@@ -1180,11 +1184,11 @@ static void get_src(struct clone *c, const XRectangle *clip)
 		if (c->src.use_shm_pixmap) {
 			XSync(c->src.dpy, False);
 		} else if (c->src.use_shm) {
-			ximage_set_size(&c->image, clip->width, clip->height);
+			ximage_prepare(&c->image, clip->width, clip->height);
 			XShmGetImage(c->src.dpy, c->src.pixmap, &c->image,
 				     clip->x, clip->y, AllPlanes);
 		} else {
-			ximage_set_size(&c->image, c->width, c->height);
+			ximage_prepare(&c->image, c->width, c->height);
 			XGetSubImage(c->src.dpy, c->src.pixmap,
 				     clip->x, clip->y, clip->width, clip->height,
 				     AllPlanes, ZPixmap,
@@ -1197,22 +1201,26 @@ static void get_src(struct clone *c, const XRectangle *clip)
 			  0, 0);
 		XSync(c->src.dpy, False);
 	} else if (c->src.use_shm) {
-		ximage_set_size(&c->image, clip->width, clip->height);
+		ximage_prepare(&c->image, clip->width, clip->height);
 		XShmGetImage(c->src.dpy, c->src.window, &c->image,
 			     clip->x, clip->y, AllPlanes);
 	} else {
-		ximage_set_size(&c->image, c->width, c->height);
+		ximage_prepare(&c->image, c->width, c->height);
 		XGetSubImage(c->src.dpy, c->src.window,
 			     clip->x, clip->y, clip->width, clip->height,
 			     AllPlanes, ZPixmap,
 			     &c->image, 0, 0);
 	}
+	c->src.display->flush = 0;
 }
 
 static void put_dst(struct clone *c, const XRectangle *clip)
 {
 	DBG(("%s-%s put_dst(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name,
 	     clip->x, clip->y, clip->width, clip->height));
+
+	c->image.obdata = (char *)&c->dst.shm;
+
 	if (c->dst.use_render) {
 		if (c->dst.use_shm_pixmap) {
 			DBG(("%s-%s using SHM pixmap composite\n",
@@ -1220,7 +1228,6 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 		} else if (c->dst.use_shm) {
 			DBG(("%s-%s using SHM image composite\n",
 			     DisplayString(c->dst.dpy), c->dst.name));
-			ximage_set_size(&c->image, clip->width, clip->height);
 			XShmPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
 				     0, 0,
 				     0, 0,
@@ -1229,7 +1236,6 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 		} else {
 			DBG(("%s-%s using composite\n",
 			     DisplayString(c->dst.dpy), c->dst.name));
-			ximage_set_size(&c->image, c->width, c->height);
 			XPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
 				  0, 0,
 				  0, 0,
@@ -1256,7 +1262,6 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 	} else if (c->dst.use_shm) {
 		DBG(("%s-%s using SHM image\n",
 		     DisplayString(c->dst.dpy), c->dst.name));
-		ximage_set_size(&c->image, clip->width, clip->height);
 		c->dst.serial = NextRequest(c->dst.dpy);
 		XShmPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
 			     0, 0,
@@ -1266,7 +1271,6 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 	} else {
 		DBG(("%s-%s using image\n",
 		     DisplayString(c->dst.dpy), c->dst.name));
-		ximage_set_size(&c->image, c->width, c->height);
 		XPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
 			  0, 0,
 			  clip->x, clip->y,
@@ -2607,7 +2611,9 @@ int main(int argc, char **argv)
 		for (i = 0; i < ctx.nclone; i++)
 			clone_update(&ctx.clones[i]);
 
-		if (ctx.timer_active && read(ctx.timer, &count, sizeof(count)) > 0 && count > 0) {
+		XPending(ctx.record);
+
+		if (ctx.timer_active && read(ctx.timer, &count, sizeof(count)) > 0) {
 			DBG(("%s timer expired (count=%ld)\n", DisplayString(ctx.display->dpy), (long)count));
 			ret = 0;
 
@@ -2619,8 +2625,6 @@ int main(int argc, char **argv)
 
 			ctx.timer_active = ret != 0;
 		}
-
-		XPending(ctx.record);
 	}
 
 	context_cleanup(&ctx);
commit d54f0fa16ddb3985ace02544fc2a58926aed7115
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 22:56:03 2013 +0100

    intel-virtual-output: Remove the stray 1
    
    The 'output-is-changed' flags was accidentally initialised to 01 rather
    than 0, causing all attached outputs to be considered to have changed
    everytime.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 1438669..c30d9a6 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -812,7 +812,7 @@ static void context_update(struct context *ctx)
 		XRROutputInfo *o;
 		XRRCrtcInfo *c;
 		RRMode mode = 0;
-		int changed = 0l;
+		int changed = 0;
 
 		o = XRRGetOutputInfo(dpy, res, output->rr_output);
 		if (o == NULL)
commit 84b66849fc005365e71a40517c192e0cd178a82b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 22:55:17 2013 +0100

    intel-virtual-output: Don't set the SHM active flag along !SHM composite paths
    
    Otherwise we may end up waiting for an event that will never be sent.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 7655a7b..1438669 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -237,7 +237,9 @@ can_use_shm(Display *dpy,
 	 *
 	 * Remove the SendEvent bit (0x80) before doing range checks on event type.
 	 */
-	codes = XInitExtension(dpy, SHMNAME);
+	codes = 0;
+	if (has_shm)
+		codes = XInitExtension(dpy, SHMNAME);
 	if (xlib_vendor_is_xorg(dpy) &&
 	    VendorRelease(dpy) < XORG_VERSION_ENCODE(1,11,0,1))
 		codes = 0;
@@ -1233,7 +1235,8 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 				  0, 0,
 				  clip->width, clip->height);
 		}
-		c->dst.serial = NextRequest(c->dst.dpy);
+		if (c->dst.use_shm)
+			c->dst.serial = NextRequest(c->dst.dpy);
 		XRenderComposite(c->dst.dpy, PictOpSrc,
 				 c->dst.pix_picture, 0, c->dst.win_picture,
 				 0, 0,
commit 13a28f607f0eb4b4906e856c3f75f53446f4f999
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 22:37:23 2013 +0100

    intel-virtual-overlay: Try to shutdown gracefully
    
    Attempt to clean up the VIRTUAL mess when we exit.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index c781f41..7655a7b 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -48,6 +48,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <signal.h>
 #include <getopt.h>
 #include <limits.h>
 #include <ctype.h>
@@ -2287,9 +2288,64 @@ static int first_display_sibling(struct context *ctx, int i)
 	return 1;
 }
 
+
 #define first_display_for_each_sibling(CTX, i) \
 	for (i = first_display_first_sibling(CTX); first_display_sibling(CTX, i); i++)
 
+static void context_cleanup(struct context *ctx)
+{
+	Display *dpy = ctx->display->dpy;
+	XRRScreenResources *res;
+	int i, j;
+
+	res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
+	if (res == NULL)
+		return;
+
+	for (i = 0; i < ctx->nclone; i++) {
+		struct clone *clone = &ctx->clones[i];
+		XRROutputInfo *output;
+
+		assert(clone->src.display == ctx->display);
+
+		output = XRRGetOutputInfo(dpy, res, clone->src.rr_output);
+		if (output == NULL)
+			continue;
+
+		if (output->crtc)
+			XRRSetCrtcConfig(dpy, res, output->crtc, CurrentTime,
+					 0, 0, None, RR_Rotate_0, NULL, 0);
+
+		for (j = 0; j < output->nmode; j++)
+			XRRDeleteOutputMode(dpy, clone->src.rr_output, output->modes[j]);
+
+		XRRFreeOutputInfo(output);
+	}
+
+	for (i = 0; i < res->nmode; i++) {
+		if (strncmp(res->modes[i].name, "VIRTUAL", 7) == 0) {
+			XRRDestroyMode(dpy, res->modes[i].id);
+			continue;
+		}
+
+		if (strcmp(res->modes[i].name, "ClaimVirtualHead") == 0) {
+			XRRDestroyMode(dpy, res->modes[i].id);
+			continue;
+		}
+	}
+
+	XRRFreeScreenResources(res);
+
+	XCloseDisplay(dpy);
+}
+
+static int done;
+
+static void signal_handler(int sig)
+{
+	done = sig;
+}
+
 int main(int argc, char **argv)
 {
 	struct context ctx;
@@ -2298,6 +2354,8 @@ int main(int argc, char **argv)
 	int daemonize = 1, bumblebee = 0, all = 0, singleton = 1;
 	int i, ret, open, fail;
 
+	signal(SIGPIPE, SIG_IGN);
+
 	while ((i = getopt(argc, argv, "abd:fhS")) != -1) {
 		switch (i) {
 		case 'd':
@@ -2432,8 +2490,12 @@ int main(int argc, char **argv)
 	if (daemonize && daemon(0, 0))
 		return EINVAL;
 
+	signal(SIGHUP, signal_handler);
+	signal(SIGINT, signal_handler);
+	signal(SIGTERM, signal_handler);
+
 	ctx.command_continuation = 0;
-	while (1) {
+	while (!done) {
 		XEvent e;
 		int reconfigure = 0;
 
@@ -2558,5 +2620,6 @@ int main(int argc, char **argv)
 		XPending(ctx.record);
 	}
 
-	return EINVAL;
+	context_cleanup(&ctx);
+	return 0;
 }
commit e6e6572ac8f15bfee204cdf6bee4661ee2c6ffbb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 22:27:42 2013 +0100

    intel-virtual-output: Fallback to probing GetScreenResources
    
    If the Display doesn't support the more recent non-forced-detection
    GetScreenResources, use the older version instead.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 0a66725..c781f41 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -165,6 +165,17 @@ static int xlib_vendor_is_xorg(Display *dpy)
 	return strstr(vendor, "X.Org") || strstr(vendor, "Xorg");
 }
 
+static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window)
+{
+	XRRScreenResources *res;
+
+	res = XRRGetScreenResourcesCurrent(dpy, window);
+	if (res == NULL)
+		res = XRRGetScreenResources(dpy, window);
+
+	return res;
+}
+
 #define XORG_VERSION_ENCODE(major,minor,patch,snap) \
     (((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap)
 
@@ -399,7 +410,7 @@ static int clone_update_modes__randr(struct clone *clone)
 	if (from_info == NULL)
 		goto err;
 
-	to_res = XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
+	to_res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
 	if (to_res == NULL)
 		goto err;
 
@@ -491,7 +502,7 @@ static int clone_update_modes__fixed(struct clone *clone)
 
 	assert(clone->src.rr_output);
 
-	res = XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
+	res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
 	if (res == NULL)
 		goto err;
 
@@ -555,7 +566,7 @@ static RROutput claim_virtual(struct display *display, char *output_name, int nc
 
 	DBG(("%s(%d)\n", __func__, nclone));
 
-	res = XRRGetScreenResourcesCurrent(dpy, display->root);
+	res = _XRRGetScreenResourcesCurrent(dpy, display->root);
 	if (res == NULL)
 		return 0;
 
@@ -789,7 +800,7 @@ static void context_update(struct context *ctx)
 
 	DBG(("%s\n", __func__));
 
-	res = XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
+	res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
 	if (res == NULL)
 		return;
 
@@ -901,7 +912,7 @@ static void context_update(struct context *ctx)
 		DBG(("%s fb bounds (%d, %d)x(%d, %d)\n", DisplayString(display->dpy),
 		     x1, y1, x2-x1, y2-y1));
 
-		res = XRRGetScreenResourcesCurrent(display->dpy, display->root);
+		res = _XRRGetScreenResourcesCurrent(display->dpy, display->root);
 		if (res == NULL)
 			continue;
 
@@ -1795,10 +1806,11 @@ static int last_display_add_clones__randr(struct context *ctx)
 
 	display_init_randr_hpd(display);
 
-	res = XRRGetScreenResourcesCurrent(display->dpy, display->root);
+	res = _XRRGetScreenResourcesCurrent(display->dpy, display->root);
 	if (res == NULL)
 		return -ENOMEM;
 
+	DBG(("%s - noutputs=%d\n", DisplayString(display->dpy), res->noutput));
 	for (i = 0; i < res->noutput; i++) {
 		XRROutputInfo *o = XRRGetOutputInfo(display->dpy, res, res->outputs[i]);
 		struct clone *clone = add_clone(ctx);
commit 7c5d269f259dd247c04a374467577cd47cc2cc27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 22:07:46 2013 +0100

    intel-virtual-overlay: Keep bumblebeed awake
    
    bumbledeed will shutdown its Xserver when the last connection to it
    closes. For the moment, leak the control socket so that the display
    stays alive. However, we will want to attach to any Xservers created by
    bumblebee as opposed to creating them.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index ec83701..0a66725 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -1686,7 +1686,6 @@ static int bumblebee_open(struct context *ctx)
 		goto err;
 	}
 	buf[len] = '\0';
-	close(fd);
 
 	DBG(("%s query result '%s'\n", __func__, buf));
 
@@ -1698,6 +1697,13 @@ static int bumblebee_open(struct context *ctx)
 		len++;
 	buf[len] = '\0';
 
+	/* XXX We must keep the control socket open whilst we want to keep
+	 * the display around.
+	 *
+	 * So what we need to do is listen for new bumblee Xservers and
+	 * bind only for their duration.
+	 */
+
 	return display_open(ctx, buf+7);
 
 err:


More information about the xorg-commit mailing list