summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-07-24 14:34:35 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-10-28 15:47:13 +0900
commit64e7d48296a7f21245203ea9bada0be90dbf360a (patch)
treec47ffc26d74e37cb60dba825a859c274eebe0dca /src/bin
parent315c2fd161b1a552c5589bae6f7a488ffea1d318 (diff)
evas/cserve2: Store Image_Data in shared array
Split image entries into Image_Data and Image_Entry. Store, find and use Image_Data descriptors from shared array. Fix some wrong hash table usages.
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/evas/evas_cserve2.h2
-rw-r--r--src/bin/evas/evas_cserve2_cache.c678
-rw-r--r--src/bin/evas/evas_cserve2_index.c18
3 files changed, 412 insertions, 286 deletions
diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h
index 361d08a768..1e1a055e21 100644
--- a/src/bin/evas/evas_cserve2.h
+++ b/src/bin/evas/evas_cserve2.h
@@ -288,7 +288,7 @@ void cserve2_cache_client_new(Client *client);
288void cserve2_cache_client_del(Client *client); 288void cserve2_cache_client_del(Client *client);
289int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid); 289int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
290void cserve2_cache_file_close(Client *client, unsigned int client_file_id); 290void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
291int cserve2_cache_image_entry_create(Client *client, int rid, unsigned int file_id, unsigned int image_id, Evas_Image_Load_Opts *opts); 291int cserve2_cache_image_entry_create(Client *client, int rid, unsigned int client_file_id, unsigned int image_id, Evas_Image_Load_Opts *opts);
292void cserve2_rgba_image_scale_do(void *src_data, void *dst_data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int alpha, int smooth); 292void cserve2_rgba_image_scale_do(void *src_data, void *dst_data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int alpha, int smooth);
293void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid); 293void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid);
294void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid); 294void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c
index 8624c08995..b8a55c9592 100644
--- a/src/bin/evas/evas_cserve2_cache.c
+++ b/src/bin/evas/evas_cserve2_cache.c
@@ -17,6 +17,7 @@
17typedef int string_t; 17typedef int string_t;
18#define ENTRY Entry base 18#define ENTRY Entry base
19#define ASENTRY(a) (&(a->base)) 19#define ASENTRY(a) (&(a->base))
20#define ENTRYID(a) ((a)->base.id)
20#define SHMOBJECT unsigned int id; unsigned int refcount 21#define SHMOBJECT unsigned int id; unsigned int refcount
21 22
22typedef struct _Entry Entry; 23typedef struct _Entry Entry;
@@ -24,6 +25,7 @@ typedef struct _Shm_Object Shm_Object;
24typedef struct _Reference Reference; 25typedef struct _Reference Reference;
25typedef struct _File_Entry File_Entry; 26typedef struct _File_Entry File_Entry;
26typedef struct _File_Data File_Data; 27typedef struct _File_Data File_Data;
28typedef struct _Image_Entry Image_Entry;
27typedef struct _Image_Data Image_Data; 29typedef struct _Image_Data Image_Data;
28typedef struct _File_Watch File_Watch; 30typedef struct _File_Watch File_Watch;
29 31
@@ -74,12 +76,17 @@ struct _File_Data {
74 Eina_Bool invalid : 1; 76 Eina_Bool invalid : 1;
75}; 77};
76 78
77// Default values for load options commented below 79
80struct _Image_Entry {
81 ENTRY;
82 Shm_Handle *shm;
83};
84
78struct _Image_Data { 85struct _Image_Data {
79 Entry base; 86 SHMOBJECT;
80 unsigned int file_id; 87 unsigned int file_id;
88 string_t shm_id;
81 Evas_Image_Load_Opts opts; 89 Evas_Image_Load_Opts opts;
82 Shm_Handle *shm;
83 Eina_Bool alpha_sparse : 1; 90 Eina_Bool alpha_sparse : 1;
84 Eina_Bool unused : 1; 91 Eina_Bool unused : 1;
85 Eina_Bool doload : 1; 92 Eina_Bool doload : 1;
@@ -178,6 +185,7 @@ static unsigned int _entry_id = 0;
178static unsigned int _freed_entry_count = 0; 185static unsigned int _freed_entry_count = 0;
179 186
180static Shared_Array *_file_data_array = NULL; 187static Shared_Array *_file_data_array = NULL;
188static Shared_Array *_image_data_array = NULL;
181 189
182static Eina_Hash *file_ids = NULL; // maps path + key --> file_id 190static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
183static Eina_Hash *file_entries = NULL; // maps file_id --> entry 191static Eina_Hash *file_entries = NULL; // maps file_id --> entry
@@ -262,7 +270,7 @@ _shm_object_id_cmp_cb(const void *data1, const void *data2)
262 return +1; 270 return +1;
263} 271}
264 272
265static inline File_Data * 273static File_Data *
266_file_data_find(unsigned int file_id) 274_file_data_find(unsigned int file_id)
267{ 275{
268 File_Data *fd; 276 File_Data *fd;
@@ -276,10 +284,11 @@ _file_data_find(unsigned int file_id)
276 } 284 }
277 else if (!fd) 285 else if (!fd)
278 ERR("Could not find file %u", file_id); 286 ERR("Could not find file %u", file_id);
287
279 return fd; 288 return fd;
280} 289}
281 290
282static inline File_Entry * 291static File_Entry *
283_file_entry_find(unsigned int entry_id) 292_file_entry_find(unsigned int entry_id)
284{ 293{
285 Entry *e; 294 Entry *e;
@@ -291,6 +300,36 @@ _file_entry_find(unsigned int entry_id)
291 return (File_Entry *) e; 300 return (File_Entry *) e;
292} 301}
293 302
303static Image_Data *
304_image_data_find(unsigned int image_id)
305{
306 Image_Data *idata;
307
308 idata = cserve2_shared_array_item_data_find(_image_data_array, &image_id,
309 _shm_object_id_cmp_cb);
310 if (idata && !idata->refcount)
311 {
312 ERR("Can not access object %u with refcount 0", image_id);
313 return NULL;
314 }
315 else if (!idata)
316 ERR("Could not find image %u", image_id);
317
318 return idata;
319}
320
321static Image_Entry *
322_image_entry_find(unsigned int entry_id)
323{
324 Entry *e;
325
326 e = (Entry *) eina_hash_find(image_entries, &entry_id);
327 if (!e || e->type != CSERVE2_IMAGE_DATA)
328 return NULL;
329
330 return (Image_Entry *) e;
331}
332
294static Eina_Bool 333static Eina_Bool
295_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem, 334_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem,
296 void *user_data EINA_UNUSED) 335 void *user_data EINA_UNUSED)
@@ -369,10 +408,10 @@ _image_opened_send(Client *client, File_Data *fd, unsigned int rid)
369} 408}
370 409
371static Msg_Loaded * 410static Msg_Loaded *
372_image_loaded_msg_create(Image_Data *entry, int *size) 411_image_loaded_msg_create(Image_Entry *ientry, Image_Data *idata, int *size)
373{ 412{
374 Msg_Loaded *msg; 413 Msg_Loaded *msg;
375 const char *shmpath = cserve2_shm_name_get(entry->shm); 414 const char *shmpath = cserve2_shm_name_get(ientry->shm);
376 int path_len; 415 int path_len;
377 char *buf; 416 char *buf;
378 417
@@ -382,11 +421,11 @@ _image_loaded_msg_create(Image_Data *entry, int *size)
382 msg = calloc(1, *size); 421 msg = calloc(1, *size);
383 msg->base.type = CSERVE2_LOADED; 422 msg->base.type = CSERVE2_LOADED;
384 423
385 msg->shm.mmap_offset = cserve2_shm_map_offset_get(entry->shm); 424 msg->shm.mmap_offset = cserve2_shm_map_offset_get(ientry->shm);
386 msg->shm.use_offset = cserve2_shm_offset_get(entry->shm); 425 msg->shm.use_offset = cserve2_shm_offset_get(ientry->shm);
387 msg->shm.mmap_size = cserve2_shm_map_size_get(entry->shm); 426 msg->shm.mmap_size = cserve2_shm_map_size_get(ientry->shm);
388 msg->shm.image_size = cserve2_shm_size_get(entry->shm); 427 msg->shm.image_size = cserve2_shm_size_get(ientry->shm);
389 msg->alpha_sparse = entry->alpha_sparse; 428 msg->alpha_sparse = idata->alpha_sparse;
390 429
391 buf = (char *)msg + sizeof(*msg); 430 buf = (char *)msg + sizeof(*msg);
392 memcpy(buf, shmpath, path_len); 431 memcpy(buf, shmpath, path_len);
@@ -395,14 +434,15 @@ _image_loaded_msg_create(Image_Data *entry, int *size)
395} 434}
396 435
397static void 436static void
398_image_loaded_send(Client *client, Image_Data *entry, unsigned int rid) 437_image_loaded_send(Client *client, Image_Entry *ientry, Image_Data *idata,
438 unsigned int rid)
399{ 439{
400 int size; 440 int size;
401 Msg_Loaded *msg; 441 Msg_Loaded *msg;
402 442
403 DBG("Sending LOADED reply for entry %d and RID: %d.", entry->base.id, rid); 443 DBG("Sending LOADED reply for entry %d and RID: %d.", idata->id, rid);
404 444
405 msg = _image_loaded_msg_create(entry, &size); 445 msg = _image_loaded_msg_create(ientry, idata, &size);
406 msg->base.rid = rid; 446 msg->base.rid = rid;
407 447
408 cserve2_client_send(client, &size, sizeof(size)); 448 cserve2_client_send(client, &size, sizeof(size));
@@ -438,6 +478,9 @@ _open_request_build(Entry *entry, int *bufsize)
438 Slave_Msg_Image_Open msg; 478 Slave_Msg_Image_Open msg;
439 File_Data *fd; 479 File_Data *fd;
440 480
481 if (!entry || entry->type != CSERVE2_IMAGE_FILE)
482 return NULL;
483
441 fd = _file_data_find(entry->id); 484 fd = _file_data_find(entry->id);
442 if (!fd) 485 if (!fd)
443 { 486 {
@@ -541,7 +584,7 @@ static Slave_Request_Funcs _open_funcs = {
541}; 584};
542 585
543static void * 586static void *
544_load_request_build(Image_Data *i, int *bufsize) 587_load_request_build(Image_Entry *ientry, int *bufsize)
545{ 588{
546 char *buf, *ptr; 589 char *buf, *ptr;
547 const char *shmpath, *loader_data; 590 const char *shmpath, *loader_data;
@@ -549,21 +592,29 @@ _load_request_build(Image_Data *i, int *bufsize)
549 int shmlen, filelen, keylen, loaderlen; 592 int shmlen, filelen, keylen, loaderlen;
550 Slave_Msg_Image_Load msg; 593 Slave_Msg_Image_Load msg;
551 File_Data *fd; 594 File_Data *fd;
595 Image_Data *idata;
596
597 idata = _image_data_find(ENTRYID(ientry));
598 if (!idata || !idata->refcount)
599 {
600 ERR("Image data not found for entry %u", ENTRYID(ientry));
601 return NULL;
602 }
552 603
553 fd = _file_data_find(i->file_id); 604 fd = _file_data_find(idata->file_id);
554 if (!fd) 605 if (!fd)
555 { 606 {
556 ERR("Could not find file data %u for image %u", i->file_id, i->base.id); 607 ERR("Could not find file data %u for image %u",
608 idata->file_id, idata->id);
557 return NULL; 609 return NULL;
558 } 610 }
559 611
560 // opening shm for this file 612 // opening shm for this file
561 i->shm = cserve2_shm_request("img", fd->w * fd->h * 4); 613 ientry->shm = cserve2_shm_request("img", fd->w * fd->h * 4);
562 if (!i->shm) 614 if (!ientry->shm)
563 return NULL; 615 return NULL;
564 616
565 shmpath = cserve2_shm_name_get(i->shm); 617 shmpath = cserve2_shm_name_get(ientry->shm);
566
567 shmlen = strlen(shmpath) + 1; 618 shmlen = strlen(shmpath) + 1;
568 filelen = strlen(cserve2_shared_string_get(fd->path)) + 1; 619 filelen = strlen(cserve2_shared_string_get(fd->path)) + 1;
569 keylen = strlen(cserve2_shared_string_get(fd->key)) + 1; 620 keylen = strlen(cserve2_shared_string_get(fd->key)) + 1;
@@ -583,18 +634,18 @@ _load_request_build(Image_Data *i, int *bufsize)
583 msg.alpha = fd->alpha; 634 msg.alpha = fd->alpha;
584 635
585 // NOTE: Not passing scale_load options 636 // NOTE: Not passing scale_load options
586 msg.opts.w = i->opts.w; 637 msg.opts.w = idata->opts.w;
587 msg.opts.h = i->opts.h; 638 msg.opts.h = idata->opts.h;
588 msg.opts.region = i->opts.region; 639 msg.opts.region = idata->opts.region;
589 msg.opts.scale_down_by = i->opts.scale_down_by; 640 msg.opts.scale_down_by = idata->opts.scale_down_by;
590 msg.opts.dpi = i->opts.dpi; 641 msg.opts.dpi = idata->opts.dpi;
591 msg.opts.degree = i->opts.degree; 642 msg.opts.degree = idata->opts.degree;
592 msg.opts.orientation = i->opts.orientation; 643 msg.opts.orientation = idata->opts.orientation;
593 644
594 msg.shm.mmap_offset = cserve2_shm_map_offset_get(i->shm); 645 msg.shm.mmap_offset = cserve2_shm_map_offset_get(ientry->shm);
595 msg.shm.image_offset = cserve2_shm_offset_get(i->shm); 646 msg.shm.image_offset = cserve2_shm_offset_get(ientry->shm);
596 msg.shm.mmap_size = cserve2_shm_map_size_get(i->shm); 647 msg.shm.mmap_size = cserve2_shm_map_size_get(ientry->shm);
597 msg.shm.image_size = cserve2_shm_size_get(i->shm); 648 msg.shm.image_size = cserve2_shm_size_get(ientry->shm);
598 649
599 msg.has_loader_data = !!loaderlen; 650 msg.has_loader_data = !!loaderlen;
600 651
@@ -611,31 +662,31 @@ _load_request_build(Image_Data *i, int *bufsize)
611 662
612 *bufsize = size; 663 *bufsize = size;
613 664
614 _entry_load_start(&i->base); 665 _entry_load_start(&ientry->base);
615 666
616 return buf; 667 return buf;
617} 668}
618 669
619static inline Eina_Bool 670static inline Eina_Bool
620_scaling_needed(Image_Data *entry, Slave_Msg_Image_Loaded *resp) 671_scaling_needed(Image_Data *idata, Slave_Msg_Image_Loaded *resp)
621{ 672{
622 return (((entry->opts.scale_load.dst_w) && (entry->opts.scale_load.dst_h)) && 673 return (((idata->opts.scale_load.dst_w) && (idata->opts.scale_load.dst_h)) &&
623 ((entry->opts.scale_load.dst_w != resp->w) || 674 ((idata->opts.scale_load.dst_w != resp->w) ||
624 (entry->opts.scale_load.dst_h != resp->h))); 675 (idata->opts.scale_load.dst_h != resp->h)));
625} 676}
626 677
627static int 678static int
628_scaling_do(Shm_Handle *scale_shm, Image_Data *entry, Image_Data *original) 679_scaling_do(Shm_Handle *scale_shm, Image_Data *idata, Image_Entry *original)
629{ 680{
630 char *scale_map, *orig_map; 681 char *scale_map, *orig_map;
631 void *src_data, *dst_data; 682 void *src_data, *dst_data;
632 File_Data *fd; 683 File_Data *fd;
633 684
634 fd = _file_data_find(entry->file_id); 685 fd = _file_data_find(idata->file_id);
635 if (!fd) 686 if (!fd)
636 { 687 {
637 ERR("Could not find file data %u for image %u", 688 ERR("Could not find file data %u for image %u",
638 entry->file_id, entry->base.id); 689 idata->file_id, idata->id);
639 return -1; 690 return -1;
640 } 691 }
641 692
@@ -659,17 +710,18 @@ _scaling_do(Shm_Handle *scale_shm, Image_Data *entry, Image_Data *original)
659 dst_data = scale_map + cserve2_shm_map_offset_get(scale_shm); 710 dst_data = scale_map + cserve2_shm_map_offset_get(scale_shm);
660 711
661 DBG("Scaling image ([%d,%d:%dx%d] --> [%d,%d:%dx%d])", 712 DBG("Scaling image ([%d,%d:%dx%d] --> [%d,%d:%dx%d])",
662 entry->opts.scale_load.src_x, entry->opts.scale_load.src_y, 713 idata->opts.scale_load.src_x, idata->opts.scale_load.src_y,
663 entry->opts.scale_load.src_w, entry->opts.scale_load.src_h, 714 idata->opts.scale_load.src_w, idata->opts.scale_load.src_h,
664 0, 0, 715 0, 0,
665 entry->opts.scale_load.dst_w, entry->opts.scale_load.dst_h); 716 idata->opts.scale_load.dst_w, idata->opts.scale_load.dst_h);
666 717
667 cserve2_rgba_image_scale_do(src_data, dst_data, 718 cserve2_rgba_image_scale_do(
668 entry->opts.scale_load.src_x, entry->opts.scale_load.src_y, 719 src_data, dst_data,
669 entry->opts.scale_load.src_w, entry->opts.scale_load.src_h, 720 idata->opts.scale_load.src_x, idata->opts.scale_load.src_y,
670 0, 0, 721 idata->opts.scale_load.src_w, idata->opts.scale_load.src_h,
671 entry->opts.scale_load.dst_w, entry->opts.scale_load.dst_h, 722 0, 0,
672 fd->alpha, entry->opts.scale_load.smooth); 723 idata->opts.scale_load.dst_w, idata->opts.scale_load.dst_h,
724 fd->alpha, idata->opts.scale_load.smooth);
673 725
674 cserve2_shm_unmap(original->shm); 726 cserve2_shm_unmap(original->shm);
675 cserve2_shm_unmap(scale_shm); 727 cserve2_shm_unmap(scale_shm);
@@ -678,51 +730,64 @@ _scaling_do(Shm_Handle *scale_shm, Image_Data *entry, Image_Data *original)
678} 730}
679 731
680static int 732static int
681_scaling_prepare_and_do(Image_Data *orig) 733_scaling_prepare_and_do(Image_Entry *ientry, Image_Data *idata)
682{ 734{
683 Shm_Handle *scale_shm; 735 Shm_Handle *scale_shm;
684 736
685 DBG("Original image's shm path %s", cserve2_shm_name_get(orig->shm)); 737 scale_shm = cserve2_shm_request("img", idata->opts.scale_load.dst_w
738 * idata->opts.scale_load.dst_h * 4);
686 739
687 scale_shm = cserve2_shm_request( 740 if (!scale_shm)
688 "img", 741 return -1;
689 orig->opts.scale_load.dst_w * orig->opts.scale_load.dst_h * 4);
690 742
691 DBG("Scale image's shm path %s", cserve2_shm_name_get(scale_shm)); 743 DBG("Scaling image from shm %s to shm %s",
744 cserve2_shm_name_get(ientry->shm), cserve2_shm_name_get(scale_shm));
692 745
693 if (_scaling_do(scale_shm, orig, orig)) return -1; 746 if (_scaling_do(scale_shm, idata, ientry) != 0)
747 return -1;
694 748
695 cserve2_shm_unref(orig->shm); /* unreference old shm */ 749 // Switch shm in original image
696 orig->shm = scale_shm; /* update shm */ 750 cserve2_shm_unref(ientry->shm);
751 cserve2_shared_string_del(idata->shm_id);
752 ientry->shm = scale_shm;
753 idata->shm_id = cserve2_shared_string_add(cserve2_shm_name_get(ientry->shm));
697 754
698 return 0; 755 return 0;
699} 756}
700 757
701static Msg_Loaded * 758static Msg_Loaded *
702_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size) 759_load_request_response(Image_Entry *ientry,
760 Slave_Msg_Image_Loaded *resp, int *size)
703{ 761{
704 _entry_load_finish(&e->base); 762 Image_Data *idata;
763
764 idata = _image_data_find(ENTRYID(ientry));
765 if (!idata)
766 {
767 ERR("Image data %u not found", ENTRYID(ientry));
768 return NULL;
769 }
705 770
706 e->base.request = NULL; 771 _entry_load_finish(ASENTRY(ientry));
772 ASENTRY(ientry)->request = NULL;
707 773
708 e->alpha_sparse = resp->alpha_sparse; 774 idata->alpha_sparse = resp->alpha_sparse;
709 if (!e->doload) 775 if (!idata->doload)
710 DBG("Entry %d loaded by speculative preload.", e->base.id); 776 DBG("Entry %d loaded by speculative preload.", idata->id);
711 777
712 if (_scaling_needed(e, resp)) 778 if (_scaling_needed(idata, resp))
713 { 779 {
780 DBG("About to scale image %u", idata->id);
714 781
715 DBG("About to scale down image %u", ASENTRY(e)->id); 782 if (!_scaling_prepare_and_do(ientry, idata))
716 783 DBG("Image %u has been scaled.", idata->id);
717 if (!_scaling_prepare_and_do(e))
718 DBG("Image %u has been scaled down.", ASENTRY(e)->id);
719 else 784 else
720 ERR("Failed to scale down image %u", ASENTRY(e)->id); 785 ERR("Failed to scale image %u", idata->id);
721 } 786 }
722 else 787 else
723 DBG("No scaling needed for image %u", ASENTRY(e)->id); 788 DBG("No scaling needed for image %u", idata->id);
724 789
725 return _image_loaded_msg_create(e, size); 790 return _image_loaded_msg_create(ientry, idata, size);
726} 791}
727 792
728static Slave_Request_Funcs _load_funcs = { 793static Slave_Request_Funcs _load_funcs = {
@@ -732,11 +797,14 @@ static Slave_Request_Funcs _load_funcs = {
732 .error = (Slave_Request_Error)_request_failed 797 .error = (Slave_Request_Error)_request_failed
733}; 798};
734 799
735static unsigned int 800static void
736_img_opts_id_get(unsigned int file_id, Evas_Image_Load_Opts *opts, 801_image_key_set(unsigned int file_id, const Evas_Image_Load_Opts *opts,
737 char *buf, int size) 802 char *buf, int size)
738{ 803{
739 uintptr_t image_id; 804 const char empty[sizeof(Evas_Image_Load_Opts)] = {0};
805
806 if (!opts)
807 opts = (Evas_Image_Load_Opts *) &empty;
740 808
741 snprintf(buf, size, 809 snprintf(buf, size,
742 "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:!([%d,%d:%dx%d]-[%dx%d:%d]):%d:%d", 810 "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:!([%d,%d:%dx%d]-[%dx%d:%d]):%d:%d",
@@ -748,25 +816,27 @@ _img_opts_id_get(unsigned int file_id, Evas_Image_Load_Opts *opts,
748 opts->scale_load.dst_w, opts->scale_load.dst_h, 816 opts->scale_load.dst_w, opts->scale_load.dst_h,
749 opts->scale_load.smooth, opts->degree, 817 opts->scale_load.smooth, opts->degree,
750 opts->orientation); 818 opts->orientation);
751
752 image_id = (uintptr_t)eina_hash_find(image_ids, buf);
753
754 return image_id;
755} 819}
756 820
757static unsigned int 821static unsigned int
758_image_data_opts_id_get(Image_Data *im, char *buf, int size) 822_image_opts_id_get(unsigned int file_id, Evas_Image_Load_Opts *opts,
823 char *buf, int size)
759{ 824{
760 return _img_opts_id_get(im->file_id, &im->opts, buf, size); 825 uintptr_t image_id;
826
827 _image_key_set(file_id, opts, buf, size);
828 image_id = (uintptr_t) eina_hash_find(image_ids, buf);
829
830 return (unsigned int) image_id;
761} 831}
762 832
763static int 833static int
764_image_entry_size_get(Image_Data *e) 834_image_entry_size_get(Image_Entry *ientry)
765{ 835{
766 int size = sizeof(Image_Data); 836 int size = sizeof(Image_Data);
767 /* XXX: get the overhead of the shm handler too */ 837 /* XXX: get the overhead of the shm handler too */
768 if (e->shm) 838 if (ientry->shm)
769 size += cserve2_shm_size_get(e->shm); 839 size += cserve2_shm_size_get(ientry->shm);
770 return size / 1024; 840 return size / 1024;
771} 841}
772 842
@@ -785,54 +855,75 @@ _file_id_free(File_Data *fd)
785} 855}
786 856
787static void 857static void
788_image_id_free(Image_Data *entry) 858_image_id_free(Image_Data *idata)
789{ 859{
790 char buf[4096]; 860 char buf[4096];
791 861
792 DBG("Removing entry image id: %d", entry->base.id); 862 DBG("Removing entry image id: %d", idata->id);
793 863
794 _image_data_opts_id_get(entry, buf, sizeof(buf)); 864 _image_opts_id_get(idata->file_id, &idata->opts, buf, sizeof(buf));
795 eina_hash_del_by_key(image_ids, buf); 865 eina_hash_del_by_key(image_ids, buf);
796} 866}
797 867
798static void 868static void
799_image_entry_free(Image_Data *entry) 869_image_entry_free(Image_Entry *ientry)
800{ 870{
801 File_Data *fd; 871 File_Data *fd;
802 File_Entry *fentry; 872 File_Entry *fentry;
873 Image_Data *idata;
803 874
804 if (entry->base.request) 875 idata = _image_data_find(ENTRYID(ientry));
805 cserve2_request_cancel_all(entry->base.request, CSERVE2_REQUEST_CANCEL); 876 if (!idata || !idata->refcount)
877 {
878 CRIT("Trying to free already freed object: %u", ENTRYID(ientry));
879 return;
880 }
806 881
807 if (entry->unused) 882 if (--idata->refcount > 0)
883 return;
884
885 if (ientry->base.request)
886 cserve2_request_cancel_all(ientry->base.request,
887 CSERVE2_REQUEST_CANCEL);
888
889 if (idata->unused)
808 { 890 {
809 image_entries_lru = eina_list_remove(image_entries_lru, entry); 891 image_entries_lru = eina_list_remove(image_entries_lru, ientry);
810 unused_mem_usage -= _image_entry_size_get(entry); 892 unused_mem_usage -= _image_entry_size_get(ientry);
811 } 893 }
812 894
813 fd = _file_data_find(entry->file_id); 895 fd = _file_data_find(idata->file_id);
814 if (fd) 896 if (fd)
815 { 897 {
816 fentry = _file_entry_find(fd->id); 898 fentry = _file_entry_find(fd->id);
817 fentry->images = eina_list_remove(fentry->images, entry); 899 fentry->images = eina_list_remove(fentry->images, ientry);
818 if (fentry && !fentry->images && !ASENTRY(fentry)->references) 900 if (fentry && !fentry->images && !ASENTRY(fentry)->references)
819 eina_hash_del_by_key(file_entries, &fd->id); 901 eina_hash_del_by_key(file_entries, &fd->id);
820 } 902 }
821 else 903 else
822 ERR("Could not find file data %u for image %u", 904 ERR("Could not find file data %u for image %u",
823 entry->file_id, ASENTRY(entry)->id); 905 idata->file_id, idata->id);
824 if (entry->shm) 906
825 cserve2_shm_unref(entry->shm); 907 if (ientry->shm)
826 free(entry); 908 cserve2_shm_unref(ientry->shm);
909 cserve2_shared_string_del(idata->shm_id);
910 idata->shm_id = 0;
911 free(ientry);
827} 912}
828 913
829static void 914static void
830_hash_image_entry_free(void *data) 915_hash_image_entry_free(void *data)
831{ 916{
832 Image_Data *entry = data; 917 Image_Entry *ientry = data;
918 Image_Data *idata;
833 919
834 _image_id_free(entry); 920 idata = _image_data_find(ENTRYID(ientry));
835 _image_entry_free(entry); 921 if (idata && idata->refcount > 0)
922 {
923 _image_id_free(idata);
924 _image_entry_free(ientry);
925 }
926 else ERR("Could not find image entry %u", ENTRYID(ientry));
836} 927}
837 928
838static void 929static void
@@ -847,7 +938,7 @@ _file_entry_free(File_Entry *fentry)
847 938
848 if (fentry->images) 939 if (fentry->images)
849 { 940 {
850 ERR("Freeing file %u image data still referenced.", ASENTRY(fentry)->id); 941 ERR("Freeing file %u image data still referenced.", ENTRYID(fentry));
851 eina_list_free(fentry->images); 942 eina_list_free(fentry->images);
852 } 943 }
853 if (ASENTRY(fentry)->request) 944 if (ASENTRY(fentry)->request)
@@ -886,7 +977,7 @@ _hash_file_entry_free(void *data)
886 // TODO: Add some checks to make sure that we are freeing an 977 // TODO: Add some checks to make sure that we are freeing an
887 // unused entry. 978 // unused entry.
888 979
889 fd = _file_data_find(ASENTRY(fentry)->id); 980 fd = _file_data_find(ENTRYID(fentry));
890 _file_id_free(fd); 981 _file_id_free(fd);
891 _file_data_free(fd); 982 _file_data_free(fd);
892 _file_entry_free(fentry); 983 _file_entry_free(fentry);
@@ -1046,7 +1137,7 @@ cserve2_cache_init(void)
1046 file_ids = eina_hash_string_superfast_new(NULL); 1137 file_ids = eina_hash_string_superfast_new(NULL);
1047 file_entries = eina_hash_int32_new(_hash_file_entry_free); 1138 file_entries = eina_hash_int32_new(_hash_file_entry_free);
1048 image_ids = eina_hash_string_superfast_new(NULL); 1139 image_ids = eina_hash_string_superfast_new(NULL);
1049 image_entries = eina_hash_string_superfast_new(_hash_image_entry_free); 1140 image_entries = eina_hash_int32_new(_hash_image_entry_free);
1050 file_watch = eina_hash_string_superfast_new(_file_watch_free); 1141 file_watch = eina_hash_string_superfast_new(_file_watch_free);
1051 1142
1052 font_sources = eina_hash_string_small_new(EINA_FREE_CB(_font_source_free)); 1143 font_sources = eina_hash_string_small_new(EINA_FREE_CB(_font_source_free));
@@ -1057,6 +1148,7 @@ cserve2_cache_init(void)
1057 5); 1148 5);
1058 1149
1059 _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0); 1150 _file_data_array = cserve2_shared_array_new(1, sizeof(File_Data), 0);
1151 _image_data_array = cserve2_shared_array_new(1, sizeof(Image_Data), 0);
1060} 1152}
1061 1153
1062void 1154void
@@ -1077,6 +1169,7 @@ cserve2_cache_shutdown(void)
1077 eina_hash_free(font_sources); 1169 eina_hash_free(font_sources);
1078 1170
1079 cserve2_shared_array_del(_file_data_array); 1171 cserve2_shared_array_del(_file_data_array);
1172 cserve2_shared_array_del(_image_data_array);
1080} 1173}
1081 1174
1082static Reference * 1175static Reference *
@@ -1096,25 +1189,29 @@ _entry_reference_add(Entry *entry, Client *client, unsigned int client_entry_id)
1096} 1189}
1097 1190
1098static void 1191static void
1099_entry_unused_push(Image_Data *e) 1192_entry_unused_push(Image_Entry *ientry)
1100{ 1193{
1101 int size = _image_entry_size_get(e); 1194 Image_Data *idata;
1195 int size;
1102 1196
1103 if ((size > max_unused_mem_usage) || !(e->doload)) 1197 idata = _image_data_find(ENTRYID(ientry));
1198
1199 size = _image_entry_size_get(ientry);
1200 if ((size > max_unused_mem_usage) || !(idata->doload))
1104 { 1201 {
1105 eina_hash_del_by_key(image_entries, &e->base.id); 1202 eina_hash_del_by_key(image_entries, &idata->id);
1106 return; 1203 return;
1107 } 1204 }
1108 while (image_entries_lru && 1205 while (image_entries_lru &&
1109 (size > (max_unused_mem_usage - unused_mem_usage))) 1206 (size > (max_unused_mem_usage - unused_mem_usage)))
1110 { 1207 {
1111 Entry *ie = eina_list_data_get(eina_list_last(image_entries_lru)); 1208 Image_Entry *ie = eina_list_data_get(eina_list_last(image_entries_lru));
1112 Eina_Bool ok = eina_hash_del_by_key(image_entries, &ie->id); 1209 Eina_Bool ok = eina_hash_del_by_key(image_entries, &(ENTRYID(ie)));
1113 if (!ok) 1210 if (!ok)
1114 { 1211 {
1115 DBG("Image %d was not found in the hash table!", ie->id); 1212 DBG("Image %d was not found in the hash table!", ENTRYID(ie));
1116 image_entries_lru = eina_list_remove(image_entries_lru, ie); 1213 image_entries_lru = eina_list_remove(image_entries_lru, ie);
1117 _image_entry_free((Image_Data*) ie); 1214 _image_entry_free(ie);
1118 } 1215 }
1119 } 1216 }
1120 if (!image_entries_lru && (unused_mem_usage != 0)) 1217 if (!image_entries_lru && (unused_mem_usage != 0))
@@ -1123,8 +1220,8 @@ _entry_unused_push(Image_Data *e)
1123 unused_mem_usage); 1220 unused_mem_usage);
1124 unused_mem_usage = 0; 1221 unused_mem_usage = 0;
1125 } 1222 }
1126 image_entries_lru = eina_list_append(image_entries_lru, e); 1223 image_entries_lru = eina_list_append(image_entries_lru, ientry);
1127 e->unused = EINA_TRUE; 1224 idata->unused = EINA_TRUE;
1128 unused_mem_usage += size; 1225 unused_mem_usage += size;
1129} 1226}
1130 1227
@@ -1154,15 +1251,20 @@ _entry_reference_del(Entry *entry, Reference *ref)
1154 } 1251 }
1155 else if (entry->type == CSERVE2_IMAGE_DATA) 1252 else if (entry->type == CSERVE2_IMAGE_DATA)
1156 { 1253 {
1157 Image_Data *ientry = (Image_Data *) entry; 1254 Image_Entry *ientry = (Image_Entry *) entry;
1158 File_Data *fd = _file_data_find(entry->id); 1255 Image_Data *idata = _image_data_find(entry->id);
1159 1256
1160 if (!fd) 1257 if (!idata || !idata->file_id)
1161 eina_hash_del_by_key(image_entries, &entry->id); 1258 eina_hash_del_by_key(image_entries, &entry->id);
1162 else if (fd->invalid)
1163 _image_entry_free(ientry);
1164 else 1259 else
1165 _entry_unused_push(ientry); 1260 {
1261 File_Data *fdata = _file_data_find(idata->file_id);
1262
1263 if (fdata->invalid)
1264 _image_entry_free(ientry);
1265 else
1266 _entry_unused_push(ientry);
1267 }
1166 } 1268 }
1167 else if (entry->type == CSERVE2_FONT_ENTRY) 1269 else if (entry->type == CSERVE2_FONT_ENTRY)
1168 { 1270 {
@@ -1249,14 +1351,17 @@ cserve2_cache_client_del(Client *client)
1249 } 1351 }
1250} 1352}
1251 1353
1252static Image_Data * 1354static Image_Entry *
1253_image_entry_new(Client *client, int rid, 1355_image_entry_new(Client *client, int rid,
1254 unsigned int client_file_id, unsigned int image_id, 1356 unsigned int client_file_id, unsigned int client_image_id,
1255 Evas_Image_Load_Opts *opts) 1357 Evas_Image_Load_Opts *opts, char *buf)
1256{ 1358{
1257 Reference *ref; 1359 Reference *ref, *oldref;
1258 Image_Data *im_entry; 1360 Image_Entry *ientry;
1361 Image_Data *idata;
1259 File_Data *fd; 1362 File_Data *fd;
1363 int idata_id;
1364 unsigned int image_id;
1260 1365
1261 ref = eina_hash_find(client->files.referencing, &client_file_id); 1366 ref = eina_hash_find(client->files.referencing, &client_file_id);
1262 if (!ref) 1367 if (!ref)
@@ -1275,32 +1380,62 @@ _image_entry_new(Client *client, int rid,
1275 return NULL; 1380 return NULL;
1276 } 1381 }
1277 1382
1278 im_entry = calloc(1, sizeof(*im_entry)); 1383 idata_id = cserve2_shared_array_item_new(_image_data_array);
1279 im_entry->base.type = CSERVE2_IMAGE_DATA; 1384 idata = cserve2_shared_array_item_data_get(_image_data_array, idata_id);
1280 im_entry->file_id = ref->entry->id; 1385 if (idata_id < 0 || !idata)
1386 {
1387 ERR("Could not create new image entry in shared array");
1388 cserve2_client_error_send(client, rid,
1389 CSERVE2_RESOURCE_ALLOCATION_FAILED);
1390 return NULL;
1391 }
1392
1393 image_id = ++_entry_id;
1394 while (eina_hash_find(image_entries, &image_id))
1395 image_id = ++_entry_id;
1396
1397 DBG("Creating new image entry: %u at index %d in shm %s",
1398 image_id, idata_id, cserve2_shared_array_name_get(_image_data_array));
1399
1400 ientry = calloc(1, sizeof(*ientry));
1401 ientry->base.id = image_id;
1402 ientry->base.type = CSERVE2_IMAGE_DATA;
1281 if (opts) 1403 if (opts)
1282 { 1404 {
1283 im_entry->opts.dpi = opts->dpi; 1405 idata->opts.dpi = opts->dpi;
1284 im_entry->opts.w = opts->w; 1406 idata->opts.w = opts->w;
1285 im_entry->opts.h = opts->h; 1407 idata->opts.h = opts->h;
1286 im_entry->opts.scale_down_by = opts->scale_down_by; 1408 idata->opts.scale_down_by = opts->scale_down_by;
1287 im_entry->opts.region.x = opts->region.x; 1409 idata->opts.region.x = opts->region.x;
1288 im_entry->opts.region.y = opts->region.y; 1410 idata->opts.region.y = opts->region.y;
1289 im_entry->opts.region.w = opts->region.w; 1411 idata->opts.region.w = opts->region.w;
1290 im_entry->opts.region.h = opts->region.h; 1412 idata->opts.region.h = opts->region.h;
1291 im_entry->opts.scale_load.src_x = opts->scale_load.src_x; 1413 idata->opts.scale_load.src_x = opts->scale_load.src_x;
1292 im_entry->opts.scale_load.src_y = opts->scale_load.src_y; 1414 idata->opts.scale_load.src_y = opts->scale_load.src_y;
1293 im_entry->opts.scale_load.src_w = opts->scale_load.src_w; 1415 idata->opts.scale_load.src_w = opts->scale_load.src_w;
1294 im_entry->opts.scale_load.src_h = opts->scale_load.src_h; 1416 idata->opts.scale_load.src_h = opts->scale_load.src_h;
1295 im_entry->opts.scale_load.dst_w = opts->scale_load.dst_w; 1417 idata->opts.scale_load.dst_w = opts->scale_load.dst_w;
1296 im_entry->opts.scale_load.dst_h = opts->scale_load.dst_h; 1418 idata->opts.scale_load.dst_h = opts->scale_load.dst_h;
1297 im_entry->opts.scale_load.smooth = opts->scale_load.smooth; 1419 idata->opts.scale_load.smooth = opts->scale_load.smooth;
1298 im_entry->opts.scale_load.scale_hint = opts->scale_load.scale_hint; 1420 idata->opts.scale_load.scale_hint = opts->scale_load.scale_hint;
1299 im_entry->opts.degree = opts->degree; 1421 idata->opts.degree = opts->degree;
1300 im_entry->opts.orientation = opts->orientation; 1422 idata->opts.orientation = opts->orientation;
1301 } 1423 }
1302 1424 idata->file_id = ref->entry->id;
1303 return im_entry; 1425 idata->refcount = 1;
1426 idata->id = image_id;
1427
1428 _image_key_set(idata->file_id, opts, buf, sizeof(buf));
1429 eina_hash_add(image_entries, &image_id, ientry);
1430 eina_hash_add(image_ids, buf, (void *)(intptr_t) image_id);
1431
1432 oldref = eina_hash_find(client->images.referencing, &client_image_id);
1433 ref = _entry_reference_add(ASENTRY(ientry), client, client_image_id);
1434 if (oldref)
1435 eina_hash_del_by_key(client->images.referencing, &client_image_id);
1436 eina_hash_add(client->images.referencing, &client_image_id, ref);
1437
1438 return ientry;
1304} 1439}
1305 1440
1306static void 1441static void
@@ -1313,7 +1448,7 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo
1313 EINA_LIST_FOREACH(fw->entries, l, fd) 1448 EINA_LIST_FOREACH(fw->entries, l, fd)
1314 { 1449 {
1315 Eina_List *ll; 1450 Eina_List *ll;
1316 Image_Data *ie; 1451 Image_Entry *ie;
1317 File_Entry *fentry; 1452 File_Entry *fentry;
1318 1453
1319 fd->invalid = EINA_TRUE; 1454 fd->invalid = EINA_TRUE;
@@ -1328,14 +1463,22 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo
1328 1463
1329 EINA_LIST_FOREACH(fentry->images, ll, ie) 1464 EINA_LIST_FOREACH(fentry->images, ll, ie)
1330 { 1465 {
1331 _image_id_free(ie); 1466 Image_Data *idata;
1332 eina_hash_set(image_entries, &ie->base.id, NULL); 1467
1333 if (ie->base.request /*&& !ie->base.request->processing*/) 1468 eina_hash_set(image_entries, &ENTRYID(ie), NULL);
1334 cserve2_request_cancel_all(ie->base.request, 1469 if (ASENTRY(ie)->request /*&& !ie->base.request->processing*/)
1470 cserve2_request_cancel_all(ASENTRY(ie)->request,
1335 CSERVE2_FILE_CHANGED); 1471 CSERVE2_FILE_CHANGED);
1336 ie->base.request = NULL; 1472 ASENTRY(ie)->request = NULL;
1337 if (ie->unused) 1473
1338 _image_entry_free(ie); 1474 idata = _image_data_find(ENTRYID(ie));
1475 if (idata)
1476 {
1477 _image_id_free(idata);
1478 if (idata->unused)
1479 _image_entry_free(ie);
1480 }
1481 else ERR("Image data %u not found", ENTRYID(ie));
1339 } 1482 }
1340 1483
1341 _file_id_free(fd); 1484 _file_id_free(fd);
@@ -1947,29 +2090,32 @@ static Eina_Bool
1947_image_data_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) 2090_image_data_entry_stats_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
1948{ 2091{
1949 Msg_Stats *msg = fdata; 2092 Msg_Stats *msg = fdata;
1950 Image_Data *id = data; 2093 Image_Entry *ientry = data;
2094 Image_Data *idata;
1951 File_Data *fd; 2095 File_Data *fd;
1952 2096
2097 idata = _image_data_find(ENTRYID(ientry));
2098
1953 // accounting numbers 2099 // accounting numbers
1954 msg->images.images_loaded++; 2100 msg->images.images_loaded++;
1955 if (id->unused) msg->images.images_unused++; 2101 if (idata->unused) msg->images.images_unused++;
1956 2102
1957 // accounting size 2103 // accounting size
1958 msg->images.images_size += _image_entry_size_get(id) * 1024; 2104 msg->images.images_size += _image_entry_size_get(ientry) * 1024;
1959 if (id->unused) msg->images.unused_size += _image_entry_size_get(id) * 1024; 2105 if (idata->unused) msg->images.unused_size += _image_entry_size_get(ientry) * 1024;
1960 2106
1961 fd = _file_data_find(id->file_id); 2107 fd = _file_data_find(idata->file_id);
1962 if (fd) 2108 if (fd)
1963 { 2109 {
1964 unsigned int image_size = fd->w * fd->h * 4; 2110 unsigned int image_size = fd->w * fd->h * 4;
1965 msg->images.requested_size += 2111 msg->images.requested_size +=
1966 (image_size * eina_list_count(id->base.references)); 2112 (image_size * eina_list_count(ASENTRY(ientry)->references));
1967 } 2113 }
1968 2114
1969#ifdef DEBUG_LOAD_TIME 2115#ifdef DEBUG_LOAD_TIME
1970 // accounting image entries load time 2116 // accounting image entries load time
1971 msg->images.images_load_time += id->base.load_time; 2117 msg->images.images_load_time += ASENTRY(ientry)->load_time;
1972 msg->images.images_saved_time += id->base.saved_time; 2118 msg->images.images_saved_time += ASENTRY(ientry)->saved_time;
1973#endif 2119#endif
1974 2120
1975 return EINA_TRUE; 2121 return EINA_TRUE;
@@ -2341,11 +2487,11 @@ cserve2_cache_file_close(Client *client, unsigned int client_file_id)
2341} 2487}
2342 2488
2343static int 2489static int
2344_cserve2_cache_fast_scaling_check(Client *client, Image_Data *entry) 2490_cserve2_cache_fast_scaling_check(Client *client, Image_Entry *ientry)
2345{ 2491{
2346 Eina_Iterator *iter; 2492 Eina_Iterator *iter;
2347 Image_Data *i; 2493 Image_Data *i;
2348 Image_Data *original = NULL; 2494 Image_Entry *original = NULL;
2349 Evas_Image_Load_Opts unscaled; 2495 Evas_Image_Load_Opts unscaled;
2350 char buf[4096]; 2496 char buf[4096];
2351 unsigned int image_id; 2497 unsigned int image_id;
@@ -2353,8 +2499,13 @@ _cserve2_cache_fast_scaling_check(Client *client, Image_Data *entry)
2353 int dst_w, dst_h; 2499 int dst_w, dst_h;
2354 Eina_Bool first_attempt = EINA_TRUE; 2500 Eina_Bool first_attempt = EINA_TRUE;
2355 File_Entry *fentry; 2501 File_Entry *fentry;
2502 Image_Data *idata;
2503
2504#warning NOT IMPLEMENTED. PLEASE REIMLPEMENT.
2505 return -1;
2506#if 0
2356 2507
2357 if (!entry) return -1; 2508 if (!ientry || !idata) return -1;
2358 2509
2359 dst_w = entry->opts.scale_load.dst_w; 2510 dst_w = entry->opts.scale_load.dst_w;
2360 dst_h = entry->opts.scale_load.dst_h; 2511 dst_h = entry->opts.scale_load.dst_h;
@@ -2375,7 +2526,7 @@ _cserve2_cache_fast_scaling_check(Client *client, Image_Data *entry)
2375 unscaled.scale_load.smooth = entry->opts.scale_load.smooth; 2526 unscaled.scale_load.smooth = entry->opts.scale_load.smooth;
2376 2527
2377try_again: 2528try_again:
2378 image_id = _img_opts_id_get(entry->file_id, &unscaled, buf, sizeof(buf)); 2529 image_id = _image_opts_id_get(entry->file_id, &unscaled, buf, sizeof(buf));
2379 if (image_id) 2530 if (image_id)
2380 { 2531 {
2381 original = eina_hash_find(image_entries, &image_id); 2532 original = eina_hash_find(image_entries, &image_id);
@@ -2430,12 +2581,7 @@ try_again:
2430 0, &unscaled); 2581 0, &unscaled);
2431 if (!original) return -1; 2582 if (!original) return -1;
2432 2583
2433 image_id = ++_entry_id; 2584 // NOTE: NOT NEEDED ANYMORE. FIXME
2434 while ((image_id == 0) || (eina_hash_find(image_entries, &image_id)))
2435 image_id = ++_entry_id;
2436 DBG("Creating new image_id: %d", image_id);
2437
2438 original->base.id = image_id;
2439 eina_hash_add(image_entries, &image_id, original); 2585 eina_hash_add(image_entries, &image_id, original);
2440 eina_hash_add(image_ids, buf, (void *)(intptr_t)image_id); 2586 eina_hash_add(image_ids, buf, (void *)(intptr_t)image_id);
2441 _entry_unused_push(original); 2587 _entry_unused_push(original);
@@ -2478,95 +2624,95 @@ do_scaling:
2478 image_entries_lru = eina_list_prepend(image_entries_lru, original); 2624 image_entries_lru = eina_list_prepend(image_entries_lru, original);
2479 } 2625 }
2480 return 0; 2626 return 0;
2627#endif
2481} 2628}
2482 2629
2483int 2630int
2484cserve2_cache_image_entry_create(Client *client, int rid, 2631cserve2_cache_image_entry_create(Client *client, int rid,
2485 unsigned int file_id, 2632 unsigned int client_file_id,
2486 unsigned int client_image_id, 2633 unsigned int client_image_id,
2487 Evas_Image_Load_Opts *opts) 2634 Evas_Image_Load_Opts *opts)
2488{ 2635{
2489 Image_Data *entry; 2636 Image_Data *idata;
2490 Reference *ref, *oldref; 2637 Image_Entry *ientry;
2638 Reference *ref;
2491 File_Entry *fentry; 2639 File_Entry *fentry;
2492 unsigned int image_id; 2640 unsigned int image_id = 0;
2493 char buf[4096]; 2641 char buf[4096];
2494 2642
2495 oldref = eina_hash_find(client->images.referencing, &client_image_id);
2496
2497 // search whether the image is already loaded by another client 2643 // search whether the image is already loaded by another client
2498 entry = _image_entry_new(client, rid, file_id, client_image_id, opts); 2644 ref = eina_hash_find(client->files.referencing, &client_file_id);
2499 if (!entry) 2645 if (ref && opts)
2500 return -1; 2646 image_id = _image_opts_id_get(ref->entry->id, opts, buf, sizeof(buf));
2501 image_id = _image_data_opts_id_get(entry, buf, sizeof(buf)); 2647
2502 if (image_id) 2648 if (image_id)
2503 { // if so, just update the references 2649 {
2504 free(entry); 2650 // Just update the references
2651 Reference *oldref;
2652
2505 DBG("found image_id %d for client image id %d", 2653 DBG("found image_id %d for client image id %d",
2506 image_id, client_image_id); 2654 image_id, client_image_id);
2507 entry = eina_hash_find(image_entries, &image_id); 2655 ientry = _image_entry_find(image_id);
2508 if (!entry) 2656 idata = _image_data_find(image_id);
2657 if (!ientry || !idata)
2509 { 2658 {
2510 ERR("image id %d is in file_ids hash, but not in entries hash" 2659 ERR("image entry %d (client id: %d) corrupted: entry %p data %p",
2511 "with entry id %d.", client_image_id, image_id); 2660 image_id, client_image_id, ientry, idata);
2512 cserve2_client_error_send(client, rid, CSERVE2_INVALID_CACHE); 2661 cserve2_client_error_send(client, rid, CSERVE2_INVALID_CACHE);
2513 return -1; 2662 return -1;
2514 } 2663 }
2515 2664
2516 if (entry->unused) 2665 // FIXME: This might be broken (wrt. refcounting)
2666 if (idata->unused)
2517 { 2667 {
2518 DBG("Re-using old image entry (id: %d) from the LRU list.", 2668 DBG("Re-using old image entry (id: %d) from the LRU list.",
2519 entry->base.id); 2669 ientry->base.id);
2520 entry->unused = EINA_FALSE; 2670 idata->unused = EINA_FALSE;
2521 image_entries_lru = eina_list_remove(image_entries_lru, entry); 2671 idata->refcount++;
2522 unused_mem_usage -= _image_entry_size_get(entry); 2672 image_entries_lru = eina_list_remove(image_entries_lru, ientry);
2673 unused_mem_usage -= _image_entry_size_get(ientry);
2523 } 2674 }
2524 _entry_load_reused(&entry->base); 2675 _entry_load_reused(&ientry->base);
2525 2676
2677 oldref = eina_hash_find(client->images.referencing, &client_image_id);
2526 if (oldref && (oldref->entry->id == image_id)) 2678 if (oldref && (oldref->entry->id == image_id))
2527 return 0; 2679 return 0;
2528 2680
2529 ref = _entry_reference_add((Entry *)entry, client, client_image_id); 2681 ref = _entry_reference_add(ASENTRY(ientry), client, client_image_id);
2530
2531 if (oldref) 2682 if (oldref)
2532 eina_hash_del_by_key(client->images.referencing, &client_image_id); 2683 eina_hash_del_by_key(client->images.referencing, &client_image_id);
2533
2534 eina_hash_add(client->images.referencing, &client_image_id, ref); 2684 eina_hash_add(client->images.referencing, &client_image_id, ref);
2685
2535 return 0; 2686 return 0;
2536 } 2687 }
2537 2688
2538 image_id = ++_entry_id; 2689 ientry = _image_entry_new(client, rid, client_file_id, client_image_id,
2539 while ((image_id == 0) || (eina_hash_find(image_entries, &image_id))) 2690 opts, buf);
2540 image_id = ++_entry_id; 2691 if (!ientry)
2541 2692 return -1;
2542 entry->base.id = image_id;
2543 eina_hash_add(image_entries, &image_id, entry);
2544 eina_hash_add(image_ids, buf, (void *)(intptr_t)image_id);
2545 ref = _entry_reference_add((Entry *)entry, client, client_image_id);
2546
2547 if (oldref)
2548 eina_hash_del_by_key(client->images.referencing, &client_image_id);
2549 eina_hash_add(client->images.referencing, &client_image_id, ref);
2550 2693
2551 fentry = _file_entry_find(entry->file_id); 2694 fentry = _file_entry_find(ref->entry->id);
2552 fentry->images = eina_list_append(fentry->images, entry); 2695 fentry->images = eina_list_append(fentry->images, ientry);
2553 2696
2554 if (opts && opts->scale_load.dst_w && opts->scale_load.dst_h) 2697 if (opts && opts->scale_load.dst_w && opts->scale_load.dst_h)
2555 { 2698 {
2556 if (!_cserve2_cache_fast_scaling_check(client, entry)) 2699 if (!_cserve2_cache_fast_scaling_check(client, ientry))
2557 return 0; 2700 return 0;
2558 } 2701 }
2559 2702
2560 ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD, 2703 ASENTRY(ientry)->request = cserve2_request_add(
2561 0, NULL, ASENTRY(fentry)->request, 2704 CSERVE2_REQ_IMAGE_SPEC_LOAD,
2562 &_load_funcs, entry); 2705 0, NULL, ASENTRY(fentry)->request,
2706 &_load_funcs, ientry);
2707
2563 return 0; 2708 return 0;
2564} 2709}
2565 2710
2566void 2711void
2567cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid) 2712cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid)
2568{ 2713{
2569 Image_Data *entry; 2714 Image_Entry *ientry;
2715 Image_Data *idata;
2570 Reference *ref; 2716 Reference *ref;
2571 File_Data *fd; 2717 File_Data *fd;
2572 2718
@@ -2578,8 +2724,15 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned
2578 return; 2724 return;
2579 } 2725 }
2580 2726
2581 entry = (Image_Data *) ref->entry; 2727 ientry = (Image_Entry *) ref->entry;
2582 fd = _file_data_find(entry->file_id); 2728 idata = _image_data_find(ENTRYID(ientry));
2729 if (!idata)
2730 {
2731 ERR("Image data not found for entry %u", ENTRYID(ientry));
2732 return;
2733 }
2734
2735 fd = _file_data_find(idata->file_id);
2583 if (!fd || fd->invalid) 2736 if (!fd || fd->invalid)
2584 { 2737 {
2585 cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED); 2738 cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED);
@@ -2589,72 +2742,35 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned
2589 DBG("Loading image id: %d", ref->entry->id); 2742 DBG("Loading image id: %d", ref->entry->id);
2590 2743
2591 // File already being loaded, just add the request to be replied 2744 // File already being loaded, just add the request to be replied
2592 if (entry->base.request) 2745 if (ASENTRY(ientry)->request)
2593 { 2746 {
2594 cserve2_request_waiter_add(entry->base.request, rid, client); 2747 cserve2_request_waiter_add(ASENTRY(ientry)->request, rid, client);
2595 if (!entry->doload) 2748 if (!idata->doload)
2596 cserve2_request_type_set(entry->base.request, CSERVE2_REQ_IMAGE_LOAD); 2749 {
2750 cserve2_request_type_set(ASENTRY(ientry)->request,
2751 CSERVE2_REQ_IMAGE_LOAD);
2752 }
2597 } 2753 }
2598 else if (entry->shm) 2754 else if (ientry->shm)
2599 _image_loaded_send(client, entry, rid); 2755 _image_loaded_send(client, ientry, idata, rid);
2600 else 2756 else
2601 { 2757 {
2602 File_Entry *fentry = _file_entry_find(entry->file_id); 2758 File_Entry *fentry = _file_entry_find(idata->file_id);
2603 ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD, 2759 ASENTRY(ientry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD,
2604 rid, client, 2760 rid, client,
2605 ASENTRY(fentry)->request, 2761 ASENTRY(fentry)->request,
2606 &_load_funcs, 2762 &_load_funcs,
2607 entry); 2763 ientry);
2608 } 2764 }
2609 2765
2610 entry->doload = EINA_TRUE; 2766 idata->doload = EINA_TRUE;
2611} 2767}
2612 2768
2613void 2769void
2614cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid) 2770cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid)
2615{ 2771{
2616 Image_Data *entry; 2772 // Same as normal load (for now)
2617 Reference *ref; 2773 return cserve2_cache_image_load(client, client_image_id, rid);
2618 File_Data *fd;
2619
2620 ref = eina_hash_find(client->images.referencing, &client_image_id);
2621 if (!ref)
2622 {
2623 ERR("Can't load: client %d has no image id %d",
2624 client->id, client_image_id);
2625 return;
2626 }
2627
2628 entry = (Image_Data *) ref->entry;
2629 fd = _file_data_find(entry->file_id);
2630 if (!fd || fd->invalid)
2631 {
2632 cserve2_client_error_send(client, rid, CSERVE2_FILE_CHANGED);
2633 return;
2634 }
2635
2636 DBG("Loading image id: %d", ref->entry->id);
2637
2638 // File already being loaded, just add the request to be replied
2639 if (entry->base.request)
2640 {
2641 cserve2_request_waiter_add(entry->base.request, rid, client);
2642 if (!entry->doload)
2643 cserve2_request_type_set(entry->base.request, CSERVE2_REQ_IMAGE_LOAD);
2644 }
2645 else if (entry->shm)
2646 _image_loaded_send(client, entry, rid);
2647 else
2648 {
2649 File_Entry *fentry = _file_entry_find(entry->file_id);
2650 ASENTRY(entry)->request = cserve2_request_add(CSERVE2_REQ_IMAGE_LOAD,
2651 rid, client,
2652 ASENTRY(fentry)->request,
2653 &_load_funcs,
2654 entry);
2655 }
2656
2657 entry->doload = EINA_TRUE;
2658} 2774}
2659 2775
2660void 2776void
diff --git a/src/bin/evas/evas_cserve2_index.c b/src/bin/evas/evas_cserve2_index.c
index dd335d8ce2..debaedce53 100644
--- a/src/bin/evas/evas_cserve2_index.c
+++ b/src/bin/evas/evas_cserve2_index.c
@@ -759,17 +759,18 @@ cserve2_shared_mempool_buffer_ref(Shared_Mempool *sm, int bufferid)
759 return ie->id; 759 return ie->id;
760} 760}
761 761
762void 762static Eina_Bool
763cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid) 763_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid)
764{ 764{
765 Index_Entry *ie; 765 Index_Entry *ie;
766 766
767 if (!sm || !bufferid) return; 767 if (!sm || !bufferid) return EINA_FALSE;
768
768 ie = _shared_index_entry_find(sm->index, bufferid); 769 ie = _shared_index_entry_find(sm->index, bufferid);
769 if (!ie || ie->refcount <= 0) 770 if (!ie || ie->refcount <= 0)
770 { 771 {
771 CRIT("Tried to delete invalid buffer or with refcount 0"); 772 CRIT("Tried to delete invalid buffer or with refcount 0");
772 return; 773 return EINA_FALSE;
773 } 774 }
774 775
775 ie->refcount--; 776 ie->refcount--;
@@ -782,7 +783,16 @@ cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid)
782 sm->empty_blocks = (Block *) eina_rbtree_inline_insert( 783 sm->empty_blocks = (Block *) eina_rbtree_inline_insert(
783 EINA_RBTREE_GET(sm->empty_blocks), EINA_RBTREE_GET(newblk), 784 EINA_RBTREE_GET(sm->empty_blocks), EINA_RBTREE_GET(newblk),
784 EINA_RBTREE_CMP_NODE_CB(_block_rbtree_cmp), NULL); 785 EINA_RBTREE_CMP_NODE_CB(_block_rbtree_cmp), NULL);
786 return EINA_TRUE;
785 } 787 }
788
789 return EINA_FALSE;
790}
791
792void
793cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid)
794{
795 _shared_mempool_buffer_del(sm, bufferid);
786} 796}
787 797
788void * 798void *