xf86-video-intel: src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna.h src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Feb 8 07:55:17 PST 2015


 src/sna/sna.h         |    4 +-
 src/sna/sna_display.c |   68 ++++++++++++++++++++++++++++++++++++++------------
 src/sna/sna_dri2.c    |    6 ++--
 src/sna/sna_present.c |   12 ++++++++
 4 files changed, 69 insertions(+), 21 deletions(-)

New commits:
commit 0c2ff5532c79029a8c3c50a83d3f719cc5c5171e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 15:21:24 2015 +0000

    sna/present: Fallback to first available CRTC if none overlap Window
    
    In order to handle PRIME offscreen Windows nicely, tie their
    presentation into the Primary CRTC (if available).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 076c7be..2cf664f 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -505,12 +505,12 @@ to_sna_from_kgem(struct kgem *kgem)
 extern xf86CrtcPtr sna_covering_crtc(struct sna *sna,
 				     const BoxRec *box,
 				     xf86CrtcPtr desired);
+extern xf86CrtcPtr sna_primary_crtc(struct sna *sna);
+extern xf86CrtcPtr sna_first_active_crtc(struct sna *sna);
 
 extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap,
 				  xf86CrtcPtr crtc, const BoxRec *clip);
 
-xf86CrtcPtr sna_mode_first_crtc(struct sna *sna);
-
 const struct ust_msc {
 	uint64_t msc;
 	int tv_sec;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 31a0ae9..038e0ee 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -355,21 +355,6 @@ const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc)
 	}
 }
 
-xf86CrtcPtr sna_mode_first_crtc(struct sna *sna)
-{
-	rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
-	if (rr && rr->primaryOutput) {
-		xf86OutputPtr output = rr->primaryOutput->devPrivate;
-		if (output->crtc && to_sna_crtc(output->crtc))
-			return output->crtc;
-	}
-
-	if (sna->mode.num_real_crtc)
-		return XF86_CRTC_CONFIG_PTR(sna->scrn)->crtc[0];
-
-	return NULL;
-}
-
 #ifndef NDEBUG
 static void gem_close(int fd, uint32_t handle);
 static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo,
@@ -6260,6 +6245,59 @@ sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
 	return best_crtc;
 }
 
+xf86CrtcPtr sna_first_active_crtc(struct sna *sna)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	rrScrPrivPtr rr;
+	int c;
+
+	if (sna->flags & SNA_IS_HOSTED)
+		return NULL;
+
+	/* If we do not own the VT, we do not own the CRTC either */
+	if (!sna->scrn->vtSema) {
+		DBG(("%s: none, VT switched\n", __FUNCTION__));
+		return NULL;
+	}
+
+	if (sna->mode.hidden) {
+		DBG(("%s: none, hidden outputs\n", __FUNCTION__));
+		return NULL;
+	}
+
+	rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
+	if (rr && rr->primaryOutput) {
+		xf86OutputPtr output = rr->primaryOutput->devPrivate;
+		xf86CrtcPtr crtc = output->crtc;
+		if (crtc && to_sna_crtc(crtc) && to_sna_crtc(crtc)->bo)
+			return crtc;
+	}
+
+	for (c = 0; c < sna->mode.num_real_crtc; c++) {
+		if (to_sna_crtc(config->crtc[c])->bo == NULL)
+			continue;
+
+		return config->crtc[c];
+	}
+
+	return NULL;
+}
+
+xf86CrtcPtr sna_primary_crtc(struct sna *sna)
+{
+	rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
+	if (rr && rr->primaryOutput) {
+		xf86OutputPtr output = rr->primaryOutput->devPrivate;
+		if (output->crtc && to_sna_crtc(output->crtc))
+			return output->crtc;
+	}
+
+	if (sna->mode.num_real_crtc)
+		return XF86_CRTC_CONFIG_PTR(sna->scrn)->crtc[0];
+
+	return NULL;
+}
+
 #define MI_LOAD_REGISTER_IMM			(0x22<<23)
 
 static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 1a86906..4a6ea15 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -3080,7 +3080,7 @@ blit:
 skip:
 	DBG(("%s: unable to show frame, unblocking client\n", __FUNCTION__));
 	if (crtc == NULL)
-		crtc = sna_mode_first_crtc(sna);
+		crtc = sna_primary_crtc(sna);
 	fake_swap_complete(sna, client, draw, crtc, type, func, data);
 	*target_msc = 0; /* offscreen, so zero out target vblank count */
 	return TRUE;
@@ -3110,7 +3110,7 @@ sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
 			sna_crtc_record_vblank(crtc, &vbl);
 	} else
 		/* Drawable not displayed, make up a *monotonic* value */
-		crtc = sna_mode_first_crtc(sna);
+		crtc = sna_primary_crtc(sna);
 
 	swap = sna_crtc_last_swap(crtc);
 	*msc = draw_current_msc(draw, crtc, swap->msc);
@@ -3208,7 +3208,7 @@ out_free_info:
 	sna_dri2_event_free(info);
 out_complete:
 	if (crtc == NULL)
-		crtc = sna_mode_first_crtc(sna);
+		crtc = sna_primary_crtc(sna);
 	swap = sna_crtc_last_swap(crtc);
 	DRI2WaitMSCComplete(client, draw,
 			    draw_current_msc(draw, crtc, swap->msc),
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 845267d..5026ece 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -95,6 +95,16 @@ sna_present_get_crtc(WindowPtr window)
 	if (crtc)
 		return crtc->randr_crtc;
 
+	/* Offscreen Window - use any CRTC as a clocksource.
+	 * This is likely to be either a Window on either VIRTUAL or PRIME
+	 * screen real estate, and ideally we would delegate to the
+	 * slave CRTC, but using our hardware is preferable to falling back
+	 * to Present's timer implemetation.
+	 */
+	crtc = sna_first_active_crtc(sna);
+	if (crtc)
+		return crtc->randr_crtc;
+
 	return NULL;
 }
 
@@ -458,7 +468,7 @@ sna_present_unflip(ScreenPtr screen, uint64_t event_id)
 		DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__));
 
 notify:
-		swap = sna_crtc_last_swap(sna_mode_first_crtc(sna));
+		swap = sna_crtc_last_swap(sna_primary_crtc(sna));
 		DBG(("%s: pipe=%d, tv=%d.%06d msc %lld, event %lld complete\n", __FUNCTION__,
 		     -1,
 		     swap->tv_sec, swap->tv_usec, (long long)swap->msc,


More information about the xorg-commit mailing list