summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-12-19 07:59:24 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-12-19 07:59:24 +0000
commitfdd7508e53043f82f9cf422fc968c6574334a667 (patch)
tree7172874beed25fbc8580fb835c98886c6ea8dd0d
parent82e480267079f8678245e37724f95ae87f55b582 (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.h2
-rw-r--r--src/sna/sna_accel.c7
-rw-r--r--src/sna/sna_dri2.c33
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)