diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-05 10:25:12 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-05 11:50:26 +0000 |
commit | 6ffd3605640bacaf0d744075622463aacf78d797 (patch) | |
tree | c067e1da323593307fe0428653998640fba9ee8c | |
parent | a09ebe0b6cc66d08e52b57851d9b8a6a1f71df2b (diff) |
sna: Deferred attachment to a pixmap needs to mark the pixmap as entirely dirty
As demonstrated with oversized glyphs and a chain of catastrophy, when
attaching our private to a pixmap after creation we need to mark the
entire CPU pixmap as dirty as we never tracked exactly which bits were
dirtied.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 2 | ||||
-rw-r--r-- | src/sna/sna.h | 12 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 79 | ||||
-rw-r--r-- | src/sna/sna_render.c | 1 |
4 files changed, 63 insertions, 31 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index d08faa47..24a47aaf 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2158,7 +2158,7 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo) struct kgem_partial_bo *io = (struct kgem_partial_bo *)bo->proxy; if (list_is_empty(&io->base.list)) - return; + return; if (bo->size == io->used) { assert(io->base.exec == NULL); diff --git a/src/sna/sna.h b/src/sna/sna.h index 1e6a803a..a1737c11 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -422,7 +422,17 @@ static inline Bool pixmap_is_scanout(PixmapPtr pixmap) return pixmap == screen->GetScreenPixmap(screen); } -struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap); +struct sna_pixmap *_sna_pixmap_attach(PixmapPtr pixmap); +inline static struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap) +{ + struct sna_pixmap *priv; + + priv = sna_pixmap(pixmap); + if (priv) + return priv; + + return _sna_pixmap_attach(pixmap); +} PixmapPtr sna_pixmap_create_upload(ScreenPtr screen, int width, int height, int depth); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 8b450b65..e34ecf07 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -410,8 +410,8 @@ _sna_pixmap_reset(PixmapPtr pixmap) return _sna_pixmap_init(priv, pixmap); } -static struct sna_pixmap *_sna_pixmap_attach(struct sna *sna, - PixmapPtr pixmap) +static struct sna_pixmap *__sna_pixmap_attach(struct sna *sna, + PixmapPtr pixmap) { struct sna_pixmap *priv; @@ -423,16 +423,18 @@ static struct sna_pixmap *_sna_pixmap_attach(struct sna *sna, return _sna_pixmap_init(priv, pixmap); } -struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap) +struct sna_pixmap *_sna_pixmap_attach(PixmapPtr pixmap) { - struct sna *sna; + struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; - priv = sna_pixmap(pixmap); - if (priv) - return priv; + DBG(("%s: serial=%ld, %dx%d, usage=%d\n", + __FUNCTION__, + pixmap->drawable.serialNumber, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->usage_hint)); - sna = to_sna_from_pixmap(pixmap); switch (pixmap->usage_hint) { case CREATE_PIXMAP_USAGE_GLYPH_PICTURE: #if FAKE_CREATE_PIXMAP_USAGE_SCRATCH_HEADER @@ -454,7 +456,17 @@ struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap) break; } - return _sna_pixmap_attach(sna, pixmap); + priv = __sna_pixmap_attach(sna, pixmap); + if (priv == NULL) + return NULL; + + DBG(("%s: created priv and marking all cpu damaged\n", __FUNCTION__)); + + sna_damage_all(&priv->cpu_damage, + pixmap->drawable.width, + pixmap->drawable.height); + + return priv; } static inline PixmapPtr @@ -468,6 +480,13 @@ create_pixmap(struct sna *sna, ScreenPtr screen, if (pixmap == NullPixmap) return NullPixmap; + DBG(("%s: serial=%ld, usage=%d, %dx%d\n", + __FUNCTION__, + pixmap->drawable.serialNumber, + pixmap->usage_hint, + pixmap->drawable.width, + pixmap->drawable.height)); + assert(sna_private_index.offset == 0); dixSetPrivate(&pixmap->devPrivates, &sna_private_index, sna); return pixmap; @@ -518,6 +537,13 @@ sna_pixmap_create_scratch(ScreenPtr screen, pixmap->drawable.bitsPerPixel = bpp; pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + DBG(("%s: serial=%ld, usage=%d, %dx%d\n", + __FUNCTION__, + pixmap->drawable.serialNumber, + pixmap->usage_hint, + pixmap->drawable.width, + pixmap->drawable.height)); + priv = _sna_pixmap_reset(pixmap); } else { pixmap = create_pixmap(sna, screen, 0, 0, depth, @@ -530,7 +556,7 @@ sna_pixmap_create_scratch(ScreenPtr screen, pixmap->drawable.depth = depth; pixmap->drawable.bitsPerPixel = bpp; - priv = _sna_pixmap_attach(sna, pixmap); + priv = __sna_pixmap_attach(sna, pixmap); if (!priv) { fbDestroyPixmap(pixmap); return NullPixmap; @@ -610,7 +636,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, if (pixmap == NullPixmap) return NullPixmap; - sna_pixmap_attach(pixmap); + __sna_pixmap_attach(sna, pixmap); } else { struct sna_pixmap *priv; @@ -623,7 +649,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen, pixmap->devKind = pad; pixmap->devPrivate.ptr = NULL; - priv = _sna_pixmap_attach(sna, pixmap); + priv = __sna_pixmap_attach(sna, pixmap); if (priv == NULL) { free(pixmap); return create_pixmap(sna, screen, @@ -1363,6 +1389,11 @@ sna_pixmap_create_upload(ScreenPtr screen, pixmap->usage_hint = CREATE_PIXMAP_USAGE_SCRATCH; pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pixmap->refcnt = 1; + + DBG(("%s: serial=%ld, usage=%d\n", + __FUNCTION__, + pixmap->drawable.serialNumber, + pixmap->usage_hint)); } else { pixmap = create_pixmap(sna, screen, 0, 0, depth, CREATE_PIXMAP_USAGE_SCRATCH); @@ -1410,19 +1441,11 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags) DBG(("%s(pixmap=%p)\n", __FUNCTION__, pixmap)); - priv = sna_pixmap(pixmap); - if (priv == NULL) { - priv = sna_pixmap_attach(pixmap); - if (priv == NULL) - return NULL; - - DBG(("%s: created priv and marking all cpu damaged\n", - __FUNCTION__)); - sna_damage_all(&priv->cpu_damage, - pixmap->drawable.width, - pixmap->drawable.height); - } + priv = sna_pixmap_attach(pixmap); + if (priv == NULL) + return NULL; + /* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */ if (priv->gpu_bo == NULL) { struct sna *sna = to_sna_from_pixmap(pixmap); unsigned flags; @@ -1459,7 +1482,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) BoxPtr box; int n; - DBG(("%s()\n", __FUNCTION__)); + DBG(("%s(pixmap=%ld, usage=%d)\n", + __FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint)); priv = sna_pixmap(pixmap); if (priv == NULL) @@ -1516,9 +1540,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) box, n); if (!ok) { if (n == 1 && !priv->pinned && - box->x1 <= 0 && box->y1 <= 0 && - box->x2 >= pixmap->drawable.width && - box->y2 >= pixmap->drawable.height) { + (box->x2 - box->x1) >= pixmap->drawable.width && + (box->y2 - box->y1) >= pixmap->drawable.height) { priv->gpu_bo = sna_replace(sna, pixmap, diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index aa9c160d..faa2730b 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -505,7 +505,6 @@ sna_render_pixmap_bo(struct sna *sna, */ if (pixmap->usage_hint != CREATE_PIXMAP_USAGE_SCRATCH_HEADER && w * pixmap->drawable.bitsPerPixel * h > 8*4096) { - priv = sna_pixmap_attach(pixmap); bo = pixmap_vmap(&sna->kgem, pixmap); if (bo) bo = kgem_bo_reference(bo); |