xf86-video-intel: 2 commits - src/sna/sna_display.c src/sna/sna.h src/sna/sna_present.c
Chris Wilson
ickle at kemper.freedesktop.org
Sat Feb 14 14:50:41 PST 2015
src/sna/sna.h | 8 --
src/sna/sna_display.c | 35 -----------
src/sna/sna_present.c | 151 +++++---------------------------------------------
3 files changed, 21 insertions(+), 173 deletions(-)
New commits:
commit 74553bf4d25f5876ef6e682d06f5825feb9e1da4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Feb 14 22:31:06 2015 +0000
sna/present: Integrate into TearFree, take 2
Following on from the previous attempt is the realisation that we can
simply disable TearFree during a Present flip queue, and re-enable
TearFree upon unflip.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 1bddf7a..bbcea08 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -311,13 +311,6 @@ struct sna {
Bool (*rrGetInfo)(ScreenPtr, Rotation *);
} mode;
- struct sna_tearfree {
- struct notifier {
- void (*func)(struct sna *, void *);
- void *data;
- } hook[2];
- } tearfree;
-
struct {
struct sna_cursor *cursors;
xf86CursorInfoPtr info;
@@ -363,6 +356,7 @@ struct sna {
bool open;
#if HAVE_PRESENT
uint64_t unflip;
+ void *tearfree;
#endif
} present;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 286e470..ac130c7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1398,39 +1398,24 @@ static bool sna_mode_enable_shadow(struct sna *sna)
if (!sna->mode.shadow_damage)
return false;
- DamageRegister(&screen->GetScreenPixmap(screen)->drawable,
- sna->mode.shadow_damage);
+ DamageRegister(&sna->front->drawable, sna->mode.shadow_damage);
return true;
}
-inline static PixmapPtr sna_screen_pixmap(struct sna *sna)
-{
- return to_screen_from_sna(sna)->GetScreenPixmap(to_screen_from_sna(sna));
-}
-
static void sna_mode_disable_shadow(struct sna *sna)
{
struct sna_pixmap *priv;
- struct notifier *nb;
if (!sna->mode.shadow_damage)
return;
DBG(("%s\n", __FUNCTION__));
- nb = &sna->tearfree.hook[0];
- if (nb->func) {
- nb->func(sna, nb->data);
- nb->func = NULL;
- }
- assert(sna->tearfree.hook[1].func == NULL);
-
priv = sna_pixmap(sna->front);
if (priv->move_to_gpu == wait_for_shadow)
priv->move_to_gpu(sna, priv, 0);
- DamageUnregister(&sna_screen_pixmap(sna)->drawable,
- sna->mode.shadow_damage);
+ DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage);
DamageDestroy(sna->mode.shadow_damage);
sna->mode.shadow_damage = NULL;
@@ -7121,14 +7106,6 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
static void shadow_flip_handler(struct drm_event_vblank *e,
void *data)
{
- struct sna *sna = data;
-
- if (sna->tearfree.hook[0].func)
- sna->tearfree.hook[0].func(sna, sna->tearfree.hook[0].data);
-
- sna->tearfree.hook[0] = sna->tearfree.hook[1];
- sna->tearfree.hook[1].func = NULL;
-
sna_mode_redisplay(data);
}
@@ -7731,12 +7708,6 @@ fixup_flip:
assert(old == sna->mode.shadow);
assert(old->refcnt >= 1);
set_shadow(sna, region);
- } else {
- if (sna->tearfree.hook[0].func) {
- sna->tearfree.hook[0].func(sna, sna->tearfree.hook[0].data);
- sna->tearfree.hook[0].func = NULL;
- }
- assert(sna->tearfree.hook[1].func == NULL);
}
} else
kgem_submit(&sna->kgem);
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 266d743..613721c 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -503,128 +503,6 @@ get_flip_bo(PixmapPtr pixmap)
return priv->gpu_bo;
}
-static bool set_front(struct sna *sna, PixmapPtr pixmap)
-{
- RegionRec *damage;
-
- DBG(("%s: pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber));
-
- if (pixmap == sna->front)
- return false;
-
- sna_pixmap_discard_shadow_damage(sna_pixmap(sna->front), NULL);
- sna->front = pixmap;
-
- /* We rely on unflip restoring the real front before any drawing */
- damage = DamageRegion(sna->mode.shadow_damage);
- RegionUninit(damage);
- damage->extents.x1 = 0;
- damage->extents.y1 = 0;
- damage->extents.x2 = pixmap->drawable.width;
- damage->extents.y2 = pixmap->drawable.height;
- damage->data = NULL;
-
- return true;
-}
-
-static void
-xchg_handler(struct sna *sna, void *data)
-{
- struct sna_present_event *info = data;
- const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
-
- DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
- sna_crtc_to_pipe(info->crtc),
- swap->tv_sec, swap->tv_usec,
- (long long)swap->msc,
- (long long)info->target_msc, (long long)info->event_id));
- present_event_notify(info->event_id, swap_ust(swap), swap->msc);
- free(info);
-}
-
-static Bool
-xchg(struct sna *sna,
- RRCrtcPtr crtc,
- uint64_t event_id,
- uint64_t target_msc,
- PixmapPtr pixmap,
- Bool sync_flip)
-{
- struct sna_present_event *info;
- bool queued;
-
- DBG(("%s(pipe=%d, event=%lld, sync_flip=%d)\n",
- __FUNCTION__,
- pipe_from_crtc(crtc),
- (long long)event_id,
- sync_flip));
-
- assert(sna->flags & SNA_TEAR_FREE);
- assert(sna->mode.shadow_damage);
- assert(sna_pixmap(pixmap) && sna_pixmap(pixmap)->gpu_bo);
- assert(sync_flip);
-
- /* This effectively disables TearFree giving the client direct
- * access into the scanout with their Pixmap.
- */
- queued = set_front(sna, pixmap);
-
- info = malloc(sizeof(struct sna_present_event));
- if (info == NULL)
- return BadAlloc;
-
- info->crtc = crtc->devPrivate;
- info->sna = sna;
- info->target_msc = target_msc;
- info->event_id = event_id;
-
- if (queued) {
- struct notifier *nb;
-
- nb = &sna->tearfree.hook[0];
- if (nb->func)
- nb++;
- if (nb->func) {
- DBG(("%s: executing existing notifier\n", __FUNCTION__));
- nb->func(sna, nb->data);
- }
- DBG(("%s: queueing tearfree notifier: sequence %d\n",
- __FUNCTION__, nb - &sna->tearfree.hook[0]));
- nb->func = xchg_handler;
- nb->data = info;
- } else {
- union drm_wait_vblank vbl;
-
- DBG(("%s: queueing vblank notifier\n", __FUNCTION__));
-
- VG_CLEAR(vbl);
- vbl.request.type =
- DRM_VBLANK_ABSOLUTE |
- DRM_VBLANK_EVENT |
- DRM_VBLANK_NEXTONMISS;
- vbl.request.sequence = target_msc;
- vbl.request.signal = (uintptr_t)MARK_PRESENT(info);
- if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(info->crtc))) {
- DBG(("%s: vblank enqueue failed\n", __FUNCTION__));
- if (!sna_fake_vblank(info)) {
- free(info);
- goto notify;
- }
- }
- }
-
- return TRUE;
-
-notify:
- DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
- pipe_from_crtc(crtc),
- gettime_ust64() / 1000000, gettime_ust64() % 1000000,
- (long long)sna_crtc_last_swap(crtc->devPrivate)->msc,
- (long long)target_msc, (long long)event_id));
- present_event_notify(event_id, gettime_ust64(), target_msc);
- return TRUE;
-}
-
static Bool
sna_present_flip(RRCrtcPtr crtc,
uint64_t event_id,
@@ -655,8 +533,11 @@ sna_present_flip(RRCrtcPtr crtc,
return FALSE;
}
- if (sna->flags & SNA_TEAR_FREE)
- return xchg(sna, crtc, event_id, target_msc, pixmap, sync_flip);
+ if (sna->flags & SNA_TEAR_FREE) {
+ sna->present.tearfree = sna->mode.shadow_damage;
+ sna->mode.shadow_damage = NULL;
+ sna->flags &= ~SNA_TEAR_FREE;
+ }
if (sna->mode.flip_active) {
DBG(("%s: flips still pending\n", __FUNCTION__));
@@ -674,6 +555,7 @@ sna_present_unflip(ScreenPtr screen, uint64_t event_id)
{
struct sna *sna = to_sna_from_screen(screen);
struct kgem_bo *bo;
+ bool ok;
DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id));
if (sna->mode.front_active == 0 || sna->mode.rr_active) {
@@ -691,11 +573,6 @@ notify:
return;
}
- if (sna->flags & SNA_TEAR_FREE) {
- set_front(sna, screen->GetScreenPixmap(screen));
- goto notify;
- }
-
if (sna->mode.flip_active) {
DBG(("%s: %d outstanding flips, queueing unflip\n", __FUNCTION__, sna->mode.flip_active));
assert(sna->present.unflip == 0);
@@ -711,13 +588,21 @@ reset_mode:
goto notify;
}
+ ok = false;
if (sna->flags & SNA_HAS_ASYNC_FLIP) {
DBG(("%s: trying async flip restore\n", __FUNCTION__));
- if (flip__async(sna, NULL, event_id, 0, bo))
- return;
+ ok = flip__async(sna, NULL, event_id, 0, bo);
+ }
+ if (!ok)
+ ok = flip(sna, NULL, event_id, 0, bo);
+
+ if (sna->present.tearfree) {
+ sna->flags |= SNA_TEAR_FREE;
+ sna->mode.shadow_damage = sna->present.tearfree;
+ sna->present.tearfree = NULL;
}
- if (!flip(sna, NULL, event_id, 0, bo))
+ if (!ok)
goto reset_mode;
}
commit c30af937f8d634d0055358cb69db2896cf595983
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Feb 14 21:53:41 2015 +0000
sna/present: Disable hardware async flips with TearFree
These two don't mix, so remove the claim that we do support async flips
when TearFree is enabled.
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 c95fe98..286e470 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5973,7 +5973,7 @@ probe_capabilities(struct sna *sna)
sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP);
if (has_flip(sna))
sna->flags |= SNA_HAS_FLIP;
- if (has_flip__async(sna))
+ if (has_flip__async(sna) && (sna->flags & SNA_TEAR_FREE) == 0)
sna->flags |= SNA_HAS_ASYNC_FLIP;
DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__,
sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled",
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 6cc9c2e..266d743 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -562,15 +562,13 @@ xchg(struct sna *sna,
assert(sna->flags & SNA_TEAR_FREE);
assert(sna->mode.shadow_damage);
assert(sna_pixmap(pixmap) && sna_pixmap(pixmap)->gpu_bo);
+ assert(sync_flip);
/* This effectively disables TearFree giving the client direct
* access into the scanout with their Pixmap.
*/
queued = set_front(sna, pixmap);
- if (!sync_flip)
- goto notify; /* XXX We will claim that the scanout is idle */
-
info = malloc(sizeof(struct sna_present_event));
if (info == NULL)
return BadAlloc;
More information about the xorg-commit
mailing list