diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-12 10:34:10 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-12 12:05:43 +0100 |
commit | dc18eaa585c36c8e5f5b4ec405a976a835fd2ac3 (patch) | |
tree | faf1b626b9d8b4986e5b035a176304fe253d8d3b | |
parent | b580abdfa68108f3e63ee1f897b6ea83b9c47935 (diff) |
sna: Make the failure to create render caches non-fatal
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 2 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 16 | ||||
-rw-r--r-- | src/sna/sna_composite.c | 3 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 6 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 500 | ||||
-rw-r--r-- | src/sna/sna_gradient.c | 3 |
6 files changed, 240 insertions, 290 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 7295befb..3c83ac59 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -629,13 +629,13 @@ static inline uint32_t pixmap_size(PixmapPtr pixmap) } bool sna_accel_init(ScreenPtr sreen, struct sna *sna); +void sna_accel_create(struct sna *sna); void sna_accel_block_handler(struct sna *sna, struct timeval **tv); void sna_accel_wakeup_handler(struct sna *sna); void sna_accel_watch_flush(struct sna *sna, int enable); void sna_accel_close(struct sna *sna); void sna_accel_free(struct sna *sna); -bool sna_accel_create(ScreenPtr screen, struct sna *sna); void sna_copy_fbcon(struct sna *sna); bool sna_composite_create(struct sna *sna); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 660c17a3..b27e7fbc 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -13874,18 +13874,24 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna) return true; } -bool sna_accel_create(ScreenPtr screen, struct sna *sna) +void sna_accel_create(struct sna *sna) { if (!sna_glyphs_create(sna)) - return false; + goto fail; if (!sna_gradients_create(sna)) - return false; + goto fail; if (!sna_composite_create(sna)) - return false; + goto fail; - return true; + return; + +fail: + xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, + "Failed to allocate caches, disabling RENDER acceleration\n"); + sna->have_render = false; + no_render_init(sna); } void sna_accel_watch_flush(struct sna *sna, int enable) diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index 48b68366..72a5a94a 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -46,6 +46,9 @@ bool sna_composite_create(struct sna *sna) xRenderColor color ={ 0 }; int error; + if (!can_render(sna)) + return true; + sna->clear = CreateSolidPicture(0, &color, &error); return sna->clear != NULL; } diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index 5d2915f1..6810c7a1 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -168,11 +168,7 @@ static Bool sna_create_screen_resources(ScreenPtr screen) free(screen->devPrivate); screen->devPrivate = NULL; - if (!sna_accel_create(screen, sna)) { - xf86DrvMsg(screen->myNum, X_ERROR, - "[intel] Failed to initialise acceleration routines\n"); - goto cleanup_front; - } + sna_accel_create(sna); sna->front = screen->CreatePixmap(screen, screen->width, diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index e299ac52..54ad510c 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -881,7 +881,7 @@ glyphs_via_mask(struct sna *sna, memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height); #if HAS_PIXMAN_GLYPHS - { + if (sna->render.glyph_cache) { pixman_glyph_t stack_glyphs[N_STACK_GLYPHS]; pixman_glyph_t *pglyphs = stack_glyphs; pixman_glyph_cache_t *cache; @@ -909,7 +909,7 @@ glyphs_via_mask(struct sna *sna, const void *ptr; if (g->info.width == 0 || g->info.height == 0) - goto next_image; + goto next_pglyph; ptr = pixman_glyph_cache_lookup(cache, g, NULL); if (ptr == NULL) { @@ -917,14 +917,14 @@ glyphs_via_mask(struct sna *sna, glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) - goto next_image; + goto next_pglyph; ptr = pixman_glyph_cache_insert(cache, g, NULL, g->info.x, g->info.y, glyph_image); if (ptr == NULL) - goto next_image; + goto next_pglyph; } pglyphs[count].x = x; @@ -932,7 +932,7 @@ glyphs_via_mask(struct sna *sna, pglyphs[count].glyph = ptr; count++; -next_image: +next_pglyph: x += g->info.xOff; y += g->info.yOff; } @@ -948,8 +948,8 @@ next_image: pixman_glyph_cache_thaw(cache); if (pglyphs != stack_glyphs) free(pglyphs); - } -#else + } else +#endif do { int n = list->len; x += list->xOff; @@ -1011,7 +1011,6 @@ next_image: } list++; } while (--nlist); -#endif pixman_image_unref(mask_image); mask = CreatePicture(0, &pixmap->drawable, @@ -1290,7 +1289,6 @@ static bool can_discard_mask(uint8_t op, PicturePtr src, PictFormatPtr mask, return color >> 24 == 0xff; } -#if HAS_PIXMAN_GLYPHS static void glyphs_fallback(CARD8 op, PicturePtr src, @@ -1356,312 +1354,254 @@ glyphs_fallback(CARD8 op, mask_format = NULL; } - cache = sna->render.glyph_cache; - pixman_glyph_cache_freeze(cache); - - count = 0; - for (n = 0; n < nlist; ++n) - count += list[n].len; - if (count > N_STACK_GLYPHS) { - pglyphs = malloc (count * sizeof(pixman_glyph_t)); - if (pglyphs == NULL) - goto out; - } +#if HAS_PIXMAN_GLYPHS + if (sna->render.glyph_cache) { + cache = sna->render.glyph_cache; + pixman_glyph_cache_freeze(cache); + + count = 0; + for (n = 0; n < nlist; ++n) + count += list[n].len; + if (count > N_STACK_GLYPHS) { + pglyphs = malloc (count * sizeof(pixman_glyph_t)); + if (pglyphs == NULL) + goto out; + } - count = 0; - x = y = 0; - while (nlist--) { - n = list->len; - x += list->xOff; - y += list->yOff; - while (n--) { - GlyphPtr g = *glyphs++; - const void *ptr; + count = 0; + x = y = 0; + while (nlist--) { + n = list->len; + x += list->xOff; + y += list->yOff; + while (n--) { + GlyphPtr g = *glyphs++; + const void *ptr; - if (g->info.width == 0 || g->info.height == 0) - goto next; + if (g->info.width == 0 || g->info.height == 0) + goto next; - ptr = pixman_glyph_cache_lookup(cache, g, NULL); - if (ptr == NULL) { - pixman_image_t *glyph_image; + ptr = pixman_glyph_cache_lookup(cache, g, NULL); + if (ptr == NULL) { + pixman_image_t *glyph_image; - glyph_image = sna_glyph_get_image(g, screen); - if (glyph_image == NULL) - goto next; + glyph_image = sna_glyph_get_image(g, screen); + if (glyph_image == NULL) + goto next; - ptr = pixman_glyph_cache_insert(cache, g, NULL, - g->info.x, - g->info.y, - glyph_image); - if (ptr == NULL) - goto out; - } + ptr = pixman_glyph_cache_insert(cache, g, NULL, + g->info.x, + g->info.y, + glyph_image); + if (ptr == NULL) + goto out; + } - pglyphs[count].x = x; - pglyphs[count].y = y; - pglyphs[count].glyph = ptr; - count++; + pglyphs[count].x = x; + pglyphs[count].y = y; + pglyphs[count].glyph = ptr; + count++; next: - x += g->info.xOff; - y += g->info.yOff; + x += g->info.xOff; + y += g->info.yOff; + } + list++; } - list++; - } - src_image = image_from_pict(src, FALSE, &src_dx, &src_dy); - if (src_image == NULL) - goto out; - - dst_image = image_from_pict(dst, TRUE, &dst_dx, &dst_dy); - if (dst_image == NULL) - goto out_free_src; - - if (mask_format) { - pixman_composite_glyphs(op, src_image, dst_image, - mask_format->format | (mask_format->depth << 24), - src_x + src_dx + region.extents.x1 - dst_x, - src_y + src_dy + region.extents.y1 - dst_y, - region.extents.x1, region.extents.y1, - region.extents.x1 + dst_dx, region.extents.y1 + dst_dy, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, - cache, count, pglyphs); - } else { - pixman_composite_glyphs_no_mask(op, src_image, dst_image, - src_x + src_dx - dst_x, src_y + src_dy - dst_y, - dst_dx, dst_dy, + src_image = image_from_pict(src, FALSE, &src_dx, &src_dy); + if (src_image == NULL) + goto out; + + dst_image = image_from_pict(dst, TRUE, &dst_dx, &dst_dy); + if (dst_image == NULL) + goto out_free_src; + + if (mask_format) { + pixman_composite_glyphs(op, src_image, dst_image, + mask_format->format | (mask_format->depth << 24), + src_x + src_dx + region.extents.x1 - dst_x, + src_y + src_dy + region.extents.y1 - dst_y, + region.extents.x1, region.extents.y1, + region.extents.x1 + dst_dx, region.extents.y1 + dst_dy, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1, cache, count, pglyphs); - } + } else { + pixman_composite_glyphs_no_mask(op, src_image, dst_image, + src_x + src_dx - dst_x, src_y + src_dy - dst_y, + dst_dx, dst_dy, + cache, count, pglyphs); + } - free_pixman_pict(dst, dst_image); + free_pixman_pict(dst, dst_image); out_free_src: - free_pixman_pict(src, src_image); + free_pixman_pict(src, src_image); out: - pixman_glyph_cache_thaw(cache); - if (pglyphs != stack_glyphs) - free(pglyphs); -} -#else -static void -glyphs_fallback(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - int src_x, - int src_y, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - struct sna *sna = to_sna_from_drawable(dst->pDrawable); - ScreenPtr screen = dst->pDrawable->pScreen; - pixman_image_t *dst_image, *mask_image, *src_image; - int dx, dy, x, y; - RegionRec region; - - glyph_extents(nlist, list, glyphs, ®ion.extents); - if (region.extents.x2 <= region.extents.x1 || - region.extents.y2 <= region.extents.y1) - return; - - DBG(("%s: (%d, %d), (%d, %d)\n", __FUNCTION__, - region.extents.x1, region.extents.y1, - region.extents.x2, region.extents.y2)); - - region.data = NULL; - RegionTranslate(®ion, dst->pDrawable->x, dst->pDrawable->y); - if (dst->pCompositeClip) - RegionIntersect(®ion, ®ion, dst->pCompositeClip); - DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", - __FUNCTION__, - RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, - RegionExtents(®ion)->x2, RegionExtents(®ion)->y2)); - if (!RegionNotEmpty(®ion)) - return; - - if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, - MOVE_READ | MOVE_WRITE)) - return; - if (dst->alphaMap && - !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, - MOVE_READ | MOVE_WRITE)) - return; - - if (src->pDrawable) { - if (!sna_drawable_move_to_cpu(src->pDrawable, - MOVE_READ)) - return; - - if (src->alphaMap && - !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, - MOVE_READ)) - return; - } - RegionTranslate(®ion, -dst->pDrawable->x, -dst->pDrawable->y); - - dst_image = image_from_pict(dst, TRUE, &x, &y); - if (dst_image == NULL) - goto cleanup_region; - DBG(("%s: dst offset (%d, %d)\n", __FUNCTION__, x, y)); - if (x | y) { - region.extents.x1 += x; - region.extents.x2 += x; - region.extents.y1 += y; - region.extents.y2 += y; - } - - src_image = image_from_pict(src, FALSE, &dx, &dy); - if (src_image == NULL) - goto cleanup_dst; - DBG(("%s: src offset (%d, %d)\n", __FUNCTION__, dx, dy)); - src_x += dx - list->xOff; - src_y += dy - list->yOff; - - if (mask_format && - (op_is_bounded(op) || (nlist == 1 && list->len == 1)) && - mask_format == glyphs_format(nlist, list, glyphs)) - mask_format = NULL; + pixman_glyph_cache_thaw(cache); + if (pglyphs != stack_glyphs) + free(pglyphs); + } else +#endif + { + pixman_image_t *mask_image; - if (mask_format) { - DBG(("%s: create mask (%d, %d)x(%d,%d) + (%d,%d) + (%d,%d), depth=%d, format=%lx [%lx], ca? %d\n", - __FUNCTION__, - region.extents.x1, region.extents.y1, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, - dst->pDrawable->x, dst->pDrawable->y, - x, y, - mask_format->depth, - (long)mask_format->format, - (long)(mask_format->depth << 24 | mask_format->format), - NeedsComponent(mask_format->format))); - mask_image = - pixman_image_create_bits(mask_format->depth << 24 | mask_format->format, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, - NULL, 0); - if (mask_image == NULL) - goto cleanup_src; - if (NeedsComponent(mask_format->format)) - pixman_image_set_component_alpha(mask_image, TRUE); + dst_image = image_from_pict(dst, TRUE, &x, &y); + if (dst_image == NULL) + goto cleanup_region; + DBG(("%s: dst offset (%d, %d)\n", __FUNCTION__, x, y)); + if (x | y) { + region.extents.x1 += x; + region.extents.x2 += x; + region.extents.y1 += y; + region.extents.y2 += y; + } - x -= region.extents.x1; - y -= region.extents.y1; - } else { - mask_image = dst_image; - src_x -= x - dst->pDrawable->x; - src_y -= y - dst->pDrawable->y; - } + src_image = image_from_pict(src, FALSE, &src_dx, &src_dy); + if (src_image == NULL) + goto cleanup_dst; + DBG(("%s: src offset (%d, %d)\n", __FUNCTION__, src_dx, src_dy)); + src_x += src_dx - list->xOff; + src_y += src_dy - list->yOff; - do { - int n = list->len; - x += list->xOff; - y += list->yOff; - while (n--) { - GlyphPtr g = *glyphs++; - pixman_image_t *glyph_image; + if (mask_format) { + DBG(("%s: create mask (%d, %d)x(%d,%d) + (%d,%d) + (%d,%d), depth=%d, format=%lx [%lx], ca? %d\n", + __FUNCTION__, + region.extents.x1, region.extents.y1, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1, + dst->pDrawable->x, dst->pDrawable->y, + x, y, + mask_format->depth, + (long)mask_format->format, + (long)(mask_format->depth << 24 | mask_format->format), + NeedsComponent(mask_format->format))); + mask_image = + pixman_image_create_bits(mask_format->depth << 24 | mask_format->format, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1, + NULL, 0); + if (mask_image == NULL) + goto cleanup_src; + if (NeedsComponent(mask_format->format)) + pixman_image_set_component_alpha(mask_image, TRUE); + + x -= region.extents.x1; + y -= region.extents.y1; + } else { + mask_image = dst_image; + src_x -= x - dst->pDrawable->x; + src_y -= y - dst->pDrawable->y; + } - if (g->info.width == 0 || g->info.height == 0) - goto next_glyph; + do { + n = list->len; + x += list->xOff; + y += list->yOff; + while (n--) { + GlyphPtr g = *glyphs++; + pixman_image_t *glyph_image; - glyph_image = sna_glyph_get_image(g, screen); - if (glyph_image == NULL) - goto next_glyph; + if (g->info.width == 0 || g->info.height == 0) + goto next_glyph; - if (mask_format) { - DBG(("%s: glyph+(%d,%d) to mask (%d, %d)x(%d, %d)\n", - __FUNCTION__, - dx, dy, - x - g->info.x, - y - g->info.y, - g->info.width, - g->info.height)); + glyph_image = sna_glyph_get_image(g, screen); + if (glyph_image == NULL) + goto next_glyph; - if (list->format == mask_format) { - assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); - pixman_image_composite(PictOpAdd, - glyph_image, - NULL, - mask_image, - dx, dy, - 0, 0, - x - g->info.x, - y - g->info.y, - g->info.width, - g->info.height); + if (mask_format) { + DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", + __FUNCTION__, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height)); + + if (list->format == mask_format) { + assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); + pixman_image_composite(PictOpAdd, + glyph_image, + NULL, + mask_image, + 0, 0, + 0, 0, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height); + } else { + pixman_image_composite(PictOpAdd, + sna->render.white_image, + glyph_image, + mask_image, + 0, 0, + 0, 0, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height); + } } else { - pixman_image_composite(PictOpAdd, - sna->render.white_image, + int xi = x - g->info.x; + int yi = y - g->info.y; + + DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n", + __FUNCTION__, + xi, yi, + g->info.width, g->info.height, + dst->pDrawable->x, + dst->pDrawable->y, + dst->pDrawable->width, + dst->pDrawable->height, + src_x + xi, + src_y + yi, + op)); + + pixman_image_composite(op, + src_image, glyph_image, - mask_image, - dx, dy, + dst_image, + src_x + xi, + src_y + yi, 0, 0, - x - g->info.x, - y - g->info.y, + xi, yi, g->info.width, g->info.height); } - } else { - int xi = x - g->info.x; - int yi = y - g->info.y; - - DBG(("%s: glyph+(%d, %d) to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n", - __FUNCTION__, - dx, dy, - xi, yi, - g->info.width, g->info.height, - dst->pDrawable->x, - dst->pDrawable->y, - dst->pDrawable->width, - dst->pDrawable->height, - src_x + xi, - src_y + yi, - op)); - - pixman_image_composite(op, - src_image, - glyph_image, - dst_image, - src_x + xi, - src_y + yi, - dx, dy, - xi, yi, - g->info.width, - g->info.height); - } next_glyph: - x += g->info.xOff; - y += g->info.yOff; + x += g->info.xOff; + y += g->info.yOff; + } + list++; + } while (--nlist); + + if (mask_format) { + DBG(("%s: glyph mask composite src=(%d+%d,%d+%d) dst=(%d, %d)x(%d, %d)\n", + __FUNCTION__, + src_x, region.extents.x1, src_y, region.extents.y1, + region.extents.x1, region.extents.y1, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1)); + pixman_image_composite(op, src_image, mask_image, dst_image, + src_x, src_y, + 0, 0, + region.extents.x1, region.extents.y1, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1); + pixman_image_unref(mask_image); } - list++; - } while (--nlist); - - if (mask_format) { - DBG(("%s: glyph mask composite src=(%d+%d,%d+%d) dst=(%d, %d)x(%d, %d)\n", - __FUNCTION__, - src_x, region.extents.x1, src_y, region.extents.y1, - region.extents.x1, region.extents.y1, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1)); - pixman_image_composite(op, src_image, mask_image, dst_image, - src_x, src_y, - 0, 0, - region.extents.x1, region.extents.y1, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1); - pixman_image_unref(mask_image); - } cleanup_src: - free_pixman_pict(src, src_image); + free_pixman_pict(src, src_image); cleanup_dst: - free_pixman_pict(dst, dst_image); + free_pixman_pict(dst, dst_image); + } + cleanup_region: RegionUninit(®ion); } -#endif void sna_glyphs(CARD8 op, @@ -1757,7 +1697,9 @@ sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) if (priv->image) { #if HAS_PIXMAN_GLYPHS struct sna *sna = to_sna_from_screen(screen); - pixman_glyph_cache_remove(sna->render.glyph_cache, glyph, NULL); + if (sna->render.glyph_cache) + pixman_glyph_cache_remove(sna->render.glyph_cache, + glyph, NULL); #endif pixman_image_unref(priv->image); priv->image = NULL; diff --git a/src/sna/sna_gradient.c b/src/sna/sna_gradient.c index a364c11f..5f06fbc8 100644 --- a/src/sna/sna_gradient.c +++ b/src/sna/sna_gradient.c @@ -382,6 +382,9 @@ bool sna_gradients_create(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); + if (!can_render(sna)) + return true; + if (!sna_alpha_cache_init(sna)) return false; |