From 15130078156d849f942fb00c4f37bd708bad0c7b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Fri, 11 Oct 2013 17:18:42 +0900 Subject: [PATCH] evas/cserve2: Merge Glyph_Data and mempool index Glyphs were previously using 3 shared buffers, now reduce to 2: - Memory pool (mempool) containing the glyph drawable data - Index table (Shared_Index / array) containing only the indexes of the buffers in the mempool - Glyph_Data table (array) containing the glyphs descriptors AS WELL as the buffer indexes. So, we just merge the two index tables into one by using directly objects of type Glyph_Data for the referencing of the mempool buffers. --- src/bin/evas/evas_cserve2.h | 3 +- src/bin/evas/evas_cserve2_cache.c | 111 +++++++++++++------------ src/bin/evas/evas_cserve2_fonts.c | 11 ++- src/bin/evas/evas_cserve2_index.c | 26 ++++-- src/bin/evas/evas_cserve2_shm_debug.c | 7 +- src/lib/evas/cserve2/evas_cs2.h | 9 +- src/lib/evas/cserve2/evas_cs2_client.c | 4 +- 7 files changed, 96 insertions(+), 75 deletions(-) diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h index 219bb0d7f7..e49bfc451d 100644 --- a/src/bin/evas/evas_cserve2.h +++ b/src/bin/evas/evas_cserve2.h @@ -381,7 +381,7 @@ void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data, int cserve2_shared_array_foreach(Shared_Array *sa, Eina_Each_Cb cb, void *data); // Shared buffers and memory pools -Shared_Mempool *cserve2_shared_mempool_new(int indextag, int generation_id, int initsize); +Shared_Mempool *cserve2_shared_mempool_new(int indextag, int index_elemsize, int generation_id, int initsize); void cserve2_shared_mempool_del(Shared_Mempool *sm); int cserve2_shared_mempool_buffer_new(Shared_Mempool *sm, int size); int cserve2_shared_mempool_buffer_ref(Shared_Mempool *sm, int bufferid); @@ -392,6 +392,7 @@ size_t cserve2_shared_mempool_size_get(Shared_Mempool *sm); const char *cserve2_shared_mempool_name_get(Shared_Mempool *sm); int cserve2_shared_mempool_generation_id_get(Shared_Mempool *sm); int cserve2_shared_mempool_generation_id_set(Shared_Mempool *sm, int generation_id); +Shared_Array *cserve2_shared_mempool_index_get(Shared_Mempool *sm); // Shared strings const char *cserve2_shared_strings_table_name_get(); diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c index 15ce2c36f4..9f92543919 100644 --- a/src/bin/evas/evas_cserve2_cache.c +++ b/src/bin/evas/evas_cserve2_cache.c @@ -90,7 +90,6 @@ struct _Font_Entry { Font_Source *src; void *ft; // Font_Info Fash_Glyph2 *glyph_entries[3]; // Fast access to the Glyph_Entry objects - Shared_Array *glyph_datas; // Contains the Glyph_Data objects unsigned int nglyphs; Eina_Bool unused : 1; Shared_Mempool *mempool; // Contains the rendered glyphs @@ -139,7 +138,6 @@ struct _File_Watch { static unsigned int _generation_id = 0; static unsigned int _entry_id = 0; -static unsigned int _glyph_id = 0; static unsigned int _font_data_id = 0; static unsigned int _freed_file_entry_count = 0; static unsigned int _freed_image_entry_count = 0; @@ -318,10 +316,12 @@ _font_data_find(unsigned int fs_id) } static Glyph_Data * -_glyph_data_find(Shared_Array *sa, unsigned int glyph_id) +_glyph_data_find(Shared_Mempool *sm, unsigned int glyph_id) { Glyph_Data *gldata; + Shared_Array *sa; + sa = cserve2_shared_mempool_index_get(sm); gldata = cserve2_shared_array_item_data_find(sa, &glyph_id, _shm_object_id_cmp_cb); if (!gldata) @@ -1214,14 +1214,13 @@ _font_entry_key_hash(const Font_Entry *key, int key_length EINA_UNUSED) static int _font_entry_memory_usage_get(Font_Entry *fe) { - int size; + int size = sizeof(Font_Entry); if (!fe) return 0; - if (!fe->mempool && !fe->glyph_datas) - return 0; + if (!fe->mempool) + return size; - size = cserve2_shared_mempool_size_get(fe->mempool); - size += cserve2_shared_array_map_size_get(fe->glyph_datas); + size += cserve2_shared_mempool_size_get(fe->mempool); size += fe->nglyphs * sizeof(Glyph_Entry); return size; @@ -1251,7 +1250,6 @@ _font_entry_free(Font_Entry *fe) for (k = 0; k < 3; k++) fash_gl_free(fe->glyph_entries[k]); - cserve2_shared_array_del(fe->glyph_datas); cserve2_shared_mempool_del(fe->mempool); cserve2_font_ft_free(fe->ft); fe->src->refcount--; @@ -1274,10 +1272,10 @@ _glyph_free_cb(void *data) if (!gl || !gl->fe) return; - gldata = _glyph_data_find(gl->fe->glyph_datas, gl->gldata_id); + gldata = _glyph_data_find(gl->fe->mempool, gl->gldata_id); if (gldata) { - cserve2_shared_string_del(gldata->shm_id); + cserve2_shared_string_del(gldata->mempool_id); gldata->refcount--; } free(gl); @@ -1864,6 +1862,7 @@ static Msg_Font_Glyphs_Loaded * _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) { Msg_Font_Glyphs_Loaded *msg; + Shared_Array *sa; unsigned int size; const char *shmname, *idxname; unsigned int shmname_size, idxname_size; @@ -1871,9 +1870,12 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) char *response, *buf; shmname = cserve2_shared_mempool_name_get(req->fe->mempool); + if (!shmname) return NULL; shmname_size = strlen(shmname) + 1; - idxname = cserve2_shared_array_name_get(req->fe->glyph_datas); + sa = cserve2_shared_mempool_index_get(req->fe->mempool); + idxname = cserve2_shared_array_name_get(sa); + if (!idxname) return NULL; idxname_size = strlen(idxname) + 1; size = sizeof(Msg_Font_Glyphs_Loaded); @@ -1904,7 +1906,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) Glyph_Data *gldata; ge = req->answer[k]; - gldata = _glyph_data_find(ge->fe->glyph_datas, ge->gldata_id); + gldata = _glyph_data_find(ge->fe->mempool, ge->gldata_id); if (!gldata) { ERR("Glyph data not found for %d", ge->gldata_id); @@ -1913,7 +1915,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size) memcpy(buf, &gldata->index, sizeof(int)); buf += sizeof(int); - memcpy(buf, &gldata->shm_id, sizeof(string_t)); + memcpy(buf, &gldata->mempool_id, sizeof(string_t)); buf += sizeof(string_t); memcpy(buf, &gldata->offset, sizeof(int)); buf += sizeof(int); @@ -2112,8 +2114,9 @@ _glyphs_load_request_response(Glyphs_Request *req, { Font_Entry *fe = req->fe; Shared_Mempool *mempool = msg->mempool; + Shared_Array *index; unsigned int j, hint; - string_t shm_id = 0; + string_t shm_id; Font_Data *fd; if (!msg->nglyphs) @@ -2131,14 +2134,12 @@ _glyphs_load_request_response(Glyphs_Request *req, DBG("Font memory usage [begin]: %d / %d", font_mem_usage, max_font_usage); cserve2_shared_mempool_generation_id_set(mempool, _generation_id); - if (!fe->glyph_datas) + index = cserve2_shared_mempool_index_get(mempool); + + if (!fd->glyph_index_shm) { - fe->glyph_datas = cserve2_shared_array_new(GLYPH_INDEX_ARRAY_TAG, - _generation_id, - sizeof(Glyph_Data), 0); - font_mem_usage += cserve2_shared_array_map_size_get(fe->glyph_datas); - fd->glyph_index_shm = cserve2_shared_string_add( - cserve2_shared_array_name_get(fe->glyph_datas)); + fd->glyph_index_shm = cserve2_shared_string_add + (cserve2_shared_array_name_get(index)); } shm_id = cserve2_shared_string_add(cserve2_shared_mempool_name_get(mempool)); @@ -2149,31 +2150,23 @@ _glyphs_load_request_response(Glyphs_Request *req, gl = fash_gl_find(fe->glyph_entries[hint], msg->glyphs[j].index); if (!gl) { - 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); + gldata = _glyph_data_find(mempool, msg->glyphs[j].buffer_id); if (!gldata) { - ERR("Could not create new Glyph_Data!"); + ERR("Could not find Glyph_Data %d", msg->glyphs[j].buffer_id); // TODO: Return error? continue; } gl = calloc(1, sizeof(*gl)); gl->fe = fe; - gl->gldata_id = ++_glyph_id; + gl->gldata_id = gldata->id; - gldata->refcount = 1; - gldata->id = gl->gldata_id; + gldata->mempool_id = cserve2_shared_string_ref(shm_id); gldata->index = msg->glyphs[j].index; - gldata->shm_id = cserve2_shared_string_ref(shm_id); - gldata->buffer_id = msg->glyphs[j].buffer_id; - gldata->offset = msg->glyphs[j].offset; // TODO: Remove? + gldata->offset = msg->glyphs[j].offset; gldata->size = msg->glyphs[j].size; gldata->rows = msg->glyphs[j].rows; gldata->width = msg->glyphs[j].width; @@ -2185,13 +2178,10 @@ _glyphs_load_request_response(Glyphs_Request *req, fe->nglyphs++; fash_gl_add(fe->glyph_entries[hint], gldata->index, gl); - 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; } - cserve2_shared_string_del(shm_id); #ifdef DEBUG_LOAD_TIME @@ -2243,6 +2233,7 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, Font_Entry *fe = data; Msg_Stats *msg = fdata; unsigned int shmsize; + Shared_Array *sa; msg->fonts.fonts_loaded++; if (fe->unused) msg->fonts.fonts_unused++; @@ -2252,8 +2243,12 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, 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); + sa = cserve2_shared_mempool_index_get(fe->mempool); + if (sa) + { + cserve2_shared_array_foreach + (sa, EINA_EACH_CB(_font_requested_size_cb), msg); + } #ifdef DEBUG_LOAD_TIME // accounting fonts load time @@ -2409,6 +2404,7 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, unsigned int len, k, nglyphs; const char *str; char *nglyphs_pos; + Shared_Array *index = NULL; // file str = cserve2_shared_string_get(fe->src->file); @@ -2449,31 +2445,36 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, buf += sizeof(int); // glyph shared index and mempool - if (fe->glyph_datas) - eina_strlcpy(buf, cserve2_shared_array_name_get(fe->glyph_datas), 64); - else - memset(buf, 0, 64); - buf += 64; - if (fe->mempool) - eina_strlcpy(buf, cserve2_shared_mempool_name_get(fe->mempool), 64); + { + index = cserve2_shared_mempool_index_get(fe->mempool); + eina_strlcpy(buf, cserve2_shared_mempool_name_get(fe->mempool), 64); + buf += 64; + eina_strlcpy(buf, cserve2_shared_array_name_get(index), 64); + buf += 64; + } else - memset(buf, 0, 64); - buf += 64; + { + memset(buf, 0, 128); + buf += 128; + } // skip nglyphs for now... nglyphs_pos = buf; buf += sizeof(int); nglyphs = 0; - for (k = 0; k < fe->nglyphs; k++) + if (index) { - Glyph_Data *gd = cserve2_shared_array_item_data_get(fe->glyph_datas, k); - if (!gd || !gd->id) break; + for (k = 0; k < fe->nglyphs; k++) + { + Glyph_Data *gd = cserve2_shared_array_item_data_get(index, k); + if (!gd || !gd->id) break; - nglyphs++; - memcpy(buf, gd, sizeof(*gd)); - buf += sizeof(*gd); + nglyphs++; + memcpy(buf, gd, sizeof(*gd)); + buf += sizeof(*gd); + } } // write real value of nglyphs diff --git a/src/bin/evas/evas_cserve2_fonts.c b/src/bin/evas/evas_cserve2_fonts.c index 51b87fe319..782a9d1ff6 100644 --- a/src/bin/evas/evas_cserve2_fonts.c +++ b/src/bin/evas/evas_cserve2_fonts.c @@ -365,9 +365,15 @@ _font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Glyphs_Loaded *response, return EINA_TRUE; on_error: - // Create invalid entry for this index. + // Create invalid entry for this index. There will be an empty slot in + // the mempool (usually 8 bytes) because we need the Glyph_Data index entry. + ERR("Could not load glyph %d. Creating empty invalid entry.", idx); memset(&response->glyphs[response->nglyphs], 0, sizeof(Slave_Msg_Glyph)); + if (buffer_id > 0) + cserve2_shared_mempool_buffer_del(response->mempool, buffer_id); + buffer_id = cserve2_shared_mempool_buffer_new(response->mempool, 1); response->glyphs[response->nglyphs].index = idx; + response->glyphs[response->nglyphs].buffer_id = buffer_id; response->nglyphs++; return EINA_FALSE; } @@ -480,7 +486,8 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED) { unsigned shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint); response->mempool = cserve2_shared_mempool_new(GLYPH_DATA_ARRAY_TAG, - 0, shmsize); + sizeof(Glyph_Data), 0, + shmsize); if (!response->mempool) return NULL; } diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c index 0a3a6299c6..e6b13ce93e 100644 --- a/src/bin/evas/evas_cserve2_index.c +++ b/src/bin/evas/evas_cserve2_index.c @@ -593,15 +593,20 @@ _shared_index_entry_get_by_id(Shared_Index *si, unsigned int id) } static Shared_Index * -_shared_index_new(int tag, int generation_id) +_shared_index_new(int tag, int index_elemsize, int generation_id) { Shared_Index *si; Index_Entry *ie; + EINA_SAFETY_ON_FALSE_RETURN_VAL(index_elemsize >= 0, NULL); + si = calloc(1, sizeof(Shared_Index)); if (!si) return NULL; - si->sa = cserve2_shared_array_new(tag, generation_id, sizeof(Index_Entry), 0); + if (!index_elemsize) + index_elemsize = sizeof(Index_Entry); + + si->sa = cserve2_shared_array_new(tag, generation_id, index_elemsize, 0); if (!si->sa) { free(si); @@ -632,12 +637,14 @@ _shared_index_del(Shared_Index *si) // Shared memory pool Shared_Mempool * -cserve2_shared_mempool_new(int indextag, int generation_id, int initsize) +cserve2_shared_mempool_new(int indextag, int index_elemsize, + int generation_id, int initsize) { Shared_Mempool *sm; size_t mapping_size; - if (initsize < 0) return NULL; + EINA_SAFETY_ON_FALSE_RETURN_VAL(initsize >= 0, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(index_elemsize >= 0, NULL); sm = calloc(1, sizeof(Shared_Mempool)); if (!sm) return NULL; @@ -652,7 +659,7 @@ cserve2_shared_mempool_new(int indextag, int generation_id, int initsize) return NULL; } - sm->index = _shared_index_new(indextag, generation_id); + sm->index = _shared_index_new(indextag, index_elemsize, generation_id); if (!sm->index) { _shared_data_shm_del(sm->ds); @@ -664,6 +671,13 @@ cserve2_shared_mempool_new(int indextag, int generation_id, int initsize) return sm; } +Shared_Array * +cserve2_shared_mempool_index_get(Shared_Mempool *sm) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(sm, NULL); + return sm->index->sa; +} + static void _shared_mempool_block_del(Eina_Rbtree *node, void *data EINA_UNUSED) { @@ -1043,7 +1057,7 @@ cserve2_shared_index_init(void) int ifaketag = STRING_MEMPOOL_FAKETAG; DBG("Initializing shared index"); - _string_mempool = cserve2_shared_mempool_new(STRING_INDEX_ARRAY_TAG, 0, 0); + _string_mempool = cserve2_shared_mempool_new(STRING_INDEX_ARRAY_TAG, 0, 0, 0); _string_entries = eina_hash_string_djb2_new(NULL); memcpy(faketag, &ifaketag, sizeof(int)); diff --git a/src/bin/evas/evas_cserve2_shm_debug.c b/src/bin/evas/evas_cserve2_shm_debug.c index 8535af45cd..10bb48453e 100644 --- a/src/bin/evas/evas_cserve2_shm_debug.c +++ b/src/bin/evas/evas_cserve2_shm_debug.c @@ -152,11 +152,6 @@ _shm_file_probe(Shm_File *sf) sf_fonts = sf; break; - case GLYPH_INDEX_ARRAY_TAG: - DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); - sf->tag = sf->header->tag; - break; - case GLYPH_DATA_ARRAY_TAG: DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); sf->tag = sf->header->tag; @@ -647,7 +642,7 @@ _glyphs_all_print(Shm_File *sf) printf(" %8u %6u %6u %5u %5u %5u %5u %5u %1u %1u %6u %6u '%s'\n", gd->id, gd->refcount, gd->index, gd->size, gd->rows, gd->width, gd->pitch, gd->num_grays, gd->hint, gd->pixel_mode, gd->buffer_id, - gd->offset, _shared_string_get(gd->shm_id)); + gd->offset, _shared_string_get(gd->mempool_id)); nglyphs++; mem_used += gd->size; diff --git a/src/lib/evas/cserve2/evas_cs2.h b/src/lib/evas/cserve2/evas_cs2.h index 35a0a3177f..a6e59945f2 100644 --- a/src/lib/evas/cserve2/evas_cs2.h +++ b/src/lib/evas/cserve2/evas_cs2.h @@ -379,14 +379,17 @@ struct _Font_Data { uint32_t dpi; }; -#define GLYPH_INDEX_ARRAY_TAG ('G' | 'L' << 8 | 'I' << 16 | 'D' << 24) #define GLYPH_DATA_ARRAY_TAG ('G' | 'L' << 8 | 'P' << 16 | 'H' << 24) struct _Glyph_Data { + // Index_Entry SHMOBJECT; + int32_t length; + int32_t offset; + int32_t shmid; + // Glyph data stuff uint32_t index; - string_t shm_id; + string_t mempool_id; // TODO: Merge with shmid? (Internally impossible atm) uint32_t buffer_id; - uint32_t offset; uint32_t size; uint32_t rows; uint32_t width; diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c index c052c279e5..67c597a0cf 100644 --- a/src/lib/evas/cserve2/evas_cs2_client.c +++ b/src/lib/evas/cserve2/evas_cs2_client.c @@ -597,9 +597,7 @@ static Eina_Bool _server_dispatch_until(unsigned int rid) { Eina_Bool failed; - fd_set rfds; unsigned int rrid; - struct timeval tv; while (1) { @@ -608,6 +606,8 @@ _server_dispatch_until(unsigned int rid) #if TIMEOUT else if (failed) { + fd_set rfds; + struct timeval tv; int sel; if (socketfd == -1)