xf86-video-intel: src/sna/sna_dri.c
Chris Wilson
ickle at kemper.freedesktop.org
Wed Sep 26 04:14:12 PDT 2012
src/sna/sna_dri.c | 74 ++++++++++++++++++++++++------------------------------
1 file changed, 34 insertions(+), 40 deletions(-)
New commits:
commit 34772cb0e724a880a8c6db936c0bb5dd129398f2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 26 12:09:39 2012 +0100
sna/dri: Handle pending flips when drawable disappears.
The async case needs special handling as the current front buffer may be
pending a flip onto the scanout which needs to be completed even if the
Drawable is destroyed.
Fixes regression from commit ad877abdc70b842afd202b2f97892d97a0b8d151
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Jul 7 17:48:52 2012 +0100
sna/dri: Attach the chain of frame events to the Window, not pixmap
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 14c718d..a59580b 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1322,20 +1322,18 @@ done:
}
static int
-sna_dri_flip_continue(struct sna *sna,
- DrawablePtr draw,
- struct sna_dri_frame_event *info)
+sna_dri_flip_continue(struct sna *sna, struct sna_dri_frame_event *info)
{
struct kgem_bo *bo;
int name;
DBG(("%s()\n", __FUNCTION__));
- assert(sna_pixmap_get_buffer(get_drawable_pixmap(draw)) == info->front);
+ assert(sna_pixmap_get_buffer(get_drawable_pixmap(info->draw)) == info->front);
name = info->back->name;
bo = get_private(info->back)->bo;
- assert(get_drawable_pixmap(draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
+ assert(get_drawable_pixmap(info->draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
info->count = sna_page_flip(sna, bo, info, info->pipe);
if (info->count == 0)
@@ -1362,8 +1360,6 @@ sna_dri_flip_continue(struct sna *sna,
static void sna_dri_flip_event(struct sna *sna,
struct sna_dri_frame_event *flip)
{
- DrawablePtr draw;
-
DBG(("%s(frame=%d, tv=%d.%06d, type=%d)\n",
__FUNCTION__,
flip->fe_frame,
@@ -1374,35 +1370,31 @@ static void sna_dri_flip_event(struct sna *sna,
if (sna->dri.flip_pending == flip)
sna->dri.flip_pending = NULL;
- draw = flip->draw;
- if (draw == NULL) {
- DBG(("%s: drawable already gone\n", __FUNCTION__));
- sna_dri_frame_event_info_free(sna, draw, flip);
- return;
- }
-
/* We assume our flips arrive in order, so we don't check the frame */
switch (flip->type) {
case DRI2_FLIP:
- DBG(("%s: flip complete\n", __FUNCTION__));
- DRI2SwapComplete(flip->client, draw,
- flip->fe_frame,
- flip->fe_tv_sec,
- flip->fe_tv_usec,
- DRI2_FLIP_COMPLETE,
- flip->client ? flip->event_complete : NULL,
- flip->event_data);
-
- sna_dri_frame_event_info_free(sna, draw, flip);
+ DBG(("%s: flip complete (drawable gone? %d)\n"
+ , __FUNCTION__, flp->draw == NULL));
+ if (flip->draw)
+ DRI2SwapComplete(flip->client, flip->draw,
+ flip->fe_frame,
+ flip->fe_tv_sec,
+ flip->fe_tv_usec,
+ DRI2_FLIP_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
+
+ sna_dri_frame_event_info_free(sna, flip->draw, flip);
break;
case DRI2_FLIP_THROTTLE:
if (!flip->next_front.name) {
DBG(("%s: flip chain complete\n", __FUNCTION__));
- sna_dri_frame_event_info_free(sna, draw, flip);
- } else if (can_flip(sna, draw, flip->front, flip->back) &&
- sna_dri_flip_continue(sna, draw, flip)) {
- DRI2SwapComplete(flip->client, draw,
+ sna_dri_frame_event_info_free(sna, flip->draw, flip);
+ } else if (flip->draw &&
+ can_flip(sna, flip->draw, flip->front, flip->back) &&
+ sna_dri_flip_continue(sna, flip)) {
+ DRI2SwapComplete(flip->client, flip->draw,
0, 0, 0,
DRI2_FLIP_COMPLETE,
flip->client ? flip->event_complete : NULL,
@@ -1410,17 +1402,19 @@ static void sna_dri_flip_event(struct sna *sna,
} else {
DBG(("%s: no longer able to flip\n", __FUNCTION__));
- flip->bo = sna_dri_copy_to_front(sna, draw, NULL,
- get_private(flip->front)->bo,
- get_private(flip->back)->bo,
- false);
- DRI2SwapComplete(flip->client, draw,
- 0, 0, 0,
- DRI2_BLIT_COMPLETE,
- flip->client ? flip->event_complete : NULL,
- flip->event_data);
+ if (flip->draw) {
+ flip->bo = sna_dri_copy_to_front(sna, flip->draw, NULL,
+ get_private(flip->front)->bo,
+ get_private(flip->back)->bo,
+ false);
+ DRI2SwapComplete(flip->client, flip->draw,
+ 0, 0, 0,
+ DRI2_BLIT_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
+ }
- sna_dri_frame_event_info_free(sna, draw, flip);
+ sna_dri_frame_event_info_free(sna, flip->draw, flip);
}
break;
@@ -1451,7 +1445,7 @@ static void sna_dri_flip_event(struct sna *sna,
flip->off_delay = 5;
sna->dri.flip_pending = flip;
- } else if (--flip->off_delay) {
+ } else if (flip->draw && --flip->off_delay) {
DBG(("%s: queuing no-flip [delay=%d]\n",
__FUNCTION__, flip->off_delay));
/* Just queue a no-op flip to trigger another event */
@@ -1465,7 +1459,7 @@ static void sna_dri_flip_event(struct sna *sna,
} else {
finish_async_flip:
DBG(("%s: async flip completed\n", __FUNCTION__));
- sna_dri_frame_event_info_free(sna, draw, flip);
+ sna_dri_frame_event_info_free(sna, flip->draw, flip);
}
break;
#endif
More information about the xorg-commit
mailing list