summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-08-19 12:22:19 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-10-28 15:47:14 +0900
commit467b1b17395cf712ee4ec1ac4a3cef710370ed6d (patch)
tree7fa5098167eb0bb85149276ed716258c61212610 /src/bin
parentc7515f3300157419c42d8a9d224c46babebae37c (diff)
evas/cserve2: Store Glyph_Data in shared mempools
- Create one Glyph_Data array per Font_Entry - Copy Font_Source descriptors in shared array - Copy font entries in shared index - Send font index path over socket - Merge Font_Source and Font_Data in shared memory - Send font index path on client connect - Repack font index after free - Pass font shm name to clients
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/evas/evas_cserve2.h27
-rw-r--r--src/bin/evas/evas_cserve2_cache.c530
-rw-r--r--src/bin/evas/evas_cserve2_fonts.c118
-rw-r--r--src/bin/evas/evas_cserve2_index.c14
-rw-r--r--src/bin/evas/evas_cserve2_main.c4
5 files changed, 445 insertions, 248 deletions
diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h
index 02ee9664c0..88f4370346 100644
--- a/src/bin/evas/evas_cserve2.h
+++ b/src/bin/evas/evas_cserve2.h
@@ -62,6 +62,8 @@ extern Eina_Prefix *_evas_cserve2_pfx;
62typedef struct _Slave Slave; 62typedef struct _Slave Slave;
63typedef struct _Slave_Thread_Data Slave_Thread_Data; 63typedef struct _Slave_Thread_Data Slave_Thread_Data;
64typedef struct _Shm_Handle Shm_Handle; 64typedef struct _Shm_Handle Shm_Handle;
65typedef struct _Shared_Array Shared_Array;
66typedef struct _Shared_Mempool Shared_Mempool;
65 67
66typedef enum { 68typedef enum {
67 FD_READ = 1, 69 FD_READ = 1,
@@ -172,14 +174,13 @@ struct _Slave_Msg_Font_Glyphs_Load {
172 unsigned int *glyphs; 174 unsigned int *glyphs;
173 } glyphs; 175 } glyphs;
174 struct { 176 struct {
175 Shm_Handle *shm; 177 Shared_Mempool *mempool;
176 unsigned int usage;
177 unsigned int nglyphs;
178 } cache; 178 } cache;
179}; 179};
180 180
181struct _Slave_Msg_Glyph { 181struct _Slave_Msg_Glyph {
182 unsigned int index; 182 unsigned int index;
183 unsigned int buffer_id;
183 unsigned int offset; 184 unsigned int offset;
184 unsigned int size; 185 unsigned int size;
185 unsigned int rows; 186 unsigned int rows;
@@ -191,21 +192,13 @@ struct _Slave_Msg_Glyph {
191 192
192typedef struct _Slave_Msg_Glyph Slave_Msg_Glyph; 193typedef struct _Slave_Msg_Glyph Slave_Msg_Glyph;
193 194
194struct _Slave_Msg_Font_Cache {
195 unsigned int nglyphs;
196 Slave_Msg_Glyph *glyphs;
197 Shm_Handle *shm;
198 unsigned int usage;
199};
200
201typedef struct _Slave_Msg_Font_Cache Slave_Msg_Font_Cache;
202
203struct _Slave_Msg_Font_Glyphs_Loaded { 195struct _Slave_Msg_Font_Glyphs_Loaded {
204 unsigned int ncaches; 196 Shared_Mempool *mempool;
205 unsigned int gl_load_time; 197 unsigned int gl_load_time;
206 unsigned int gl_render_time; 198 unsigned int gl_render_time;
207 unsigned int gl_slave_time; 199 unsigned int gl_slave_time;
208 Slave_Msg_Font_Cache **caches; 200 Slave_Msg_Glyph *glyphs;
201 unsigned int nglyphs;
209}; 202};
210 203
211typedef struct _Slave_Msg_Font_Load Slave_Msg_Font_Load; 204typedef struct _Slave_Msg_Font_Load Slave_Msg_Font_Load;
@@ -349,8 +342,6 @@ void cserve2_font_ft_free(void *fontinfo);
349void cserve2_shared_index_init(void); 342void cserve2_shared_index_init(void);
350void cserve2_shared_index_shutdown(void); 343void cserve2_shared_index_shutdown(void);
351 344
352typedef struct _Shared_Array Shared_Array;
353typedef struct _Shared_Mempool Shared_Mempool;
354typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *sa, 345typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *sa,
355 const void *elem, 346 const void *elem,
356 void *user_data); 347 void *user_data);
@@ -382,7 +373,9 @@ int cserve2_shared_mempool_buffer_new(Shared_Mempool *sm, int size);
382int cserve2_shared_mempool_buffer_ref(Shared_Mempool *sm, int bufferid); 373int cserve2_shared_mempool_buffer_ref(Shared_Mempool *sm, int bufferid);
383void cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid); 374void cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid);
384void *cserve2_shared_mempool_buffer_get(Shared_Mempool *sm, int bufferid); 375void *cserve2_shared_mempool_buffer_get(Shared_Mempool *sm, int bufferid);
385 376int cserve2_shared_mempool_buffer_offset_get(Shared_Mempool *sm, int bufferid);
377size_t cserve2_shared_mempool_size_get(Shared_Mempool *sm);
378const char *cserve2_shared_mempool_name_get(Shared_Mempool *sm);
386 379
387// Shared strings 380// Shared strings
388const char *cserve2_shared_strings_table_name_get(); 381const 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 efe90be849..7c7932ef8a 100644
--- a/src/bin/evas/evas_cserve2_cache.c
+++ b/src/bin/evas/evas_cserve2_cache.c
@@ -26,7 +26,6 @@ typedef struct _File_Watch File_Watch;
26 26
27typedef struct _Font_Source Font_Source; 27typedef struct _Font_Source Font_Source;
28typedef struct _Font_Entry Font_Entry; 28typedef struct _Font_Entry Font_Entry;
29typedef struct _Font_Cache Font_Cache;
30 29
31typedef enum { 30typedef enum {
32 CSERVE2_IMAGE_FILE, 31 CSERVE2_IMAGE_FILE,
@@ -62,22 +61,23 @@ struct _Font_Source {
62 string_t key; 61 string_t key;
63 string_t name; 62 string_t name;
64 string_t file; 63 string_t file;
65 int references; 64 int refcount;
66 void *ft; 65 void *ft; // Font_Source_Info
67}; 66};
68 67
69struct _Font_Entry { 68struct _Font_Entry {
70 Entry base; 69 ENTRY;
71 unsigned int rend_flags; 70 unsigned int rend_flags;
72 unsigned int size; 71 unsigned int size;
73 unsigned int dpi; 72 unsigned int dpi;
73 unsigned int font_data_id;
74 Font_Source *src; 74 Font_Source *src;
75 void *ft; 75 void *ft; // Font_Info
76 Fash_Glyph2 *glyphs; 76 Fash_Glyph2 *glyph_entries; // Fast access to the Glyph_Entry objects
77 Shared_Array *glyph_datas; // Contains the Glyph_Data objects
77 unsigned int nglyphs; 78 unsigned int nglyphs;
78 Eina_List *caches;
79 Font_Cache *last_cache;
80 Eina_Bool unused : 1; 79 Eina_Bool unused : 1;
80 Shared_Mempool *mempool; // Contains the rendered glyphs
81#ifdef DEBUG_LOAD_TIME 81#ifdef DEBUG_LOAD_TIME
82 struct timeval rstart; // start of the glyphs load request 82 struct timeval rstart; // start of the glyphs load request
83 struct timeval rfinish; // finish of the glyphs load request 83 struct timeval rfinish; // finish of the glyphs load request
@@ -89,19 +89,9 @@ struct _Font_Entry {
89#endif 89#endif
90}; 90};
91 91
92struct _Font_Cache {
93 Font_Entry *fe;
94 Shm_Handle *shm;
95 unsigned int usage;
96 int inuse;
97 Shared_Array *glyphs; // Contains gldata_id only
98 unsigned int nglyphs;
99};
100
101struct _Glyph_Entry { 92struct _Glyph_Entry {
102 unsigned int gldata_id; 93 unsigned int gldata_id;
103 Font_Entry *fe; 94 Font_Entry *fe;
104 Font_Cache *fc;
105}; 95};
106 96
107struct _Glyphs_Request { 97struct _Glyphs_Request {
@@ -119,13 +109,6 @@ struct _Glyphs_Request {
119 109
120typedef struct _Glyphs_Request Glyphs_Request; 110typedef struct _Glyphs_Request Glyphs_Request;
121 111
122struct _Glyphs_Group {
123 Font_Cache *fc;
124 Eina_List *glyphs;
125};
126
127typedef struct _Glyphs_Group Glyphs_Group;
128
129struct _Reference { 112struct _Reference {
130 Client *client; 113 Client *client;
131 Entry *entry; 114 Entry *entry;
@@ -140,12 +123,15 @@ struct _File_Watch {
140 123
141static unsigned int _entry_id = 0; 124static unsigned int _entry_id = 0;
142static unsigned int _glyph_id = 0; 125static unsigned int _glyph_id = 0;
126static unsigned int _font_data_id = 0;
143static unsigned int _freed_file_entry_count = 0; 127static unsigned int _freed_file_entry_count = 0;
144static unsigned int _freed_image_entry_count = 0; 128static unsigned int _freed_image_entry_count = 0;
129static unsigned int _freed_font_entry_count = 0;
130static Eina_Bool _shutdown = EINA_FALSE;
145 131
146static Shared_Array *_file_data_array = NULL; 132static Shared_Array *_file_data_array = NULL;
147static Shared_Array *_image_data_array = NULL; 133static Shared_Array *_image_data_array = NULL;
148static Shared_Array *_glyph_data_array = NULL; 134static Shared_Array *_font_data_array = NULL;
149 135
150static Eina_Hash *file_ids = NULL; // maps path + key --> file_id 136static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
151static Eina_Hash *file_entries = NULL; // maps file_id --> entry 137static Eina_Hash *file_entries = NULL; // maps file_id --> entry
@@ -296,12 +282,28 @@ _image_entry_find(unsigned int entry_id)
296 return (Image_Entry *) e; 282 return (Image_Entry *) e;
297} 283}
298 284
285static Font_Data *
286_font_data_find(unsigned int fs_id)
287{
288 Font_Data *fdata;
289
290 fdata = cserve2_shared_array_item_data_find(_font_data_array,
291 &fs_id, _shm_object_id_cmp_cb);
292 if (!fdata)
293 {
294 ERR("Could not find font data %u", fs_id);
295 return NULL;
296 }
297
298 return fdata;
299}
300
299static Glyph_Data * 301static Glyph_Data *
300_glyph_data_find(unsigned int glyph_id) 302_glyph_data_find(Shared_Array *sa, unsigned int glyph_id)
301{ 303{
302 Glyph_Data *gldata; 304 Glyph_Data *gldata;
303 305
304 gldata = cserve2_shared_array_item_data_find(_glyph_data_array, &glyph_id, 306 gldata = cserve2_shared_array_item_data_find(sa, &glyph_id,
305 _shm_object_id_cmp_cb); 307 _shm_object_id_cmp_cb);
306 if (!gldata) 308 if (!gldata)
307 { 309 {
@@ -327,6 +329,9 @@ _repack()
327 int count; 329 int count;
328 Eina_Bool updated = EINA_FALSE; 330 Eina_Bool updated = EINA_FALSE;
329 331
332 if (_shutdown)
333 return;
334
330 // Repack when we have 10% fragmentation over the whole shm buffer 335 // Repack when we have 10% fragmentation over the whole shm buffer
331 336
332 count = cserve2_shared_array_size_get(_file_data_array); 337 count = cserve2_shared_array_size_get(_file_data_array);
@@ -341,7 +346,7 @@ _repack()
341 _shm_object_id_cmp_cb, NULL); 346 _shm_object_id_cmp_cb, NULL);
342 if (!sa) 347 if (!sa)
343 { 348 {
344 ERR("Failed to repack array. Keeping previous references!"); 349 ERR("Failed to repack files array. Keeping previous references!");
345 goto skip_files; 350 goto skip_files;
346 } 351 }
347 352
@@ -364,7 +369,7 @@ skip_files:
364 _shm_object_id_cmp_cb, NULL); 369 _shm_object_id_cmp_cb, NULL);
365 if (!sa) 370 if (!sa)
366 { 371 {
367 ERR("Failed to repack array. Keeping previous references!"); 372 ERR("Failed to repack images array. Keeping previous references!");
368 goto skip_images; 373 goto skip_images;
369 } 374 }
370 375
@@ -375,12 +380,35 @@ skip_files:
375 } 380 }
376skip_images: 381skip_images:
377 382
383 count = cserve2_shared_array_size_get(_font_data_array);
384 if ((count > 0) && (_freed_font_entry_count > 100 ||
385 ((_freed_font_entry_count * 100) / count >= 10)))
386 {
387 DBG("Repacking font data array: %s",
388 cserve2_shared_array_name_get(_font_data_array));
389
390 sa = cserve2_shared_array_repack(_font_data_array,
391 _repack_skip_cb,
392 _shm_object_id_cmp_cb, NULL);
393 if (!sa)
394 {
395 ERR("Failed to repack fonts array. Keeping previous references!");
396 goto skip_fonts;
397 }
398
399 cserve2_shared_array_del(_font_data_array);
400 _freed_font_entry_count = 0;
401 _font_data_array = sa;
402 updated = EINA_TRUE;
403 }
404skip_fonts:
405
378 if (updated) 406 if (updated)
379 cserve2_index_list_send(cserve2_shared_strings_index_name_get(), 407 cserve2_index_list_send(cserve2_shared_strings_index_name_get(),
380 cserve2_shared_strings_table_name_get(), 408 cserve2_shared_strings_table_name_get(),
381 cserve2_shared_array_name_get(_file_data_array), 409 cserve2_shared_array_name_get(_file_data_array),
382 cserve2_shared_array_name_get(_image_data_array), 410 cserve2_shared_array_name_get(_image_data_array),
383 NULL, 411 cserve2_shared_array_name_get(_font_data_array),
384 NULL); 412 NULL);
385} 413}
386 414
@@ -1055,15 +1083,32 @@ _font_entry_key_hash(const Font_Entry *key, int key_length EINA_UNUSED)
1055static void 1083static void
1056_font_entry_free(Font_Entry *fe) 1084_font_entry_free(Font_Entry *fe)
1057{ 1085{
1058 fash_gl_free(fe->glyphs); 1086 Font_Data *fd;
1059 fe->src->references--; 1087
1060 if (fe->ft) cserve2_font_ft_free(fe->ft); 1088 if (!fe) return;
1061 if (fe->src->references <= 0) 1089
1090 fd = _font_data_find(fe->font_data_id);
1091 if (fd)
1092 {
1093 fd->refcount = 0;
1094 cserve2_shared_string_del(fd->glyph_index_shm);
1095 cserve2_shared_string_del(fd->file);
1096 cserve2_shared_string_del(fd->name);
1097 }
1098
1099 fash_gl_free(fe->glyph_entries);
1100 cserve2_shared_array_del(fe->glyph_datas);
1101 cserve2_font_ft_free(fe->ft);
1102 fe->src->refcount--;
1103 if (fe->src->refcount <= 0)
1062 { 1104 {
1063 const char *key = cserve2_shared_string_get(fe->src->key); 1105 const char *key = cserve2_shared_string_get(fe->src->key);
1064 eina_hash_del_by_key(font_sources, key); 1106 eina_hash_del_by_key(font_sources, key);
1065 } 1107 }
1066 free(fe); 1108 free(fe);
1109
1110 _freed_font_entry_count++;
1111 _repack();
1067} 1112}
1068 1113
1069static void 1114static void
@@ -1072,24 +1117,31 @@ _glyph_free_cb(void *data)
1072 Glyph_Entry *gl = data; 1117 Glyph_Entry *gl = data;
1073 Glyph_Data *gldata; 1118 Glyph_Data *gldata;
1074 1119
1075 if (!gl) return; 1120 if (!gl || !gl->fe) return;
1076 gldata = _glyph_data_find(gl->gldata_id); 1121
1077 cserve2_shared_string_del(gldata->shm_id); 1122 gldata = _glyph_data_find(gl->fe->glyph_datas, gl->gldata_id);
1078 gldata->refcount--; 1123 if (gldata)
1124 {
1125 cserve2_shared_string_del(gldata->shm_id);
1126 gldata->refcount--;
1127 }
1079 free(gl); 1128 free(gl);
1080} 1129}
1081 1130
1082static void 1131static void
1083_font_source_free(Font_Source *fs) 1132_font_source_free(Font_Source *fs)
1084{ 1133{
1134 if (!fs) return;
1135
1085 cserve2_shared_string_del(fs->key); 1136 cserve2_shared_string_del(fs->key);
1086 cserve2_shared_string_del(fs->name); 1137 cserve2_shared_string_del(fs->name);
1087 cserve2_shared_string_del(fs->file); 1138 cserve2_shared_string_del(fs->file);
1088 if (fs->ft) cserve2_font_source_ft_free(fs->ft); 1139 cserve2_font_source_ft_free(fs->ft);
1089 1140
1090 free(fs); 1141 free(fs);
1091} 1142}
1092 1143
1144#if 0
1093static void 1145static void
1094_font_shm_promote(Font_Cache *fc) 1146_font_shm_promote(Font_Cache *fc)
1095{ 1147{
@@ -1161,6 +1213,7 @@ _font_shm_lru_flush(void)
1161 l_next = eina_list_next(l); 1213 l_next = eina_list_next(l);
1162 } 1214 }
1163} 1215}
1216#endif
1164 1217
1165void 1218void
1166cserve2_cache_init(void) 1219cserve2_cache_init(void)
@@ -1180,16 +1233,13 @@ cserve2_cache_init(void)
1180 1233
1181 _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0); 1234 _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0);
1182 _image_data_array = cserve2_shared_array_new(1, sizeof(Image_Data), 0); 1235 _image_data_array = cserve2_shared_array_new(1, sizeof(Image_Data), 0);
1183 _glyph_data_array = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0); 1236 _font_data_array = cserve2_shared_array_new(1, sizeof(Font_Data), 0);
1184} 1237}
1185 1238
1186void 1239void
1187cserve2_cache_shutdown(void) 1240cserve2_cache_shutdown(void)
1188{ 1241{
1189 Font_Cache *fc; 1242 _shutdown = EINA_TRUE;
1190
1191 EINA_LIST_FREE(font_shm_lru, fc)
1192 _font_shm_free(fc);
1193 1243
1194 eina_hash_free(image_entries); 1244 eina_hash_free(image_entries);
1195 eina_hash_free(image_ids); 1245 eina_hash_free(image_ids);
@@ -1202,7 +1252,7 @@ cserve2_cache_shutdown(void)
1202 1252
1203 cserve2_shared_array_del(_file_data_array); 1253 cserve2_shared_array_del(_file_data_array);
1204 cserve2_shared_array_del(_image_data_array); 1254 cserve2_shared_array_del(_image_data_array);
1205 cserve2_shared_array_del(_glyph_data_array); 1255 cserve2_shared_array_del(_font_data_array);
1206} 1256}
1207 1257
1208static Reference * 1258static Reference *
@@ -1304,7 +1354,7 @@ _entry_reference_del(Entry *entry, Reference *ref)
1304 { 1354 {
1305 Font_Entry *fe = (Font_Entry *)entry; 1355 Font_Entry *fe = (Font_Entry *)entry;
1306 fe->unused = EINA_TRUE; 1356 fe->unused = EINA_TRUE;
1307 if (!fe->caches) 1357 if (!fe->mempool)
1308 eina_hash_del_by_key(font_entries, fe); 1358 eina_hash_del_by_key(font_entries, fe);
1309 } 1359 }
1310 else 1360 else
@@ -1372,7 +1422,7 @@ cserve2_cache_client_new(Client *client)
1372 cserve2_shared_strings_table_name_get(), 1422 cserve2_shared_strings_table_name_get(),
1373 cserve2_shared_array_name_get(_file_data_array), 1423 cserve2_shared_array_name_get(_file_data_array),
1374 cserve2_shared_array_name_get(_image_data_array), 1424 cserve2_shared_array_name_get(_image_data_array),
1375 NULL, 1425 cserve2_shared_array_name_get(_font_data_array),
1376 client); 1426 client);
1377} 1427}
1378 1428
@@ -1647,7 +1697,7 @@ _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
1647 for (i = req->current; i < req->nglyphs; i++) 1697 for (i = req->current; i < req->nglyphs; i++)
1648 { 1698 {
1649 Glyph_Entry *ge; 1699 Glyph_Entry *ge;
1650 ge = fash_gl_find(fe->glyphs, req->glyphs[i]); 1700 ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
1651 if (ge) 1701 if (ge)
1652 { 1702 {
1653 req->answer[req->nanswer++] = ge; 1703 req->answer[req->nanswer++] = ge;
@@ -1657,7 +1707,7 @@ _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
1657 fe->gl_saved_time += 1707 fe->gl_saved_time +=
1658 (fe->gl_load_time / fe->nglyphs); 1708 (fe->gl_load_time / fe->nglyphs);
1659#endif 1709#endif
1660 ge->fc->inuse++; 1710 //ge->fc->inuse++;
1661 } 1711 }
1662 else 1712 else
1663 break; 1713 break;
@@ -1669,6 +1719,7 @@ _glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
1669 return (req->nanswer == req->nglyphs); 1719 return (req->nanswer == req->nglyphs);
1670} 1720}
1671 1721
1722#if 0
1672/* organize answer (cache1{gl1, gl2,}, cache2{gl3,gl4,gl5}, cache3{gl6}) 1723/* organize answer (cache1{gl1, gl2,}, cache2{gl3,gl4,gl5}, cache3{gl6})
1673 */ 1724 */
1674static Eina_List * 1725static Eina_List *
@@ -1676,8 +1727,18 @@ _glyphs_group_create(Glyphs_Request *req)
1676{ 1727{
1677 Eina_List *groups = NULL; 1728 Eina_List *groups = NULL;
1678 unsigned int i; 1729 unsigned int i;
1730 Glyphs_Group *gg;
1731
1732 gg = calloc(1, sizeof(*gg));
1733 groups = eina_list_append(groups, gg);
1679 1734
1680 for (i = 0; i < req->nanswer; i++) 1735 for (i = 0; i < req->nanswer; i++)
1736 gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]);
1737
1738 return groups;
1739
1740 /*
1741 for (i = 0; i < req->nanswer; i++)
1681 { 1742 {
1682 Eina_List *l; 1743 Eina_List *l;
1683 Glyphs_Group *iter, *gg = NULL; 1744 Glyphs_Group *iter, *gg = NULL;
@@ -1702,6 +1763,7 @@ _glyphs_group_create(Glyphs_Request *req)
1702 } 1763 }
1703 1764
1704 return groups; 1765 return groups;
1766 */
1705} 1767}
1706 1768
1707static Msg_Font_Glyphs_Loaded * 1769static Msg_Font_Glyphs_Loaded *
@@ -1799,6 +1861,76 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
1799 1861
1800 return (Msg_Font_Glyphs_Loaded *)resp; 1862 return (Msg_Font_Glyphs_Loaded *)resp;
1801} 1863}
1864#endif
1865
1866static Msg_Font_Glyphs_Loaded *
1867_glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
1868{
1869 Msg_Font_Glyphs_Loaded *msg;
1870 unsigned int size;
1871 const char *shmname;
1872 unsigned int shmname_size;
1873 unsigned int k;
1874 char *response, *buf;
1875
1876 shmname = cserve2_shared_mempool_name_get(req->fe->mempool);
1877 shmname_size = strlen(shmname) + 1;
1878
1879 size = sizeof(Msg_Font_Glyphs_Loaded);
1880 size += sizeof(int) * 2;
1881 size += shmname_size;
1882 size += req->nanswer * 9 * sizeof(int);
1883
1884 response = malloc(size);
1885 if (!response) return NULL;
1886 msg = (Msg_Font_Glyphs_Loaded *) response;
1887 buf = response + sizeof(Msg_Font_Glyphs_Loaded);
1888
1889 msg->base.type = CSERVE2_FONT_GLYPHS_LOADED;
1890 memcpy(buf, &shmname_size, sizeof(int));
1891 buf += sizeof(int);
1892 memcpy(buf, shmname, shmname_size);
1893 buf += shmname_size;
1894 memcpy(buf, &req->nanswer, sizeof(int));
1895 buf += sizeof(int);
1896
1897 for (k = 0; k < req->nanswer; k++)
1898 {
1899 Glyph_Entry *ge;
1900 Glyph_Data *gldata;
1901
1902 ge = req->answer[k];
1903 gldata = _glyph_data_find(ge->fe->glyph_datas, ge->gldata_id);
1904 if (!gldata)
1905 {
1906 ERR("Glyph data not found for %d", ge->gldata_id);
1907 continue;
1908 }
1909
1910 memcpy(buf, &gldata->index, sizeof(int));
1911 buf += sizeof(int);
1912 memcpy(buf, &gldata->shm_id, sizeof(string_t));
1913 buf += sizeof(string_t);
1914 memcpy(buf, &gldata->offset, sizeof(int));
1915 buf += sizeof(int);
1916 memcpy(buf, &gldata->size, sizeof(int));
1917 buf += sizeof(int);
1918 memcpy(buf, &gldata->rows, sizeof(int));
1919 buf += sizeof(int);
1920 memcpy(buf, &gldata->width, sizeof(int));
1921 buf += sizeof(int);
1922 memcpy(buf, &gldata->pitch, sizeof(int));
1923 buf += sizeof(int);
1924 memcpy(buf, &gldata->num_grays, sizeof(int));
1925 buf += sizeof(int);
1926 memcpy(buf, &gldata->pixel_mode, sizeof(int));
1927 buf += sizeof(int);
1928 }
1929
1930 *resp_size = size;
1931 return msg;
1932}
1933
1802 1934
1803static void 1935static void
1804_glyphs_loaded_send(Glyphs_Request *req, unsigned int rid) 1936_glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
@@ -1846,7 +1978,10 @@ _file_path_join(const char *path, const char *end)
1846} 1978}
1847 1979
1848static Glyphs_Request * 1980static Glyphs_Request *
1849_glyphs_request_create(Client *client, const char *source, const char *name, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs) 1981_glyphs_request_create(Client *client, const char *source, const char *name,
1982 unsigned int hint, unsigned int rend_flags,
1983 unsigned int size, unsigned int dpi,
1984 unsigned int *glyphs, unsigned int nglyphs)
1850{ 1985{
1851 char *fullname; 1986 char *fullname;
1852 Glyphs_Request *req = calloc(1, sizeof(*req)); 1987 Glyphs_Request *req = calloc(1, sizeof(*req));
@@ -1909,7 +2044,7 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
1909 for (i = req->current; i < req->nglyphs; i++) 2044 for (i = req->current; i < req->nglyphs; i++)
1910 { 2045 {
1911 Glyph_Entry *ge; 2046 Glyph_Entry *ge;
1912 ge = fash_gl_find(fe->glyphs, req->glyphs[i]); 2047 ge = fash_gl_find(fe->glyph_entries, req->glyphs[i]);
1913 if (ge) 2048 if (ge)
1914 { 2049 {
1915 req->answer[req->nanswer++] = ge; 2050 req->answer[req->nanswer++] = ge;
@@ -1919,7 +2054,7 @@ _glyphs_load_request_prepare(Glyphs_Request *req)
1919 fe->gl_saved_time += 2054 fe->gl_saved_time +=
1920 (fe->gl_load_time / fe->nglyphs); 2055 (fe->gl_load_time / fe->nglyphs);
1921#endif 2056#endif
1922 ge->fc->inuse++; 2057 //ge->fc->inuse++;
1923 } 2058 }
1924 else 2059 else
1925 req->render[req->nrender++] = req->glyphs[i]; 2060 req->render[req->nrender++] = req->glyphs[i];
@@ -1932,7 +2067,6 @@ _glyphs_load_request_build(void *data, int *size EINA_UNUSED)
1932 Glyphs_Request *req = data; 2067 Glyphs_Request *req = data;
1933 Slave_Msg_Font_Glyphs_Load *msg = NULL; 2068 Slave_Msg_Font_Glyphs_Load *msg = NULL;
1934 Font_Entry *fe = req->fe; 2069 Font_Entry *fe = req->fe;
1935 Font_Cache *fc;
1936 2070
1937#ifdef DEBUG_LOAD_TIME 2071#ifdef DEBUG_LOAD_TIME
1938 gettimeofday(&fe->rstart, NULL); 2072 gettimeofday(&fe->rstart, NULL);
@@ -1947,15 +2081,7 @@ _glyphs_load_request_build(void *data, int *size EINA_UNUSED)
1947 msg->font.rend_flags = fe->rend_flags; 2081 msg->font.rend_flags = fe->rend_flags;
1948 msg->glyphs.nglyphs = req->nrender; 2082 msg->glyphs.nglyphs = req->nrender;
1949 msg->glyphs.glyphs = req->render; 2083 msg->glyphs.glyphs = req->render;
1950 2084 msg->cache.mempool = fe->mempool;
1951 // Trying to reuse last filled cache.
1952 fc = fe->last_cache;
1953 if (fc)
1954 {
1955 msg->cache.shm = fc->shm;
1956 msg->cache.usage = fc->usage;
1957 msg->cache.nglyphs = fc->nglyphs;
1958 }
1959 2085
1960 return msg; 2086 return msg;
1961} 2087}
@@ -1972,81 +2098,67 @@ _glyphs_load_request_response(Glyphs_Request *req,
1972 Slave_Msg_Font_Glyphs_Loaded *msg, int *size) 2098 Slave_Msg_Font_Glyphs_Loaded *msg, int *size)
1973{ 2099{
1974 Font_Entry *fe = req->fe; 2100 Font_Entry *fe = req->fe;
1975 Font_Cache *fc = NULL; 2101 Shared_Mempool *mempool = msg->mempool;
1976 unsigned int i; 2102 unsigned int j;
2103 string_t shm_id = 0;
1977 2104
1978 if (fe->last_cache && fe->last_cache->shm == msg->caches[0]->shm) 2105 if (!msg->nglyphs)
1979 fc = fe->last_cache; 2106 return _glyphs_loaded_msg_create(req, size);
1980 2107
1981 for (i = 0; i < msg->ncaches; i++) 2108 if (!mempool)
2109 mempool = cserve2_shared_mempool_new(0);
2110
2111 if (!fe->glyph_datas)
2112 fe->glyph_datas = cserve2_shared_array_new(1, sizeof(Glyph_Data), 0);
2113
2114 shm_id = cserve2_shared_string_add(cserve2_shared_mempool_name_get(mempool));
2115 for (j = 0; j < msg->nglyphs; j++)
1982 { 2116 {
1983 unsigned int j; 2117 Glyph_Entry *gl;
1984 Slave_Msg_Font_Cache *c = msg->caches[i];
1985 string_t shm_id;
1986 2118
1987 if (!fc) 2119 gl = fash_gl_find(fe->glyph_entries, msg->glyphs[j].index);
1988 { 2120 if (!gl)
1989 fc = calloc(1, sizeof(*fc));
1990 fe->caches = eina_list_append(fe->caches, fc);
1991 fe->last_cache = fc;
1992 fc->fe = fe;
1993 fc->shm = c->shm;
1994 fc->glyphs = cserve2_shared_array_new(1, sizeof(int), 0);
1995 fc->nglyphs = 0;
1996 fc->inuse = 0;
1997 font_shm_lru = eina_list_append(font_shm_lru, fc);
1998 font_mem_usage += _font_shm_size_get(fc);
1999 }
2000 fc->usage = c->usage;
2001 shm_id = cserve2_shared_string_add(cserve2_shm_name_get(fc->shm));
2002 for (j = 0; j < c->nglyphs; j++)
2003 { 2121 {
2004 Glyph_Entry *gl; 2122 int glyph_id;
2123 Glyph_Data *gldata;
2005 2124
2006 gl = fash_gl_find(fe->glyphs, c->glyphs[j].index); 2125 glyph_id = cserve2_shared_array_item_new(fe->glyph_datas);
2007 if (!gl) 2126 gldata = cserve2_shared_array_item_data_get(fe->glyph_datas,
2127 glyph_id);
2128 if (!gldata)
2008 { 2129 {
2009 int glyph_id, idx, *gldata_id; 2130 ERR("Could not create new Glyph_Data!");
2010 Glyph_Data *gldata; 2131 // TODO: Return error?
2011 2132 continue;
2012 gl = calloc(1, sizeof(*gl));
2013 gl->fe = fe;
2014 gl->fc = fc;
2015 gl->gldata_id = ++_glyph_id;
2016
2017 glyph_id = cserve2_shared_array_item_new(_glyph_data_array);
2018 gldata = cserve2_shared_array_item_data_get(_glyph_data_array,
2019 glyph_id);
2020 gldata->refcount = 1;
2021 gldata->id = gl->gldata_id;
2022 gldata->index = c->glyphs[j].index;
2023 gldata->shm_id = cserve2_shared_string_ref(shm_id);
2024 gldata->offset = c->glyphs[j].offset;
2025 gldata->size = c->glyphs[j].size;
2026 gldata->rows = c->glyphs[j].rows;
2027 gldata->width = c->glyphs[j].width;
2028 gldata->pitch = c->glyphs[j].pitch;
2029 gldata->num_grays = c->glyphs[j].num_grays;
2030 gldata->pixel_mode = c->glyphs[j].pixel_mode;
2031 font_mem_usage += sizeof(*gl) + sizeof(*gldata);
2032 idx = cserve2_shared_array_item_new(fc->glyphs);
2033 gldata_id = cserve2_shared_array_item_data_get(fc->glyphs, idx);
2034 *gldata_id = gldata->id;
2035 fc->nglyphs++;
2036 fe->nglyphs++;
2037 fash_gl_add(fe->glyphs, gldata->index, gl);
2038 } 2133 }
2039 req->answer[req->nanswer++] = gl;
2040 gl->fc->inuse++;
2041 }
2042 2134
2043 cserve2_shared_string_del(shm_id); 2135 gl = calloc(1, sizeof(*gl));
2044 free(c); // FIXME: We are freeing this here because we only do a 2136 gl->fe = fe;
2045 // simple free on the response message. Later we need to 2137 gl->gldata_id = ++_glyph_id;
2046 // setup a free callback for the slave response. 2138
2047 fc = NULL; 2139 gldata->refcount = 1;
2140 gldata->id = gl->gldata_id;
2141 gldata->index = msg->glyphs[j].index;
2142 gldata->shm_id = cserve2_shared_string_ref(shm_id);
2143 gldata->buffer_id = msg->glyphs[j].buffer_id;
2144 gldata->offset = msg->glyphs[j].offset; // TODO: Remove?
2145 gldata->size = msg->glyphs[j].size;
2146 gldata->rows = msg->glyphs[j].rows;
2147 gldata->width = msg->glyphs[j].width;
2148 gldata->pitch = msg->glyphs[j].pitch;
2149 gldata->num_grays = msg->glyphs[j].num_grays;
2150 gldata->pixel_mode = msg->glyphs[j].pixel_mode;
2151
2152 fe->nglyphs++;
2153 fash_gl_add(fe->glyph_entries, gldata->index, gl);
2154
2155 font_mem_usage += sizeof(*gl) + sizeof(*gldata);
2156 }
2157 req->answer[req->nanswer++] = gl;
2048 } 2158 }
2049 2159
2160 cserve2_shared_string_del(shm_id);
2161
2050#ifdef DEBUG_LOAD_TIME 2162#ifdef DEBUG_LOAD_TIME
2051 gettimeofday(&fe->rfinish, NULL); 2163 gettimeofday(&fe->rfinish, NULL);
2052 fe->gl_request_time += _timeval_sub(&fe->rfinish, &fe->rstart); 2164 fe->gl_request_time += _timeval_sub(&fe->rfinish, &fe->rstart);
@@ -2055,7 +2167,7 @@ _glyphs_load_request_response(Glyphs_Request *req,
2055 fe->gl_slave_time += msg->gl_slave_time; 2167 fe->gl_slave_time += msg->gl_slave_time;
2056#endif 2168#endif
2057 2169
2058 _font_shm_lru_flush(); 2170 fe->mempool = mempool;
2059 2171
2060 return _glyphs_loaded_msg_create(req, size); 2172 return _glyphs_loaded_msg_create(req, size);
2061} 2173}
@@ -2075,6 +2187,9 @@ static Slave_Request_Funcs _glyphs_load_funcs = {
2075static Eina_Bool 2187static Eina_Bool
2076_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) 2188_font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
2077{ 2189{
2190 // FIXME TODO Must reimplement this
2191
2192#if 0
2078 Font_Entry *fe = data; 2193 Font_Entry *fe = data;
2079 Msg_Stats *msg = fdata; 2194 Msg_Stats *msg = fdata;
2080 Eina_List *iter; 2195 Eina_List *iter;
@@ -2119,6 +2234,8 @@ _font_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
2119 msg->fonts.glyphs_slave_time += fe->gl_slave_time; 2234 msg->fonts.glyphs_slave_time += fe->gl_slave_time;
2120#endif 2235#endif
2121 2236
2237#endif
2238
2122 return EINA_TRUE; 2239 return EINA_TRUE;
2123} 2240}
2124 2241
@@ -2207,8 +2324,6 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
2207 struct _debug_info *di = fdata; 2324 struct _debug_info *di = fdata;
2208 unsigned int size = di->size; 2325 unsigned int size = di->size;
2209 Font_Entry *fe = data; 2326 Font_Entry *fe = data;
2210 Font_Cache *fc;
2211 Eina_List *iter;
2212 const char *str; 2327 const char *str;
2213 2328
2214 // filelen 2329 // filelen
@@ -2240,20 +2355,7 @@ _font_entry_debug_size_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EIN
2240 // ncaches 2355 // ncaches
2241 size += sizeof(int); 2356 size += sizeof(int);
2242 2357
2243 EINA_LIST_FOREACH(fe->caches, iter, fc) 2358 size += cserve2_shared_mempool_size_get(fe->mempool);
2244 {
2245 // shmnamelen + shmname
2246 size += sizeof(int);
2247 size += strlen(cserve2_shm_name_get(fc->shm)) + 1;
2248
2249 // size + usage
2250 size += 2 * sizeof(int);
2251
2252 // nglyphs
2253 size += sizeof(int);
2254
2255 size += (4 + 3 + 2) * sizeof(int) * fc->nglyphs;
2256 }
2257 2359
2258 di->size = size; 2360 di->size = size;
2259 di->nfonts++; 2361 di->nfonts++;
@@ -2267,6 +2369,94 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
2267 char **pos = fdata; 2369 char **pos = fdata;
2268 char *buf = *pos; 2370 char *buf = *pos;
2269 Font_Entry *fe = data; 2371 Font_Entry *fe = data;
2372 unsigned int len, k, nglyphs;
2373 const char *str;
2374 char *nglyphs_pos;
2375
2376 // file
2377 str = cserve2_shared_string_get(fe->src->file);
2378 len = str ? (strlen(str) + 1) : 0;
2379
2380 memcpy(buf, &len, sizeof(int));
2381 buf += sizeof(int);
2382
2383 if (len)
2384 {
2385 memcpy(buf, str, len);
2386 buf += len;
2387 }
2388
2389 // name
2390 str = cserve2_shared_string_get(fe->src->name);
2391 len = str ? (strlen(str) + 1) : 0;
2392
2393 memcpy(buf, &len, sizeof(int));
2394 buf += sizeof(int);
2395
2396 if (len)
2397 {
2398 memcpy(buf, str, len);
2399 buf += len;
2400 }
2401
2402 // rend_flags, size, dpi, unused
2403 memcpy(buf, &fe->rend_flags, sizeof(int));
2404 buf += sizeof(int);
2405 memcpy(buf, &fe->size, sizeof(int));
2406 buf += sizeof(int);
2407 memcpy(buf, &fe->dpi, sizeof(int));
2408 buf += sizeof(int);
2409
2410 len = fe->unused;
2411 memcpy(buf, &len, sizeof(int));
2412 buf += sizeof(int);
2413
2414 // glyph shared index and mempool
2415 if (fe->glyph_datas)
2416 eina_strlcpy(buf, cserve2_shared_array_name_get(fe->glyph_datas), 64);
2417 else
2418 memset(buf, 0, 64);
2419 buf += 64;
2420
2421 if (fe->mempool)
2422 eina_strlcpy(buf, cserve2_shared_mempool_name_get(fe->mempool), 64);
2423 else
2424 memset(buf, 0, 64);
2425 buf += 64;
2426
2427 // skip nglyphs for now...
2428 nglyphs_pos = buf;
2429 buf += sizeof(int);
2430
2431 nglyphs = 0;
2432 for (k = 0; k < fe->nglyphs; k++)
2433 {
2434 Glyph_Data *gd = cserve2_shared_array_item_data_get(fe->glyph_datas, k);
2435 if (!gd || !gd->id) break;
2436
2437 nglyphs++;
2438 memcpy(buf, gd, sizeof(*gd));
2439 buf += sizeof(*gd);
2440 }
2441
2442 // write real value of nglyphs
2443 memcpy(nglyphs_pos, &nglyphs, sizeof(int));
2444 if (nglyphs != fe->nglyphs)
2445 {
2446 WRN("Found %u valid glyphs when the font advertised %u entries",
2447 nglyphs, fe->nglyphs);
2448 }
2449
2450 *pos = buf;
2451 return EINA_TRUE;
2452}
2453
2454 // FIXME TODO Must reimplement this
2455#if 0
2456
2457 char **pos = fdata;
2458 char *buf = *pos;
2459 Font_Entry *fe = data;
2270 Font_Cache *fc; 2460 Font_Cache *fc;
2271 Eina_List *iter; 2461 Eina_List *iter;
2272 unsigned int len; 2462 unsigned int len;
@@ -2376,6 +2566,7 @@ _font_entry_debug_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNU
2376 2566
2377 *pos = buf; 2567 *pos = buf;
2378 return EINA_TRUE; 2568 return EINA_TRUE;
2569#endif
2379} 2570}
2380 2571
2381static void * 2572static void *
@@ -2852,12 +3043,16 @@ cserve2_cache_image_unload(Client *client, unsigned int client_image_id)
2852} 3043}
2853 3044
2854int 3045int
2855cserve2_cache_font_load(Client *client, const char *source, const char *name, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int rid) 3046cserve2_cache_font_load(Client *client, const char *source, const char *name,
3047 unsigned int rend_flags, unsigned int size,
3048 unsigned int dpi, unsigned int rid)
2856{ 3049{
2857 Reference *ref; 3050 Reference *ref;
2858 Font_Source *fs; 3051 Font_Source *fs;
3052 Font_Data *fd;
2859 Font_Entry *fe; 3053 Font_Entry *fe;
2860 char *fullname; 3054 char *fullname;
3055 int fd_index;
2861 3056
2862 if (source && !*source) 3057 if (source && !*source)
2863 source = NULL; 3058 source = NULL;
@@ -2891,10 +3086,9 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name, un
2891 fe->size = size; 3086 fe->size = size;
2892 fe->dpi = dpi; 3087 fe->dpi = dpi;
2893 fe->base.type = CSERVE2_FONT_ENTRY; 3088 fe->base.type = CSERVE2_FONT_ENTRY;
2894 fe->glyphs = fash_gl_new(_glyph_free_cb); 3089 fe->glyph_entries = fash_gl_new(_glyph_free_cb);
2895 ref = _entry_reference_add((Entry *)fe, client, 0); 3090 ref = _entry_reference_add((Entry *)fe, client, 0);
2896 client->fonts.referencing = eina_list_append( 3091 client->fonts.referencing = eina_list_append(client->fonts.referencing, ref);
2897 client->fonts.referencing, ref);
2898 fe->unused = EINA_FALSE; 3092 fe->unused = EINA_FALSE;
2899 3093
2900 fs = _cserve2_font_source_find(fullname); 3094 fs = _cserve2_font_source_find(fullname);
@@ -2912,14 +3106,28 @@ cserve2_cache_font_load(Client *client, const char *source, const char *name, un
2912 else 3106 else
2913 { 3107 {
2914 fs->file = cserve2_shared_string_add(name); 3108 fs->file = cserve2_shared_string_add(name);
3109 fs->name = 0;
2915 fs->key = cserve2_shared_string_ref(fs->file); 3110 fs->key = cserve2_shared_string_ref(fs->file);
2916 key = name; 3111 key = name;
2917 } 3112 }
2918 eina_hash_direct_add(font_sources, key, fs); 3113 eina_hash_add(font_sources, key, fs);
2919 } 3114 }
2920 3115
3116 // Copy descriptor to Shared Array
3117 fd_index = cserve2_shared_array_item_new(_font_data_array);
3118 fd = cserve2_shared_array_item_data_get(_font_data_array, fd_index);
3119 fd->size = fe->size;
3120 fd->rend_flags = fe->rend_flags;
3121 fd->dpi = fe->dpi;
3122 fd->id = ++_font_data_id;
3123 fd->refcount = 1;
3124 fd->name = cserve2_shared_string_ref(fs->name);
3125 fd->file = cserve2_shared_string_ref(fs->file);
3126 fd->glyph_index_shm = 0;
3127
2921 fe->src = fs; 3128 fe->src = fs;
2922 fs->references++; 3129 fe->font_data_id = fd->id;
3130 fs->refcount++;
2923 DBG("adding FONT_LOAD '%s' request.", name); 3131 DBG("adding FONT_LOAD '%s' request.", name);
2924 fe->base.request = cserve2_request_add(CSERVE2_REQ_FONT_LOAD, rid, client, 3132 fe->base.request = cserve2_request_add(CSERVE2_REQ_FONT_LOAD, rid, client,
2925 NULL, &_font_load_funcs, fe); 3133 NULL, &_font_load_funcs, fe);
@@ -2958,7 +3166,11 @@ cserve2_cache_font_unload(Client *client, const char *source, const char *name,
2958} 3166}
2959 3167
2960int 3168int
2961cserve2_cache_font_glyphs_load(Client *client, const char *source, const char *name, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid) 3169cserve2_cache_font_glyphs_load(Client *client, const char *source,
3170 const char *name, unsigned int hint,
3171 unsigned int rend_flags, unsigned int size,
3172 unsigned int dpi, unsigned int *glyphs,
3173 unsigned int nglyphs, unsigned int rid)
2962{ 3174{
2963 Glyphs_Request *req; 3175 Glyphs_Request *req;
2964 3176
@@ -2985,8 +3197,17 @@ cserve2_cache_font_glyphs_load(Client *client, const char *source, const char *n
2985} 3197}
2986 3198
2987int 3199int
2988cserve2_cache_font_glyphs_used(Client *client, const char *source, const char *name, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid EINA_UNUSED) 3200cserve2_cache_font_glyphs_used(Client *client, const char *source,
2989{ 3201 const char *name, unsigned int hint,
3202 unsigned int rend_flags, unsigned int size,
3203 unsigned int dpi, unsigned int *glyphs,
3204 unsigned int nglyphs,
3205 unsigned int rid EINA_UNUSED)
3206{
3207 // FIXME TODO: Must reimplement this
3208 return 0;
3209
3210#if 0
2990 Glyphs_Group *gg; 3211 Glyphs_Group *gg;
2991 Eina_List *groups; 3212 Eina_List *groups;
2992 Glyphs_Request *req; 3213 Glyphs_Request *req;
@@ -3008,13 +3229,14 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source, const char *n
3008 // glyphs which are not cached anymore, but are in use on the client. 3229 // glyphs which are not cached anymore, but are in use on the client.
3009 EINA_LIST_FREE(groups, gg) 3230 EINA_LIST_FREE(groups, gg)
3010 { 3231 {
3011 _font_shm_promote(gg->fc); 3232 //_font_shm_promote(gg->fc);
3012 eina_list_free(gg->glyphs); 3233 eina_list_free(gg->glyphs);
3013 free(gg); 3234 free(gg);
3014 } 3235 }
3015 3236
3016 _glyphs_request_free(req); 3237 _glyphs_request_free(req);
3017 return 0; 3238 return 0;
3239#endif
3018} 3240}
3019 3241
3020void 3242void
diff --git a/src/bin/evas/evas_cserve2_fonts.c b/src/bin/evas/evas_cserve2_fonts.c
index af8139e3ca..8690888943 100644
--- a/src/bin/evas/evas_cserve2_fonts.c
+++ b/src/bin/evas/evas_cserve2_fonts.c
@@ -47,7 +47,6 @@ struct _Font_Info
47 int dpi; 47 int dpi;
48 int max_h; 48 int max_h;
49 unsigned int runtime_rend; 49 unsigned int runtime_rend;
50 int shmsize;
51}; 50};
52 51
53struct _Font_Source_Info 52struct _Font_Source_Info
@@ -281,14 +280,6 @@ _font_slave_load(const void *cmddata, void *data EINA_UNUSED)
281 return response; 280 return response;
282} 281}
283 282
284static Shm_Handle *
285_font_slave_memory_alloc(Font_Info *fi)
286{
287 Shm_Handle *shm = cserve2_shm_request("font", fi->shmsize);
288
289 return shm;
290}
291
292/* This function will load the "index" glyph to the glyph slot of the font. 283/* This function will load the "index" glyph to the glyph slot of the font.
293 * In order to use or render it, one should access it from the glyph slot, 284 * In order to use or render it, one should access it from the glyph slot,
294 * or get the glyph using FT_Get_Glyph(). 285 * or get the glyph using FT_Get_Glyph().
@@ -326,39 +317,48 @@ _font_slave_glyph_load(Font_Info *fi, unsigned int idx, unsigned int hint)
326 * given Font Cache. 317 * given Font Cache.
327 */ 318 */
328static Eina_Bool 319static Eina_Bool
329_font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int idx) 320_font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Glyphs_Loaded *response,
321 unsigned int idx)
330{ 322{
331 Font_Source_Info *fsi = fi->fsi; 323 Font_Source_Info *fsi = fi->fsi;
332 unsigned int glyphsize; 324 unsigned int glyphsize;
333 char *cachedata = cserve2_shm_map(c->shm);
334 FT_Glyph glyph; 325 FT_Glyph glyph;
335 FT_BitmapGlyph bglyph; 326 FT_BitmapGlyph bglyph;
327 char *data;
328 int buffer_id = 0;
336 329
337 FT_Get_Glyph(fsi->face->glyph, &glyph); 330 FT_Get_Glyph(fsi->face->glyph, &glyph);
338 FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); 331 FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
339 bglyph = (FT_BitmapGlyph)glyph; 332 bglyph = (FT_BitmapGlyph)glyph;
340 333
341 glyphsize = bglyph->bitmap.pitch * bglyph->bitmap.rows; 334 glyphsize = bglyph->bitmap.pitch * bglyph->bitmap.rows;
342 335 if (!glyphsize)
343 if (c->usage + glyphsize > cserve2_shm_size_get(c->shm))
344 { 336 {
345 FT_Done_Glyph(glyph); 337 FT_Done_Glyph(glyph);
346 return EINA_FALSE; 338 return EINA_FALSE;
347 } 339 }
348 340
349 memcpy(cachedata + c->usage, bglyph->bitmap.buffer, glyphsize); 341 buffer_id = cserve2_shared_mempool_buffer_new(response->mempool, glyphsize);
342 data = cserve2_shared_mempool_buffer_get(response->mempool, buffer_id);
343 if (!data)
344 {
345 FT_Done_Glyph(glyph);
346 return EINA_FALSE;
347 }
348 memcpy(data, bglyph->bitmap.buffer, glyphsize);
350 349
351 // TODO: Check if we have problems with alignment 350 // TODO: Check if we have problems with alignment
352 c->glyphs[c->nglyphs].index = idx; 351 response->glyphs[response->nglyphs].index = idx;
353 c->glyphs[c->nglyphs].offset = c->usage; 352 response->glyphs[response->nglyphs].buffer_id = buffer_id;
354 c->glyphs[c->nglyphs].size = glyphsize; 353 response->glyphs[response->nglyphs].offset =
355 c->glyphs[c->nglyphs].rows = bglyph->bitmap.rows; 354 cserve2_shared_mempool_buffer_offset_get(response->mempool, buffer_id);
356 c->glyphs[c->nglyphs].width = bglyph->bitmap.width; 355 response->glyphs[response->nglyphs].size = glyphsize;
357 c->glyphs[c->nglyphs].pitch = bglyph->bitmap.pitch; 356 response->glyphs[response->nglyphs].rows = bglyph->bitmap.rows;
358 c->glyphs[c->nglyphs].num_grays = bglyph->bitmap.num_grays; 357 response->glyphs[response->nglyphs].width = bglyph->bitmap.width;
359 c->glyphs[c->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode; 358 response->glyphs[response->nglyphs].pitch = bglyph->bitmap.pitch;
360 c->usage += glyphsize; 359 response->glyphs[response->nglyphs].num_grays = bglyph->bitmap.num_grays;
361 c->nglyphs++; 360 response->glyphs[response->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode;
361 response->nglyphs++;
362 362
363 FT_Done_Glyph(glyph); 363 FT_Done_Glyph(glyph);
364 364
@@ -465,15 +465,12 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
465 Slave_Msg_Font_Glyphs_Loaded *response; 465 Slave_Msg_Font_Glyphs_Loaded *response;
466 Font_Info *fi; 466 Font_Info *fi;
467 unsigned int i; 467 unsigned int i;
468 unsigned int total_glyphs = 0;
469#ifdef DEBUG_LOAD_TIME 468#ifdef DEBUG_LOAD_TIME
470 unsigned int gl_load_time = 0; 469 unsigned int gl_load_time = 0;
471 unsigned int gl_render_time = 0; 470 unsigned int gl_render_time = 0;
472 struct timeval tv_start, tv_end; 471 struct timeval tv_start, tv_end;
473 struct timeval rstart, rfinish; 472 struct timeval rstart, rfinish;
474#endif 473#endif
475 Eina_List *caches = NULL;
476 Slave_Msg_Font_Cache *c = NULL;
477 474
478 fi = msg->font.ftdata2; 475 fi = msg->font.ftdata2;
479 476
@@ -483,41 +480,22 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
483 480
484 _font_slave_size_use(fi); 481 _font_slave_size_use(fi);
485 482
486 if (msg->cache.shm) 483 response = malloc(sizeof(*response)
484 + sizeof(Slave_Msg_Glyph) * (msg->glyphs.nglyphs));
485 if (!response) return NULL;
486
487 response->nglyphs = 0;
488 response->glyphs = (void *) (response + 1);
489 response->mempool = msg->cache.mempool;
490 if (!response->mempool)
487 { 491 {
488 c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) * 492 unsigned shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint);
489 (msg->glyphs.nglyphs)); 493 response->mempool = cserve2_shared_mempool_new(shmsize);
490 c->nglyphs = 0; 494 if (!response->mempool) return NULL;
491 c->glyphs = (void *)(c + 1);
492 c->shm = msg->cache.shm;
493 c->usage = msg->cache.usage;
494 caches = eina_list_append(caches, c);
495 total_glyphs = msg->cache.nglyphs;
496 } 495 }
497 496
498 if (!fi->shmsize) 497 for (i = 0; i < msg->glyphs.nglyphs; i++)
499 fi->shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint);
500
501 i = 0;
502
503 while (i < msg->glyphs.nglyphs)
504 { 498 {
505 Eina_Bool r = EINA_TRUE;
506
507 if (!c)
508 {
509 Shm_Handle *shm;
510 shm = _font_slave_memory_alloc(fi);
511 c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) *
512 (msg->glyphs.nglyphs - i));
513 c->nglyphs = 0;
514 c->glyphs = (void *)(c + 1);
515 c->shm = shm;
516 c->usage = 0;
517 caches = eina_list_append(caches, c);
518 total_glyphs = 0;
519 }
520
521#ifdef DEBUG_LOAD_TIME 499#ifdef DEBUG_LOAD_TIME
522 gettimeofday(&tv_start, NULL); 500 gettimeofday(&tv_start, NULL);
523#endif 501#endif
@@ -530,32 +508,14 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
530 tv_start.tv_sec = tv_end.tv_sec; 508 tv_start.tv_sec = tv_end.tv_sec;
531 tv_start.tv_usec = tv_end.tv_usec; 509 tv_start.tv_usec = tv_end.tv_usec;
532#endif 510#endif
533 r = _font_slave_glyph_render(fi, c, msg->glyphs.glyphs[i]); 511 _font_slave_glyph_render(fi, response, msg->glyphs.glyphs[i]);
534#ifdef DEBUG_LOAD_TIME 512#ifdef DEBUG_LOAD_TIME
535 gettimeofday(&tv_end, NULL); 513 gettimeofday(&tv_end, NULL);
536 gl_render_time += _timeval_sub(&tv_end, &tv_start); 514 gl_render_time += _timeval_sub(&tv_end, &tv_start);
537#endif 515#endif
538 } 516 }
539 if (!r) // SHM is full
540 {
541 fi->shmsize = _font_slave_int_shm_prev_calculate
542 (c->usage, total_glyphs);
543 c = NULL;
544 continue;
545 }
546 i++;
547 total_glyphs++;
548 } 517 }
549 518
550 response = malloc(sizeof(*response) +
551 sizeof(c) * eina_list_count(caches));
552 response->ncaches = eina_list_count(caches);
553 response->caches = (void *)(response + 1);
554
555 i = 0;
556 EINA_LIST_FREE(caches, c)
557 response->caches[i++] = c;
558
559#ifdef DEBUG_LOAD_TIME 519#ifdef DEBUG_LOAD_TIME
560 response->gl_load_time = gl_load_time; 520 response->gl_load_time = gl_load_time;
561 response->gl_render_time = gl_render_time; 521 response->gl_render_time = gl_render_time;
@@ -630,6 +590,8 @@ cserve2_font_source_ft_free(void *fontsource)
630{ 590{
631 Font_Source_Info *fsi = fontsource; 591 Font_Source_Info *fsi = fontsource;
632 592
593 if (!fsi) return;
594
633 FT_Done_Face(fsi->face); 595 FT_Done_Face(fsi->face);
634 free(fsi->data); 596 free(fsi->data);
635 free(fsi); 597 free(fsi);
@@ -640,6 +602,8 @@ cserve2_font_ft_free(void *fontinfo)
640{ 602{
641 Font_Info *fi = fontinfo; 603 Font_Info *fi = fontinfo;
642 604
605 if (!fi) return;
606
643 FT_Done_Size(fi->size); 607 FT_Done_Size(fi->size);
644 free(fi); 608 free(fi);
645} 609}
diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c
index ccb49039d9..7c3f176d89 100644
--- a/src/bin/evas/evas_cserve2_index.c
+++ b/src/bin/evas/evas_cserve2_index.c
@@ -837,6 +837,20 @@ cserve2_shared_mempool_buffer_offset_get(Shared_Mempool *sm, int bufferid)
837 return ie->offset; 837 return ie->offset;
838} 838}
839 839
840size_t
841cserve2_shared_mempool_size_get(Shared_Mempool *sm)
842{
843 if (!sm) return 0;
844 return cserve2_shm_map_size_get(sm->ds->shm);
845}
846
847const char *
848cserve2_shared_mempool_name_get(Shared_Mempool *sm)
849{
850 if (!sm) return NULL;
851 return cserve2_shm_name_get(sm->ds->shm);
852}
853
840 854
841// Shared strings 855// Shared strings
842 856
diff --git a/src/bin/evas/evas_cserve2_main.c b/src/bin/evas/evas_cserve2_main.c
index ae4a80e854..00a0fe4d9f 100644
--- a/src/bin/evas/evas_cserve2_main.c
+++ b/src/bin/evas/evas_cserve2_main.c
@@ -47,6 +47,9 @@ cserve2_index_list_send(const char *strings_index_path,
47 Msg_Index_List msg; 47 Msg_Index_List msg;
48 const int size = sizeof(msg); 48 const int size = sizeof(msg);
49 49
50 if (!client_list)
51 return;
52
50 INF("New shared index: strings: '%s':'%s' files: '%s' images: '%s', fonts: '%s'", 53 INF("New shared index: strings: '%s':'%s' files: '%s' images: '%s', fonts: '%s'",
51 strings_index_path, strings_entries_path, 54 strings_index_path, strings_entries_path,
52 files_index_path, images_index_path, fonts_index_path); 55 files_index_path, images_index_path, fonts_index_path);
@@ -339,6 +342,7 @@ static void
339_clients_finish(void) 342_clients_finish(void)
340{ 343{
341 eina_hash_free(client_list); 344 eina_hash_free(client_list);
345 client_list = NULL;
342} 346}
343 347
344int 348int