From fbc690ccaf12d6536951d0ba403dfbb92c7c4115 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 1 Oct 2021 09:47:41 +0200 Subject: [PATCH] modesetting: Consider RandR primary output for selectioh of sync crtc. The "sync crtc" is the crtc used to drive the display timing of a drawable under DRI2 and DRI3/Present. If a drawable intersects multiple video outputs, then normally the crtc is chosen which has the largest intersection area with the drawable. If multiple outputs / crtc's have exacty the same intersection area then the crtc chosen was simply the first one with maximum intersection. Iow. the choice was random, depending on plugging order of displays. This adds the ability to choose a preferred output in such a tie situation. The RandR output marked as "primary output" is chosen on such a tie. This new behaviour and its implementation is consistent with other video ddx drivers. See amdgpu-ddx, ati-ddx and nouveau-ddx for reference. This commit is a straightforward port from amdgpu-ddx. Signed-off-by: Mario Kleiner (cherry picked from commit 4b75e65766a9ef3a26d4c1c9d7af9fc6d1d7be5b) --- hw/xfree86/drivers/modesetting/vblank.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c index c8da476b5..ea9e7a88c 100644 --- a/hw/xfree86/drivers/modesetting/vblank.c +++ b/hw/xfree86/drivers/modesetting/vblank.c @@ -120,7 +120,8 @@ static RRCrtcPtr rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint) { rrScrPrivPtr pScrPriv; - RRCrtcPtr crtc, best_crtc; + RROutputPtr primary_output; + RRCrtcPtr crtc, best_crtc, primary_crtc; int coverage, best_coverage; int c; BoxRec crtc_box, cover_box; @@ -136,6 +137,11 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint) if (!pScrPriv) return NULL; + primary_crtc = NULL; + primary_output = RRFirstOutput(pScreen); + if (primary_output) + primary_crtc = primary_output->crtc; + for (c = 0; c < pScrPriv->numCrtcs; c++) { crtc = pScrPriv->crtcs[c]; @@ -146,7 +152,8 @@ rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint) rr_crtc_box(crtc, &crtc_box); box_intersect(&cover_box, &crtc_box, box); coverage = box_area(&cover_box); - if (coverage > best_coverage) { + if ((coverage > best_coverage) || + (coverage == best_coverage && crtc == primary_crtc)) { best_crtc = crtc; best_coverage = coverage; }