diff options
author | Shinwoo Kim <cinoo.kim@samsung.com> | 2018-08-23 05:56:58 +0000 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2018-11-29 16:01:48 -0800 |
commit | 3a89ea15b9d58f195986cb363f421782b0150272 (patch) | |
tree | cc2d486e18ea5c6bd90494f3365aefaee8d0e601 /src | |
parent | 3f2560a8213d8d4dfc4c7516248fa8cc0712ad49 (diff) |
evas cache image: compare with cached image file
As cache2 knows cached image could be not matched even though
hash key is not different.
Please refer to the following comment of evas_cache2_image_open.
/* image we found doesn't match what's on disk (stat info wise)
* so dirty the active cache entry so we never find it again. this
* also implicitly guarantees that we only have 1 active copy
* of an image at a given key. we wither find it and keep re-reffing
* it or we dirty it and get it out */
The hash key is created base on the image file address.
If the image file address to find does not equal cached image file address
then it means that the cached image is no longer valid.
This case could happen with the following step.
(1) Call evas_object_image_memfile_set with content data A
(2) Call evas_object_image_memfile_set with content data B
(3) Add timer with short time (ex: 0.01 sec)
(4) Delete A image, and add A image in timer callback
(5) Delete B image, and add B image in timer callback
Sometimes you could see image of A from the B image, because newly created
image at step 5 has same address of setp 1.
Reviewed-by: Cedric BAIL <cedric.bail@free.fr>
Differential Revision: https://phab.enlightenment.org/D6870
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/evas/cache/evas_cache_image.c | 46 | ||||
-rw-r--r-- | src/tests/evas/evas_test_image.c | 103 |
2 files changed, 133 insertions, 16 deletions
diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 52447df9d0..adc38a86ec 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c | |||
@@ -796,28 +796,42 @@ evas_cache_image_mmap_request(Evas_Cache_Image *cache, | |||
796 | /* find image by key in active mmap hash */ | 796 | /* find image by key in active mmap hash */ |
797 | SLKL(engine_lock); | 797 | SLKL(engine_lock); |
798 | im = eina_hash_find(cache->mmap_activ, hkey); | 798 | im = eina_hash_find(cache->mmap_activ, hkey); |
799 | if ((im) && (!im->load_failed)) goto on_ok; | 799 | if (im) |
800 | else if ((im) && (im->load_failed)) | ||
801 | { | 800 | { |
802 | _evas_cache_image_dirty_add(im); | 801 | if (im->f != f) |
803 | im = NULL; | 802 | { |
803 | /* as active cache find - if we match in lru and its invalid, dirty */ | ||
804 | _evas_cache_image_dirty_add(im); | ||
805 | /* this image never used, so it have to be deleted */ | ||
806 | _evas_cache_image_entry_delete(cache, im); | ||
807 | im = NULL; | ||
808 | } | ||
809 | else if (!im->load_failed) goto on_ok; | ||
810 | else if (im->load_failed) | ||
811 | { | ||
812 | _evas_cache_image_dirty_add(im); | ||
813 | im = NULL; | ||
814 | } | ||
804 | } | 815 | } |
805 | 816 | ||
806 | /* find image by key in inactive/lru hash */ | 817 | /* find image by key in inactive/lru hash */ |
807 | im = eina_hash_find(cache->mmap_inactiv, hkey); | 818 | im = eina_hash_find(cache->mmap_inactiv, hkey); |
808 | if ((im) && (!im->load_failed)) | 819 | if (im) |
809 | { | ||
810 | _evas_cache_image_lru_del(im); | ||
811 | _evas_cache_image_activ_add(im); | ||
812 | goto on_ok; | ||
813 | } | ||
814 | else if ((im) && (im->load_failed)) | ||
815 | { | 820 | { |
816 | /* as active cache find - if we match in lru and its invalid, dirty */ | 821 | if (im->f != f) |
817 | _evas_cache_image_dirty_add(im); | 822 | { |
818 | /* this image never used, so it have to be deleted */ | 823 | /* as active cache find - if we match in lru and its invalid, dirty */ |
819 | _evas_cache_image_entry_delete(cache, im); | 824 | _evas_cache_image_dirty_add(im); |
820 | im = NULL; | 825 | /* this image never used, so it have to be deleted */ |
826 | _evas_cache_image_entry_delete(cache, im); | ||
827 | im = NULL; | ||
828 | } | ||
829 | else if (!im->load_failed) | ||
830 | { | ||
831 | _evas_cache_image_lru_del(im); | ||
832 | _evas_cache_image_activ_add(im); | ||
833 | goto on_ok; | ||
834 | } | ||
821 | } | 835 | } |
822 | 836 | ||
823 | im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); | 837 | im = _evas_cache_image_entry_new(cache, hkey, NULL, f, NULL, key, lo, error); |
diff --git a/src/tests/evas/evas_test_image.c b/src/tests/evas/evas_test_image.c index bbe64654af..9e7da26b16 100644 --- a/src/tests/evas/evas_test_image.c +++ b/src/tests/evas/evas_test_image.c | |||
@@ -627,6 +627,108 @@ EFL_START_TEST(evas_object_image_partially_load_orientation) | |||
627 | } | 627 | } |
628 | EFL_END_TEST | 628 | EFL_END_TEST |
629 | 629 | ||
630 | static int | ||
631 | _file_to_memory(const char *filename, char **result) | ||
632 | { | ||
633 | int size; | ||
634 | FILE *f; | ||
635 | |||
636 | f = fopen(filename, "rb"); | ||
637 | if (f == NULL) | ||
638 | { | ||
639 | *result = NULL; | ||
640 | return -1; | ||
641 | } | ||
642 | |||
643 | fseek(f, 0, SEEK_END); | ||
644 | size = ftell(f); | ||
645 | fseek(f, 0, SEEK_SET); | ||
646 | *result = (char *)malloc(size + 1); | ||
647 | if ((size_t)size != fread(*result, sizeof(char), size, f)) | ||
648 | { | ||
649 | free(*result); | ||
650 | return -1; | ||
651 | } | ||
652 | fclose(f); | ||
653 | (*result)[size] = 0; | ||
654 | return size; | ||
655 | } | ||
656 | |||
657 | EFL_START_TEST(evas_object_image_cached_data_comparision) | ||
658 | { | ||
659 | int i; | ||
660 | int size, size2; | ||
661 | char *content, *content2; | ||
662 | int w, h, n_w, n_h; | ||
663 | int w2, h2, n_w2, n_h2; | ||
664 | const uint32_t *d, *n_d; | ||
665 | const uint32_t *d2, *n_d2; | ||
666 | const char *img_path, *img_path2; | ||
667 | Evas_Object *img, *img2; | ||
668 | |||
669 | Evas *e = _setup_evas(); | ||
670 | |||
671 | img_path = TESTS_IMG_DIR "/Pic1.png"; | ||
672 | size = _file_to_memory(img_path, &content); | ||
673 | fail_if(size < 0); | ||
674 | |||
675 | img = evas_object_image_add(e); | ||
676 | evas_object_image_memfile_set(img, content, size, "png", NULL); | ||
677 | evas_object_image_fill_set(img, 0, 0, 250, 250); | ||
678 | evas_object_resize(img, 250, 250); | ||
679 | evas_object_move(img, 0, 0); | ||
680 | evas_object_show(img); | ||
681 | |||
682 | evas_object_image_size_get(img, &w, &h); | ||
683 | d = evas_object_image_data_get(img, EINA_FALSE); | ||
684 | |||
685 | img_path2 = TESTS_IMG_DIR "/Pic4.png"; | ||
686 | size2 = _file_to_memory(img_path2, &content2); | ||
687 | |||
688 | img2 = evas_object_image_add(e); | ||
689 | evas_object_image_memfile_set(img2, content2, size2, "png", NULL); | ||
690 | evas_object_image_fill_set(img2, 0, 0, 250, 250); | ||
691 | evas_object_resize(img2, 250, 250); | ||
692 | evas_object_move(img2, 250, 250); | ||
693 | evas_object_show(img2); | ||
694 | |||
695 | evas_object_image_size_get(img, &w2, &h2); | ||
696 | d2 = evas_object_image_data_get(img, EINA_FALSE); | ||
697 | |||
698 | for (i = 0; i < 100; i++) | ||
699 | { | ||
700 | evas_object_del(img); | ||
701 | evas_object_del(img2); | ||
702 | |||
703 | img = evas_object_image_add(e); | ||
704 | evas_object_image_memfile_set(img, content, size, "png", NULL); | ||
705 | evas_object_image_fill_set(img, 0, 0, 250, 250); | ||
706 | evas_object_resize(img, 250, 250); | ||
707 | evas_object_move(img, 0, 0); | ||
708 | evas_object_show(img); | ||
709 | |||
710 | evas_object_image_size_get(img, &n_w, &n_h); | ||
711 | n_d = evas_object_image_data_get(img, EINA_FALSE); | ||
712 | |||
713 | fail_if(w != n_w || h != n_h); | ||
714 | fail_if(memcmp(d, n_d, w * h * 4)); | ||
715 | |||
716 | img2 = evas_object_image_add(e); | ||
717 | evas_object_image_memfile_set(img2, content2, size2, "png", NULL); | ||
718 | evas_object_image_fill_set(img2, 0, 0, 250, 250); | ||
719 | evas_object_resize(img2, 250, 250); | ||
720 | evas_object_move(img2, 250, 250); | ||
721 | evas_object_show(img2); | ||
722 | |||
723 | evas_object_image_size_get(img, &n_w2, &n_h2); | ||
724 | n_d2 = evas_object_image_data_get(img, EINA_FALSE); | ||
725 | |||
726 | fail_if(w2 != n_w2 || h2 != n_h2); | ||
727 | fail_if(memcmp(d2, n_d2, w2 * h2 * 4)); | ||
728 | } | ||
729 | } | ||
730 | EFL_END_TEST | ||
731 | |||
630 | EFL_START_TEST(evas_object_image_defaults) | 732 | EFL_START_TEST(evas_object_image_defaults) |
631 | { | 733 | { |
632 | Evas *e = _setup_evas(); | 734 | Evas *e = _setup_evas(); |
@@ -891,6 +993,7 @@ void evas_test_image_object(TCase *tc) | |||
891 | tcase_add_test(tc, evas_object_image_map_unmap); | 993 | tcase_add_test(tc, evas_object_image_map_unmap); |
892 | #endif | 994 | #endif |
893 | tcase_add_test(tc, evas_object_image_partially_load_orientation); | 995 | tcase_add_test(tc, evas_object_image_partially_load_orientation); |
996 | tcase_add_test(tc, evas_object_image_cached_data_comparision); | ||
894 | } | 997 | } |
895 | 998 | ||
896 | 999 | ||