xf86-video-intel: 2 commits - src/sna/sna_dri2.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Jun 23 09:57:10 PDT 2015
src/sna/sna_dri2.c | 119 ++++++++++++++++++++++++++++++++++-------------------
1 file changed, 78 insertions(+), 41 deletions(-)
New commits:
commit 293450a23ddbc7beafb786b24ce7981af84330b1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jun 23 17:54:36 2015 +0100
sna/dri2: Rearrange proxy tracking for single-CRTC flipping
Looks like amalgamating the per-CRTC xchg with the blit caused a few
regressions with TearFree single monitor flipping.
References: https://bugs.freedesktop.org/show_bug.cgi?id=91066
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 166b8ae..5d0492a 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1906,7 +1906,6 @@ can_flip(struct sna * sna,
}
DBG(("%s: yes, pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber));
- assert(dri2_window(win)->front == NULL);
return true;
}
@@ -2013,9 +2012,9 @@ overlaps_other_crtc(struct sna *sna, xf86CrtcPtr desired)
static bool
can_xchg_crtc(struct sna *sna,
DrawablePtr draw,
+ xf86CrtcPtr crtc,
DRI2BufferPtr front,
- DRI2BufferPtr back,
- xf86CrtcPtr crtc)
+ DRI2BufferPtr back)
{
WindowPtr win = (WindowPtr)draw;
PixmapPtr pixmap;
@@ -2163,6 +2162,7 @@ sna_dri2_xchg(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back)
static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc, DRI2BufferPtr front, DRI2BufferPtr back)
{
WindowPtr win = (WindowPtr)draw;
+ struct dri2_window *priv = dri2_window(win);
DRI2Buffer2Ptr tmp;
struct kgem_bo *bo;
@@ -2186,8 +2186,6 @@ static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr cr
sna->ignore_copy_area = false;
}
- assert(dri2_window(win)->front == NULL);
-
tmp = calloc(1, sizeof(*tmp) + sizeof(struct sna_dri2_private));
if (tmp == NULL) {
back->attachment = -1;
@@ -2195,7 +2193,13 @@ static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr cr
get_private(back)->pixmap = get_private(front)->pixmap;
get_private(back)->proxy = sna_dri2_reference_buffer(get_private(front)->proxy ?: front);
}
- dri2_window(win)->front = sna_dri2_reference_buffer(back);
+
+ if (priv->front) {
+ assert(front == priv->front);
+ assert(get_private(priv->front)->refcnt > 1);
+ get_private(priv->front)->refcnt--;
+ }
+ priv->front = sna_dri2_reference_buffer(back);
return;
}
@@ -2207,14 +2211,24 @@ static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr cr
get_private(tmp)->size = get_private(back)->size;
get_private(tmp)->pixmap = get_private(front)->pixmap;
get_private(tmp)->proxy = sna_dri2_reference_buffer(get_private(front)->proxy ?: front);
+ mark_stale(back);
- dri2_window(win)->front = tmp;
+ if (priv->front) {
+ DBG(("%s: replacing Window frontbuffer (was handle=%d) now handle=%d\n",
+ __FUNCTION__,
+ get_private(priv->front)->bo->handle,
+ get_private(tmp)->bo->handle));
+ assert(front == priv->front);
+ assert(get_private(priv->front)->refcnt > 1);
+ get_private(priv->front)->refcnt--;
+ }
+ priv->front = tmp;
if (get_private(front)->proxy) {
DBG(("%s: reusing current proxy frontbuffer\n", __FUNCTION__));
front->attachment = DRI2BufferBackLeft;
ref(get_private(tmp)->bo);
- back->attachment = -1;
+ back->attachment = DRI2BufferFrontLeft;
} else {
DBG(("%s: allocating new backbuffer\n", __FUNCTION__));
back->name = 0;
@@ -2232,7 +2246,7 @@ static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr cr
if (bo != NULL)
kgem_bo_destroy(&sna->kgem, bo);
get_private(back)->bo = NULL;
- back->attachment = -1;
+ back->attachment = DRI2BufferFrontLeft;
}
}
}
@@ -2343,8 +2357,10 @@ static void chain_swap(struct sna_dri2_event *chain)
if (can_xchg(chain->sna, chain->draw, chain->front, chain->back)) {
sna_dri2_xchg(chain->draw, chain->front, chain->back);
- } else if (can_xchg_crtc(chain->sna, chain->draw, chain->front, chain->back, chain->crtc)) {
- sna_dri2_xchg_crtc(chain->sna, chain->draw, chain->crtc, chain->front, chain->back);
+ } else if (can_xchg_crtc(chain->sna, chain->draw, chain->crtc,
+ chain->front, chain->back)) {
+ sna_dri2_xchg_crtc(chain->sna, chain->draw, chain->crtc,
+ chain->front, chain->back);
} else {
assert(chain->queued);
__sna_dri2_copy_event(chain, DRI2_BO);
@@ -2471,8 +2487,10 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event)
} else if (can_xchg(info->sna, draw, info->front, info->back)) {
sna_dri2_xchg(draw, info->front, info->back);
info->type = SWAP_WAIT;
- } else if (can_xchg_crtc(sna, draw, info->front, info->back, info->crtc)) {
- sna_dri2_xchg_crtc(sna, draw, info->crtc, info->front, info->back);
+ } else if (can_xchg_crtc(sna, draw, info->crtc,
+ info->front, info->back)) {
+ sna_dri2_xchg_crtc(sna, draw, info->crtc,
+ info->front, info->back);
info->type = SWAP_WAIT;
} else {
assert(info->queued);
@@ -2581,10 +2599,12 @@ sna_dri2_immediate_blit(struct sna *sna,
DBG(("%s: no pending blit, starting chain\n", __FUNCTION__));
- if (can_xchg(chain->sna, chain->draw, chain->front, chain->back)) {
- sna_dri2_xchg(chain->draw, chain->front, chain->back);
- } else if (can_xchg_crtc(chain->sna, chain->draw, chain->front, chain->back, chain->crtc)) {
- sna_dri2_xchg_crtc(chain->sna, chain->draw, chain->crtc, chain->front, chain->back);
+ if (can_xchg(info->sna, info->draw, info->front, info->back)) {
+ sna_dri2_xchg(info->draw, info->front, info->back);
+ } else if (can_xchg_crtc(info->sna, info->draw, info->crtc,
+ info->front, info->back)) {
+ sna_dri2_xchg_crtc(info->sna, info->draw, info->crtc,
+ info->front, info->back);
} else
__sna_dri2_copy_event(info, sync | DRI2_BO);
@@ -2611,7 +2631,8 @@ sna_dri2_immediate_blit(struct sna *sna,
get_private(info->back)->bo->handle,
get_private(info->back)->copy.bo ? get_private(info->back)->copy.bo->active_scanout : 0,
get_private(info->back)->copy.bo ? get_private(info->back)->copy.bo->handle : 0));
- assert(get_private(info->back)->bo->active_scanout == 0);
+ assert(get_private(info->back)->bo->active_scanout == 0 ||
+ get_private(info->back)->bo->scanout);
if (get_private(info->back)->copy.bo) {
assert(get_private(info->back)->copy.bo->active_scanout);
get_private(info->back)->copy.bo->active_scanout--;
@@ -3122,30 +3143,18 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
assert(get_private(front)->bo->refcnt);
assert(get_private(back)->bo->refcnt);
- if (get_private(front)->pixmap != get_drawable_pixmap(draw)) {
- DBG(("%s: decoupled DRI2 front pixmap=%ld, actual pixmap=%ld\n",
- __FUNCTION__,
- get_private(front)->pixmap->drawable.serialNumber,
- get_drawable_pixmap(draw)->drawable.serialNumber));
- goto skip;
- }
-
if (get_private(back)->stale) {
DBG(("%s: stale back buffer\n", __FUNCTION__));
goto skip;
}
- assert(sna_pixmap_from_drawable(draw)->flush);
-
if (draw->type != DRAWABLE_PIXMAP) {
WindowPtr win = (WindowPtr)draw;
struct dri2_window *priv = dri2_window(win);
- if (priv->front) {
- assert(front == priv->front);
- assert(get_private(priv->front)->refcnt > 1);
- get_private(priv->front)->refcnt--;
- priv->front = NULL;
- }
+
+ if (priv->front)
+ front = priv->front;
+
if (win->clipList.extents.x2 <= win->clipList.extents.x1 ||
win->clipList.extents.y2 <= win->clipList.extents.y1) {
DBG(("%s: window clipped (%d, %d), (%d, %d)\n",
@@ -3158,6 +3167,16 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
}
}
+ if (get_private(front)->pixmap != get_drawable_pixmap(draw)) {
+ DBG(("%s: decoupled DRI2 front pixmap=%ld, actual pixmap=%ld\n",
+ __FUNCTION__,
+ get_private(front)->pixmap->drawable.serialNumber,
+ get_drawable_pixmap(draw)->drawable.serialNumber));
+ goto skip;
+ }
+
+ assert(sna_pixmap_from_drawable(draw)->flush);
+
/* Drawable not displayed... just complete the swap */
if ((sna->flags & SNA_NO_WAIT) == 0)
crtc = sna_dri2_get_crtc(draw);
commit ac2aee9f5a54c6fa8e48b512905a5fe84cbba204
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 22 14:36:35 2015 +0100
sna/dri2: Rearrange assert to avoid false-positive
One assert(active_scanout) was firing when feed in an old flip bo, which
in hindsight was quite expected.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 2cde0c6..166b8ae 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -212,17 +212,31 @@ sna_dri2_cache_bo(struct sna *sna,
{
struct dri_bo *c;
- if (draw == NULL)
+ if (draw == NULL) {
+ DBG(("%s: no draw, releasing handle=%d\n",
+ __FUNCTION__, bo->handle));
goto err;
+ }
- if (bo->refcnt > 1)
+ if (bo->refcnt > 1) {
+ DBG(("%s: multiple references [%d], releasing handle\n",
+ __FUNCTION__, bo->refcnt, bo->handle));
goto err;
+ }
- if ((draw->height << 16 | draw->width) != get_private(buffer)->size)
+ if ((draw->height << 16 | draw->width) != get_private(buffer)->size) {
+ DBG(("%s: wrong size [%dx%d], releasing handle\n",
+ __FUNCTION__,
+ get_private(buffer)->size & 0xffff, get_private(buffer)->size >> 16,
+ bo->handle));
goto err;
+ }
- if (bo->scanout && front_pitch(draw) != bo->pitch)
+ if (bo->scanout && front_pitch(draw) != bo->pitch) {
+ DBG(("%s: scanout with pitch change [%d %= %d], releasing handle\n",
+ __FUNCTION__, bo->pitch, front_pitch(draw), bo->handle));
goto err;
+ }
c = malloc(sizeof(*c));
if (!c)
@@ -237,7 +251,7 @@ sna_dri2_cache_bo(struct sna *sna,
return;
err:
- assert(bo->active_scanout == 0);
+ assert(bo->active_scanout == 0 || bo->scanout);
kgem_bo_destroy(&sna->kgem, bo);
}
@@ -2234,7 +2248,7 @@ static void frame_swap_complete(struct sna_dri2_event *frame, int type)
swap = sna_crtc_last_swap(frame->crtc);
DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc=%lld], tv=%d.%06d\n",
- __FUNCTION__, type, (long)frame->draw, frame->pipe,
+ __FUNCTION__, type, (long)frame->draw->id, frame->pipe,
(long long)swap->msc,
(long long)draw_current_msc(frame->draw, frame->crtc, swap->msc),
swap->tv_sec, swap->tv_usec));
@@ -2311,10 +2325,10 @@ static void chain_swap(struct sna_dri2_event *chain)
*/
if (get_private(chain->back)->copy.bo) {
tmp.bo = get_private(chain->back)->copy.bo;
- assert(tmp.bo->active_scanout);
DBG(("%s: removing active marker [%d] from handle=%d\n",
__FUNCTION__,
tmp.bo->active_scanout, tmp.bo->handle));
+ assert(tmp.bo->active_scanout);
tmp.bo->active_scanout--;
tmp.bo = get_private(chain->back)->bo;
@@ -2351,6 +2365,10 @@ static void chain_swap(struct sna_dri2_event *chain)
get_private(chain->back)->copy.bo = ref(get_private(chain->back)->bo);
get_private(chain->back)->copy.name = chain->back->name;
get_private(chain->back)->copy.flags = chain->back->flags;
+ DBG(("%s: adding active marker [%d] to handle=%d\n",
+ __FUNCTION__,
+ get_private(chain->back)->bo->active_scanout,
+ get_private(chain->back)->bo->handle));
get_private(chain->back)->bo->active_scanout++;
}
assert(get_private(chain->back)->bo != get_private(chain->front)->bo);
More information about the xorg-commit
mailing list