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.
This commit is contained in:
Jean-Philippe Andre 2013-10-11 17:18:42 +09:00
parent 7b62d77cf5
commit 1513007815
7 changed files with 96 additions and 75 deletions

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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)