evas/cserve2: Merge Glyph_Data and mempool index
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 11 Oct 2013 08:18:42 +0000 (17:18 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:16 +0000 (15:47 +0900)
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
src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_fonts.c
src/bin/evas/evas_cserve2_index.c
src/bin/evas/evas_cserve2_shm_debug.c
src/lib/evas/cserve2/evas_cs2.h
src/lib/evas/cserve2/evas_cs2_client.c

index 219bb0d..e49bfc4 100644 (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();
index 15ce2c3..9f92543 100644 (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
index 51b87fe..782a9d1 100644 (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;
      }
 
index 0a3a629..e6b13ce 100644 (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));
index 8535af4..10bb484 100644 (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;
index 35a0a31..a6e5994 100644 (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;
index c052c27..67c597a 100644 (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)