forked from enlightenment/efl
evas/cserve2: Fix refcount for glyphs & glyph buffers
Maybe a little overkill on the iterations (ref/unref), but at least we can really track down which glyphs are currently being used.
This commit is contained in:
parent
e74cac57e4
commit
6b6e33e262
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
#include "evas_font_ot.h"
|
#include "evas_font_ot.h"
|
||||||
|
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
#include "../cserve2/evas_cs2_private.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct _Evas_Glyph
|
struct _Evas_Glyph
|
||||||
{
|
{
|
||||||
RGBA_Font_Glyph *fg;
|
RGBA_Font_Glyph *fg;
|
||||||
|
@ -227,6 +231,19 @@ evas_common_font_rgba_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
|
||||||
void
|
void
|
||||||
evas_common_font_glyphs_ref(Evas_Glyph_Array *array)
|
evas_common_font_glyphs_ref(Evas_Glyph_Array *array)
|
||||||
{
|
{
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
if (evas_cserve2_use_get() && !array->refcount)
|
||||||
|
{
|
||||||
|
Eina_Iterator *iter;
|
||||||
|
Evas_Glyph *glyph;
|
||||||
|
|
||||||
|
iter = eina_inarray_iterator_new(array->array);
|
||||||
|
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||||
|
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_TRUE);
|
||||||
|
eina_iterator_free(iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
array->refcount++;
|
array->refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +252,19 @@ evas_common_font_glyphs_unref(Evas_Glyph_Array *array)
|
||||||
{
|
{
|
||||||
if (--array->refcount) return;
|
if (--array->refcount) return;
|
||||||
|
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
if (evas_cserve2_use_get())
|
||||||
|
{
|
||||||
|
Eina_Iterator *iter;
|
||||||
|
Evas_Glyph *glyph;
|
||||||
|
|
||||||
|
iter = eina_inarray_iterator_new(array->array);
|
||||||
|
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||||
|
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_FALSE);
|
||||||
|
eina_iterator_free(iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
eina_inarray_free(array->array);
|
eina_inarray_free(array->array);
|
||||||
evas_common_font_int_unref(array->fi);
|
evas_common_font_int_unref(array->fi);
|
||||||
free(array);
|
free(array);
|
||||||
|
@ -274,6 +304,18 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
||||||
if (text_props->len < unit) unit = text_props->len;
|
if (text_props->len < unit) unit = text_props->len;
|
||||||
if (text_props->glyphs && text_props->glyphs->refcount == 1)
|
if (text_props->glyphs && text_props->glyphs->refcount == 1)
|
||||||
{
|
{
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
if (evas_cserve2_use_get())
|
||||||
|
{
|
||||||
|
Eina_Iterator *iter;
|
||||||
|
Evas_Glyph *glyph;
|
||||||
|
|
||||||
|
iter = eina_inarray_iterator_new(text_props->glyphs->array);
|
||||||
|
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||||
|
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_FALSE);
|
||||||
|
eina_iterator_free(iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
glyphs = text_props->glyphs->array;
|
glyphs = text_props->glyphs->array;
|
||||||
glyphs->len = 0;
|
glyphs->len = 0;
|
||||||
reused_glyphs = EINA_TRUE;
|
reused_glyphs = EINA_TRUE;
|
||||||
|
@ -318,6 +360,11 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
||||||
glyph->idx = idx;
|
glyph->idx = idx;
|
||||||
glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
|
glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
|
||||||
glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
|
glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
|
||||||
|
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
if (reused_glyphs && evas_cserve2_use_get())
|
||||||
|
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_TRUE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
EVAS_FONT_WALK_TEXT_END();
|
EVAS_FONT_WALK_TEXT_END();
|
||||||
|
|
||||||
|
@ -327,10 +374,11 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
||||||
|
|
||||||
text_props->glyphs = malloc(sizeof(*text_props->glyphs));
|
text_props->glyphs = malloc(sizeof(*text_props->glyphs));
|
||||||
if (!text_props->glyphs) goto error;
|
if (!text_props->glyphs) goto error;
|
||||||
text_props->glyphs->refcount = 1;
|
text_props->glyphs->refcount = 0;
|
||||||
text_props->glyphs->array = glyphs;
|
text_props->glyphs->array = glyphs;
|
||||||
text_props->glyphs->fi = fi;
|
text_props->glyphs->fi = fi;
|
||||||
fi->references++;
|
fi->references++;
|
||||||
|
evas_common_font_glyphs_ref(text_props->glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if there's a request queue in fi, if so ask cserve2 to render
|
/* check if there's a request queue in fi, if so ask cserve2 to render
|
||||||
|
|
|
@ -262,6 +262,7 @@ _request_resend(unsigned int rid)
|
||||||
Client_Request *cr;
|
Client_Request *cr;
|
||||||
Eina_Bool found = EINA_FALSE;
|
Eina_Bool found = EINA_FALSE;
|
||||||
|
|
||||||
|
DBG("Re-sending %d requests...", eina_list_count(_requests));
|
||||||
EINA_LIST_FOREACH(_requests, l, cr)
|
EINA_LIST_FOREACH(_requests, l, cr)
|
||||||
{
|
{
|
||||||
if (rid)
|
if (rid)
|
||||||
|
@ -337,9 +338,13 @@ _server_reconnect()
|
||||||
if (!_server_dispatch_until(SPECIAL_RID_INDEX_LIST))
|
if (!_server_dispatch_until(SPECIAL_RID_INDEX_LIST))
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
#warning TODO: Reopen all files, images, fonts...
|
/* NOTE: (TODO?)
|
||||||
|
* Either we reopen all images & fonts now
|
||||||
|
* Or we wait until new data is required again to request cserve2 to load
|
||||||
|
* it for us. Not sure which approch is the best now.
|
||||||
|
* So, for the moment, we'll just wait until the client needs new data.
|
||||||
|
*/
|
||||||
|
|
||||||
DBG("Re-sending %d requests...", eina_list_count(_requests));
|
|
||||||
if (!_request_resend(0))
|
if (!_request_resend(0))
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
|
@ -768,7 +773,7 @@ _image_loaded_cb(void *data, const void *msg_received, int size)
|
||||||
|
|
||||||
if (msg_error->error == CSERVE2_NOT_LOADED)
|
if (msg_error->error == CSERVE2_NOT_LOADED)
|
||||||
{
|
{
|
||||||
#warning Code path to check
|
#warning Code path to check: cserve2 restart
|
||||||
DBG("Trying to reopen the image");
|
DBG("Trying to reopen the image");
|
||||||
ie->open_rid = _image_open_server_send(ie);
|
ie->open_rid = _image_open_server_send(ie);
|
||||||
if (_server_dispatch_until(ie->open_rid))
|
if (_server_dispatch_until(ie->open_rid))
|
||||||
|
@ -1399,6 +1404,7 @@ struct _Glyph_Map
|
||||||
Shared_Index index;
|
Shared_Index index;
|
||||||
Shared_Buffer mempool;
|
Shared_Buffer mempool;
|
||||||
Eina_Clist glyphs;
|
Eina_Clist glyphs;
|
||||||
|
Eina_List *mempool_lru;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CS_Glyph_Out
|
struct _CS_Glyph_Out
|
||||||
|
@ -1409,15 +1415,27 @@ struct _CS_Glyph_Out
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
unsigned int rid;
|
unsigned int rid;
|
||||||
Glyph_Map *map;
|
Glyph_Map *map;
|
||||||
|
Shared_Buffer *sb;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
Eina_Bool used;
|
Eina_Bool used;
|
||||||
|
int refcount;
|
||||||
|
int pending_ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_glyphs_map_free(Glyph_Map *map)
|
_glyphs_map_free(Glyph_Map *map)
|
||||||
{
|
{
|
||||||
|
Shared_Buffer *mempool;
|
||||||
|
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
|
|
||||||
|
EINA_LIST_FREE(map->mempool_lru, mempool)
|
||||||
|
{
|
||||||
|
eina_file_map_free(mempool->f, mempool->data);
|
||||||
|
eina_file_close(mempool->f);
|
||||||
|
free(mempool);
|
||||||
|
}
|
||||||
eina_file_map_free(map->mempool.f, map->mempool.data);
|
eina_file_map_free(map->mempool.f, map->mempool.data);
|
||||||
eina_file_close(map->mempool.f);
|
eina_file_close(map->mempool.f);
|
||||||
eina_file_map_free(map->index.f, map->index.data);
|
eina_file_map_free(map->index.f, map->index.data);
|
||||||
|
@ -1643,48 +1661,52 @@ _glyph_map_remap_check(Glyph_Map *map)
|
||||||
{
|
{
|
||||||
Eina_Bool changed = EINA_FALSE;
|
Eina_Bool changed = EINA_FALSE;
|
||||||
int oldcount;
|
int oldcount;
|
||||||
const void *oldmap = map->mempool.data;
|
|
||||||
|
|
||||||
if (!map->mempool.f)
|
|
||||||
{
|
|
||||||
WRN("The glyph mempool has been closed.");
|
|
||||||
if (!map->mempool.path)
|
|
||||||
return EINA_FALSE;
|
|
||||||
|
|
||||||
DBG("Remapping from %s", map->mempool.path);
|
|
||||||
map->mempool.f = eina_file_open(map->mempool.path, EINA_TRUE);
|
|
||||||
if (!map->mempool.f)
|
|
||||||
{
|
|
||||||
ERR("Could not open shm file: %d %m", errno);
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
map->mempool.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eina_file_refresh(map->mempool.f)
|
if (eina_file_refresh(map->mempool.f)
|
||||||
|| (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size))
|
|| (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size))
|
||||||
{
|
{
|
||||||
CS_Glyph_Out *gl;
|
CS_Glyph_Out *gl;
|
||||||
|
Shared_Buffer *oldbuf = NULL;
|
||||||
|
|
||||||
WRN("Glyph pool has been resized.");
|
WRN("Glyph pool has been resized.");
|
||||||
eina_file_map_free(map->mempool.f, map->mempool.data);
|
|
||||||
map->mempool.data = eina_file_map_all(map->mempool.f, EINA_FILE_RANDOM);
|
// Queue old mempool into mempool_lru unless refcount == 0
|
||||||
if (map->mempool.data)
|
// We want to keep the old glyph bitmap data in memory because of
|
||||||
map->mempool.size = eina_file_size_get(map->mempool.f);
|
// asynchronous rendering and also because remap could happen
|
||||||
|
// after some glyphs have been requested but not all for the current
|
||||||
|
// draw.
|
||||||
|
|
||||||
|
if (map->mempool.refcount > 0)
|
||||||
|
{
|
||||||
|
oldbuf = calloc(1, sizeof(Glyph_Map));
|
||||||
|
oldbuf->f = eina_file_dup(map->mempool.f);
|
||||||
|
oldbuf->data = map->mempool.data;
|
||||||
|
oldbuf->size = map->mempool.size;
|
||||||
|
oldbuf->refcount = map->mempool.refcount;
|
||||||
|
eina_strlcpy(oldbuf->path, map->mempool.path, SHARED_BUFFER_PATH_MAX);
|
||||||
|
map->mempool_lru = eina_list_append(map->mempool_lru, oldbuf);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
map->mempool.size = 0;
|
{
|
||||||
|
eina_file_map_free(map->mempool.f, map->mempool.data);
|
||||||
|
}
|
||||||
|
map->mempool.data = eina_file_map_all(map->mempool.f, EINA_FILE_RANDOM);
|
||||||
|
map->mempool.size = eina_file_size_get(map->mempool.f);
|
||||||
|
map->mempool.refcount = 0;
|
||||||
changed = EINA_TRUE;
|
changed = EINA_TRUE;
|
||||||
|
|
||||||
// Remap loaded glyphs
|
// Remap unused but loaded glyphs
|
||||||
#warning Infinite loop again here. FONT RELOAD IS STILL BROKEN.
|
|
||||||
EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs,
|
EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs,
|
||||||
CS_Glyph_Out, map_entry)
|
CS_Glyph_Out, map_entry)
|
||||||
{
|
{
|
||||||
if (map->mempool.data)
|
if (!gl->refcount)
|
||||||
gl->base.bitmap.buffer = (unsigned char *)
|
{
|
||||||
map->mempool.data + gl->offset;
|
gl->sb = &map->mempool;
|
||||||
else
|
gl->base.bitmap.buffer = (unsigned char *) gl->sb->data + gl->offset;
|
||||||
gl->base.bitmap.buffer = NULL;
|
}
|
||||||
|
else if (oldbuf)
|
||||||
|
gl->sb = oldbuf;
|
||||||
|
else CRIT("Invalid refcount state");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1692,7 +1714,6 @@ _glyph_map_remap_check(Glyph_Map *map)
|
||||||
oldcount = map->index.count;
|
oldcount = map->index.count;
|
||||||
_shared_index_remap_check(&map->index, sizeof(Glyph_Data));
|
_shared_index_remap_check(&map->index, sizeof(Glyph_Data));
|
||||||
changed |= (oldcount != map->index.count);
|
changed |= (oldcount != map->index.count);
|
||||||
changed |= (oldmap != map->mempool.data);
|
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
@ -1744,6 +1765,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
|
||||||
eina_clist_element_init(&gl->map_entry);
|
eina_clist_element_init(&gl->map_entry);
|
||||||
}
|
}
|
||||||
gl->map = fe->map;
|
gl->map = fe->map;
|
||||||
|
gl->sb = &fe->map->mempool;
|
||||||
gl->offset = gd->offset;
|
gl->offset = gd->offset;
|
||||||
gl->size = gd->size;
|
gl->size = gd->size;
|
||||||
gl->base.bitmap.rows = gd->rows;
|
gl->base.bitmap.rows = gd->rows;
|
||||||
|
@ -1790,20 +1812,9 @@ _glyph_request_cb(void *data, const void *msg, int size)
|
||||||
|
|
||||||
if (err->error == CSERVE2_NOT_LOADED)
|
if (err->error == CSERVE2_NOT_LOADED)
|
||||||
{
|
{
|
||||||
|
// This can happen in case cserve2 restarted.
|
||||||
DBG("Reloading the font: %s from %s", fe->name, fe->source);
|
DBG("Reloading the font: %s from %s", fe->name, fe->source);
|
||||||
|
|
||||||
// This will crash for sure.
|
|
||||||
/*
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
if (fe->fash[i])
|
|
||||||
fash_gl_free(fe->fash[i]);
|
|
||||||
fe->fash[i] = NULL;
|
|
||||||
}
|
|
||||||
_glyphs_map_free(fe->map);
|
|
||||||
fe->map = NULL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD)))
|
if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD)))
|
||||||
{
|
{
|
||||||
ERR("Failed to send font load message");
|
ERR("Failed to send font load message");
|
||||||
|
@ -1811,7 +1822,7 @@ _glyph_request_cb(void *data, const void *msg, int size)
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning Code path to check
|
#warning Code path to check: cserve2 restart
|
||||||
|
|
||||||
if (fe->glyphs_queue_count)
|
if (fe->glyphs_queue_count)
|
||||||
_glyph_request_server_send(fe, grd->hints, EINA_FALSE);
|
_glyph_request_server_send(fe, grd->hints, EINA_FALSE);
|
||||||
|
@ -1910,13 +1921,14 @@ _glyph_request_cb(void *data, const void *msg, int size)
|
||||||
if (gl)
|
if (gl)
|
||||||
{
|
{
|
||||||
gl->map = fe->map;
|
gl->map = fe->map;
|
||||||
|
gl->sb = &fe->map->mempool;
|
||||||
gl->offset = offset;
|
gl->offset = offset;
|
||||||
gl->size = glsize;
|
gl->size = glsize;
|
||||||
gl->base.bitmap.rows = rows;
|
gl->base.bitmap.rows = rows;
|
||||||
gl->base.bitmap.width = width;
|
gl->base.bitmap.width = width;
|
||||||
gl->base.bitmap.pitch = pitch;
|
gl->base.bitmap.pitch = pitch;
|
||||||
gl->base.bitmap.buffer = (unsigned char *)
|
gl->base.bitmap.buffer =
|
||||||
fe->map->mempool.data + gl->offset;
|
(unsigned char *) gl->map->mempool.data + gl->offset;
|
||||||
gl->base.bitmap.num_grays = num_grays;
|
gl->base.bitmap.num_grays = num_grays;
|
||||||
gl->base.bitmap.pixel_mode = pixel_mode;
|
gl->base.bitmap.pixel_mode = pixel_mode;
|
||||||
gl->rid = 0;
|
gl->rid = 0;
|
||||||
|
@ -1926,7 +1938,13 @@ _glyph_request_cb(void *data, const void *msg, int size)
|
||||||
WRN("Glyph offset out of the buffer. Refreshing map.");
|
WRN("Glyph offset out of the buffer. Refreshing map.");
|
||||||
if (!_glyph_map_remap_check(fe->map))
|
if (!_glyph_map_remap_check(fe->map))
|
||||||
{
|
{
|
||||||
ERR("Failed to remap glyph mempool!");
|
// This is very problematic. Evas expects the glyph to
|
||||||
|
// be valid after this point.
|
||||||
|
// We could set rows & width to 0 to avoid crashes but
|
||||||
|
// then display might be b0rken.
|
||||||
|
// Also, all the previous glyphs might be out of the
|
||||||
|
// memory range now, so we're in a pretty bad situation.
|
||||||
|
CRIT("Failed to remap glyph mempool!");
|
||||||
gl->base.bitmap.buffer = NULL;
|
gl->base.bitmap.buffer = NULL;
|
||||||
//gl->base.bitmap.rows = 0;
|
//gl->base.bitmap.rows = 0;
|
||||||
//gl->base.bitmap.width = 0;
|
//gl->base.bitmap.width = 0;
|
||||||
|
@ -2067,16 +2085,15 @@ evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flag
|
||||||
if (!glyph)
|
if (!glyph)
|
||||||
{
|
{
|
||||||
glyph = calloc(1, sizeof(*glyph));
|
glyph = calloc(1, sizeof(*glyph));
|
||||||
|
|
||||||
glyph->idx = idx;
|
glyph->idx = idx;
|
||||||
|
|
||||||
fash_gl_add(fash, idx, glyph);
|
fash_gl_add(fash, idx, glyph);
|
||||||
|
|
||||||
eina_clist_add_head(&fe->glyphs_queue, &glyph->map_entry);
|
eina_clist_add_head(&fe->glyphs_queue, &glyph->map_entry);
|
||||||
fe->glyphs_queue_count++;
|
fe->glyphs_queue_count++;
|
||||||
}
|
}
|
||||||
else if (!glyph->used)
|
else if (!glyph->used)
|
||||||
{
|
{
|
||||||
|
// FIXME: This code path seems unused (not logical)
|
||||||
|
CRIT("Is this code path even valid?");
|
||||||
eina_clist_add_head(&fe->glyphs_used, &glyph->used_list);
|
eina_clist_add_head(&fe->glyphs_used, &glyph->used_list);
|
||||||
fe->glyphs_used_count++;
|
fe->glyphs_used_count++;
|
||||||
glyph->used = EINA_TRUE;
|
glyph->used = EINA_TRUE;
|
||||||
|
@ -2114,6 +2131,7 @@ evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags h
|
||||||
if (!glyph)
|
if (!glyph)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
// Glyph was requested but the bitmap data was not loaded yet.
|
||||||
if (!glyph->map)
|
if (!glyph->map)
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
@ -2162,7 +2180,8 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SHARED_INDEX
|
#if USE_SHARED_INDEX
|
||||||
_font_entry_glyph_map_rebuild_check(fe, hints);
|
#warning TODO MUST REIMPLEMENT THIS FUNCTION
|
||||||
|
//_font_entry_glyph_map_rebuild_check(fe, hints);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (out->rid)
|
if (out->rid)
|
||||||
|
@ -2174,10 +2193,79 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// promote shm and font entry in lru or something
|
// promote shm and font entry in lru or something
|
||||||
|
|
||||||
return &(out->base);
|
return &(out->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref)
|
||||||
|
{
|
||||||
|
CS_Glyph_Out *glout;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(evas_cserve2_use_get());
|
||||||
|
|
||||||
|
// For debugging only.
|
||||||
|
static int inc = 0, dec = 0;
|
||||||
|
if (incref) inc++; else dec++;
|
||||||
|
|
||||||
|
// glout = (CS_Glyph_Out *) glyph;
|
||||||
|
glout = (CS_Glyph_Out *) (((char *) glyph) - offsetof(CS_Glyph_Out, base));
|
||||||
|
|
||||||
|
if (incref)
|
||||||
|
{
|
||||||
|
if (!glout->sb)
|
||||||
|
{
|
||||||
|
// This can happen when cserve2 restarted.
|
||||||
|
glout->pending_ref++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!glout->refcount)
|
||||||
|
glout->sb->refcount++;
|
||||||
|
if (glout->pending_ref)
|
||||||
|
{
|
||||||
|
glout->refcount += glout->pending_ref;
|
||||||
|
glout->pending_ref = 0;
|
||||||
|
}
|
||||||
|
glout->refcount++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(glout->refcount > 0);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(glout->sb);
|
||||||
|
if (glout->pending_ref)
|
||||||
|
{
|
||||||
|
glout->refcount += glout->pending_ref;
|
||||||
|
glout->pending_ref = 0;
|
||||||
|
glout->sb->refcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glout->refcount--;
|
||||||
|
if (!glout->refcount)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(glout->sb->refcount > 0);
|
||||||
|
glout->sb->refcount--;
|
||||||
|
|
||||||
|
if (!glout->sb->refcount)
|
||||||
|
DBG("Shared buffer %p reached refcount ZERO. %d/%d", glout->sb, dec, inc);
|
||||||
|
|
||||||
|
//if (glout->sb->data != glout->map->mempool.data)
|
||||||
|
if (glout->sb != &glout->map->mempool)
|
||||||
|
{
|
||||||
|
if (!glout->sb->refcount)
|
||||||
|
{
|
||||||
|
DBG("Glyph shared buffer reached refcount 0. Unmapping.");
|
||||||
|
glout->map->mempool_lru =
|
||||||
|
eina_list_remove(glout->map->mempool_lru, glout->sb);
|
||||||
|
eina_file_map_free(glout->sb->f, glout->sb->data);
|
||||||
|
eina_file_close(glout->sb->f);
|
||||||
|
free(glout->sb);
|
||||||
|
}
|
||||||
|
glout->sb = &glout->map->mempool;
|
||||||
|
glout->base.bitmap.buffer =
|
||||||
|
(unsigned char *) glout->sb->data + glout->offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fast access to shared index tables
|
// Fast access to shared index tables
|
||||||
|
@ -2720,7 +2808,7 @@ _shared_image_entry_image_data_find(Image_Entry *ie)
|
||||||
const File_Data *fdata = _shared_image_entry_file_data_find(ie);
|
const File_Data *fdata = _shared_image_entry_file_data_find(ie);
|
||||||
if (!fdata)
|
if (!fdata)
|
||||||
{
|
{
|
||||||
ERR("File is not opened by cserve2");
|
DBG("File is not opened by cserve2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
file_id = fdata->id;
|
file_id = fdata->id;
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct _Shared_Buffer
|
||||||
Eina_File *f;
|
Eina_File *f;
|
||||||
char *data;
|
char *data;
|
||||||
int size;
|
int size;
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Index_Table
|
struct _Index_Table
|
||||||
|
@ -89,4 +90,5 @@ void evas_cserve2_font_free(Font_Entry *fe);
|
||||||
Eina_Bool evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
Eina_Bool evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
||||||
Eina_Bool evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) EINA_WARN_UNUSED_RESULT;
|
Eina_Bool evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) EINA_WARN_UNUSED_RESULT;
|
||||||
RGBA_Font_Glyph_Out *evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
RGBA_Font_Glyph_Out *evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
||||||
|
void evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue