summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-11-11 14:22:38 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-11-11 14:37:07 +0000
commitc6e6ae1829e06ee8fe8eb063f2433cce603c9f96 (patch)
tree87eb6e094b1c53afdaa151131211f97559860a75
parent8f50950f467eb2440009a807081f3ba2c9db209b (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.h12
-rw-r--r--src/sna/sna_accel.c3
-rw-r--r--src/sna/sna_driver.c10
-rw-r--r--src/sna/sna_glyphs.c93
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)