xf86-video-intel: 6 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_display_fake.c src/sna/sna_trapezoids_boxes.c tools/virtual.c

Chris Wilson ickle at kemper.freedesktop.org
Tue May 6 03:25:25 PDT 2014


 src/sna/sna_accel.c            |   26 +++--
 src/sna/sna_display.c          |  188 +++++++++++++++++++++++++++--------------
 src/sna/sna_display_fake.c     |   47 +++-------
 src/sna/sna_trapezoids_boxes.c |    7 +
 tools/virtual.c                |   14 ++-
 5 files changed, 174 insertions(+), 108 deletions(-)

New commits:
commit f62dfd8f518bb4117d395f81b684340dc4f1ede5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 6 07:37:59 2014 +0100

    sna: Allow connectors without an associated encoder
    
    In the future, we may see a setup where connectors are created without
    being attached to a specific encoder, instead associated with multiple
    generic encoders - such as DP MST sink devices. To handle this, we need
    to recheck their active encoder at runtime after branch configuration
    events (or possibly hotplug).
    
    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 f0c130f..aedabec 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -129,9 +129,11 @@ struct sna_property {
 
 struct sna_output {
 	int id;
-	int encoder_id, encoder_idx;
 	int serial;
 
+	unsigned possible_encoders;
+	unsigned attached_encoders;
+
 	unsigned int is_panel : 1;
 
 	uint32_t edid_idx;
@@ -158,6 +160,11 @@ struct sna_output {
 
 };
 
+inline static unsigned count_to_mask(int x)
+{
+	return (1 << x) - 1;
+}
+
 static inline struct sna_output *to_sna_output(xf86OutputPtr output)
 {
 	return output->driver_private;
@@ -2640,14 +2647,75 @@ output_ignored(ScrnInfoPtr scrn, const char *name)
 	return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0);
 }
 
+static bool
+gather_encoders(struct sna *sna,
+		drmModeResPtr res,
+		uint32_t id, int count,
+		struct drm_mode_get_encoder *out)
+{
+	union compat_mode_get_connector compat_conn;
+	struct drm_mode_modeinfo dummy;
+	struct drm_mode_get_encoder enc;
+	uint32_t *ids = NULL;
+
+	VG_CLEAR(compat_conn);
+	memset(out, 0, sizeof(*out));
+
+	do {
+		free(ids);
+		ids = malloc(sizeof(*ids) * count);
+		if (ids == 0)
+			return false;
+
+		compat_conn.conn.connector_id = id;
+		compat_conn.conn.count_props = 0;
+		compat_conn.conn.count_modes = 1; /* skip detect */
+		compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
+		compat_conn.conn.count_encoders = count;
+		compat_conn.conn.encoders_ptr = (uintptr_t)ids;
+
+		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
+			DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
+			compat_conn.conn.count_encoders = count = 0;
+		}
+
+		if (count == compat_conn.conn.count_encoders)
+			break;
+
+		count = compat_conn.conn.count_encoders;
+	} while (1);
+
+	for (count = 0; count < compat_conn.conn.count_encoders; count++) {
+		enc.encoder_id = ids[count];
+		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
+			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno));
+			count = 0;
+			break;
+		}
+		out->possible_crtcs |= enc.possible_crtcs;
+		out->possible_clones |= enc.possible_clones;
+
+		for (id = 0; id < res->count_encoders; id++) {
+			if (enc.encoder_id == res->encoders[id]) {
+				out->crtc_id |= 1 << id;
+				break;
+			}
+		}
+	}
+
+	free(ids);
+	return count > 0;
+}
+
 /* We need to map from kms encoder based possible_clones mask to X output based
  * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
  * can have more than one output hanging off the same encoder.
  */
 static void
-sna_mode_compute_possible_outputs(struct sna *sna, drmModeResPtr res)
+sna_mode_compute_possible_outputs(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int encoder_mask[32];
 	int i, j;
 
 	assert(sna->mode.num_real_output < 32);
@@ -2656,55 +2724,25 @@ sna_mode_compute_possible_outputs(struct sna *sna, drmModeResPtr res)
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 		struct sna_output *sna_output = to_sna_output(output);
-		struct drm_mode_get_encoder enc;
-
-		assert(to_sna_output(output));
 
-		sna_output->encoder_idx = -1;
-		output->possible_clones = 0;
-
-		VG_CLEAR(enc);
-		enc.encoder_id = sna_output->encoder_id;
-
-		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
-			DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno));
-			continue;
-		}
+		assert(sna_output);
 
-		for (j = 0; j < res->count_encoders; j++) {
-			if (enc.encoder_id == res->encoders[j]) {
-				sna_output->encoder_idx = j;
-				break;
-			}
-		}
-		assert(sna_output->encoder_idx != -1);
-
-		output->possible_clones = enc.possible_clones;
+		output->possible_clones = sna_output->possible_encoders;
+		encoder_mask[i] = sna_output->attached_encoders;
 	}
 
 	/* Convert from encoder numbering to output numbering */
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
-		unsigned mask = output->possible_clones;
-		unsigned clones = 0;
+		unsigned clones;
 
-		assert(to_sna_output(output));
 		if (output->possible_clones == 0)
 			continue;
 
-		for (j = 0; j < sna->mode.num_real_output; j++) {
-			struct sna_output *sna_output = to_sna_output(config->output[j]);
-
-			if (i == j)
-				continue;
-
-			if (sna_output->encoder_idx == -1)
-				continue;
-
-			if (mask & (1 << sna_output->encoder_idx))
+		clones = 0;
+		for (j = 0; j < sna->mode.num_real_output; j++)
+			if (i != j && output->possible_clones & encoder_mask[j])
 				clones |= 1 << j;
-		}
-
 		output->possible_clones = clones;
 
 		DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
@@ -2724,6 +2762,7 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	struct drm_mode_modeinfo dummy;
 	struct sna_output *sna_output;
 	xf86OutputPtr *outputs, output;
+	unsigned possible_encoders, attached_encoders;
 	const char *output_name;
 	char name[32];
 	int len, i;
@@ -2733,7 +2772,7 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
 
 	VG_CLEAR(compat_conn);
-	VG_CLEAR(enc);
+	memset(&enc, 0, sizeof(enc));
 
 	compat_conn.conn.connector_id = id;
 	compat_conn.conn.count_props = 0;
@@ -2743,16 +2782,10 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id;
 
 	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
-		DBG(("%s: GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno));
+		DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
 		return -1;
 	}
 
-	if (compat_conn.conn.count_encoders != 1) {
-		DBG(("%s: unexpected number [%d] of encoders attached\n",
-		     __FUNCTION__, compat_conn.conn.count_encoders));
-		return 0;
-	}
-
 	if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
 		output_name = output_names[compat_conn.conn.connector_type];
 	else
@@ -2761,9 +2794,38 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	if (output_ignored(scrn, name))
 		return 0;
 
-	if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
-		DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno));
-		return 0;
+	if (enc.encoder_id) {
+		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
+			DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno));
+			return 0;
+		}
+
+		possible_encoders = enc.possible_clones;
+		attached_encoders = 0;
+		for (i = 0; i < res->count_encoders; i++) {
+			if (enc.encoder_id == res->encoders[i]) {
+				attached_encoders = 1 << i;
+				break;
+			}
+		}
+
+		if (attached_encoders == 0) {
+			DBG(("%s: failed to find attached encoder\n", __FUNCTION__));
+			return 0;
+		}
+	} else {
+		DBG(("%s: unexpected number [%d] of encoders attached\n",
+		     __FUNCTION__, compat_conn.conn.count_encoders));
+		if (!gather_encoders(sna, res, id, compat_conn.conn.count_encoders, &enc)) {
+			DBG(("%s: gather encoders failed\n", __FUNCTION__));
+			return 0;
+		}
+		possible_encoders = enc.possible_clones;
+		attached_encoders = enc.crtc_id;
+
+		memset(&enc, 0, sizeof(enc));
+		enc.encoder_id = compat_conn.conn.encoder_id;
+		(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc);
 	}
 
 	if (xf86IsEntityShared(scrn->entityList[0])) {
@@ -2845,12 +2907,13 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	xf86OutputUseScreenMonitor(output, !config->num_output);
 
 	sna_output->id = compat_conn.conn.connector_id;
-	sna_output->encoder_id = enc.encoder_id;
-	sna_output->encoder_idx = -1;
 	sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
 	sna_output->edid_idx = find_property(sna, sna_output, "EDID");
 	sna_output->dpms_id = find_property_id(sna, sna_output, "DPMS");
 
+	sna_output->possible_encoders = possible_encoders;
+	sna_output->attached_encoders = attached_encoders;
+
 	output->mm_width = compat_conn.conn.mm_width;
 	output->mm_height = compat_conn.conn.mm_height;
 
@@ -2862,7 +2925,7 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 	if (sna_output->is_panel)
 		sna_output_backlight_init(output);
 
-	output->possible_crtcs = enc.possible_crtcs & ((1 << sna->mode.num_real_crtc) - 1);
+	output->possible_crtcs = enc.possible_crtcs & count_to_mask(sna->mode.num_real_crtc);
 	output->interlaceAllowed = TRUE;
 
 	if (serial) {
@@ -2880,9 +2943,11 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial)
 			output->crtc = (void *)(uintptr_t)enc.crtc_id;
 	}
 
-	DBG(("%s: created output '%s' %d (possible crtc:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n",
-	     __FUNCTION__, name, id,
+	DBG(("%s: created output '%s' %d, encoder=%d (possible crtc:%x, attached encoders:%x, possible clones:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n",
+	     __FUNCTION__, name, id, enc.encoder_id,
 	     (uint32_t)output->possible_crtcs,
+	     sna_output->attached_encoders,
+	     sna_output->possible_encoders,
 	     serial, sna_output->edid_idx, sna_output->dpms_id,
 	     (unsigned long)(uintptr_t)output->crtc));
 
@@ -2964,6 +3029,8 @@ void sna_mode_discover(struct sna *sna)
 			changed |= sna_output_add(sna, res->connectors[i], res, serial) > 0;
 	}
 
+	drmModeFreeResources(res);
+
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
 		if (to_sna_output(output)->serial != serial) {
@@ -2973,14 +3040,12 @@ void sna_mode_discover(struct sna *sna)
 	}
 
 	if (changed) {
-		sna_mode_compute_possible_outputs(sna, res);
+		sna_mode_compute_possible_outputs(sna);
 
 		/* Reorder user visible listing */
 		sort_randr_outputs(sna, screen);
 		xf86RandR12TellChanged(screen);
 	}
-
-	drmModeFreeResources(res);
 }
 
 static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
@@ -4415,7 +4480,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 
 		sna->mode.num_real_output = xf86_config->num_output;
 
-		sna_mode_compute_possible_outputs(sna, res);
+		sna_mode_compute_possible_outputs(sna);
 
 		sna->mode.max_crtc_width  = res->max_width;
 		sna->mode.max_crtc_height = res->max_height;
commit ea602f7e10c6319c4213776b49f2ae25739af316
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 6 06:58:35 2014 +0100

    sna: Discard the TearFree damage when doing a full CPU migration
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ef7f842..61210b1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1974,6 +1974,8 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
 		if (priv->cpu_bo)
 			kgem_bo_undo(&sna->kgem, priv->cpu_bo);
+		if (priv->move_to_gpu)
+			sna_pixmap_discard_shadow_damage(priv, NULL);
 	}
 
 	if (flags & MOVE_WRITE && priv->gpu_bo && priv->gpu_bo->proxy) {
@@ -2526,6 +2528,15 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 	}
 
+	if (priv->move_to_gpu) {
+		if ((flags & MOVE_READ) == 0)
+			sna_pixmap_discard_shadow_damage(priv, region);
+		if (!priv->move_to_gpu(sna, priv, MOVE_READ)) {
+			DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
+			return NULL;
+		}
+	}
+
 	if (flags & MOVE_WHOLE_HINT) {
 		DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n",
 		       __FUNCTION__,
@@ -2538,16 +2549,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
 	}
 
-
-	if (priv->move_to_gpu) {
-		if ((flags & MOVE_READ) == 0)
-			sna_pixmap_discard_shadow_damage(priv, region);
-		if (!priv->move_to_gpu(sna, priv, MOVE_READ)) {
-			DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
-			return NULL;
-		}
-	}
-
 	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
 		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
 		RegionTranslate(region, dx, dy);
@@ -4353,7 +4354,7 @@ create_upload_tiled_x(struct kgem *kgem,
 
 static bool
 try_upload_blt(PixmapPtr pixmap, RegionRec *region,
-		int x, int y, int w, int  h, char *bits, int stride)
+	       int x, int y, int w, int  h, char *bits, int stride)
 {
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
@@ -4488,7 +4489,8 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	}
 	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
-	if (priv->cow || priv->move_to_gpu) {
+	if ((priv->cow || priv->move_to_gpu) &&
+	    (!replaces || !sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE))) {
 		DBG(("%s: no, has COW or pending move-to-gpu\n", __FUNCTION__));
 		return false;
 	}
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 6a1d022..f0c130f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -909,7 +909,10 @@ void sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
 	     wait->region.extents.x2, wait->region.extents.y2));
 
 	assert(wait);
-	RegionSubtract(&wait->region, &wait->region, region);
+	if (region)
+		RegionSubtract(&wait->region, &wait->region, region);
+	else
+		RegionEmpty(&wait->region);
 }
 
 static bool sna_mode_enable_shadow(struct sna *sna)
commit b8d71e029cec5c8d1c7e344331b86d2e27f6bc24
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 5 20:59:24 2014 +0100

    sna: Tidy computation of clone/crtcs for fake outputs
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
index 0821478..97c463c 100644
--- a/src/sna/sna_display_fake.c
+++ b/src/sna/sna_display_fake.c
@@ -239,9 +239,8 @@ static bool add_fake_output(struct sna *sna, bool late)
 	xf86CrtcPtr crtc;
 	RROutputPtr clones[32];
 	RRCrtcPtr crtcs[32];
-	unsigned mask;
 	char buf[80];
-	int i, j, len;
+	int i, len;
 
 	if (sna->mode.num_fake >= 32)
 		return false;
@@ -264,6 +263,9 @@ static bool add_fake_output(struct sna *sna, bool late)
 	output->interlaceAllowed = FALSE;
 	output->subpixel_order = SubPixelNone;
 
+	output->possible_crtcs = ~((1 << sna->mode.num_real_crtc) - 1);
+	output->possible_clones = ~((1 << sna->mode.num_real_output) - 1);
+
 	if (late) {
 		ScreenPtr screen = xf86ScrnToScreen(scrn);
 
@@ -277,46 +279,27 @@ static bool add_fake_output(struct sna *sna, bool late)
 
 		RRPostPendingProperties(output->randr_output);
 
-		mask = (1 << ++sna->mode.num_fake) - 1;
-		for (i = j = 0; i < xf86_config->num_output; i++) {
-			output = xf86_config->output[i];
-			if (output->driver_private)
-				continue;
-
-			output->possible_crtcs = mask << sna->mode.num_real_crtc;
-			output->possible_clones = mask << sna->mode.num_real_output;
-
-			clones[j++] = output->randr_output;
-		}
-		assert(j == sna->mode.num_fake);
-
-		for (i = j = 0; i < xf86_config->num_crtc; i++) {
-			crtc = xf86_config->crtc[i];
-			if (crtc->driver_private)
-				continue;
+		for (i = sna->mode.num_real_output; i < xf86_config->num_output; i++)
+			clones[i - sna->mode.num_real_output] = xf86_config->output[i]->randr_output;
+		assert(i - sna->mode.num_real_output == sna->mode.num_fake + 1);
 
-			crtcs[j++] = crtc->randr_crtc;
-		}
-		assert(j == sna->mode.num_fake);
+		for (i = sna->mode.num_real_crtc; i < xf86_config->num_crtc; i++)
+			crtcs[i - sna->mode.num_real_crtc] = xf86_config->crtc[i]->randr_crtc;
+		assert(i - sna->mode.num_real_crtc == sna->mode.num_fake + 1);
 
-		for (i = 0; i < xf86_config->num_output; i++) {
-			output = xf86_config->output[i];
-			if (output->driver_private)
-				continue;
+		for (i = sna->mode.num_real_output; i < xf86_config->num_output; i++) {
+			RROutputPtr rr_output = xf86_config->output[i]->randr_output;
 
-			if (!RROutputSetCrtcs(output->randr_output, crtcs, j) ||
-			    !RROutputSetClones(output->randr_output, clones, j))
+			if (!RROutputSetCrtcs(rr_output, crtcs, sna->mode.num_fake + 1) ||
+			    !RROutputSetClones(rr_output, clones, sna->mode.num_fake + 1))
 				goto err;
 		}
 
 		RRCrtcSetRotations(crtc->randr_crtc,
 				   RR_Rotate_All | RR_Reflect_All);
-	} else {
-		mask = (1 << ++sna->mode.num_fake) - 1;
-		output->possible_crtcs = mask << sna->mode.num_real_crtc;
-		output->possible_clones = mask << sna->mode.num_real_output;
 	}
 
+	sna->mode.num_fake++;
 	return true;
 
 err:
commit 77507909a18b687698f6d4e436ef66d942308fc3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 5 19:43:25 2014 +0100

    intel-virtual-output: Grab the server whilst cleanging up the local output
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 0966590..a74b7ce 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -572,6 +572,9 @@ static int clone_update_modes__randr(struct clone *clone)
 		}
 	}
 
+	/* Create matching modes for the real output on the virtual */
+	XGrabServer(clone->src.dpy);
+
 	/* Clear all current UserModes on the output, including any active ones */
 	if (to_info->crtc) {
 		DBG(("%s(%s-%s): disabling active CRTC\n", __func__,
@@ -586,8 +589,6 @@ static int clone_update_modes__randr(struct clone *clone)
 
 	clone->src.rr_crtc = 0;
 
-	/* Create matching modes for the real output on the virtual */
-	XGrabServer(clone->src.dpy);
 	for (i = 0; i < from_info->nmode; i++) {
 		XRRModeInfo *mode, *old;
 		RRMode id;
commit 56126d00503fd9bc6fe30781ecddb2fb67de817b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 5 18:17:01 2014 +0100

    sna: Refine hints to allow inplace writes whilst compositing aligned traps
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids_boxes.c b/src/sna/sna_trapezoids_boxes.c
index 898efb5..335b2ce 100644
--- a/src/sna/sna_trapezoids_boxes.c
+++ b/src/sna/sna_trapezoids_boxes.c
@@ -209,8 +209,11 @@ composite_aligned_boxes(struct sna *sna,
 		     __FUNCTION__));
 
 		flags = MOVE_READ | MOVE_WRITE;
-		if (n == 1 && op <= PictOpSrc)
-			flags = MOVE_WRITE | MOVE_INPLACE_HINT;
+		if (op <= PictOpSrc) {
+			flags |= MOVE_INPLACE_HINT;
+			if (n == 1)
+				flags &= ~MOVE_READ;
+		}
 
 		if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &clip, flags))
 			goto done;
commit 464ef44ab1d691a4bffecbe88be8182adf9fd4ff
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon May 5 14:49:31 2014 +0100

    intel-virtual-output: Copy existing CRTC information
    
    If we fail to disable the remote output during initialisation, copy the
    current configuration in order to try and keep the bookkeeping in order.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 9d498a4..0966590 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -560,6 +560,15 @@ static int clone_update_modes__randr(struct clone *clone)
 		if (disable_crtc(clone->dst.dpy, from_res, from_info->crtc)) {
 			clone->dst.rr_crtc = 0;
 			clone->dst.mode.id = 0;
+		} else {
+			XRRCrtcInfo *c = XRRGetCrtcInfo(clone->dst.dpy, from_res, from_info->crtc);
+			if (c) {
+				clone->dst.x = c->x;
+				clone->dst.y = c->y;
+				clone->dst.rotation = c->rotation;
+				clone->dst.mode.id = c->mode;
+				XRRFreeCrtcInfo(c);
+			}
 		}
 	}
 


More information about the xorg-commit mailing list