summaryrefslogtreecommitdiff
path: root/driver/xf86-video-intel/uxa/uxa-glyphs.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xf86-video-intel/uxa/uxa-glyphs.c')
-rw-r--r--driver/xf86-video-intel/uxa/uxa-glyphs.c76
1 files changed, 54 insertions, 22 deletions
diff --git a/driver/xf86-video-intel/uxa/uxa-glyphs.c b/driver/xf86-video-intel/uxa/uxa-glyphs.c
index 823cf82f7..6c9ea0d6c 100644
--- a/driver/xf86-video-intel/uxa/uxa-glyphs.c
+++ b/driver/xf86-video-intel/uxa/uxa-glyphs.c
@@ -111,6 +111,9 @@ static void uxa_unrealize_glyph_caches(ScreenPtr pScreen)
uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
int i;
+ if (!uxa_screen->glyph_cache_initialized)
+ return;
+
for (i = 0; i < UXA_NUM_GLYPH_CACHE_FORMATS; i++) {
uxa_glyph_cache_t *cache = &uxa_screen->glyphCaches[i];
@@ -120,6 +123,7 @@ static void uxa_unrealize_glyph_caches(ScreenPtr pScreen)
if (cache->glyphs)
free(cache->glyphs);
}
+ uxa_screen->glyph_cache_initialized = FALSE;
}
void uxa_glyphs_fini(ScreenPtr pScreen)
@@ -145,6 +149,10 @@ static Bool uxa_realize_glyph_caches(ScreenPtr pScreen)
};
int i;
+ if (uxa_screen->glyph_cache_initialized)
+ return TRUE;
+
+ uxa_screen->glyph_cache_initialized = TRUE;
memset(uxa_screen->glyphCaches, 0, sizeof(uxa_screen->glyphCaches));
for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
@@ -164,7 +172,12 @@ static Bool uxa_realize_glyph_caches(ScreenPtr pScreen)
INTEL_CREATE_PIXMAP_TILING_X);
if (!pixmap)
goto bail;
- assert (uxa_pixmap_is_offscreen(pixmap));
+ if (!uxa_pixmap_is_offscreen(pixmap)) {
+ /* Presume shadow is in-effect */
+ pScreen->DestroyPixmap(pixmap);
+ uxa_unrealize_glyph_caches(pScreen);
+ return TRUE;
+ }
component_alpha = NeedsComponent(pPictFormat->format);
picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
@@ -197,13 +210,6 @@ bail:
Bool uxa_glyphs_init(ScreenPtr pScreen)
{
- /* We are trying to initialise per screen resources prior to the
- * complete initialisation of the screen. So ensure the components
- * that we depend upon are initialsed prior to our use.
- */
- if (!CreateScratchPixmapsForScreen(pScreen->myNum))
- return FALSE;
-
#if HAS_DIXREGISTERPRIVATEKEY
if (!dixRegisterPrivateKey(&uxa_glyph_key, PRIVATE_GLYPH, 0))
return FALSE;
@@ -212,10 +218,11 @@ Bool uxa_glyphs_init(ScreenPtr pScreen)
return FALSE;
#endif
- if (!uxa_realize_glyph_caches(pScreen))
- return FALSE;
+ /* Skip pixmap creation if we don't intend to use it. */
+ if (uxa_get_screen(pScreen)->force_fallback)
+ return TRUE;
- return TRUE;
+ return uxa_realize_glyph_caches(pScreen);
}
/* The most efficient thing to way to upload the glyph to the screen
@@ -293,18 +300,19 @@ uxa_glyph_cache_upload_glyph(ScreenPtr screen,
}
void
-uxa_glyph_unrealize(ScreenPtr pScreen,
- GlyphPtr pGlyph)
+uxa_glyph_unrealize(ScreenPtr screen,
+ GlyphPtr glyph)
{
struct uxa_glyph *priv;
- priv = uxa_glyph_get_private(pGlyph);
+ /* Use Lookup in case we have not attached to this glyph. */
+ priv = dixLookupPrivate(&glyph->devPrivates, &uxa_glyph_key);
if (priv == NULL)
return;
priv->cache->glyphs[priv->pos] = NULL;
- uxa_glyph_set_private(pGlyph, NULL);
+ uxa_glyph_set_private(glyph, NULL);
free(priv);
}
@@ -780,9 +788,8 @@ uxa_glyphs_to_dst(CARD8 op,
mask_pixmap =
uxa_get_drawable_pixmap(this_atlas->pDrawable);
- assert (uxa_pixmap_is_offscreen(mask_pixmap));
-
- if (!uxa_screen->info->prepare_composite(op,
+ if (!uxa_pixmap_is_offscreen(mask_pixmap) ||
+ !uxa_screen->info->prepare_composite(op,
localSrc, this_atlas, pDst,
src_pixmap, mask_pixmap, dst_pixmap))
return -1;
@@ -930,6 +937,11 @@ uxa_glyphs_via_mask(CARD8 op,
if (!pixmap)
return 1;
+ if (!uxa_pixmap_is_offscreen(pixmap)) {
+ screen->DestroyPixmap(pixmap);
+ return -1;
+ }
+
uxa_clear_pixmap(screen, uxa_screen, pixmap);
component_alpha = NeedsComponent(maskFormat->format);
@@ -983,9 +995,8 @@ uxa_glyphs_via_mask(CARD8 op,
src_pixmap =
uxa_get_drawable_pixmap(this_atlas->pDrawable);
- assert (uxa_pixmap_is_offscreen(src_pixmap));
-
- if (!uxa_screen->info->prepare_composite(PictOpAdd,
+ if (!uxa_pixmap_is_offscreen(src_pixmap) ||
+ !uxa_screen->info->prepare_composite(PictOpAdd,
this_atlas, NULL, mask,
src_pixmap, NULL, pixmap))
return -1;
@@ -1022,6 +1033,19 @@ next_glyph:
return 0;
}
+static Bool
+is_solid(PicturePtr picture)
+{
+ if (picture->pSourcePict) {
+ SourcePict *source = picture->pSourcePict;
+ return source->type == SourcePictTypeSolidFill;
+ } else {
+ return (picture->repeat &&
+ picture->pDrawable->width == 1 &&
+ picture->pDrawable->height == 1);
+ }
+}
+
void
uxa_glyphs(CARD8 op,
PicturePtr pSrc,
@@ -1040,8 +1064,11 @@ uxa_glyphs(CARD8 op,
if (!uxa_screen->info->prepare_composite ||
uxa_screen->swappedOut ||
+ uxa_screen->force_fallback ||
!uxa_drawable_is_offscreen(pDst->pDrawable) ||
- pDst->alphaMap || pSrc->alphaMap) {
+ pDst->alphaMap || pSrc->alphaMap ||
+ /* XXX we fail to handle (rare) non-solid sources correctly. */
+ !is_solid(pSrc)) {
fallback:
uxa_check_glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
return;
@@ -1122,6 +1149,11 @@ fallback:
if (!pixmap)
return;
+ if (!uxa_pixmap_is_offscreen(pixmap)) {
+ screen->DestroyPixmap(pixmap);
+ goto fallback;
+ }
+
gc = GetScratchGC(depth, screen);
if (!gc) {
screen->DestroyPixmap(pixmap);