diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-12-19 07:59:24 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-12-19 07:59:24 +0000 |
commit | fdd7508e53043f82f9cf422fc968c6574334a667 (patch) | |
tree | 7172874beed25fbc8580fb835c98886c6ea8dd0d | |
parent | 82e480267079f8678245e37724f95ae87f55b582 (diff) |
sna/dri2: Decouple Window cache on Pixmap changes
If the Pixmap for a Window is changed (i.e. Composite
redirection/unredirection), we also need to decouple any associated DRI2
front buffer for the Pixmap (e.g. used for single CRTC flipping).
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 2 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 7 | ||||
-rw-r--r-- | src/sna/sna_dri2.c | 33 |
3 files changed, 36 insertions, 6 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 3e16f7e5..3116f116 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -539,6 +539,7 @@ bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen); void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event); void sna_dri2_vblank_handler(struct drm_event_vblank *event); void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo); +void sna_dri2_decouple_window(WindowPtr win); void sna_dri2_destroy_window(WindowPtr win); void sna_dri2_close(struct sna *sna, ScreenPtr pScreen); #else @@ -546,6 +547,7 @@ static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return fa static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { } static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { } static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { } +static inline void sna_dri2_decouple_window(WindowPtr win) { } static inline void sna_dri2_destroy_window(WindowPtr win) { } static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { } #endif diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index c7021879..59207695 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -17593,6 +17593,13 @@ sna_get_window_pixmap(WindowPtr window) static void sna_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) { + DBG(("%s: window=%ld, old pixmap=%ld new pixmap=%ld\n", + __FUNCTION__, window->drawable.id, + get_window_pixmap(window) ? get_window_pixmap(window)->drawable.serialNumber : 0, + pixmap->drawable.serialNumber)); + + sna_dri2_decouple_window(window); + *(PixmapPtr *)__get_private(window, sna_window_key) = pixmap; } diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index d0760fcb..8f8baefb 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -446,10 +446,11 @@ sna_dri2_create_buffer(DrawablePtr draw, uint32_t size; int bpp; - DBG(("%s pixmap=%ld, (attachment=%d, format=%d, drawable=%dx%d)\n", + DBG(("%s pixmap=%ld, (attachment=%d, format=%d, drawable=%dx%d), window?=%d\n", __FUNCTION__, get_drawable_pixmap(draw)->drawable.serialNumber, - attachment, format, draw->width, draw->height)); + attachment, format, draw->width, draw->height, + draw->type != DRAWABLE_PIXMAP)); pixmap = NULL; size = (uint32_t)draw->height << 16 | draw->width; @@ -464,11 +465,12 @@ sna_dri2_create_buffer(DrawablePtr draw, if (buffer) { private = get_private(buffer); - DBG(("%s: reusing front buffer attachment, win=%lu %dx%d, pixmap=%ld %dx%d, handle=%d, name=%d\n", + DBG(("%s: reusing front buffer attachment, win=%lu %dx%d, pixmap=%ld [%ld] %dx%d, handle=%d, name=%d\n", __FUNCTION__, draw->type != DRAWABLE_PIXMAP ? (long)draw->id : (long)0, draw->width, draw->height, pixmap->drawable.serialNumber, + private->pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, private->bo->handle, buffer->name)); @@ -1400,19 +1402,37 @@ sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client) return info; } +void sna_dri2_decouple_window(WindowPtr win) +{ + struct dri2_window *priv; + + priv = dri2_window(win); + if (priv == NULL) + return; + + DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); + + if (priv->front) { + struct sna *sna = to_sna_from_drawable(&win->drawable); + assert(priv->crtc); + sna_shadow_unset_crtc(sna, priv->crtc); + _sna_dri2_destroy_buffer(sna, priv->front); + priv->front = NULL; + } +} + void sna_dri2_destroy_window(WindowPtr win) { - struct sna *sna; struct dri2_window *priv; priv = dri2_window(win); if (priv == NULL) return; - DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.serialNumber)); - sna = to_sna_from_drawable(&win->drawable); + DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); if (priv->front) { + struct sna *sna = to_sna_from_drawable(&win->drawable); assert(priv->crtc); sna_shadow_unset_crtc(sna, priv->crtc); _sna_dri2_destroy_buffer(sna, priv->front); @@ -3120,6 +3140,7 @@ out_complete: } #else void sna_dri2_destroy_window(WindowPtr win) { } +void sna_dri2_decouple_window(WindowPtr win) { } #endif static bool has_i830_dri(void) |