diff options
Diffstat (limited to 'driver/xf86-video-intel/uxa/uxa-glyphs.c')
-rw-r--r-- | driver/xf86-video-intel/uxa/uxa-glyphs.c | 76 |
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); |