diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-30 21:19:35 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-30 23:10:27 +0000 |
commit | a7adcc8e47ba550e7c36a6543a6e0d99040c7354 (patch) | |
tree | e479e3e2310ac5d5cedae9185f12e11b418bc47f | |
parent | c8d4f5d32af94f712cc81ff495b19907261759ea (diff) |
sna: Stash the last scratch pixmap
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 67 |
2 files changed, 50 insertions, 18 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 1bb81d03..ae161a2a 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -213,6 +213,7 @@ struct sna { struct list dirty_pixmaps; PixmapPtr front, shadow; + PixmapPtr freed_pixmap; struct sna_mode { uint32_t fb_id; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index c0c72eec..0b04db86 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -135,8 +135,16 @@ static Bool sna_destroy_private(PixmapPtr pixmap, struct sna_pixmap *priv) kgem_bo_destroy(&sna->kgem, priv->cpu_bo); } + if (!sna->freed_pixmap) { + sna->freed_pixmap = pixmap; + priv->gpu_bo = NULL; + priv->cpu_bo = NULL; + priv->mapped = 0; + return false; + } + free(priv); - return TRUE; + return true; } static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap) @@ -228,15 +236,25 @@ sna_pixmap_create_scratch(ScreenPtr screen, CREATE_PIXMAP_USAGE_SCRATCH); /* you promise never to access this via the cpu... */ - pixmap = fbCreatePixmap(screen, 0, 0, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pixmap) - return NullPixmap; - - priv = _sna_pixmap_attach(pixmap); - if (!priv) { - fbDestroyPixmap(pixmap); - return NullPixmap; + if (sna->freed_pixmap) { + pixmap = sna->freed_pixmap; + sna->freed_pixmap = NULL; + + priv = sna_pixmap(pixmap); + memset(priv, 0, sizeof(*priv)); + list_init(&priv->list); + priv->pixmap = pixmap; + } else { + pixmap = fbCreatePixmap(screen, 0, 0, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pixmap) + return NullPixmap; + + priv = _sna_pixmap_attach(pixmap); + if (!priv) { + fbDestroyPixmap(pixmap); + return NullPixmap; + } } priv->gpu_bo = kgem_create_2d(&sna->kgem, @@ -753,15 +771,22 @@ sna_pixmap_create_upload(ScreenPtr screen, return fbCreatePixmap(screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH); - pixmap = fbCreatePixmap(screen, 0, 0, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pixmap) - return NullPixmap; + if (sna->freed_pixmap) { + pixmap = sna->freed_pixmap; + sna->freed_pixmap = NULL; - priv = malloc(sizeof(*priv)); - if (!priv) { - fbDestroyPixmap(pixmap); - return NullPixmap; + priv = sna_pixmap(pixmap); + } else { + pixmap = fbCreatePixmap(screen, 0, 0, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pixmap) + return NullPixmap; + + priv = malloc(sizeof(*priv)); + if (!priv) { + fbDestroyPixmap(pixmap); + return NullPixmap; + } } priv->gpu_bo = kgem_create_buffer(&sna->kgem, @@ -6175,6 +6200,12 @@ Bool sna_accel_create(struct sna *sna) void sna_accel_close(struct sna *sna) { + if (sna->freed_pixmap) { + assert(sna->freed_pixmap->refcnt == 1); + sna_destroy_pixmap(sna->freed_pixmap); + sna->freed_pixmap = NULL; + } + sna_glyphs_close(sna); sna_gradients_close(sna); |