diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-11 14:22:38 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-11-11 14:37:07 +0000 |
commit | c6e6ae1829e06ee8fe8eb063f2433cce603c9f96 (patch) | |
tree | 87eb6e094b1c53afdaa151131211f97559860a75 | |
parent | 8f50950f467eb2440009a807081f3ba2c9db209b (diff) |
sna/glyphs: Cache the glyph pixman_image_t wrapper
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 12 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 3 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 10 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 93 |
4 files changed, 57 insertions, 61 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 4ed26586..52142cb9 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -146,8 +146,17 @@ struct sna_pixmap { uint8_t gpu :1; }; +struct sna_glyph { + PicturePtr atlas; + pixman_image_t *image; + struct sna_coordinate coordinate; + uint16_t size, pos; +}; + extern DevPrivateKeyRec sna_private_index; extern DevPrivateKeyRec sna_pixmap_index; +extern DevPrivateKeyRec sna_gc_index; +extern DevPrivateKeyRec sna_glyph_key; static inline PixmapPtr get_window_pixmap(WindowPtr window) { @@ -181,8 +190,6 @@ struct sna_gc { long serial; }; -extern DevPrivateKeyRec sna_gc_index; - static inline struct sna_gc *sna_gc(GCPtr gc) { return (struct sna_gc *)gc->devPrivates; @@ -597,7 +604,6 @@ void sna_composite_trifan(CARD8 op, Bool sna_gradients_create(struct sna *sna); void sna_gradients_close(struct sna *sna); -Bool sna_glyphs_init(ScreenPtr screen); Bool sna_glyphs_create(struct sna *sna); void sna_glyphs(CARD8 op, PicturePtr src, diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 02f2fe03..b095cd2b 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -8327,9 +8327,6 @@ Bool sna_accel_init(ScreenPtr screen, struct sna *sna) if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna)) return FALSE; - if (!sna_glyphs_init(screen)) - return FALSE; - sna_font_key = AllocateFontPrivateIndex(); screen->RealizeFont = sna_realize_font; screen->UnrealizeFont = sna_unrealize_font; diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index e14ad1ea..d834c0a6 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -83,6 +83,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. DevPrivateKeyRec sna_private_index; DevPrivateKeyRec sna_pixmap_index; DevPrivateKeyRec sna_gc_index; +DevPrivateKeyRec sna_glyph_key; +DevPrivateKeyRec sna_glyph_image_key; static OptionInfoRec sna_options[] = { {OPTION_TILING_FB, "LinearFramebuffer", OPTV_BOOLEAN, {0}, FALSE}, @@ -812,10 +814,16 @@ sna_register_all_privates(void) return FALSE; assert(sna_pixmap_index.offset == sizeof(void*)); - if (!dixRegisterPrivateKey(&sna_gc_index, PRIVATE_GC, sizeof(struct sna_gc))) + if (!dixRegisterPrivateKey(&sna_gc_index, PRIVATE_GC, + sizeof(struct sna_gc))) return FALSE; assert(sna_gc_index.offset == 0); + if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH, + sizeof(struct sna_glyph))) + return FALSE; + assert(sna_glyph_key.offset == 0); + return TRUE; } diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index b189930a..08951774 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -106,17 +106,9 @@ static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char #define assert_pixmap_contains_box(p, b) #endif -struct sna_glyph { - PicturePtr atlas; - struct sna_coordinate coordinate; - uint16_t size, pos; -}; - -static DevPrivateKeyRec sna_glyph_key; - -static inline struct sna_glyph *glyph_get_private(GlyphPtr glyph) +static inline struct sna_glyph *sna_glyph(GlyphPtr glyph) { - return dixGetPrivateAddr(&glyph->devPrivates, &sna_glyph_key); + return (struct sna_glyph *)glyph->devPrivates; } #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) @@ -354,7 +346,7 @@ glyph_cache(ScreenPtr screen, } assert(cache->glyphs[pos] == NULL); - priv = glyph_get_private(glyph); + priv = sna_glyph(glyph); cache->glyphs[pos] = priv; priv->atlas = cache->picture; priv->size = size; @@ -393,7 +385,6 @@ static void apply_damage(struct sna_composite_op *op, sna_damage_add_box(op->damage, &box); } -#define GET_PRIVATE(g) ((struct sna_glyph *)((char *)(g)->devPrivates + priv_offset)) static Bool glyphs_to_dst(struct sna *sna, CARD8 op, @@ -404,7 +395,6 @@ glyphs_to_dst(struct sna *sna, { struct sna_composite_op tmp; ScreenPtr screen = dst->pDrawable->pScreen; - const int priv_offset = sna_glyph_key.offset; int index = screen->myNum; PicturePtr glyph_atlas; BoxPtr rects; @@ -441,7 +431,7 @@ glyphs_to_dst(struct sna *sna, if (glyph->info.width == 0 || glyph->info.height == 0) goto next_glyph; - priv = *GET_PRIVATE(glyph); + priv = *sna_glyph(glyph); if (priv.atlas == NULL) { if (glyph_atlas) { tmp.done(sna, &tmp); @@ -452,7 +442,7 @@ glyphs_to_dst(struct sna *sna, priv.atlas = GlyphPicture(glyph)[index]; priv.coordinate.x = priv.coordinate.y = 0; } else - priv = *GET_PRIVATE(glyph); + priv = *sna_glyph(glyph); } if (priv.atlas != glyph_atlas) { @@ -534,7 +524,6 @@ glyphs_slow(struct sna *sna, { struct sna_composite_op tmp; ScreenPtr screen = dst->pDrawable->pScreen; - const int priv_offset = sna_glyph_key.offset; int index = screen->myNum; int16_t x, y; @@ -565,14 +554,14 @@ glyphs_slow(struct sna *sna, if (glyph->info.width == 0 || glyph->info.height == 0) goto next_glyph; - priv = *GET_PRIVATE(glyph); + priv = *sna_glyph(glyph); if (priv.atlas == NULL) { if (!glyph_cache(screen, &sna->render, glyph)) { /* no cache for this glyph */ priv.atlas = GlyphPicture(glyph)[index]; priv.coordinate.x = priv.coordinate.y = 0; } else - priv = *GET_PRIVATE(glyph); + priv = *sna_glyph(glyph); } DBG(("%s: glyph=(%d, %d)x(%d, %d), src=(%d, %d), mask=(%d, %d)\n", @@ -672,7 +661,6 @@ glyphs_via_mask(struct sna *sna, { ScreenPtr screen = dst->pDrawable->pScreen; struct sna_composite_op tmp; - const int priv_offset = sna_glyph_key.offset; int index = screen->myNum; CARD32 component_alpha; PixmapPtr pixmap; @@ -728,7 +716,7 @@ glyphs_via_mask(struct sna *sna, int s; DBG(("%s: small mask [format=%lx, depth=%d], rendering glyphs to upload buffer\n", - __FUNCTION__, format->format, format->depth)); + __FUNCTION__, (unsigned long)format->format, format->depth)); upload: pixmap = sna_pixmap_create_upload(screen, @@ -758,7 +746,6 @@ upload: PicturePtr picture; pixman_image_t *glyph_image; int16_t xi, yi; - int dx, dy; if (g->info.width == 0 || g->info.height == 0) goto next_image; @@ -774,17 +761,26 @@ upload: yi + g->info.height <= 0) goto next_image; - picture = GlyphPicture(g)[s]; - if (picture == NULL) - goto next_image; + glyph_image = sna_glyph(g)->image; + if (glyph_image == NULL) { + int dx, dy; - glyph_image = image_from_pict(picture, FALSE, &dx, &dy); - if (!glyph_image) - goto next_image; + picture = GlyphPicture(g)[s]; + if (picture == NULL) + goto next_image; - DBG(("%s: glyph+(%d,%d) to mask (%d, %d)x(%d, %d)\n", + glyph_image = image_from_pict(picture, + FALSE, + &dx, &dy); + if (!glyph_image) + goto next_image; + + assert(dx == 0 && dy == 0); + sna_glyph(g)->image = glyph_image; + } + + DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", __FUNCTION__, - dx,dy, xi, yi, g->info.width, g->info.height)); @@ -793,12 +789,11 @@ upload: glyph_image, NULL, mask_image, - dx, dy, + 0, 0, 0, 0, xi, yi, g->info.width, g->info.height); - free_pixman_pict(picture, glyph_image); next_image: x += g->info.xOff; @@ -851,7 +846,7 @@ next_image: if (glyph->info.width == 0 || glyph->info.height == 0) goto next_glyph; - priv = GET_PRIVATE(glyph); + priv = sna_glyph(glyph); if (priv->atlas != NULL) { this_atlas = priv->atlas; r.src = priv->coordinate; @@ -920,17 +915,6 @@ next_glyph: return TRUE; } -Bool sna_glyphs_init(ScreenPtr screen) -{ - if (!dixRegisterPrivateKey(&sna_glyph_key, - PRIVATE_GLYPH, - sizeof(struct sna_glyph))) - return FALSE; - - return TRUE; - (void)screen; -} - Bool sna_glyphs_create(struct sna *sna) { return realize_glyph_caches(sna); @@ -1271,19 +1255,20 @@ fallback: void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) { - struct sna_glyph_cache *cache; - struct sna_glyph *priv; - struct sna *sna; + struct sna_glyph *priv = sna_glyph(glyph); - priv = glyph_get_private(glyph); - if (priv->atlas == NULL) - return; + if (priv->image) { + pixman_image_unref(priv->image); + priv->image = NULL; + } - sna = to_sna_from_screen(screen); - cache = &sna->render.glyph[priv->pos & 1]; - assert(cache->glyphs[priv->pos >> 1] == priv); - cache->glyphs[priv->pos >> 1] = NULL; - priv->atlas = NULL; + if (priv->atlas) { + struct sna *sna = to_sna_from_screen(screen); + struct sna_glyph_cache *cache = &sna->render.glyph[priv->pos&1]; + assert(cache->glyphs[priv->pos >> 1] == priv); + cache->glyphs[priv->pos >> 1] = NULL; + priv->atlas = NULL; + } } void sna_glyphs_close(struct sna *sna) |