summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-02-18 14:30:55 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-02-18 15:42:06 +0000
commit1f16d854264ea923303b79379266bd789fd9dd4d (patch)
tree832ab240ff45d4c19a0a7180f49838f601d00626 /src
parentb3ba758a0186c9abc6c0583f52775ea714165134 (diff)
sna/dri: Prevent swapping a decoupled DRI2Buffer
If the DRI2Buffer is no longer valid for the Drawable, for example the window had just been reparent, just complete the swap without triggering any assertions. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna_dri.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 7fea15f3..5d5ea178 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -261,6 +261,7 @@ sna_dri_create_buffer(DrawablePtr draw,
private->bo->handle, buffer->name));
assert(private->pixmap == pixmap);
+ assert(sna_pixmap(pixmap)->flush);
assert(sna_pixmap(pixmap)->gpu_bo == private->bo);
assert(sna_pixmap(pixmap)->pinned & PIN_DRI);
assert(kgem_bo_flink(&sna->kgem, private->bo) == buffer->name);
@@ -1309,7 +1310,7 @@ can_exchange(struct sna * sna,
__FUNCTION__));
return false;
}
- assert(get_private(front)->pixmap == sna->front);
+ assert(get_private(front)->pixmap != sna->front);
if (!get_private(back)->scanout) {
DBG(("%s: no, DRI2 drawable was too small at time of creation)\n",
@@ -1767,6 +1768,7 @@ sna_dri_page_flip_handler(struct sna *sna,
struct sna_dri_frame_event *info = to_frame_event(event->user_data);
DBG(("%s: pending flip_count=%d\n", __FUNCTION__, info->count));
+ assert(info->count > 0);
/* Is this the event whose info shall be delivered to higher level? */
if (event->user_data & 1) {
@@ -2105,9 +2107,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
DRI2BufferPtr back, CARD64 *target_msc, CARD64 divisor,
CARD64 remainder, DRI2SwapEventPtr func, void *data)
{
- ScreenPtr screen = draw->pScreen;
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct sna *sna = to_sna(scrn);
+ struct sna *sna = to_sna_from_drawable(draw);
drmVBlank vbl;
int pipe;
struct sna_dri_frame_event *info = NULL;
@@ -2135,13 +2135,16 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
assert(get_private(back)->bo->refcnt);
assert(get_private(back)->bo->flush);
+ if (get_private(front)->pixmap != get_drawable_pixmap(draw))
+ goto skip;
+
assert(sna_pixmap_from_drawable(draw)->flush);
/* Drawable not displayed... just complete the swap */
pipe = sna_dri_get_pipe(draw);
if (pipe == -1) {
DBG(("%s: off-screen, immediate update\n", __FUNCTION__));
- goto blit_fallback;
+ goto blit;
}
if (can_flip(sna, draw, front, back) &&
@@ -2154,7 +2157,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
info = calloc(1, sizeof(struct sna_dri_frame_event));
if (!info)
- goto blit_fallback;
+ goto blit;
info->draw = draw;
info->client = client;
@@ -2210,7 +2213,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
vbl.request.sequence = *target_msc;
vbl.request.signal = (unsigned long)info;
if (sna_wait_vblank(sna, &vbl))
- goto blit_fallback;
+ goto blit;
return TRUE;
}
@@ -2250,11 +2253,11 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
vbl.request.sequence -= 1;
vbl.request.signal = (unsigned long)info;
if (sna_wait_vblank(sna, &vbl))
- goto blit_fallback;
+ goto blit;
return TRUE;
-blit_fallback:
+blit:
pipe = DRI2_BLIT_COMPLETE;
if (can_exchange(sna, draw, front, back)) {
DBG(("%s -- xchg\n", __FUNCTION__));
@@ -2269,6 +2272,7 @@ blit_fallback:
}
if (info)
sna_dri_frame_event_info_free(sna, draw, info);
+skip:
DRI2SwapComplete(client, draw, 0, 0, 0, pipe, func, data);
*target_msc = 0; /* offscreen, so zero out target vblank count */
return TRUE;