summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-12 10:34:10 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-12 12:05:43 +0100
commitdc18eaa585c36c8e5f5b4ec405a976a835fd2ac3 (patch)
treefaf1b626b9d8b4986e5b035a176304fe253d8d3b
parentb580abdfa68108f3e63ee1f897b6ea83b9c47935 (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.h2
-rw-r--r--src/sna/sna_accel.c16
-rw-r--r--src/sna/sna_composite.c3
-rw-r--r--src/sna/sna_driver.c6
-rw-r--r--src/sna/sna_glyphs.c500
-rw-r--r--src/sna/sna_gradient.c3
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, &region.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(&region, dst->pDrawable->x, dst->pDrawable->y);
- if (dst->pCompositeClip)
- RegionIntersect(&region, &region, dst->pCompositeClip);
- DBG(("%s: clipped extents (%d, %d), (%d, %d)\n",
- __FUNCTION__,
- RegionExtents(&region)->x1, RegionExtents(&region)->y1,
- RegionExtents(&region)->x2, RegionExtents(&region)->y2));
- if (!RegionNotEmpty(&region))
- return;
-
- if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
- 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(&region, -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(&region);
}
-#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;