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

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 4 03:43:41 PDT 2015


 src/sna/sna_display.c |   26 +++++-
 tools/virtual.c       |  210 +++++++++++++++++++++++++++++++-------------------
 2 files changed, 155 insertions(+), 81 deletions(-)

New commits:
commit 7d30ccea214b54879fe34f0cab123aa3dc1b362c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 4 11:32:41 2015 +0100

    sna: Ensure compat_output is sane after sorting outputs
    
    We always arrange for the panels to be first, and we want to use that
    for our compat output.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index bf6ca89..965c35c 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4520,6 +4520,7 @@ static void sort_config_outputs(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 	qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank);
+	config->compat_output = 0; /* make sure it is a sane value */
 	sna_mode_compute_possible_outputs(sna);
 }
 
@@ -6337,13 +6338,23 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 				crtc->enabled = TRUE;
 				crtc_enabled++;
 
+				output_set_gamma(output, crtc);
+
+				if (output->conf_monitor) {
+					output->mm_width = output->conf_monitor->mon_width;
+					output->mm_height = output->conf_monitor->mon_height;
+				}
+
+#if 0
+				sna_output_attach_edid(output);
+				sna_output_attach_tile(output);
+#endif
+
 				if (output->mm_width == 0 || output->mm_height == 0) {
 					output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI);
 					output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI);
 				}
 
-				output_set_gamma(output, crtc);
-
 				M = calloc(1, sizeof(DisplayModeRec));
 				if (M) {
 					*M = crtc->desiredMode;
@@ -6564,6 +6575,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 
 		xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 		xf86_config->xf86_crtc_notify = sna_crtc_config_notify;
+		xf86_config->compat_output = 0;
 
 		for (i = 0; i < res->count_crtcs; i++)
 			if (!sna_crtc_add(scrn, res->crtcs[i]))
commit 1525b0177862b1533232d6de923d40256a738845
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 2 15:24:38 2015 +0100

    intel-virtual-output: Fix cloning fixed mode outputs
    
    When using a fixed mode, e.g. a Display without RandR support like
    Xnest, we have to remember to hook up the connection during
    recofiguration of VIRTUAL outputs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index f5cba1a..ffda54a 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -145,6 +145,7 @@ struct output {
 	XRenderPictFormat *use_render;
 
 	int x, y;
+	int width, height;
 	XRRModeInfo mode;
 	Rotation rotation;
 };
@@ -250,6 +251,10 @@ can_use_shm(Display *dpy,
 	XExtCodes *codes;
 	int major, minor, has_shm, has_pixmap;
 
+	*shm_event = 0;
+	*shm_opcode = 0;
+	*shm_pixmap = 0;
+
 	if (!XShmQueryExtension(dpy))
 		return 0;
 
@@ -824,6 +829,10 @@ static int clone_update_modes__fixed(struct clone *clone)
 	RRMode id;
 	int i, j, ret = ENOENT;
 
+	DBG(X11, ("%s-%s cloning modes fixed %dx%d\n",
+	     DisplayString(clone->dst.dpy), clone->dst.name,
+	     clone->dst.width, clone->dst.height));
+
 	assert(clone->src.rr_output);
 
 	res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window);
@@ -852,8 +861,8 @@ static int clone_update_modes__fixed(struct clone *clone)
 
 	/* Create matching mode for the real output on the virtual */
 	memset(&mode, 0, sizeof(mode));
-	mode.width = clone->width;
-	mode.height = clone->height;
+	mode.width = clone->dst.width;
+	mode.height = clone->dst.height;
 	mode.nameLength = sprintf(mode_name, "FAKE-%dx%d", mode.width, mode.height);
 	mode.name = mode_name;
 
@@ -1097,20 +1106,20 @@ static int clone_init_xfer(struct clone *clone)
 		width = 0;
 		height = 0;
 	} else if (clone->dri3.xid) {
-		width = clone->dst.display->width;
-		height = clone->dst.display->height;
+		width = clone->dst.width;
+		height = clone->dst.height;
 	} else {
 		width = mode_width(&clone->src.mode, clone->src.rotation);
 		height = mode_height(&clone->src.mode, clone->src.rotation);
 	}
 
+	DBG(DRAW, ("%s-%s create xfer, %dx%d (currently %dx%d)\n",
+	     DisplayString(clone->dst.dpy), clone->dst.name,
+	     width, height, clone->width, clone->height));
+
 	if (width == clone->width && height == clone->height)
 		return 0;
 
-	DBG(DRAW, ("%s-%s create xfer, %dx%d\n",
-	     DisplayString(clone->dst.dpy), clone->dst.name,
-	     width, height));
-
 	if (clone->shm.shmaddr) {
 		if (clone->src.use_shm)
 			XShmDetach(clone->src.dpy, &clone->src.shm);
@@ -1340,8 +1349,19 @@ static int context_update(struct context *ctx)
 		struct clone *clone;
 		int x1, x2, y1, y2;
 
-		if (display->rr_active == 0)
+		if (display->rr_active == 0) {
+			for (clone = display->clone; clone; clone = clone->next) {
+				struct output *output = &clone->src;
+				if (output->mode.id) {
+					clone->dst.mode.id = -1;
+					clone->dst.rr_crtc = -1;
+				} else {
+					clone->dst.mode.id = 0;
+					clone->dst.rr_crtc = 0;
+				}
+			}
 			continue;
+		}
 
 		x1 = y1 = INT_MAX;
 		x2 = y2 = INT_MIN;
@@ -1795,6 +1815,8 @@ static void get_src(struct clone *c, const XRectangle *clip)
 	c->image.obdata = (char *)&c->src.shm;
 
 	if (c->src.use_render) {
+		DBG(DRAW, ("%s-%s get_src via XRender\n",
+			   DisplayString(c->dst.dpy), c->dst.name));
 		XRenderComposite(c->src.dpy, PictOpSrc,
 				 c->src.win_picture, 0, c->src.pix_picture,
 				 clip->x, clip->y,
@@ -1815,16 +1837,22 @@ static void get_src(struct clone *c, const XRectangle *clip)
 				     &c->image, 0, 0);
 		}
 	} else if (c->src.pixmap) {
+		DBG(DRAW, ("%s-%s get_src XCopyArea (SHM/DRI3)\n",
+			   DisplayString(c->dst.dpy), c->dst.name));
 		XCopyArea(c->src.dpy, c->src.window, c->src.pixmap, c->src.gc,
 			  clip->x, clip->y,
 			  clip->width, clip->height,
 			  0, 0);
 		XSync(c->src.dpy, False);
 	} else if (c->src.use_shm) {
+		DBG(DRAW, ("%s-%s get_src XShmGetImage\n",
+			   DisplayString(c->dst.dpy), c->dst.name));
 		ximage_prepare(&c->image, clip->width, clip->height);
 		XShmGetImage(c->src.dpy, c->src.window, &c->image,
 			     clip->x, clip->y, AllPlanes);
 	} else {
+		DBG(DRAW, ("%s-%s get_src XGetSubImage (slow)\n",
+			   DisplayString(c->dst.dpy), c->dst.name));
 		ximage_prepare(&c->image, c->width, c->height);
 		XGetSubImage(c->src.dpy, c->src.window,
 			     clip->x, clip->y, clip->width, clip->height,
@@ -1903,6 +1931,9 @@ static int clone_paint(struct clone *c)
 {
 	XRectangle clip;
 
+	if (c->width == 0 || c->height == 0)
+		return 0;
+
 	DBG(DRAW, ("%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,
@@ -1977,6 +2008,10 @@ static int clone_paint(struct clone *c)
 		clip.height = c->damaged.y2 - c->damaged.y1;
 		get_src(c, &clip);
 
+		DBG(DRAW, ("%s-%s target offset %dx%d\n",
+			   DisplayString(c->dst.dpy), c->dst.name,
+			   c->dst.x - c->src.x, c->dst.y - c->src.y));
+
 		clip.x += c->dst.x - c->src.x;
 		clip.y += c->dst.y - c->src.y;
 		put_dst(c, &clip);
@@ -2285,6 +2320,8 @@ static int clone_init_depth(struct clone *clone)
 	if (ret)
 		return ret;
 
+	clone->depth = depth;
+
 	DBG(X11, ("%s-%s using depth %d, requires xrender for src? %d, for dst? %d\n",
 	     DisplayString(clone->dst.dpy), clone->dst.name,
 	     clone->depth,
@@ -2625,6 +2662,11 @@ static int last_display_add_clones__randr(struct context *ctx)
 			return ret;
 		}
 
+		clone->dst.x = 0;
+		clone->dst.y = 0;
+		clone->dst.width = display->width;
+		clone->dst.height = display->height;
+
 		ret = clone_update_modes__randr(clone);
 		if (ret) {
 			fprintf(stderr, "Failed to clone output \"%s\" from display \"%s\"\n",
@@ -2701,8 +2743,8 @@ static int last_display_add_clones__xinerama(struct context *ctx)
 		}
 
 		/* Replace the modes on the local VIRTUAL output with the remote Screen */
-		clone->width = xi[n].width;
-		clone->height = xi[n].height;
+		clone->dst.width = xi[n].width;
+		clone->dst.height = xi[n].height;
 		clone->dst.x = xi[n].x_org;
 		clone->dst.y = xi[n].y_org;
 		clone->dst.rr_crtc = -1;
@@ -2731,64 +2773,67 @@ static int last_display_add_clones__display(struct context *ctx)
 	Display *dpy = display->dpy;
 	struct clone *clone;
 	Screen *scr;
+	int count, s;
 	char buf[80];
 	int ret;
 	RROutput id;
 
+	count = ScreenCount(dpy);
+	DBG(X11, ("%s(%s) - %d screens\n", __func__, DisplayString(dpy), count));
+	for (s = 0; s < count; s++) {
+		clone = add_clone(ctx);
+		if (clone == NULL)
+			return -ENOMEM;
 
-	DBG(X11, ("%s(%s)\n", __func__, DisplayString(dpy)));
-	clone = add_clone(ctx);
-	if (clone == NULL)
-		return -ENOMEM;
+		clone->depth = 24;
+		clone->next = display->clone;
+		display->clone = clone;
 
-	clone->depth = 24;
-	clone->next = display->clone;
-	display->clone = clone;
+		id = claim_virtual(ctx->display, buf, ctx->nclone);
+		if (id == 0) {
+			fprintf(stderr, "Failed to find available VirtualHead \"%s\" for on display \"%s\"\n",
+				buf, DisplayString(dpy));
+		}
+		ret = clone_output_init(clone, &clone->src, ctx->display, buf, id);
+		if (ret) {
+			fprintf(stderr, "Failed to add display \"%s\"\n",
+				DisplayString(ctx->display->dpy));
+			return ret;
+		}
 
-	id = claim_virtual(ctx->display, buf, ctx->nclone);
-	if (id == 0) {
-		fprintf(stderr, "Failed to find available VirtualHead \"%s\" for on display \"%s\"\n",
-			buf, DisplayString(dpy));
-	}
-	ret = clone_output_init(clone, &clone->src, ctx->display, buf, id);
-	if (ret) {
-		fprintf(stderr, "Failed to add display \"%s\"\n",
-			DisplayString(ctx->display->dpy));
-		return ret;
-	}
+		sprintf(buf, "SCREEN%d", s);
+		ret = clone_output_init(clone, &clone->dst, display, buf, 0);
+		if (ret) {
+			fprintf(stderr, "Failed to add display \"%s\"\n",
+				DisplayString(dpy));
+			return ret;
+		}
 
-	sprintf(buf, "WHOLE");
-	ret = clone_output_init(clone, &clone->dst, display, buf, 0);
-	if (ret) {
-		fprintf(stderr, "Failed to add display \"%s\"\n",
-			DisplayString(dpy));
-		return ret;
-	}
+		ret = clone_init_depth(clone);
+		if (ret) {
+			fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n",
+				DisplayString(dpy));
+			return ret;
+		}
 
-	ret = clone_init_depth(clone);
-	if (ret) {
-		fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n",
-			DisplayString(dpy));
-		return ret;
-	}
+		/* Replace the modes on the local VIRTUAL output with the remote Screen */
+		scr = ScreenOfDisplay(dpy, s);
+		clone->dst.width = scr->width;
+		clone->dst.height = scr->height;
+		clone->dst.x = 0;
+		clone->dst.y = 0;
+		clone->dst.rr_crtc = -1;
+		ret = clone_update_modes__fixed(clone);
+		if (ret) {
+			fprintf(stderr, "Failed to clone display \"%s\"\n",
+				DisplayString(dpy));
+			return ret;
+		}
 
-	/* Replace the modes on the local VIRTUAL output with the remote Screen */
-	scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
-	clone->width = scr->width;
-	clone->height = scr->height;
-	clone->dst.x = 0;
-	clone->dst.y = 0;
-	clone->dst.rr_crtc = -1;
-	ret = clone_update_modes__fixed(clone);
-	if (ret) {
-		fprintf(stderr, "Failed to clone display \"%s\"\n",
-			DisplayString(dpy));
-		return ret;
+		clone->active = ctx->active;
+		ctx->active = clone;
 	}
 
-	clone->active = ctx->active;
-	ctx->active = clone;
-
 	return 0;
 }
 
@@ -3201,6 +3246,33 @@ static void context_cleanup(struct context *ctx)
 	XCloseDisplay(dpy);
 }
 
+static void update_cursor_image(struct context *ctx)
+{
+	XFixesCursorImage *cur;
+	int i;
+
+	DBG(CURSOR, ("%s cursor changed\n",
+		     DisplayString(ctx->display->dpy)));
+
+	cur = XFixesGetCursorImage(ctx->display->dpy);
+	if (cur == NULL)
+		return;
+
+	display_load_visible_cursor(&ctx->display[0], cur);
+	for (i = 1; i < ctx->ndisplay; i++) {
+		struct display *display = &ctx->display[i];
+
+		DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy)));
+		display->cursor_moved++;
+		if (display->cursor != display->invisible_cursor) {
+			display->cursor_visible++;
+			context_enable_timer(display->ctx);
+		}
+	}
+
+	XFree(cur);
+}
+
 static int done;
 
 static void signal_handler(int sig)
@@ -3382,6 +3454,7 @@ int main(int argc, char **argv)
 	signal(SIGTERM, signal_handler);
 
 	ctx.command_continuation = 0;
+	update_cursor_image(&ctx);
 	while (!done) {
 		XEvent e;
 		int reconfigure = 0;
@@ -3414,28 +3487,7 @@ int main(int argc, char **argv)
 					if (ctx.active)
 						context_enable_timer(&ctx);
 				} else if (e.type == ctx.display->xfixes_event + XFixesCursorNotify) {
-					XFixesCursorImage *cur;
-
-					DBG(CURSOR, ("%s cursor changed\n",
-					     DisplayString(ctx.display->dpy)));
-
-					cur = XFixesGetCursorImage(ctx.display->dpy);
-					if (cur == NULL)
-						continue;
-
-					display_load_visible_cursor(&ctx.display[0], cur);
-					for (i = 1; i < ctx.ndisplay; i++) {
-						struct display *display = &ctx.display[i];
-
-						DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy)));
-						display->cursor_moved++;
-						if (display->cursor != display->invisible_cursor) {
-							display->cursor_visible++;
-							context_enable_timer(display->ctx);
-						}
-					}
-
-					XFree(cur);
+					update_cursor_image(&ctx);
 				} else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) {
 					DBG(XRR, ("%s screen changed (reconfigure pending? %d)\n",
 					     DisplayString(ctx.display->dpy), reconfigure));
commit d0ba02666d786f63a88f7c69b82246560521adc7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 3 13:07:03 2015 +0100

    sna: Force a configuration reprobe if we detect a mismatch in initial state
    
    If we find that the kernel has more active CRTC than we successfully
    enable, something is amiss and more importantly we are leaving an
    existing active CRTC blank. As a failsafe, if we detect this, fallback
    to doing a full probe for the initial configuration.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index b313100..bf6ca89 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6213,6 +6213,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 {
 	ScrnInfoPtr scrn = sna->scrn;
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	int crtc_active, crtc_enabled;
 	int width, height;
 	int i, j;
 
@@ -6250,6 +6251,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 	}
 
 	/* Copy the existing modes on each CRTCs */
+	crtc_active = crtc_enabled = 0;
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		xf86CrtcPtr crtc = config->crtc[i];
 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
@@ -6278,6 +6280,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 		crtc->desiredX = mode.x;
 		crtc->desiredY = mode.y;
 		crtc->desiredTransformPresent = FALSE;
+		crtc_active++;
 	}
 
 	/* Reconstruct outputs pointing to active CRTC */
@@ -6332,6 +6335,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 				output->crtc = crtc;
 				output->status = XF86OutputStatusConnected;
 				crtc->enabled = TRUE;
+				crtc_enabled++;
 
 				if (output->mm_width == 0 || output->mm_height == 0) {
 					output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI);
@@ -6360,6 +6364,12 @@ static bool sna_probe_initial_configuration(struct sna *sna)
 		}
 	}
 
+	if (crtc_active != crtc_enabled) {
+		DBG(("%s: only enabled %d out of %d active CRTC, forcing a reconfigure\n",
+		     __FUNCTION__, crtc_enabled, crtc_active));
+		return false;
+	}
+
 	width = height = 0;
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
 		xf86CrtcPtr crtc = config->crtc[i];


More information about the xorg-commit mailing list