diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-06-12 22:38:01 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-06-12 22:30:31 +0100 |
commit | 86888723901030c5cb9da16cbb03508d4b13332f (patch) | |
tree | d7916dbf5a6275a68ecd4c25d012a7641641e24f | |
parent | b881d1b16a8beec024ac18eca8308418e34cb05d (diff) |
sna: Just do a pointer exchange when flipping with no scanout
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 2 | ||||
-rw-r--r-- | src/sna/sna_display.c | 14 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 47 |
3 files changed, 50 insertions, 13 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 7456f05a..ae8e5548 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -274,6 +274,8 @@ extern int sna_do_pageflip(struct sna *sna, PixmapPtr *old_front, uint32_t *old_fb); +extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap); + void sna_mode_delete_fb(struct sna *sna, PixmapPtr pixmap, uint32_t fb); static inline struct sna * diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index e893a370..c2347ef3 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1523,6 +1523,20 @@ static int do_page_flip(struct sna *sna, void *data, int ref_crtc_hw_id) return count; } +PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap) +{ + PixmapPtr old = sna->front; + ScrnInfoPtr scrn = sna->scrn; + + sna->front = pixmap; + pixmap->refcnt++; + + sna_redirect_screen_pixmap(scrn, old, sna->front); + scrn->displayWidth = sna_pixmap_get_bo(pixmap)->pitch / sna->mode.cpp; + + return old; +} + int sna_do_pageflip(struct sna *sna, PixmapPtr pixmap, diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 14a2f3d1..75e2c444 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -670,7 +670,8 @@ can_flip(struct sna * sna, ScreenPtr screen = draw->pScreen; - assert(draw->type == DRAWABLE_WINDOW); + if (draw->type == DRAWABLE_PIXMAP) + return FALSE; if (front->format != back->format) { DBG(("%s: no, format mismatch, front = %d, back = %d\n", @@ -969,10 +970,30 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, (long long)divisor, (long long)remainder)); + flip = 0; + if (can_flip(sna, draw, front, back)) { + DBG(("%s: can flip\n", __FUNCTION__)); + swap_type = DRI2_FLIP; + flip = 1; + } + /* Drawable not displayed... just complete the swap */ pipe = sna_dri_get_pipe(draw); - if (pipe == -1) - goto blit_fallback; + if (pipe == -1) { + struct sna_dri_private *back_priv = back->driverPrivate; + PixmapPtr pixmap; + + if (!flip) + goto blit_fallback; + + pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap); + pixmap->refcnt--; + assert(pixmap->refcnt > 0); + sna_dri_exchange_buffers(draw, front, back); + DRI2SwapComplete(client, draw, 0, 0, 0, + DRI2_EXCHANGE_COMPLETE, func, data); + return TRUE; + } /* Truncate to match kernel interfaces; means occasional overflow * misses, but that's generally not a big deal */ @@ -1002,13 +1023,6 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, sna_dri_reference_buffer(front); sna_dri_reference_buffer(back); - flip = 0; - if (can_flip(sna, draw, front, back)) { - DBG(("%s: can flip\n", __FUNCTION__)); - swap_type = DRI2_FLIP; - flip = 1; - } - info->type = swap_type; if (divisor == 0) goto immediate; @@ -1155,9 +1169,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw, DBG(("%s()\n", __FUNCTION__)); - /* Drawable not displayed... just complete the swap */ - pipe = sna_dri_get_pipe(draw); - if (pipe == -1 || !can_flip(sna, draw, front, back)) { + if (!can_flip(sna, draw, front, back)) { BoxRec box, *boxes; int n; @@ -1194,6 +1206,15 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw, return; } + pipe = sna_dri_get_pipe(draw); + if (pipe == -1) { + /* Drawable not displayed... just complete the swap */ + pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap); + pixmap->refcnt--; + assert(pixmap->refcnt > 0); + goto exchange; + } + if (!sna->dri.flip_pending[pipe]) { struct sna_dri_frame_event *info; DRI2BufferPtr t; |