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