diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h index 88f4370346..badd33c8d6 100644 --- a/src/bin/evas/evas_cserve2.h +++ b/src/bin/evas/evas_cserve2.h @@ -352,6 +352,7 @@ const char *cserve2_shared_array_name_get(Shared_Array *sa); void cserve2_shared_array_del(Shared_Array *sa); int cserve2_shared_array_size_get(Shared_Array *sa); int cserve2_shared_array_count_get(Shared_Array *sa); +int cserve2_shared_array_map_size_get(Shared_Array *sa); int cserve2_shared_array_item_size_get(Shared_Array *sa); int cserve2_shared_array_generation_id_get(Shared_Array *sa); int cserve2_shared_array_size_set(Shared_Array *sa, int newcount); diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index 7c7932ef8a..86fb80464c 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -1080,12 +1080,34 @@ _font_entry_key_hash(const Font_Entry *key, int key_length EINA_UNUSED) return hash; } +static int +_font_entry_memory_usage_get(Font_Entry *fe) +{ + int size; + + if (!fe) return 0; + if (!fe->mempool && !fe->glyph_datas) + return 0; + + size = cserve2_shared_mempool_size_get(fe->mempool); + size += cserve2_shared_array_map_size_get(fe->glyph_datas); + size += fe->nglyphs * sizeof(Glyph_Entry); + + return size; +} + static void _font_entry_free(Font_Entry *fe) { Font_Data *fd; + int size; if (!fe) return; + size = _font_entry_memory_usage_get(fe); + + DBG("Font memory usage down: %d -> %d / %d", font_mem_usage, + font_mem_usage - size, max_font_usage); + font_mem_usage -= size; fd = _font_data_find(fe->font_data_id); if (fd) @@ -1098,6 +1120,7 @@ _font_entry_free(Font_Entry *fe) fash_gl_free(fe->glyph_entries); cserve2_shared_array_del(fe->glyph_datas); + cserve2_shared_mempool_del(fe->mempool); cserve2_font_ft_free(fe->ft); fe->src->refcount--; if (fe->src->refcount <= 0) @@ -1141,79 +1164,49 @@ _font_source_free(Font_Source *fs) free(fs); } -#if 0 static void -_font_shm_promote(Font_Cache *fc) +_font_lru_update(Font_Entry *fe) { Eina_List *l; - l = eina_list_data_find_list(font_shm_lru, fc); - font_shm_lru = eina_list_demote_list(font_shm_lru, l); -} - -static int -_font_shm_size_get(Font_Cache *fc) -{ - int size; - - size = sizeof(*fc) + cserve2_shm_size_get(fc->shm); - - return size; -} - -static void -_font_shm_free(Font_Cache *fc) -{ - Glyph_Data *gd; - Font_Entry *fe = fc->fe; - unsigned int k; - - fe->caches = eina_list_remove(fe->caches, fc); - if (fc == fe->last_cache) - fe->last_cache = NULL; - - for (k = 0; k < fc->nglyphs; k++) + l = eina_list_data_find_list(font_shm_lru, fe); + if (l) { - int *gldata_id = cserve2_shared_array_item_data_get(fc->glyphs, k); - gd = _glyph_data_find(*gldata_id); - fash_gl_del(fe->glyphs, gd->index); + if (fe->unused) + font_shm_lru = eina_list_promote_list(font_shm_lru, l); + else + font_shm_lru = eina_list_demote_list(font_shm_lru, l); } - - cserve2_shared_array_del(fc->glyphs); - cserve2_shm_unref(fc->shm); - free(fc); - - if (!fe->caches) - eina_hash_del_by_key(font_entries, fe); + else + font_shm_lru = eina_list_append(font_shm_lru, fe); } static void -_font_shm_lru_flush(void) +_font_lru_flush(void) { Eina_List *l, *l_next; l = font_shm_lru; l_next = eina_list_next(l); + DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage); + while (l && font_mem_usage > max_font_usage) { - int size; - Font_Cache *fc; + Font_Entry *fe; - fc = eina_list_data_get(l); - if (fc->fe->unused && fc->inuse == 0) + fe = eina_list_data_get(l); + if (fe->unused) { font_shm_lru = eina_list_remove_list(font_shm_lru, l); - size = _font_shm_size_get(fc); - size += fc->nglyphs * sizeof(Glyph_Entry); - _font_shm_free(fc); - font_mem_usage -= size; + eina_hash_del_by_key(font_entries, fe); } l = l_next; l_next = eina_list_next(l); } + + DBG("Font memory usage [end]: %d / %d", font_mem_usage, max_font_usage); } -#endif void cserve2_cache_init(void) @@ -1352,10 +1345,10 @@ _entry_reference_del(Entry *entry, Reference *ref) } else if (entry->type == CSERVE2_FONT_ENTRY) { - Font_Entry *fe = (Font_Entry *)entry; + Font_Entry *fe = (Font_Entry *) entry; fe->unused = EINA_TRUE; - if (!fe->mempool) - eina_hash_del_by_key(font_entries, fe); + _font_lru_update(fe); + _font_lru_flush(); } else ERR("Wrong type of entry."); @@ -1719,150 +1712,6 @@ _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load) return (req->nanswer == req->nglyphs); } -#if 0 -/* organize answer (cache1{gl1, gl2,}, cache2{gl3,gl4,gl5}, cache3{gl6}) - */ -static Eina_List * -_glyphs_group_create(Glyphs_Request *req) -{ - Eina_List *groups = NULL; - unsigned int i; - Glyphs_Group *gg; - - gg = calloc(1, sizeof(*gg)); - groups = eina_list_append(groups, gg); - - for (i = 0; i < req->nanswer; i++) - gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]); - - return groups; - - /* - for (i = 0; i < req->nanswer; i++) - { - Eina_List *l; - Glyphs_Group *iter, *gg = NULL; - Font_Cache *fc = req->answer[i]->fc; - - EINA_LIST_FOREACH(groups, l, iter) - { - if (iter->fc == fc) - { - gg = iter; - break; - } - } - - if (!gg) - { - gg = calloc(1, sizeof(*gg)); - gg->fc = fc; - groups = eina_list_append(groups, gg); - } - gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]); - } - - return groups; - */ -} - -static Msg_Font_Glyphs_Loaded * -_glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) -{ - Msg_Font_Glyphs_Loaded msg; - unsigned int size; - Eina_List *ll, *answers = NULL; - const char *shmname; - unsigned int shmsize; - char *resp, *buf; - Glyphs_Group *iter; - - memset(&msg, 0, sizeof(msg)); - msg.base.type = CSERVE2_FONT_GLYPHS_LOADED; - - answers = _glyphs_group_create(req); - msg.ncaches = eina_list_count(answers); - size = sizeof(msg); - - // calculate size of message - // ncaches * sizeof(cache) + nglyphs1 * sizeof(glyph) + - // nglyphs2 * sizeof(glyph)... - - EINA_LIST_FOREACH(answers, ll, iter) - { - shmname = cserve2_shm_name_get(iter->fc->shm); - shmsize = eina_stringshare_strlen(shmname) + 1; - // shm namelen + name - size += sizeof(int) + shmsize; - - // nglyphs - size += sizeof(int); - // nglyphs * (index + offset + size + rows + width + pitch + - // num_grays + pixel_mode) - size += eina_list_count(iter->glyphs) * 9 * sizeof(int); - } - - resp = malloc(size); - memcpy(resp, &msg, sizeof(msg)); - buf = resp + sizeof(msg); - - EINA_LIST_FREE(answers, iter) - { - Glyph_Entry *gl; - unsigned int nglyphs; - - shmname = cserve2_shm_name_get(iter->fc->shm); - shmsize = eina_stringshare_strlen(shmname) + 1; - memcpy(buf, &shmsize, sizeof(int)); - buf += sizeof(int); - memcpy(buf, shmname, shmsize); - buf += shmsize; - - nglyphs = eina_list_count(iter->glyphs); - memcpy(buf, &nglyphs, sizeof(int)); - buf += sizeof(int); - - iter->fc->inuse -= eina_list_count(iter->glyphs); - - EINA_LIST_FREE(iter->glyphs, gl) - { - // TODO: Factorize memcpy - Glyph_Data *gldata; - - gldata = _glyph_data_find(gl->gldata_id); - memcpy(buf, &gldata->index, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->shm_id, sizeof(string_t)); - buf += sizeof(string_t); - memcpy(buf, &gldata->offset, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->size, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->rows, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->width, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->pitch, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->num_grays, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->pixel_mode, sizeof(int)); - buf += sizeof(int); - } - - /* We are removing SHMs from the beginning of the list, so this - * gives a higher priority to them */ - _font_shm_promote(iter->fc); - eina_list_free(iter->glyphs); - free(iter); - } - - *resp_size = size; - - return (Msg_Font_Glyphs_Loaded *)resp; -} -#endif - static Msg_Font_Glyphs_Loaded * _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) { @@ -2105,11 +1954,19 @@ _glyphs_load_request_response(Glyphs_Request *req, if (!msg->nglyphs) return _glyphs_loaded_msg_create(req, size); + DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage); + if (!mempool) - mempool = cserve2_shared_mempool_new(0); + { + mempool = cserve2_shared_mempool_new(0); + font_mem_usage += cserve2_shared_mempool_size_get(mempool); + } if (!fe->glyph_datas) - fe->glyph_datas = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0); + { + fe->glyph_datas = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0); + font_mem_usage += cserve2_shared_array_map_size_get(fe->glyph_datas); + } shm_id = cserve2_shared_string_add(cserve2_shared_mempool_name_get(mempool)); for (j = 0; j < msg->nglyphs; j++) @@ -2119,9 +1976,11 @@ _glyphs_load_request_response(Glyphs_Request *req, gl = fash_gl_find(fe->glyph_entries, msg->glyphs[j].index); if (!gl) { - int glyph_id; + int glyph_id, orig_mapsize, new_mapsize; Glyph_Data *gldata; + orig_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas); + glyph_id = cserve2_shared_array_item_new(fe->glyph_datas); gldata = cserve2_shared_array_item_data_get(fe->glyph_datas, glyph_id); @@ -2152,7 +2011,9 @@ _glyphs_load_request_response(Glyphs_Request *req, fe->nglyphs++; fash_gl_add(fe->glyph_entries, gldata->index, gl); - font_mem_usage += sizeof(*gl) + sizeof(*gldata); + new_mapsize = cserve2_shared_array_map_size_get(fe->glyph_datas); + font_mem_usage += new_mapsize - orig_mapsize; + font_mem_usage += sizeof(*gl); } req->answer[req->nanswer++] = gl; } @@ -2169,6 +2030,9 @@ _glyphs_load_request_response(Glyphs_Request *req, fe->mempool = mempool; + DBG("Font memory usage [end]: %d / %d", font_mem_usage, max_font_usage); + _font_lru_flush(); + return _glyphs_loaded_msg_create(req, size); } @@ -2185,42 +2049,39 @@ static Slave_Request_Funcs _glyphs_load_funcs = { }; static Eina_Bool -_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) +_font_requested_size_cb(const Eina_Hash *hash EINA_UNUSED, + Glyph_Data *gldata, Msg_Stats *msg) { - // FIXME TODO Must reimplement this + if (gldata->refcount) + msg->fonts.requested_size += gldata->size; -#if 0 + return EINA_TRUE; +} + + +static Eina_Bool +_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, + const void *key EINA_UNUSED, void *data, void *fdata) +{ Font_Entry *fe = data; Msg_Stats *msg = fdata; - Eina_List *iter; - Font_Cache *fc; - int nrefs = eina_list_count(fe->base.references); + unsigned int shmsize; msg->fonts.fonts_loaded++; if (fe->unused) msg->fonts.fonts_unused++; // accounting size - EINA_LIST_FOREACH(fe->caches, iter, fc) - { - unsigned int fc_usage, shmsize; - /* This is not real requested usage, but an approximation. We don't - * know how many times each glyph would be used by each client, but - * assume that a similar set of glyphs from a given font would be used - * by each client, thus counting them one time per client referencing - * them. - */ - fc_usage = fc->usage * nrefs; - shmsize = cserve2_shm_size_get(fc->shm); + shmsize = cserve2_shared_mempool_size_get(fe->mempool); + msg->fonts.real_size += shmsize; + if (fe->unused) msg->fonts.unused_size += shmsize; - msg->fonts.requested_size += fc_usage; - msg->fonts.real_size += shmsize; - if (fe->unused) msg->fonts.unused_size += shmsize; - } + cserve2_shared_array_foreach(fe->glyph_datas, + EINA_EACH_CB(_font_requested_size_cb), msg); #ifdef DEBUG_LOAD_TIME // accounting fonts load time msg->fonts.fonts_load_time += fe->base.load_time; - if (fe->caches) + if (fe->mempool) { msg->fonts.fonts_used_load_time += fe->base.load_time; msg->fonts.fonts_used_saved_time += fe->base.saved_time; @@ -2232,8 +2093,6 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU msg->fonts.glyphs_saved_time += fe->gl_saved_time; msg->fonts.glyphs_request_time += fe->gl_request_time; msg->fonts.glyphs_slave_time += fe->gl_slave_time; -#endif - #endif return EINA_TRUE; @@ -2319,52 +2178,53 @@ struct _debug_info }; static Eina_Bool -_font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) +_font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, + const void *key EINA_UNUSED, void *data, void *fdata) { struct _debug_info *di = fdata; - unsigned int size = di->size; Font_Entry *fe = data; const char *str; // filelen - size += sizeof(int); + di->size+= sizeof(int); // file if (fe->src->file) { str = cserve2_shared_string_get(fe->src->file); - size += strlen(str) + 1; + di->size+= strlen(str) + 1; } // namelen - size += sizeof(int); + di->size+= sizeof(int); // name if (fe->src->name) { str = cserve2_shared_string_get(fe->src->file); - size += strlen(str) + 1; + di->size+= strlen(str) + 1; } - // rend_flags, size, dpi - size += 3 * sizeof(int); + // rend_flags, size, dpi, unused + di->size+= 4 * sizeof(int); - // unused - size += sizeof(int); + // glyph_data_shm and glyph_mempool_shm (short strings) + di->size+= 2 * 64; - // ncaches - size += sizeof(int); + // nglyphs + di->size+= sizeof(int); - size += cserve2_shared_mempool_size_get(fe->mempool); + // glyphs + di->size+= fe->nglyphs * sizeof(Glyph_Data); - di->size = size; di->nfonts++; return EINA_TRUE; } static Eina_Bool -_font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) +_font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, + const void *key EINA_UNUSED, void *data, void *fdata) { char **pos = fdata; char *buf = *pos; @@ -2451,124 +2311,6 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU return EINA_TRUE; } - // FIXME TODO Must reimplement this -#if 0 - - char **pos = fdata; - char *buf = *pos; - Font_Entry *fe = data; - Font_Cache *fc; - Eina_List *iter; - unsigned int len; - unsigned int unused; - unsigned int ncaches; - const char *str; - - // filelen + file - len = 0; - if (fe->src->file) - { - str = cserve2_shared_string_get(fe->src->file); - len = strlen(str) + 1; - } - memcpy(buf, &len, sizeof(int)); - buf += sizeof(int); - if (len) memcpy(buf, cserve2_shared_string_get(fe->src->file), len); - buf += len; - - // namelen + name - len = 0; - if (fe->src->name) - { - str = cserve2_shared_string_get(fe->src->name); - len = strlen(str) + 1; - } - memcpy(buf, &len, sizeof(int)); - buf += sizeof(int); - if (len) memcpy(buf, cserve2_shared_string_get(fe->src->name), len); - buf += len; - - // rend_flags, size, dpi - memcpy(buf, &fe->rend_flags, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &fe->size, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &fe->dpi, sizeof(int)); - buf += sizeof(int); - - // unused - unused = fe->unused; - memcpy(buf, &unused, sizeof(int)); - buf += sizeof(int); - - // ncaches - ncaches = eina_list_count(fe->caches); - memcpy(buf, &ncaches, sizeof(int)); - buf += sizeof(int); - - EINA_LIST_FOREACH(fe->caches, iter, fc) - { - Glyph_Data *gldata; - const char *shmname; - unsigned int shmsize; - unsigned int k; - - // shmnamelen + shmname - shmname = cserve2_shm_name_get(fc->shm); - len = strlen(shmname) + 1; - memcpy(buf, &len, sizeof(int)); - buf += sizeof(int); - memcpy(buf, shmname, len); - buf += len; - - // TODO: Simplify memcpy operations (can be factorized into 1) - - // size, usage, nglyphs - shmsize = cserve2_shm_size_get(fc->shm); - memcpy(buf, &shmsize, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &fc->usage, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &fc->nglyphs, sizeof(int)); - buf += sizeof(int); - - for (k = 0; k < fc->nglyphs; k++) - { - int *gldata_id = cserve2_shared_array_item_data_get( - fc->glyphs, fc->nglyphs); - gldata = _glyph_data_find(*gldata_id); - - // index, shm_id, offset, size - memcpy(buf, &gldata->index, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->shm_id, sizeof(string_t)); - buf += sizeof(string_t); - memcpy(buf, &gldata->offset, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->size, sizeof(int)); - buf += sizeof(int); - - // rows, width, pitch - memcpy(buf, &gldata->rows, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->width, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->pitch, sizeof(int)); - buf += sizeof(int); - - // num_grays, pixel_mode - memcpy(buf, &gldata->num_grays, sizeof(int)); - buf += sizeof(int); - memcpy(buf, &gldata->pixel_mode, sizeof(int)); - buf += sizeof(int); - } - } - - *pos = buf; - return EINA_TRUE; -#endif -} - static void * _cserve2_cache_font_debug(unsigned int rid, unsigned int *size) { @@ -2582,27 +2324,24 @@ _cserve2_cache_font_debug(unsigned int rid, unsigned int *size) msg.base.type = CSERVE2_FONT_DEBUG; msg.base.rid = rid; + eina_strlcpy(msg.fonts_index_path, + cserve2_shared_array_name_get(_font_data_array), + sizeof(msg.fonts_index_path)); - // First calculate how much size is needed for this message: - - // nfonts - di.size += sizeof(unsigned int); - - // size needed for each font entry + // First calculate how much size is needed for this message eina_hash_foreach(font_entries, _font_entry_debug_size_cb, &di); // Now really create the message buf = malloc(di.size); pos = buf; + // nfonts + msg.nfonts = di.nfonts; + // msg base memcpy(buf, &msg, sizeof(msg)); pos += sizeof(msg); - // nfonts - memcpy(pos, &di.nfonts, sizeof(unsigned int)); - pos += sizeof(unsigned int); - eina_hash_foreach(font_entries, _font_entry_debug_cb, &pos); *size = di.size; @@ -3072,6 +2811,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name, _entry_load_reused(&fe->base); fe->unused = EINA_FALSE; + _font_lru_update(fe); if (fe->base.request) cserve2_request_waiter_add(fe->base.request, rid, client); @@ -3090,6 +2830,7 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name, ref = _entry_reference_add((Entry *)fe, client, 0); client->fonts.referencing = eina_list_append(client->fonts.referencing, ref); fe->unused = EINA_FALSE; + _font_lru_update(fe); fs = _cserve2_font_source_find(fullname); if (!fs) @@ -3204,12 +2945,6 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source, unsigned int nglyphs, unsigned int rid EINA_UNUSED) { - // FIXME TODO: Must reimplement this - return 0; - -#if 0 - Glyphs_Group *gg; - Eina_List *groups; Glyphs_Request *req; DBG("Received report of used glyphs from client %d", client->id); @@ -3221,22 +2956,12 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source, return 0; } - _glyphs_request_check(req, EINA_FALSE); - groups = _glyphs_group_create(req); - - // Promote SHMs which are still cached and in use - // TODO: We can use later the information from request_prepare to preload - // glyphs which are not cached anymore, but are in use on the client. - EINA_LIST_FREE(groups, gg) - { - //_font_shm_promote(gg->fc); - eina_list_free(gg->glyphs); - free(gg); - } + // TODO: We could finetune based on which glyphs exactly are used. + req->fe->unused = EINA_FALSE; + _font_lru_update(req->fe); _glyphs_request_free(req); return 0; -#endif } void diff --git a/src/bin/evas/evas_cserve2_debug.c b/src/bin/evas/evas_cserve2_debug.c index e68e1138fc..10b9d5c92f 100644 --- a/src/bin/evas/evas_cserve2_debug.c +++ b/src/bin/evas/evas_cserve2_debug.c @@ -177,8 +177,6 @@ _debug_msg_send(void) } typedef struct _Font_Entry Font_Entry; -typedef struct _Cache_Entry Cache_Entry; -typedef struct _Glyph_Entry Glyph_Entry; struct _Font_Entry { @@ -188,27 +186,9 @@ struct _Font_Entry unsigned int size; unsigned int dpi; unsigned int unused; - Eina_List *caches; -}; - -struct _Cache_Entry -{ - const char *shmname; - unsigned int size; - unsigned int usage; - Eina_List *glyphs; -}; - -struct _Glyph_Entry -{ - 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; + char glyph_data_shm[64]; + char glyph_mempool_shm[64]; + Eina_List *glyphs; // Glyph_Data }; #define READIT(_dst, _src) \ @@ -217,6 +197,7 @@ struct _Glyph_Entry _src += sizeof(_dst); \ } while(0) +#if 0 static Glyph_Entry * _parse_glyph_entry(char **msg) { @@ -267,6 +248,7 @@ _parse_cache_entry(char **msg) return ce; } +#endif static Font_Entry * _parse_font_entry(char **msg) @@ -291,12 +273,18 @@ _parse_font_entry(char **msg) READIT(fe->dpi, buf); READIT(fe->unused, buf); + eina_strlcpy(fe->glyph_data_shm, buf, 64); + buf += 64; + eina_strlcpy(fe->glyph_mempool_shm, buf, 64); + buf += 64; + READIT(n, buf); while (n--) { - Cache_Entry *ce; - ce = _parse_cache_entry(&buf); - fe->caches = eina_list_append(fe->caches, ce); + Glyph_Data *gd = calloc(1, sizeof(Glyph_Data)); + memcpy(gd, buf, sizeof(Glyph_Data)); + buf += sizeof(Glyph_Data); + fe->glyphs = eina_list_append(fe->glyphs, gd); } *msg = buf; @@ -307,7 +295,7 @@ _parse_font_entry(char **msg) static Eina_List * _debug_msg_read(void) { - Msg_Base *msg = NULL; + Msg_Font_Debug *msg = NULL; char *buf; int size; unsigned int nfonts; @@ -317,16 +305,16 @@ _debug_msg_read(void) while (!msg) msg = _server_read(&size); - if (msg->type != CSERVE2_FONT_DEBUG) + if (msg->base.type != CSERVE2_FONT_DEBUG) { - ERR("Invalid message received from server." + ERR("Invalid message received from server. " "Something went badly wrong."); return NULL; } buf = (char *)msg + sizeof(*msg); - READIT(nfonts, buf); + nfonts = msg->nfonts; while (nfonts--) { Font_Entry *fe; @@ -334,34 +322,18 @@ _debug_msg_read(void) fonts = eina_list_append(fonts, fe); } + printf("Font index table: %s\n", msg->fonts_index_path); + printf("Contains %u fonts\n\n", msg->nfonts); return fonts; } -static void -_glyph_entry_free(Glyph_Entry *ge) -{ - free(ge); -} - -static void -_cache_entry_free(Cache_Entry *ce) -{ - Glyph_Entry *ge; - - EINA_LIST_FREE(ce->glyphs, ge) - _glyph_entry_free(ge); - - eina_stringshare_del(ce->shmname); - free(ce); -} - static void _font_entry_free(Font_Entry *fe) { - Cache_Entry *ce; + Glyph_Data *gd; - EINA_LIST_FREE(fe->caches, ce) - _cache_entry_free(ce); + EINA_LIST_FREE(fe->glyphs, gd) + free(gd); eina_stringshare_del(fe->name); eina_stringshare_del(fe->file); @@ -369,7 +341,7 @@ _font_entry_free(Font_Entry *fe) } static void -_glyph_entry_print(Glyph_Entry *ge) +_glyph_data_print(Glyph_Data *gd) { const char *pxmode[] = { "FT_PIXEL_MODE_NONE", @@ -380,29 +352,18 @@ _glyph_entry_print(Glyph_Entry *ge) "FT_PIXEL_MODE_LCD", "FT_PIXEL_MODE_LCD_V" }; - printf("\t\tGLYPH %u offset: %u size: %u %ux%u pitch: %u grays: %u " - "pixel mode: %s\n", - ge->index, ge->offset, ge->size, ge->width, ge->rows, ge->pitch, - ge->num_grays, pxmode[ge->pixel_mode]); -} - -static void -_cache_entry_print(Cache_Entry *ce) -{ - Eina_List *l; - Glyph_Entry *ge; - - printf("\tSHM %s used %u/%u\n", ce->shmname, ce->usage, ce->size); - - EINA_LIST_FOREACH(ce->glyphs, l, ge) - _glyph_entry_print(ge); + printf(" GLYPH id: %-4u refcount %-2u: index: %-6u offset: %-6u size: %-3u " + "%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s\n", + gd->id, gd->refcount, gd->index, gd->offset, gd->size, + gd->width, gd->rows, gd->pitch, + gd->num_grays, pxmode[gd->pixel_mode]); } static void _font_entry_print(Font_Entry *fe) { Eina_List *l; - Cache_Entry *ce; + Glyph_Data *gd; printf("FONT %s:%s size: %u dpi: %u %s%s%s %s\n", fe->file, fe->name, fe->size, fe->dpi, @@ -410,18 +371,46 @@ _font_entry_print(Font_Entry *fe) fe->rend_flags & 1 ? "SLANT " : "", fe->rend_flags & 2 ? "WEIGHT" : "", fe->unused ? "(unused)" : ""); + printf(" Index: %s\n" + " Mempool: %s\n" + " Glyph count: %u\n", + fe->glyph_data_shm, fe->glyph_mempool_shm, + eina_list_count(fe->glyphs)); - EINA_LIST_FOREACH(fe->caches, l, ce) - _cache_entry_print(ce); + EINA_LIST_FOREACH(fe->glyphs, l, gd) + _glyph_data_print(gd); putchar('\n'); } +static void +_shared_index_print(Msg_Index_List *msg, size_t size) +{ + if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST) + { + ERR("Invalid message received from server. " + "Something went wrong."); + return; + } + + printf("Printing shared indexes status.\n"); + printf("===============================\n\n"); + printf("Generation ID: %-4d\n", msg->generation_id); + printf("Strings entries path: %s\n", msg->strings_entries_path); + printf("Strings index path: %s\n", msg->strings_index_path); + printf("Files index path: %s\n", msg->files_index_path); + printf("Images index path: %s\n", msg->images_index_path); + printf("Fonts index path: %s\n", msg->fonts_index_path); + printf("\n\n\n"); +} + int main(void) { Eina_List *fonts; Font_Entry *fe; + Msg_Index_List *msg = NULL; + int size; eina_init(); _evas_cserve2_debug_log_dom = eina_log_domain_register @@ -431,6 +420,11 @@ main(void) ERR("Could not connect to server."); return -1; } + + while (!msg) + msg = _server_read(&size); + _shared_index_print(msg, size); + _debug_msg_send(); fonts = _debug_msg_read(); EINA_LIST_FREE(fonts, fe) diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c index 7c3f176d89..ec63660493 100644 --- a/src/bin/evas/evas_cserve2_index.c +++ b/src/bin/evas/evas_cserve2_index.c @@ -292,6 +292,13 @@ cserve2_shared_array_count_get(Shared_Array *sa) return sa->header->emptyidx; } +int +cserve2_shared_array_map_size_get(Shared_Array *sa) +{ + if (!sa || !sa->ds) return 0; + return cserve2_shm_map_size_get(sa->ds->shm); +} + int cserve2_shared_array_item_size_get(Shared_Array *sa) { @@ -841,7 +848,8 @@ size_t cserve2_shared_mempool_size_get(Shared_Mempool *sm) { if (!sm) return 0; - return cserve2_shm_map_size_get(sm->ds->shm); + return cserve2_shm_map_size_get(sm->ds->shm) + + cserve2_shared_array_map_size_get(sm->index->sa); } const char * diff --git a/src/bin/evas/evas_cserve2_usage.c b/src/bin/evas/evas_cserve2_usage.c index bcf0cdd7d0..3ab78a8383 100644 --- a/src/bin/evas/evas_cserve2_usage.c +++ b/src/bin/evas/evas_cserve2_usage.c @@ -176,48 +176,81 @@ _usage_msg_send(void) } } +static void +_shared_index_print(Msg_Base *data, size_t size) +{ + Msg_Index_List *msg = (Msg_Index_List *) data; + + if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST) + { + ERR("Invalid message received from server. " + "Something went wrong."); + return; + } + + printf("Printing shared indexes status.\n"); + printf("===============================\n\n"); + printf("Generation ID: %-4d\n", msg->generation_id); + printf("Strings entries path: %s\n", msg->strings_entries_path); + printf("Strings index path: %s\n", msg->strings_index_path); + printf("Files index path: %s\n", msg->files_index_path); + printf("Images index path: %s\n", msg->images_index_path); + printf("Fonts index path: %s\n", msg->fonts_index_path); + printf("\n\n\n"); +} + static void _usage_msg_read(void) { - Msg_Stats *msg = NULL; + Msg_Stats *stats = NULL; int size; printf("Requesting server statistics.\n\n"); - while (!msg) - msg = _server_read(&size); - if (msg->base.type != CSERVE2_STATS) + while (!stats) { - ERR("Invalid message received from server." - "Something went badly wrong."); - return; + Msg_Base *msg = _server_read(&size); + if (!msg) continue; + switch (msg->type) + { + case CSERVE2_INDEX_LIST: + _shared_index_print(msg, size); + break; + case CSERVE2_STATS: + stats = (Msg_Stats *) msg; + break; + default: + ERR("Invalid message received from server. " + "Something went badly wrong."); + return; + } } printf("Printing server usage.\n"); printf("======================\n\n"); printf("\nImage Usage Statistics:\n"); printf("----------------------\n\n"); - printf("Image headers usage: %d bytes\n", msg->images.files_size); - printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024); - printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024); - printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024); - printf("Image headers load time: %dus\n", msg->images.files_load_time); - printf("Image headers saved time: %dus\n", msg->images.files_saved_time); - printf("Image data load time: %dus\n", msg->images.images_load_time); - printf("Image data saved time: %dus\n", msg->images.images_saved_time); + printf("Image headers usage: %d bytes\n", stats->images.files_size); + printf("Image data requested: %d kbytes\n", stats->images.requested_size / 1024); + printf("Image data usage: %d kbytes\n", stats->images.images_size / 1024); + printf("Image data unused: %d kbytes\n", stats->images.unused_size / 1024); + printf("Image headers load time: %dus\n", stats->images.files_load_time); + printf("Image headers saved time: %dus\n", stats->images.files_saved_time); + printf("Image data load time: %dus\n", stats->images.images_load_time); + printf("Image data saved time: %dus\n", stats->images.images_saved_time); printf("\nFont Usage Statistics:\n"); printf("----------------------\n\n"); - printf("Requested usage: %d bytes\n", msg->fonts.requested_size); - printf("Real usage: %d bytes\n", msg->fonts.real_size); - printf("Unused size: %d bytes\n", msg->fonts.unused_size); - printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time); - printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time); - printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time); - printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time); - printf("Glyphs render time: %dus\n", msg->fonts.glyphs_render_time); - printf("Glyphs saved time: %dus\n", msg->fonts.glyphs_saved_time); - printf("Glyphs request time: %dus\n", msg->fonts.glyphs_request_time); - printf("Glyphs slave time: %dus\n", msg->fonts.glyphs_slave_time); + printf("Requested usage: %d bytes\n", stats->fonts.requested_size); + printf("Real usage: %d bytes\n", stats->fonts.real_size); + printf("Unused size: %d bytes\n", stats->fonts.unused_size); + printf("Fonts load time: %dus\n", stats->fonts.fonts_load_time); + printf("Fonts used load time: %dus\n", stats->fonts.fonts_used_load_time); + printf("Fonts used saved time: %dus\n", stats->fonts.fonts_used_saved_time); + printf("Glyphs load time: %dus\n", stats->fonts.glyphs_load_time); + printf("Glyphs render time: %dus\n", stats->fonts.glyphs_render_time); + printf("Glyphs saved time: %dus\n", stats->fonts.glyphs_saved_time); + printf("Glyphs request time: %dus\n", stats->fonts.glyphs_request_time); + printf("Glyphs slave time: %dus\n", stats->fonts.glyphs_slave_time); printf("\n"); } diff --git a/src/lib/evas/cserve2/evas_cs2.h b/src/lib/evas/cserve2/evas_cs2.h index b233be6c2e..32e70a7863 100644 --- a/src/lib/evas/cserve2/evas_cs2.h +++ b/src/lib/evas/cserve2/evas_cs2.h @@ -231,6 +231,7 @@ struct _Msg_Stats { * * Content of the message follows: * + * * char fonts_index_path[64] * * number of font entries; * * each font entry: * - unsigned int filelen @@ -241,15 +242,15 @@ struct _Msg_Stats { * - unsigned int size; * - unsigned int dpi; * - unsigned int unused; - * - ncaches: - * - each cache: - * * usigned int shmnamelen; - * * const char shmname; - * * unsigned int size; - * * unsigned int usage; - * * unsigned int nglyphs; - * * each glyph: + * - const char glyph_data_shm[64]; + * - const char glyph_mempool_shm[64]; + * - unsigned int nglyphs; + * - each glyph: Glyph_Data struct + * - unsigned int id; + * - unsigned int refcount; * - unsigned int index; + * - unsigned int shm_id; // shared string id + * - unsigned int buffer_id; * - unsigned int offset; * - unsigned int size; * - unsigned int rows; @@ -260,6 +261,8 @@ struct _Msg_Stats { */ struct _Msg_Font_Debug { Msg_Base base; + char fonts_index_path[64]; + int nfonts; }; /**