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