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;
Fash_Glyph2 *glyphs;
unsigned int nglyphs;
Eina_Inlist *caches;
Eina_List *caches;
Font_Cache *last_cache;
Eina_Bool unused : 1;
#ifdef DEBUG_LOAD_TIME
@ -90,27 +90,18 @@ struct _Font_Entry {
};
struct _Font_Cache {
EINA_INLIST;
Font_Entry *fe;
Shm_Handle *shm;
unsigned int usage;
int inuse;
Eina_Inlist *glyphs;
Shared_Array *glyphs; // Contains gldata_id only
unsigned int nglyphs;
};
struct _Glyph_Entry {
EINA_INLIST;
unsigned int gldata_id;
Font_Entry *fe;
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 {
@ -148,11 +139,13 @@ struct _File_Watch {
};
static unsigned int _entry_id = 0;
static unsigned int _glyph_id = 0;
static unsigned int _freed_file_entry_count = 0;
static unsigned int _freed_image_entry_count = 0;
static Shared_Array *_file_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_entries = NULL; // maps file_id --> entry
@ -303,6 +296,22 @@ _image_entry_find(unsigned int entry_id)
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
_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem,
void *user_data EINA_UNUSED)
@ -1061,6 +1070,12 @@ static void
_glyph_free_cb(void *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);
}
@ -1096,18 +1111,22 @@ _font_shm_size_get(Font_Cache *fc)
static void
_font_shm_free(Font_Cache *fc)
{
Glyph_Data *gd;
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)
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);
fc->glyphs = eina_inlist_remove(fc->glyphs, fc->glyphs);
fash_gl_del(fe->glyphs, gl->index);
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);
}
cserve2_shared_array_del(fc->glyphs);
cserve2_shm_unref(fc->shm);
free(fc);
@ -1161,6 +1180,7 @@ cserve2_cache_init(void)
_file_data_array = cserve2_shared_array_new(1, sizeof(File_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
@ -1182,6 +1202,7 @@ cserve2_cache_shutdown(void)
cserve2_shared_array_del(_file_data_array);
cserve2_shared_array_del(_image_data_array);
cserve2_shared_array_del(_glyph_data_array);
}
static Reference *
@ -1716,7 +1737,7 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
size += sizeof(int);
// nglyphs * (index + offset + size + rows + width + pitch +
// 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);
@ -1743,21 +1764,27 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
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);
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);
memcpy(buf, &gl->size, sizeof(int));
memcpy(buf, &gldata->size, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->rows, sizeof(int));
memcpy(buf, &gldata->rows, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->width, sizeof(int));
memcpy(buf, &gldata->width, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->pitch, sizeof(int));
memcpy(buf, &gldata->pitch, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->num_grays, sizeof(int));
memcpy(buf, &gldata->num_grays, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->pixel_mode, sizeof(int));
memcpy(buf, &gldata->pixel_mode, sizeof(int));
buf += sizeof(int);
}
@ -1955,21 +1982,23 @@ _glyphs_load_request_response(Glyphs_Request *req,
{
unsigned int j;
Slave_Msg_Font_Cache *c = msg->caches[i];
string_t shm_id;
if (!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;
fc->fe = fe;
fc->shm = c->shm;
fc->glyphs = NULL;
fc->glyphs = cserve2_shared_array_new(1, sizeof(int), 0);
fc->nglyphs = 0;
fc->inuse = 0;
font_shm_lru = eina_list_append(font_shm_lru, fc);
font_mem_usage += _font_shm_size_get(fc);
}
fc->usage = c->usage;
shm_id = cserve2_shared_string_add(cserve2_shm_name_get(fc->shm));
for (j = 0; j < c->nglyphs; j++)
{
Glyph_Entry *gl;
@ -1977,27 +2006,41 @@ _glyphs_load_request_response(Glyphs_Request *req,
gl = fash_gl_find(fe->glyphs, c->glyphs[j].index);
if (!gl)
{
int glyph_id, idx, *gldata_id;
Glyph_Data *gldata;
gl = calloc(1, sizeof(*gl));
gl->fe = fe;
gl->fc = fc;
gl->index = c->glyphs[j].index;
gl->offset = c->glyphs[j].offset;
gl->size = c->glyphs[j].size;
gl->rows = c->glyphs[j].rows;
gl->width = c->glyphs[j].width;
gl->pitch = c->glyphs[j].pitch;
gl->num_grays = c->glyphs[j].num_grays;
gl->pixel_mode = c->glyphs[j].pixel_mode;
font_mem_usage += sizeof(*gl);
fc->glyphs = eina_inlist_append(fc->glyphs, EINA_INLIST_GET(gl));
gl->gldata_id = ++_glyph_id;
glyph_id = cserve2_shared_array_item_new(_glyph_data_array);
gldata = cserve2_shared_array_item_data_get(_glyph_data_array,
glyph_id);
gldata->refcount = 1;
gldata->id = gl->gldata_id;
gldata->index = c->glyphs[j].index;
gldata->shm_id = cserve2_shared_string_ref(shm_id);
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++;
fe->nglyphs++;
fash_gl_add(fe->glyphs, gl->index, gl);
fash_gl_add(fe->glyphs, gldata->index, gl);
}
req->answer[req->nanswer++] = gl;
gl->fc->inuse++;
}
cserve2_shared_string_del(shm_id);
free(c); // FIXME: We are freeing this here because we only do a
// simple free on the response message. Later we need to
// 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;
Msg_Stats *msg = fdata;
Eina_List *iter;
Font_Cache *fc;
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++;
// accounting size
EINA_INLIST_FOREACH(fe->caches, fc)
EINA_LIST_FOREACH(fe->caches, iter, fc)
{
unsigned int fc_usage, shmsize;
/* 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;
Font_Entry *fe = data;
Font_Cache *fc;
Eina_List *iter;
const char *str;
// filelen
@ -2195,10 +2240,8 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
// ncaches
size += sizeof(int);
EINA_INLIST_FOREACH(fe->caches, fc)
EINA_LIST_FOREACH(fe->caches, iter, fc)
{
Glyph_Entry *gl;
// shmnamelen + shmname
size += sizeof(int);
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
size += sizeof(int);
EINA_INLIST_FOREACH(fc->glyphs, gl)
{
// index, offset, size
size += 3 * sizeof(int);
// rows, width, pitch
size += 3 * sizeof(int);
// num_grays, pixel_mode
size += 2 * sizeof(int);
}
size += (4 + 3 + 2) * sizeof(int) * fc->nglyphs;
}
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;
Font_Entry *fe = data;
Font_Cache *fc;
Eina_List *iter;
unsigned int len;
unsigned int unused;
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);
// ncaches
ncaches = eina_inlist_count(fe->caches);
ncaches = eina_list_count(fe->caches);
memcpy(buf, &ncaches, 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;
unsigned int shmsize;
unsigned int k;
// shmnamelen + shmname
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));
buf += sizeof(int);
EINA_INLIST_FOREACH(fc->glyphs, gl)
for (k = 0; k < fc->nglyphs; k++)
{
// index, offset, size
memcpy(buf, &gl->index, sizeof(int));
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, &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);
memcpy(buf, &gl->size, sizeof(int));
memcpy(buf, &gldata->size, sizeof(int));
buf += sizeof(int);
// rows, width, pitch
memcpy(buf, &gl->rows, sizeof(int));
memcpy(buf, &gldata->rows, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->width, sizeof(int));
memcpy(buf, &gldata->width, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->pitch, sizeof(int));
memcpy(buf, &gldata->pitch, sizeof(int));
buf += sizeof(int);
// num_grays, pixel_mode
memcpy(buf, &gl->num_grays, sizeof(int));
memcpy(buf, &gldata->num_grays, sizeof(int));
buf += sizeof(int);
memcpy(buf, &gl->pixel_mode, sizeof(int));
memcpy(buf, &gldata->pixel_mode, 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 _File_Data File_Data;
typedef struct _Image_Data Image_Data;
typedef struct _Glyph_Data Glyph_Data;
typedef struct _Shared_Array_Header Shared_Array_Header;
typedef int string_t;
#define SHMOBJECT unsigned int id; unsigned int refcount
struct _Shared_Array_Header
{
struct _Shared_Array_Header {
int32_t tag;
int32_t elemsize;
int32_t count;
@ -303,13 +303,11 @@ struct _Shared_Array_Header
int32_t _reserved2;
};
struct _Shm_Object
{
struct _Shm_Object {
SHMOBJECT;
};
struct _Index_Entry
{
struct _Index_Entry {
SHMOBJECT;
// Block entry
int32_t length;
@ -332,7 +330,7 @@ struct _File_Data {
struct _Image_Data {
SHMOBJECT;
unsigned int file_id;
uint32_t file_id;
string_t shm_id;
Evas_Image_Load_Opts opts;
Eina_Bool alpha_sparse : 1;
@ -340,6 +338,19 @@ struct _Image_Data {
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 {
Msg_Base base;
int error;

View File

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