evas/cserve2: Store glyphs in shared arrays

Also, change the internal structure of glyph listing:
 - Use lists instead of inlists

Switch to use Glyph_Data instead of Glyph_Entry
This commit is contained in:
Jean-Philippe Andre 2013-08-07 18:48:00 +09:00
parent 28a5c6f587
commit 7ebda2d123
3 changed files with 129 additions and 74 deletions

View File

@ -75,7 +75,7 @@ struct _Font_Entry {
void *ft; void *ft;
Fash_Glyph2 *glyphs; Fash_Glyph2 *glyphs;
unsigned int nglyphs; unsigned int nglyphs;
Eina_Inlist *caches; Eina_List *caches;
Font_Cache *last_cache; Font_Cache *last_cache;
Eina_Bool unused : 1; Eina_Bool unused : 1;
#ifdef DEBUG_LOAD_TIME #ifdef DEBUG_LOAD_TIME
@ -90,27 +90,18 @@ struct _Font_Entry {
}; };
struct _Font_Cache { struct _Font_Cache {
EINA_INLIST;
Font_Entry *fe; Font_Entry *fe;
Shm_Handle *shm; Shm_Handle *shm;
unsigned int usage; unsigned int usage;
int inuse; int inuse;
Eina_Inlist *glyphs; Shared_Array *glyphs; // Contains gldata_id only
unsigned int nglyphs; unsigned int nglyphs;
}; };
struct _Glyph_Entry { struct _Glyph_Entry {
EINA_INLIST; unsigned int gldata_id;
Font_Entry *fe; Font_Entry *fe;
Font_Cache *fc; Font_Cache *fc;
unsigned int index;
unsigned int offset;
unsigned int size;
unsigned int rows;
unsigned int width;
unsigned int pitch;
unsigned int num_grays;
unsigned int pixel_mode;
}; };
struct _Glyphs_Request { struct _Glyphs_Request {
@ -148,11 +139,13 @@ struct _File_Watch {
}; };
static unsigned int _entry_id = 0; static unsigned int _entry_id = 0;
static unsigned int _glyph_id = 0;
static unsigned int _freed_file_entry_count = 0; static unsigned int _freed_file_entry_count = 0;
static unsigned int _freed_image_entry_count = 0; static unsigned int _freed_image_entry_count = 0;
static Shared_Array *_file_data_array = NULL; static Shared_Array *_file_data_array = NULL;
static Shared_Array *_image_data_array = NULL; static Shared_Array *_image_data_array = NULL;
static Shared_Array *_glyph_data_array = NULL;
static Eina_Hash *file_ids = NULL; // maps path + key --> file_id static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
static Eina_Hash *file_entries = NULL; // maps file_id --> entry static Eina_Hash *file_entries = NULL; // maps file_id --> entry
@ -303,6 +296,22 @@ _image_entry_find(unsigned int entry_id)
return (Image_Entry *) e; return (Image_Entry *) e;
} }
static Glyph_Data *
_glyph_data_find(unsigned int glyph_id)
{
Glyph_Data *gldata;
gldata = cserve2_shared_array_item_data_find(_glyph_data_array, &glyph_id,
_shm_object_id_cmp_cb);
if (!gldata)
{
ERR("Could not find glyph %u", glyph_id);
return NULL;
}
return gldata;
}
static Eina_Bool static Eina_Bool
_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem, _repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem,
void *user_data EINA_UNUSED) void *user_data EINA_UNUSED)
@ -1061,6 +1070,12 @@ static void
_glyph_free_cb(void *data) _glyph_free_cb(void *data)
{ {
Glyph_Entry *gl = data; Glyph_Entry *gl = data;
Glyph_Data *gldata;
if (!gl) return;
gldata = _glyph_data_find(gl->gldata_id);
cserve2_shared_string_del(gldata->shm_id);
gldata->refcount--;
free(gl); free(gl);
} }
@ -1096,18 +1111,22 @@ _font_shm_size_get(Font_Cache *fc)
static void static void
_font_shm_free(Font_Cache *fc) _font_shm_free(Font_Cache *fc)
{ {
Glyph_Data *gd;
Font_Entry *fe = fc->fe; Font_Entry *fe = fc->fe;
fe->caches = eina_inlist_remove(fe->caches, EINA_INLIST_GET(fc)); unsigned int k;
fe->caches = eina_list_remove(fe->caches, fc);
if (fc == fe->last_cache) if (fc == fe->last_cache)
fe->last_cache = NULL; fe->last_cache = NULL;
while (fc->glyphs) for (k = 0; k < fc->nglyphs; k++)
{ {
Glyph_Entry *gl = EINA_INLIST_CONTAINER_GET(fc->glyphs, Glyph_Entry); int *gldata_id = cserve2_shared_array_item_data_get(fc->glyphs, k);
fc->glyphs = eina_inlist_remove(fc->glyphs, fc->glyphs); gd = _glyph_data_find(*gldata_id);
fash_gl_del(fe->glyphs, gl->index); fash_gl_del(fe->glyphs, gd->index);
} }
cserve2_shared_array_del(fc->glyphs);
cserve2_shm_unref(fc->shm); cserve2_shm_unref(fc->shm);
free(fc); free(fc);
@ -1161,6 +1180,7 @@ cserve2_cache_init(void)
_file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0); _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0);
_image_data_array = cserve2_shared_array_new(1, sizeof(Image_Data), 0); _image_data_array = cserve2_shared_array_new(1, sizeof(Image_Data), 0);
_glyph_data_array = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0);
} }
void void
@ -1182,6 +1202,7 @@ cserve2_cache_shutdown(void)
cserve2_shared_array_del(_file_data_array); cserve2_shared_array_del(_file_data_array);
cserve2_shared_array_del(_image_data_array); cserve2_shared_array_del(_image_data_array);
cserve2_shared_array_del(_glyph_data_array);
} }
static Reference * static Reference *
@ -1716,7 +1737,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
size += sizeof(int); size += sizeof(int);
// nglyphs * (index + offset + size + rows + width + pitch + // nglyphs * (index + offset + size + rows + width + pitch +
// num_grays + pixel_mode) // num_grays + pixel_mode)
size += eina_list_count(iter->glyphs) * 8 * sizeof(int); size += eina_list_count(iter->glyphs) * 9 * sizeof(int);
} }
resp = malloc(size); resp = malloc(size);
@ -1743,21 +1764,27 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
EINA_LIST_FREE(iter->glyphs, gl) EINA_LIST_FREE(iter->glyphs, gl)
{ {
memcpy(buf, &gl->index, sizeof(int)); // TODO: Factorize memcpy
Glyph_Data *gldata;
gldata = _glyph_data_find(gl->gldata_id);
memcpy(buf, &gldata->index, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->offset, sizeof(int)); memcpy(buf, &gldata->shm_id, sizeof(string_t));
buf += sizeof(string_t);
memcpy(buf, &gldata->offset, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->size, sizeof(int)); memcpy(buf, &gldata->size, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->rows, sizeof(int)); memcpy(buf, &gldata->rows, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->width, sizeof(int)); memcpy(buf, &gldata->width, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->pitch, sizeof(int)); memcpy(buf, &gldata->pitch, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->num_grays, sizeof(int)); memcpy(buf, &gldata->num_grays, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->pixel_mode, sizeof(int)); memcpy(buf, &gldata->pixel_mode, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
} }
@ -1955,21 +1982,23 @@ _glyphs_load_request_response(Glyphs_Request *req,
{ {
unsigned int j; unsigned int j;
Slave_Msg_Font_Cache *c = msg->caches[i]; Slave_Msg_Font_Cache *c = msg->caches[i];
string_t shm_id;
if (!fc) if (!fc)
{ {
fc = calloc(1, sizeof(*fc)); fc = calloc(1, sizeof(*fc));
fe->caches = eina_inlist_append(fe->caches, EINA_INLIST_GET(fc)); fe->caches = eina_list_append(fe->caches, fc);
fe->last_cache = fc; fe->last_cache = fc;
fc->fe = fe; fc->fe = fe;
fc->shm = c->shm; fc->shm = c->shm;
fc->glyphs = NULL; fc->glyphs = cserve2_shared_array_new(1, sizeof(int), 0);
fc->nglyphs = 0; fc->nglyphs = 0;
fc->inuse = 0; fc->inuse = 0;
font_shm_lru = eina_list_append(font_shm_lru, fc); font_shm_lru = eina_list_append(font_shm_lru, fc);
font_mem_usage += _font_shm_size_get(fc); font_mem_usage += _font_shm_size_get(fc);
} }
fc->usage = c->usage; fc->usage = c->usage;
shm_id = cserve2_shared_string_add(cserve2_shm_name_get(fc->shm));
for (j = 0; j < c->nglyphs; j++) for (j = 0; j < c->nglyphs; j++)
{ {
Glyph_Entry *gl; Glyph_Entry *gl;
@ -1977,27 +2006,41 @@ _glyphs_load_request_response(Glyphs_Request *req,
gl = fash_gl_find(fe->glyphs, c->glyphs[j].index); gl = fash_gl_find(fe->glyphs, c->glyphs[j].index);
if (!gl) if (!gl)
{ {
int glyph_id, idx, *gldata_id;
Glyph_Data *gldata;
gl = calloc(1, sizeof(*gl)); gl = calloc(1, sizeof(*gl));
gl->fe = fe; gl->fe = fe;
gl->fc = fc; gl->fc = fc;
gl->index = c->glyphs[j].index; gl->gldata_id = ++_glyph_id;
gl->offset = c->glyphs[j].offset;
gl->size = c->glyphs[j].size; glyph_id = cserve2_shared_array_item_new(_glyph_data_array);
gl->rows = c->glyphs[j].rows; gldata = cserve2_shared_array_item_data_get(_glyph_data_array,
gl->width = c->glyphs[j].width; glyph_id);
gl->pitch = c->glyphs[j].pitch; gldata->refcount = 1;
gl->num_grays = c->glyphs[j].num_grays; gldata->id = gl->gldata_id;
gl->pixel_mode = c->glyphs[j].pixel_mode; gldata->index = c->glyphs[j].index;
font_mem_usage += sizeof(*gl); gldata->shm_id = cserve2_shared_string_ref(shm_id);
fc->glyphs = eina_inlist_append(fc->glyphs, EINA_INLIST_GET(gl)); gldata->offset = c->glyphs[j].offset;
gldata->size = c->glyphs[j].size;
gldata->rows = c->glyphs[j].rows;
gldata->width = c->glyphs[j].width;
gldata->pitch = c->glyphs[j].pitch;
gldata->num_grays = c->glyphs[j].num_grays;
gldata->pixel_mode = c->glyphs[j].pixel_mode;
font_mem_usage += sizeof(*gl) + sizeof(*gldata);
idx = cserve2_shared_array_item_new(fc->glyphs);
gldata_id = cserve2_shared_array_item_data_get(fc->glyphs, idx);
*gldata_id = gldata->id;
fc->nglyphs++; fc->nglyphs++;
fe->nglyphs++; fe->nglyphs++;
fash_gl_add(fe->glyphs, gl->index, gl); fash_gl_add(fe->glyphs, gldata->index, gl);
} }
req->answer[req->nanswer++] = gl; req->answer[req->nanswer++] = gl;
gl->fc->inuse++; gl->fc->inuse++;
} }
cserve2_shared_string_del(shm_id);
free(c); // FIXME: We are freeing this here because we only do a free(c); // FIXME: We are freeing this here because we only do a
// simple free on the response message. Later we need to // simple free on the response message. Later we need to
// setup a free callback for the slave response. // setup a free callback for the slave response.
@ -2034,6 +2077,7 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
{ {
Font_Entry *fe = data; Font_Entry *fe = data;
Msg_Stats *msg = fdata; Msg_Stats *msg = fdata;
Eina_List *iter;
Font_Cache *fc; Font_Cache *fc;
int nrefs = eina_list_count(fe->base.references); int nrefs = eina_list_count(fe->base.references);
@ -2041,7 +2085,7 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
if (fe->unused) msg->fonts.fonts_unused++; if (fe->unused) msg->fonts.fonts_unused++;
// accounting size // accounting size
EINA_INLIST_FOREACH(fe->caches, fc) EINA_LIST_FOREACH(fe->caches, iter, fc)
{ {
unsigned int fc_usage, shmsize; unsigned int fc_usage, shmsize;
/* This is not real requested usage, but an approximation. We don't /* This is not real requested usage, but an approximation. We don't
@ -2164,6 +2208,7 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
unsigned int size = di->size; unsigned int size = di->size;
Font_Entry *fe = data; Font_Entry *fe = data;
Font_Cache *fc; Font_Cache *fc;
Eina_List *iter;
const char *str; const char *str;
// filelen // filelen
@ -2195,10 +2240,8 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
// ncaches // ncaches
size += sizeof(int); size += sizeof(int);
EINA_INLIST_FOREACH(fe->caches, fc) EINA_LIST_FOREACH(fe->caches, iter, fc)
{ {
Glyph_Entry *gl;
// shmnamelen + shmname // shmnamelen + shmname
size += sizeof(int); size += sizeof(int);
size += strlen(cserve2_shm_name_get(fc->shm)) + 1; size += strlen(cserve2_shm_name_get(fc->shm)) + 1;
@ -2209,17 +2252,7 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
// nglyphs // nglyphs
size += sizeof(int); size += sizeof(int);
EINA_INLIST_FOREACH(fc->glyphs, gl) size += (4 + 3 + 2) * sizeof(int) * fc->nglyphs;
{
// index, offset, size
size += 3 * sizeof(int);
// rows, width, pitch
size += 3 * sizeof(int);
// num_grays, pixel_mode
size += 2 * sizeof(int);
}
} }
di->size = size; di->size = size;
@ -2235,6 +2268,7 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
char *buf = *pos; char *buf = *pos;
Font_Entry *fe = data; Font_Entry *fe = data;
Font_Cache *fc; Font_Cache *fc;
Eina_List *iter;
unsigned int len; unsigned int len;
unsigned int unused; unsigned int unused;
unsigned int ncaches; unsigned int ncaches;
@ -2278,15 +2312,16 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
buf += sizeof(int); buf += sizeof(int);
// ncaches // ncaches
ncaches = eina_inlist_count(fe->caches); ncaches = eina_list_count(fe->caches);
memcpy(buf, &ncaches, sizeof(int)); memcpy(buf, &ncaches, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
EINA_INLIST_FOREACH(fe->caches, fc) EINA_LIST_FOREACH(fe->caches, iter, fc)
{ {
Glyph_Entry *gl; Glyph_Data *gldata;
const char *shmname; const char *shmname;
unsigned int shmsize; unsigned int shmsize;
unsigned int k;
// shmnamelen + shmname // shmnamelen + shmname
shmname = cserve2_shm_name_get(fc->shm); shmname = cserve2_shm_name_get(fc->shm);
@ -2307,28 +2342,34 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
memcpy(buf, &fc->nglyphs, sizeof(int)); memcpy(buf, &fc->nglyphs, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
EINA_INLIST_FOREACH(fc->glyphs, gl) for (k = 0; k < fc->nglyphs; k++)
{ {
// index, offset, size int *gldata_id = cserve2_shared_array_item_data_get(
memcpy(buf, &gl->index, sizeof(int)); fc->glyphs, fc->nglyphs);
gldata = _glyph_data_find(*gldata_id);
// index, shm_id, offset, size
memcpy(buf, &gldata->index, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->offset, sizeof(int)); memcpy(buf, &gldata->shm_id, sizeof(string_t));
buf += sizeof(string_t);
memcpy(buf, &gldata->offset, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->size, sizeof(int)); memcpy(buf, &gldata->size, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
// rows, width, pitch // rows, width, pitch
memcpy(buf, &gl->rows, sizeof(int)); memcpy(buf, &gldata->rows, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->width, sizeof(int)); memcpy(buf, &gldata->width, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->pitch, sizeof(int)); memcpy(buf, &gldata->pitch, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
// num_grays, pixel_mode // num_grays, pixel_mode
memcpy(buf, &gl->num_grays, sizeof(int)); memcpy(buf, &gldata->num_grays, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(buf, &gl->pixel_mode, sizeof(int)); memcpy(buf, &gldata->pixel_mode, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
} }
} }

View File

@ -287,12 +287,12 @@ typedef struct _Shm_Object Shm_Object;
typedef struct _Index_Entry Index_Entry; typedef struct _Index_Entry Index_Entry;
typedef struct _File_Data File_Data; typedef struct _File_Data File_Data;
typedef struct _Image_Data Image_Data; typedef struct _Image_Data Image_Data;
typedef struct _Glyph_Data Glyph_Data;
typedef struct _Shared_Array_Header Shared_Array_Header; typedef struct _Shared_Array_Header Shared_Array_Header;
typedef int string_t; typedef int string_t;
#define SHMOBJECT unsigned int id; unsigned int refcount #define SHMOBJECT unsigned int id; unsigned int refcount
struct _Shared_Array_Header struct _Shared_Array_Header {
{
int32_t tag; int32_t tag;
int32_t elemsize; int32_t elemsize;
int32_t count; int32_t count;
@ -303,13 +303,11 @@ struct _Shared_Array_Header
int32_t _reserved2; int32_t _reserved2;
}; };
struct _Shm_Object struct _Shm_Object {
{
SHMOBJECT; SHMOBJECT;
}; };
struct _Index_Entry struct _Index_Entry {
{
SHMOBJECT; SHMOBJECT;
// Block entry // Block entry
int32_t length; int32_t length;
@ -332,7 +330,7 @@ struct _File_Data {
struct _Image_Data { struct _Image_Data {
SHMOBJECT; SHMOBJECT;
unsigned int file_id; uint32_t file_id;
string_t shm_id; string_t shm_id;
Evas_Image_Load_Opts opts; Evas_Image_Load_Opts opts;
Eina_Bool alpha_sparse : 1; Eina_Bool alpha_sparse : 1;
@ -340,6 +338,19 @@ struct _Image_Data {
Eina_Bool doload : 1; Eina_Bool doload : 1;
}; };
struct _Glyph_Data {
SHMOBJECT;
uint32_t index;
string_t shm_id;
uint32_t offset;
uint32_t size;
uint32_t rows;
uint32_t width;
uint32_t pitch;
uint32_t num_grays;
uint32_t pixel_mode;
};
struct _Msg_Error { struct _Msg_Error {
Msg_Base base; Msg_Base base;
int error; int error;

View File

@ -1356,6 +1356,7 @@ _glyph_request_cb(void *data, const void *msg, int size)
for (i = 0; i < nglyphs; i++) for (i = 0; i < nglyphs; i++)
{ {
string_t shm_id;
unsigned int idx, offset, glsize; unsigned int idx, offset, glsize;
int rows, width, pitch, num_grays, pixel_mode; int rows, width, pitch, num_grays, pixel_mode;
CS_Glyph_Out *gl; CS_Glyph_Out *gl;
@ -1366,6 +1367,8 @@ _glyph_request_cb(void *data, const void *msg, int size)
memcpy(&idx, buf, sizeof(int)); memcpy(&idx, buf, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(&shm_id, buf, sizeof(string_t));
buf += sizeof(string_t);
memcpy(&offset, buf, sizeof(int)); memcpy(&offset, buf, sizeof(int));
buf += sizeof(int); buf += sizeof(int);
memcpy(&glsize, buf, sizeof(int)); memcpy(&glsize, buf, sizeof(int));