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

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


 tools/virtual.c |  207 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 125 insertions(+), 82 deletions(-)

New commits:
commit 5af9d69485a241156c343b67a741bc024e3f6edf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 19:50:17 2013 +0100

    intel-virtual-output: Reorder the fds
    
    We can't place the record fd at after the displays as we may wish to
    clone more displays later and use the simplification that they are in a
    linear, contiguous block at the end of the fd array.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 39812bc..1beccac 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -2302,6 +2302,12 @@ int main(int argc, char **argv)
 	XRRSelectInput(ctx.display->dpy, ctx.display->root, RRScreenChangeNotifyMask);
 	XFixesSelectCursorInput(ctx.display->dpy, ctx.display->root, XFixesDisplayCursorNotifyMask);
 
+	ret = add_fd(&ctx, record_mouse(&ctx));
+	if (ret) {
+		fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy));
+		return -ret;
+	}
+
 	open = fail = 0;
 	for (i = optind; i < argc; i++) {
 		ret = last_display_clone(&ctx, display_open(&ctx, argv[i]));
@@ -2332,12 +2338,6 @@ int main(int argc, char **argv)
 	if (open == 0)
 		return fail ? ECONNREFUSED : 0;
 
-	ret = add_fd(&ctx, record_mouse(&ctx));
-	if (ret) {
-		fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy));
-		return -ret;
-	}
-
 	if (daemonize && daemon(0, 0))
 		return EINVAL;
 
@@ -2346,18 +2346,26 @@ int main(int argc, char **argv)
 		XEvent e;
 		int reconfigure = 0;
 
+		DBG(("polling - enable timer? %d, nfd=%d\n", enable_timer, ctx.nfd));
 		ret = poll(ctx.pfd + !enable_timer, ctx.nfd - !enable_timer, -1);
 		if (ret <= 0)
 			break;
 
+		/* pfd[0] is the timer, pfd[1] is the local display, pfd[2] is the mouse, pfd[3+] are the remotes */
+
+		DBG(("poll reports %d fd awake\n", ret));
 		if (ctx.pfd[1].revents) {
 			int damaged = 0;
 
+			DBG(("%s woken up\n", DisplayString(ctx.display[0].dpy)));
 			do {
 				XNextEvent(ctx.display->dpy, &e);
 
 				if (e.type == ctx.display->damage_event + XDamageNotify ) {
 					const XDamageNotifyEvent *de = (const XDamageNotifyEvent *)&e;
+					DBG(("%s damaged: (%d, %d)x(%d, %d)\n",
+					     DisplayString(ctx.display->dpy),
+					     de->area.x, de->area.y, de->area.width, de->area.height));
 					for (i = 0; i < ctx.nclone; i++)
 						clone_damage(&ctx.clones[i], &de->area);
 					if (!enable_timer)
@@ -2375,6 +2383,8 @@ int main(int argc, char **argv)
 
 					XFree(cur);
 				} else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) {
+					DBG(("%s screen changed (reconfigure pending? %d)\n",
+					     DisplayString(ctx.display->dpy), reconfigure));
 					reconfigure = 1;
 					if (!enable_timer)
 						enable_timer = read(ctx.timer, &count, sizeof(count)) > 0;
@@ -2405,13 +2415,15 @@ int main(int argc, char **argv)
 		}
 
 		for (i = 1; ret && i < ctx.ndisplay; i++) {
-			if (ctx.pfd[i+1].revents == 0)
+			if (ctx.pfd[i+2].revents == 0)
 				continue;
 
+			DBG(("%s woken up\n", DisplayString(ctx.display[i].dpy)));
 			do {
 				XNextEvent(ctx.display[i].dpy, &e);
 
-				if (ctx.display[i].rr_event && e.type == ctx.display[i].rr_event + RRNotify) {
+				DBG(("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type));
+				if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) {
 					XRRNotifyEvent *re = (XRRNotifyEvent *)&e;
 					if (re->subtype == RRNotify_OutputChange) {
 						XRROutputPropertyNotifyEvent *ro = (XRROutputPropertyNotifyEvent *)re;
@@ -2424,7 +2436,7 @@ int main(int argc, char **argv)
 						}
 					}
 				}
-			} while (XPending(ctx.display[i].dpy) || poll(&ctx.pfd[i+1], 1, 0) > 0);
+			} while (XPending(ctx.display[i].dpy) || poll(&ctx.pfd[i+2], 1, 0) > 0);
 
 			ret--;
 		}
commit 88d43dc2aea1ee4b8a3248bf442f5be362b32fbe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 17:30:15 2013 +0100

    intel-virtual-output: Refactor the image resizing code
    
    And add lots of debug and robustness.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index b4d4460..39812bc 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -94,6 +94,7 @@ struct display {
 	int cursor;
 
 	int flush;
+	int send;
 };
 
 struct output {
@@ -109,7 +110,7 @@ struct output {
 	Pixmap pixmap;
 	GC gc;
 
-	int serial;
+	long serial;
 	int use_shm;
 	int use_shm_pixmap;
 
@@ -203,10 +204,6 @@ can_use_shm(Display *dpy,
 	XSync(dpy, False);
 	has_shm = success && _x_error_occurred == 0;
 
-	codes = XInitExtension(dpy, SHMNAME);
-	if (codes == NULL)
-		has_pixmap = 0;
-
 	/* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent,
 	 * the Xserver may crash if it does not take care when processing
 	 * the event type. For instance versions of Xorg prior to 1.11.1
@@ -218,12 +215,11 @@ can_use_shm(Display *dpy,
 	 *
 	 * Remove the SendEvent bit (0x80) before doing range checks on event type.
 	 */
-	if (has_pixmap &&
-	    xlib_vendor_is_xorg(dpy) &&
+	codes = XInitExtension(dpy, SHMNAME);
+	if (xlib_vendor_is_xorg(dpy) &&
 	    VendorRelease(dpy) < XORG_VERSION_ENCODE(1,11,0,1))
-		has_pixmap = 0;
-
-	if (has_pixmap) {
+		codes = 0;
+	if (codes) {
 		XShmCompletionEvent e;
 
 		e.type = codes->first_event;
@@ -237,23 +233,19 @@ can_use_shm(Display *dpy,
 		e.offset = 0;
 
 		XSendEvent(dpy, e.drawable, False, 0, (XEvent *)&e);
-
 		XSync(dpy, False);
-		has_pixmap = _x_error_occurred == 0;
-	}
 
-	if (success)
-		XShmDetach(dpy, &shm);
+		if (_x_error_occurred == 0) {
+			*shm_opcode = codes->major_opcode;
+			*shm_event = codes->first_event;
+			*shm_pixmap = has_pixmap;
+		}
+	}
 
+	XShmDetach(dpy, &shm);
 	shmctl(shm.shmid, IPC_RMID, NULL);
 	shmdt(shm.shmaddr);
 
-	if (has_pixmap) {
-		*shm_opcode = codes->major_opcode;
-		*shm_event = codes->first_event;
-		*shm_pixmap = has_pixmap;
-	}
-
 	return has_shm;
 }
 
@@ -555,6 +547,7 @@ static void init_image(struct clone *clone)
 		image->bits_per_pixel = 16;
 		break;
 	}
+	image->obdata = (char *)&clone->shm;
 
 	ret = XInitImage(image);
 	assert(ret);
@@ -1015,6 +1008,9 @@ static int clone_output_init(struct clone *clone, struct output *output,
 	output->use_shm = display->has_shm;
 	output->use_shm_pixmap = display->has_shm_pixmap;
 
+	DBG(("%s-%s use shm? %d (use shm pixmap? %d)\n",
+	     DisplayString(dpy), name, display->has_shm, display->has_shm_pixmap));
+
 	depth = output->use_shm ? display->depth : 16;
 	if (depth < clone->depth)
 		clone->depth = depth;
@@ -1022,26 +1018,11 @@ static int clone_output_init(struct clone *clone, struct output *output,
 	return 0;
 }
 
-static void send_shm(struct output *o, int serial)
+static void ximage_set_size(XImage *image, int width, int height)
 {
-	XShmCompletionEvent e;
-
-	if (o->display->shm_event == 0) {
-		XSync(o->dpy, False);
-		return;
-	}
-
-	e.type = o->display->shm_event;
-	e.send_event = 1;
-	e.serial = serial;
-	e.drawable = o->pixmap;
-	e.major_code = o->display->shm_opcode;
-	e.minor_code = X_ShmPutImage;
-	e.shmseg = 0;
-	e.offset = 0;
-
-	XSendEvent(o->dpy, o->window, False, 0, (XEvent *)&e);
-	o->serial = serial;
+	image->width = width;
+	image->height = height;
+	image->bytes_per_line = stride_for_depth(width, image->depth);
 }
 
 static void get_src(struct clone *c, const XRectangle *clip)
@@ -1058,15 +1039,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) {
-			c->image.width = clip->width;
-			c->image.height = clip->height;
-			c->image.obdata = (char *)&c->shm;
+			ximage_set_size(&c->image, clip->width, clip->height);
 			XShmGetImage(c->src.dpy, c->src.pixmap, &c->image,
 				     clip->x, clip->y, AllPlanes);
 		} else {
-			c->image.width = c->width;
-			c->image.height = c->height;
-			c->image.obdata = 0;
+			ximage_set_size(&c->image, c->width, c->height);
 			XGetSubImage(c->src.dpy, c->src.pixmap,
 				     clip->x, clip->y, clip->width, clip->height,
 				     AllPlanes, ZPixmap,
@@ -1079,15 +1056,11 @@ static void get_src(struct clone *c, const XRectangle *clip)
 			  0, 0);
 		XSync(c->src.dpy, False);
 	} else if (c->src.use_shm) {
-		c->image.width = clip->width;
-		c->image.height = clip->height;
-		c->image.obdata = (char *)&c->shm;
+		ximage_set_size(&c->image, clip->width, clip->height);
 		XShmGetImage(c->src.dpy, c->src.window, &c->image,
 			     clip->x, clip->y, AllPlanes);
 	} else {
-		c->image.width = c->width;
-		c->image.height = c->height;
-		c->image.obdata = 0;
+		ximage_set_size(&c->image, c->width, c->height);
 		XGetSubImage(c->src.dpy, c->src.window,
 			     clip->x, clip->y, clip->width, clip->height,
 			     AllPlanes, ZPixmap,
@@ -1100,46 +1073,48 @@ 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));
 	if (c->dst.use_render) {
-		int serial;
 		if (c->dst.use_shm_pixmap) {
+			DBG(("%s-%s using SHM pixmap composite\n",
+			     DisplayString(c->dst.dpy), c->dst.name));
 		} else if (c->dst.use_shm) {
-			c->image.width = clip->width;
-			c->image.height = clip->height;
-			c->image.obdata = (char *)&c->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,
 				     clip->width, clip->height,
 				     False);
 		} else {
-			c->image.width = c->width;
-			c->image.height = c->height;
-			c->image.obdata = 0;
+			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,
 				  clip->width, clip->height);
 		}
-		serial = NextRequest(c->dst.dpy);
+		c->dst.serial = NextRequest(c->dst.dpy);
 		XRenderComposite(c->dst.dpy, PictOpSrc,
 				 c->dst.pix_picture, 0, c->dst.win_picture,
 				 0, 0,
 				 0, 0,
 				 clip->x, clip->y,
 				 clip->width, clip->height);
-		if (c->dst.use_shm)
-			send_shm(&c->dst, serial);
+		c->dst.display->send |= c->dst.use_shm;
 	} else if (c->dst.pixmap) {
-		int serial = NextRequest(c->dst.dpy);
+		DBG(("%s-%s using SHM pixmap\n",
+		     DisplayString(c->dst.dpy), c->dst.name));
+		c->dst.serial = NextRequest(c->dst.dpy);
 		XCopyArea(c->dst.dpy, c->dst.pixmap, c->dst.window, c->dst.gc,
 			  0, 0,
 			  clip->width, clip->height,
 			  clip->x, clip->y);
-		send_shm(&c->dst, serial);
+		c->dst.display->send = 1;
 	} else if (c->dst.use_shm) {
-		c->image.width = clip->width;
-		c->image.height = clip->height;
-		c->image.obdata = (char *)&c->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,
@@ -1147,9 +1122,9 @@ static void put_dst(struct clone *c, const XRectangle *clip)
 			     clip->width, clip->height,
 			     True);
 	} else {
-		c->image.width = c->width;
-		c->image.height = c->height;
-		c->image.obdata = 0;
+		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,
@@ -1164,8 +1139,12 @@ static int clone_paint(struct clone *c)
 {
 	XRectangle clip;
 
-	DBG(("%s-%s paint clone\n",
-	     DisplayString(c->dst.dpy), c->dst.name));
+	DBG(("%s-%s paint clone, damaged (%d, %d), (%d, %d) [(%d, %d), (%d,  %d)]\n",
+	     DisplayString(c->dst.dpy), c->dst.name,
+	     c->damaged.x1, c->damaged.y1,
+	     c->damaged.x2, c->damaged.y2,
+	     c->src.x, c->src.y,
+	     c->src.x + c->width, c->src.y + c->height));
 
 	if (c->damaged.x1 < c->src.x)
 		c->damaged.x1 = c->src.x;
@@ -1181,6 +1160,9 @@ static int clone_paint(struct clone *c)
 	if (c->damaged.y2 <= c->damaged.y1)
 		goto done;
 
+	DBG(("%s-%s is damaged, last SHM serial: %ld, now %ld\n",
+	     DisplayString(c->dst.dpy), c->dst.name,
+	     (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy)));
 	if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy))
 		return EAGAIN;
 
@@ -2137,9 +2119,42 @@ static int first_display_register_as_singleton(struct context *ctx)
 	} while (1);
 }
 
+static void display_flush_send(struct display *display)
+{
+	XShmCompletionEvent e;
+
+	if (!display->send)
+		return;
+
+	DBG(("%s flushing send (serial now %ld) (has shm send? %d)\n",
+	     DisplayString(display->dpy),
+	     (long)NextRequest(display->dpy),
+	     display->shm_event));
+
+	if (display->shm_event == 0) {
+		XSync(display->dpy, False);
+		display->flush = 0;
+		return;
+	}
+
+	e.type = display->shm_event;
+	e.send_event = 1;
+	e.serial = 0;
+	e.drawable = display->root;
+	e.major_code = display->shm_opcode;
+	e.minor_code = X_ShmPutImage;
+	e.shmseg = 0;
+	e.offset = 0;
+
+	XSendEvent(display->dpy, display->root, False, 0, (XEvent *)&e);
+	display->send = 0;
+	display->flush = 1;
+}
+
 static void display_flush(struct display *display)
 {
 	display_flush_cursor(display);
+	display_flush_send(display);
 
 	if (!display->flush)
 		return;
commit 1b07f16ffeb3152817e9e4f77ca0f2c403fb9040
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 2 18:10:27 2013 +0100

    intel-virtual-overlay: Fix logic inversion from previous commit
    
    "if (!active == 0)"
    
    Whoops, but keep the debugging that highlighted the error.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index ba443b2..b4d4460 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -690,6 +690,8 @@ static void context_update(struct context *ctx)
 	int context_changed = 0;
 	int i, n;
 
+	DBG(("%s\n", __func__));
+
 	res = XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
 	if (res == NULL)
 		return;
@@ -709,6 +711,11 @@ static void context_update(struct context *ctx)
 		if (o->crtc)
 			c = XRRGetCrtcInfo(dpy, res, o->crtc);
 		if (c) {
+			DBG(("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> (x=%d, y=%d, rotation=%d, mode=%ld)\n",
+			     DisplayString(ctx->display->dpy), output->name,
+			     output->x, output->y, output->rotation, output->mode.id,
+			     c->x, c->y, output->rotation, c->mode));
+
 			changed |= output->rotation |= c->rotation;
 			output->rotation = c->rotation;
 
@@ -721,6 +728,10 @@ static void context_update(struct context *ctx)
 			changed |= output->mode.id != mode;
 			mode = c->mode;
 			XRRFreeCrtcInfo(c);
+		} else {
+			DBG(("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> off\n",
+			     DisplayString(ctx->display->dpy), output->name,
+			     output->x, output->y, output->rotation, output->mode.id));
 		}
 		output->rr_crtc = o->crtc;
 		XRRFreeOutputInfo(o);
@@ -739,12 +750,16 @@ static void context_update(struct context *ctx)
 			output->mode.id = 0;
 		}
 
+		DBG(("%s-%s changed? %d\n",
+		     DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed));
+
 		if (changed)
 			clone_init_xfer(&ctx->clones[n]);
 		context_changed |= changed;
 	}
 	XRRFreeScreenResources(res);
 
+	DBG(("%s changed? %d\n", DisplayString(ctx->display->dpy), context_changed));
 	if (!context_changed)
 		return;
 
@@ -753,7 +768,7 @@ static void context_update(struct context *ctx)
 		struct clone *clone;
 		int x1, x2, y1, y2;
 
-		if (!display->rr_active == 0)
+		if (display->rr_active == 0)
 			continue;
 
 		x1 = y1 = INT_MAX;
@@ -994,6 +1009,7 @@ static int clone_output_init(struct clone *clone, struct output *output,
 	output->dpy = dpy;
 
 	output->rr_output = rr_output;
+	output->rotation = RR_Rotate_0;
 
 	output->window = display->root;
 	output->use_shm = display->has_shm;


More information about the xorg-commit mailing list