summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2008-12-02 02:32:22 +0000
committerCarsten Haitzler <raster@rasterman.com>2008-12-02 02:32:22 +0000
commit72c25fd2fc3f44205f85f77867c77358c7ab57db (patch)
tree06ae815f9e2126eb794b8c7252cc466c456c874d
parent1a897239c71ad8af78dbf80f058a4351e19aaae0 (diff)
quick - evas scalecache put this in svn do i dont lose my patch. i'll revert
and work on gettign the leak fixed. SVN revision: 37898
Diffstat (limited to '')
-rw-r--r--legacy/evas/configure.ac4
-rw-r--r--legacy/evas/src/lib/cache/evas_cache.h4
-rw-r--r--legacy/evas/src/lib/cache/evas_cache_engine_image.c3
-rw-r--r--legacy/evas/src/lib/cache/evas_cache_image.c132
-rw-r--r--legacy/evas/src/lib/engines/common/evas_image_load.c4
-rw-r--r--legacy/evas/src/lib/engines/common/evas_image_main.c31
-rw-r--r--legacy/evas/src/lib/engines/common/evas_scale_sample.c5
-rw-r--r--legacy/evas/src/lib/include/evas_common.h100
-rw-r--r--legacy/evas/src/modules/engines/software_generic/evas_engine.c243
9 files changed, 449 insertions, 77 deletions
diff --git a/legacy/evas/configure.ac b/legacy/evas/configure.ac
index 29b2ac07a3..b3a109318f 100644
--- a/legacy/evas/configure.ac
+++ b/legacy/evas/configure.ac
@@ -386,7 +386,9 @@ AC_CHECK_HEADERS(pthread.h sched.h,
386) 386)
387### disable pthreads by default for now - some wierd deadlock issue with 387### disable pthreads by default for now - some wierd deadlock issue with
388# barriers (makes no sense) 388# barriers (makes no sense)
389#build_pthreads="no" 389# disable pthread code - messes with scalecache (whihc really is a much
390# bigger general speedup
391build_pthreads="no"
390AC_MSG_CHECKING(whether to build pthread code) 392AC_MSG_CHECKING(whether to build pthread code)
391AC_ARG_ENABLE(pthreads, 393AC_ARG_ENABLE(pthreads,
392 AC_HELP_STRING([--enable-pthreads], [enable threaded rendering]), 394 AC_HELP_STRING([--enable-pthreads], [enable threaded rendering]),
diff --git a/legacy/evas/src/lib/cache/evas_cache.h b/legacy/evas/src/lib/cache/evas_cache.h
index f3cee96c27..142f3c6b44 100644
--- a/legacy/evas/src/lib/cache/evas_cache.h
+++ b/legacy/evas/src/lib/cache/evas_cache.h
@@ -57,6 +57,9 @@ struct _Evas_Cache_Image
57 int usage; 57 int usage;
58 int limit; 58 int limit;
59 int references; 59 int references;
60
61 Eina_List *scaled;
62 int scaledmem;
60}; 63};
61 64
62struct _Evas_Cache_Engine_Image_Func 65struct _Evas_Cache_Engine_Image_Func
@@ -126,6 +129,7 @@ EAPI Image_Entry* evas_cache_image_alone(Image_Entry *im);
126EAPI Image_Entry* evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h); 129EAPI Image_Entry* evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h);
127EAPI void evas_cache_image_load_data(Image_Entry *im); 130EAPI void evas_cache_image_load_data(Image_Entry *im);
128EAPI void evas_cache_image_surface_alloc(Image_Entry *im, int w, int h); 131EAPI void evas_cache_image_surface_alloc(Image_Entry *im, int w, int h);
132EAPI void evas_cache_image_surface_dealloc(Image_Entry *im);
129EAPI DATA32* evas_cache_image_pixels(Image_Entry *im); 133EAPI DATA32* evas_cache_image_pixels(Image_Entry *im);
130EAPI Image_Entry* evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace); 134EAPI Image_Entry* evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace);
131EAPI Image_Entry* evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace); 135EAPI Image_Entry* evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace);
diff --git a/legacy/evas/src/lib/cache/evas_cache_engine_image.c b/legacy/evas/src/lib/cache/evas_cache_engine_image.c
index d048dc4c82..76b4121c46 100644
--- a/legacy/evas/src/lib/cache/evas_cache_engine_image.c
+++ b/legacy/evas/src/lib/cache/evas_cache_engine_image.c
@@ -192,7 +192,7 @@ evas_cache_engine_image_init(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_
192 parent->references++; 192 parent->references++;
193 193
194 new->brother = NULL; 194 new->brother = NULL;
195 195
196 return new; 196 return new;
197} 197}
198 198
@@ -260,6 +260,7 @@ evas_cache_engine_image_flush(Evas_Cache_Engine_Image *cache)
260 eim = (Engine_Image_Entry *) cache->lru->last; 260 eim = (Engine_Image_Entry *) cache->lru->last;
261 _evas_cache_engine_image_dealloc(cache, eim); 261 _evas_cache_engine_image_dealloc(cache, eim);
262 } 262 }
263 evas_common_image_set_cache(evas_common_image_get_cache());
263} 264}
264 265
265EAPI void 266EAPI void
diff --git a/legacy/evas/src/lib/cache/evas_cache_image.c b/legacy/evas/src/lib/cache/evas_cache_image.c
index bc9c328ade..73477d7533 100644
--- a/legacy/evas/src/lib/cache/evas_cache_image.c
+++ b/legacy/evas/src/lib/cache/evas_cache_image.c
@@ -45,19 +45,38 @@ static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry
45 45
46static void 46static void
47_evas_cache_image_make_dirty(Evas_Cache_Image *cache, 47_evas_cache_image_make_dirty(Evas_Cache_Image *cache,
48 Image_Entry *im) 48 Image_Entry *ie)
49{ 49{
50 im->flags.cached = 1; 50 ie->flags.cached = 1;
51 im->flags.dirty = 1; 51 ie->flags.dirty = 1;
52 im->flags.activ = 0; 52 ie->flags.activ = 0;
53 im->flags.lru_nodata = 0; 53 ie->flags.lru_nodata = 0;
54 cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im)); 54 cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(ie));
55 55
56 if (im->cache_key) 56 if (ie->cache_key)
57 { 57 {
58 eina_stringshare_del(im->cache_key); 58 eina_stringshare_del(ie->cache_key);
59 im->cache_key = NULL; 59 ie->cache_key = NULL;
60 } 60 }
61
62 while (ie->scalecache.others)
63 {
64 Image_Entry *ie2;
65
66 ie2 = ie->scalecache.others->data;
67 cache->usage -= cache->func.mem_size_get(ie2);
68 if (ie2->scalecache.usage >= 6)
69 {
70 ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
71 ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
72 ie->cache->scaled =
73 eina_list_remove(ie->cache->scaled, ie2);
74 }
75 ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
76 ie2->scalecache.parent = NULL;
77 evas_cache_image_drop(ie2);
78 }
79
61} 80}
62 81
63static void 82static void
@@ -92,7 +111,6 @@ _evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
92 im->flags.cached = 1; 111 im->flags.cached = 1;
93 cache->inactiv = evas_hash_direct_add(cache->inactiv, key, im); 112 cache->inactiv = evas_hash_direct_add(cache->inactiv, key, im);
94 cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im)); 113 cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
95 cache->usage += cache->func.mem_size_get(im);
96 } 114 }
97 else 115 else
98 { 116 {
@@ -108,7 +126,6 @@ _evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
108 { 126 {
109 im->flags.lru_nodata = 0; 127 im->flags.lru_nodata = 0;
110 cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im)); 128 cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im));
111 cache->usage -= cache->func.mem_size_get(im);
112 } 129 }
113} 130}
114 131
@@ -160,6 +177,24 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
160 if (cache->func.debug) 177 if (cache->func.debug)
161 cache->func.debug("deleting", ie); 178 cache->func.debug("deleting", ie);
162 179
180 while (ie->scalecache.others)
181 {
182 Image_Entry *ie2;
183
184 ie2 = ie->scalecache.others->data;
185 cache->usage -= cache->func.mem_size_get(ie2);
186 if (ie2->scalecache.usage >= 6)
187 {
188 ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
189 ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
190 ie->cache->scaled =
191 eina_list_remove(ie->cache->scaled, ie2);
192 }
193 ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
194 ie2->scalecache.parent = NULL;
195 evas_cache_image_drop(ie2);
196 }
197
163 cache->func.destructor(ie); 198 cache->func.destructor(ie);
164 199
165 _evas_cache_image_remove_activ(cache, ie); 200 _evas_cache_image_remove_activ(cache, ie);
@@ -251,7 +286,7 @@ _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
251 wmin = w > 0 ? w : 1; 286 wmin = w > 0 ? w : 1;
252 hmin = h > 0 ? h : 1; 287 hmin = h > 0 ? h : 1;
253 if (ie->allocated.w == wmin && ie->allocated.h == hmin) 288 if (ie->allocated.w == wmin && ie->allocated.h == hmin)
254 return ; 289 return;
255 290
256#ifdef BUILD_ASYNC_PRELOAD 291#ifdef BUILD_ASYNC_PRELOAD
257 pthread_mutex_lock(&mutex_surface_alloc); 292 pthread_mutex_lock(&mutex_surface_alloc);
@@ -382,6 +417,9 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb)
382 417
383 new->references = 1; 418 new->references = 1;
384 419
420 new->scaled = NULL;
421 new->scaledmem = 0;
422
385 return new; 423 return new;
386} 424}
387 425
@@ -603,6 +641,20 @@ evas_cache_image_drop(Image_Entry *im)
603 assert(im); 641 assert(im);
604 assert(im->cache); 642 assert(im->cache);
605 643
644 if (im->scalecache.parent)
645 {
646 im->scalecache.parent->cache->usage -= im->scalecache.parent->cache->func.mem_size_get(im);
647 if (im->scalecache.usage >= 6)
648 {
649 im->scalecache.parent->scalecache.mem -= im->scalecache.dst_w * im->scalecache.dst_h;
650 im->scalecache.parent->cache->scaledmem -= im->scalecache.dst_w * im->scalecache.dst_h;
651 im->scalecache.parent->cache->scaled =
652 eina_list_remove(im->scalecache.parent->cache->scaled, im);
653 }
654 im->scalecache.parent->scalecache.others =
655 eina_list_remove(im->scalecache.parent->scalecache.others, im);
656 }
657
606 im->references--; 658 im->references--;
607 cache = im->cache; 659 cache = im->cache;
608 660
@@ -643,13 +695,31 @@ evas_cache_image_data_not_needed(Image_Entry *im)
643EAPI Image_Entry * 695EAPI Image_Entry *
644evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h) 696evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
645{ 697{
646 Image_Entry *im_dirty = im; 698 Image_Entry *im_dirty = im, *ie = im;
647 Evas_Cache_Image *cache; 699 Evas_Cache_Image *cache;
648 700
649 assert(im); 701 assert(im);
650 assert(im->cache); 702 assert(im->cache);
651 703
652 cache = im->cache; 704 cache = im->cache;
705 while (ie->scalecache.others)
706 {
707 Image_Entry *ie2;
708
709 ie2 = ie->scalecache.others->data;
710 cache->usage -= cache->func.mem_size_get(ie2);
711 if (ie2->scalecache.usage >= 6)
712 {
713 ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
714 ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
715 ie->cache->scaled =
716 eina_list_remove(ie->cache->scaled, ie2);
717 }
718 ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
719 ie2->scalecache.parent = NULL;
720 evas_cache_image_drop(ie2);
721 }
722
653 if (!(im->flags.dirty)) 723 if (!(im->flags.dirty))
654 { 724 {
655 if (im->references == 1) im_dirty = im; 725 if (im->references == 1) im_dirty = im;
@@ -815,6 +885,41 @@ evas_cache_image_surface_alloc(Image_Entry *im, int w, int h)
815 cache->func.debug("surface-alloc", im); 885 cache->func.debug("surface-alloc", im);
816} 886}
817 887
888EAPI void
889evas_cache_image_surface_dealloc(Image_Entry *im)
890{
891 Evas_Cache_Image *cache;
892
893 assert(im);
894 assert(im->cache);
895
896 cache = im->cache;
897
898 if (!((RGBA_Image *)im)->image.data) return;
899 if (!im->info.loader) return;
900 if (!im->info.module) return;
901 if (!im->flags.loaded) return;
902
903 im->flags.loaded = 0;
904
905#ifdef BUILD_ASYNC_PRELOAD
906 pthread_mutex_lock(&mutex_surface_alloc);
907#endif
908
909 printf("-------- actual dealloc %p\n", im);
910 _evas_cache_image_remove_lru_nodata(cache, im);
911 cache->func.surface_delete(im);
912 im->allocated.w = 0;
913 im->allocated.h = 0;
914
915#ifdef BUILD_ASYNC_PRELOAD
916 pthread_mutex_unlock(&mutex_surface_alloc);
917#endif
918
919 if (cache->func.debug)
920 cache->func.debug("surface-dealloc", im);
921}
922
818EAPI Image_Entry * 923EAPI Image_Entry *
819evas_cache_image_size_set(Image_Entry *im, int w, int h) 924evas_cache_image_size_set(Image_Entry *im, int w, int h)
820{ 925{
@@ -890,7 +995,6 @@ evas_cache_image_load_data(Image_Entry *im)
890 { 995 {
891 _evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h); 996 _evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
892 im->flags.loaded = 0; 997 im->flags.loaded = 0;
893
894 return ; 998 return ;
895 } 999 }
896 1000
diff --git a/legacy/evas/src/lib/engines/common/evas_image_load.c b/legacy/evas/src/lib/engines/common/evas_image_load.c
index 27b2eef786..8d0a94c21b 100644
--- a/legacy/evas/src/lib/engines/common/evas_image_load.c
+++ b/legacy/evas/src/lib/engines/common/evas_image_load.c
@@ -43,6 +43,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
43 char *dot; 43 char *dot;
44 int i; 44 int i;
45 45
46 if (ie->info.loader)
47 {
48 if (!evas_common_load_rgba_image_data_from_file(ie)) return 0;
49 }
46 dot = strrchr (ie->file, '.'); 50 dot = strrchr (ie->file, '.');
47 if (dot) 51 if (dot)
48 { 52 {
diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c
index 438cfc68b2..623aaa04bc 100644
--- a/legacy/evas/src/lib/engines/common/evas_image_main.c
+++ b/legacy/evas/src/lib/engines/common/evas_image_main.c
@@ -405,7 +405,36 @@ EAPI void
405evas_common_image_set_cache(int size) 405evas_common_image_set_cache(int size)
406{ 406{
407 if (eci != NULL) 407 if (eci != NULL)
408 evas_cache_image_set(eci, size); 408 {
409 Evas_Cache_Image *cache = eci;
410
411 evas_cache_image_set(eci, size);
412 while (cache->scaledmem > (cache->limit >> 2))
413 {
414 Eina_List *l;
415 Image_Entry *ie;
416
417 l = eina_list_last(cache->scaled);
418 while (l)
419 {
420 ie = l->data;
421 if (ie->scalecache.parent) break;
422 l = l->prev;
423 }
424 if (!l)
425 {
426 break;
427 }
428 ie->scalecache.parent->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
429 cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
430 cache->scaled =
431 eina_list_remove_list(cache->scaled, l);
432 ie->scalecache.parent->scalecache.others =
433 eina_list_remove(ie->scalecache.parent->scalecache.others, ie);
434 ie->scalecache.parent = NULL;
435 evas_cache_image_drop(ie);
436 }
437 }
409} 438}
410 439
411EAPI int 440EAPI int
diff --git a/legacy/evas/src/lib/engines/common/evas_scale_sample.c b/legacy/evas/src/lib/engines/common/evas_scale_sample.c
index 0d57717760..a1c3d6b022 100644
--- a/legacy/evas/src/lib/engines/common/evas_scale_sample.c
+++ b/legacy/evas/src/lib/engines/common/evas_scale_sample.c
@@ -271,9 +271,10 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
271 /* scale to dst */ 271 /* scale to dst */
272 dptr = dst_ptr; 272 dptr = dst_ptr;
273#ifdef DIRECT_SCALE 273#ifdef DIRECT_SCALE
274 if ((!src->cache_entry.flags.alpha) && 274 if ((dc->render_op == _EVAS_RENDER_COPY) ||
275 ((!src->cache_entry.flags.alpha) &&
275 (!dst->cache_entry.flags.alpha) && 276 (!dst->cache_entry.flags.alpha) &&
276 (!dc->mul.use)) 277 (!dc->mul.use)))
277 { 278 {
278 for (y = 0; y < dst_clip_h; y++) 279 for (y = 0; y < dst_clip_h; y++)
279 { 280 {
diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h
index 59f3834d24..30ed5f12b8 100644
--- a/legacy/evas/src/lib/include/evas_common.h
+++ b/legacy/evas/src/lib/include/evas_common.h
@@ -270,64 +270,70 @@ struct _Image_Entry_Flags
270 270
271struct _Image_Entry 271struct _Image_Entry
272{ 272{
273 EINA_INLIST; 273 EINA_INLIST;
274 274
275 Evas_Cache_Image *cache; 275 Evas_Cache_Image *cache;
276 276
277 const char *cache_key; 277 const char *cache_key;
278 278
279 const char *file; 279 const char *file;
280 const char *key; 280 const char *key;
281 281
282 const void *target; 282 const void *target;
283 283
284 time_t timestamp; 284 time_t timestamp;
285 time_t laststat; 285 time_t laststat;
286 286
287 int references; 287 int references;
288 288
289 unsigned char scale; 289 unsigned char scale;
290 290
291 RGBA_Image_Loadopts load_opts; 291 RGBA_Image_Loadopts load_opts;
292 int space; 292 int space;
293 int w; 293 int w;
294 int h; 294 int h;
295 295
296 struct 296 struct {
297 { 297 int w;
298 int w; 298 int h;
299 int h; 299 } allocated;
300 } allocated; 300
301 301 struct {
302 struct 302 void *module;
303 { 303 void *loader;
304 void *module; 304 } info;
305 void *loader; 305
306 } info; 306 Image_Entry_Flags flags;
307 307 struct {
308 Image_Entry_Flags flags; 308 int usage;
309 int mem;
310 int src_x, src_y, src_w, src_h;
311 int dst_w, dst_h;
312 int smooth;
313 Image_Entry *parent;
314 Eina_List *others;
315 } scalecache;
309}; 316};
310 317
311struct _Engine_Image_Entry 318struct _Engine_Image_Entry
312{ 319{
313 EINA_INLIST; 320 EINA_INLIST;
314 321
315 /* Upper Engine data. */ 322 /* Upper Engine data. */
316 Image_Entry *src; 323 Image_Entry *src;
317 324
318 /* Cache stuff. */ 325 /* Cache stuff. */
319 Evas_Cache_Engine_Image *cache; 326 Evas_Cache_Engine_Image *cache;
320 const char *cache_key; 327 const char *cache_key;
321 328
322 struct 329 struct {
323 { 330 Evas_Bool cached : 1;
324 Evas_Bool cached : 1; 331 Evas_Bool activ : 1;
325 Evas_Bool activ : 1; 332 Evas_Bool dirty : 1;
326 Evas_Bool dirty : 1; 333 Evas_Bool loaded : 1;
327 Evas_Bool loaded : 1; 334 Evas_Bool need_parent : 1;
328 Evas_Bool need_parent : 1;
329 } flags; 335 } flags;
330 336
331 int references; 337 int references;
332 int w; 338 int w;
333 int h; 339 int h;
diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c
index 1435b3146a..ddd277da7c 100644
--- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c
+++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c
@@ -731,6 +731,175 @@ eng_image_data_preload_cancel(void *data, void *image)
731 evas_cache_image_preload_cancel(&im->cache_entry); 731 evas_cache_image_preload_cancel(&im->cache_entry);
732} 732}
733 733
734#define SCALECACHE 1
735
736#ifdef SCALECACHE
737static Image_Entry *
738_sc_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth)
739{
740 Eina_List *l;
741 Image_Entry *ie = NULL;
742
743 for (l = im->scalecache.others; l; l = l->next)
744 {
745 ie = l->data;
746 if ((ie->scalecache.dst_w == dst_w) &&
747 (ie->scalecache.dst_h == dst_h) &&
748 (ie->scalecache.src_w == src_w) &&
749 (ie->scalecache.src_h == src_h) &&
750 (ie->scalecache.src_x == src_x) &&
751 (ie->scalecache.src_y == src_y) &&
752 (ie->scalecache.smooth == smooth))
753 {
754 if (l != ie->scalecache.others)
755 {
756 im->scalecache.others = eina_list_remove_list(im->scalecache.others, l);
757 im->scalecache.others = eina_list_prepend(im->scalecache.others, ie);
758 }
759 ie->scalecache.usage++;
760 return ie;
761 }
762 }
763 return NULL;
764}
765
766static void
767_sc_clean(Image_Entry *im)
768{
769 while ((im->scalecache.mem > (im->cache->limit >> 2)) ||
770 (eina_list_count(im->scalecache.others) > 40))
771 {
772 Eina_List *l;
773 Image_Entry *ie;
774
775 printf("clean %i > %i\n", im->cache->scaledmem, im->cache->limit >> 2);
776 l = eina_list_last(im->scalecache.others);
777 ie = l->data;
778 if (ie->scalecache.usage >= 6)
779 {
780 im->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
781 im->cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
782 im->cache->scaled =
783 eina_list_remove(im->cache->scaled, ie);
784 }
785 im->scalecache.others = eina_list_remove_list(im->scalecache.others, l);
786 ie->scalecache.parent = NULL;
787 evas_cache_image_drop(ie);
788 }
789}
790
791static Image_Entry *
792_sc_new(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth)
793{
794 Image_Entry *ie;
795
796 ie = evas_cache_image_empty(im->cache);
797 evas_cache_image_colorspace(ie, EVAS_COLORSPACE_ARGB8888);
798 im->scalecache.usage++;
799 im->scalecache.others = eina_list_prepend(im->scalecache.others, ie);
800 ie->scalecache.src_x = src_x;
801 ie->scalecache.src_y = src_y;
802 ie->scalecache.src_w = src_w;
803 ie->scalecache.src_h = src_h;
804 ie->scalecache.dst_w = dst_w;
805 ie->scalecache.dst_h = dst_h;
806 ie->scalecache.smooth = smooth;
807 ie->scalecache.parent = im;
808 return ie;
809}
810
811static int
812_sc_fill(Image_Entry *im, Image_Entry *ie)
813{
814 RGBA_Draw_Context *tctx;
815
816 ie->scalecache.usage++;
817 if (ie->scalecache.usage < 5) return 0;
818 if (ie->scalecache.usage >= 6)
819 {
820 ie->scalecache.parent->scalecache.usage--;
821 if (ie->scalecache.parent->scalecache.usage <= 0)
822 {
823 ie->scalecache.parent->scalecache.usage = 0;
824 if ((im->info.loader) &&
825 (im->flags.loaded) &&
826 (im->info.module) &&
827 (im->file) &&
828 (((RGBA_Image*)im)->image.data));
829 {
830 evas_cache_image_surface_dealloc(im);
831 }
832 }
833 im->cache->scaled =
834 eina_list_remove(im->cache->scaled, ie);
835 im->cache->scaled =
836 eina_list_prepend(im->cache->scaled, ie);
837 return 1;
838 }
839 im->scalecache.usage += 10;
840 im->cache->func.load(im);
841 ie->scalecache.usage = 6;
842 im->scalecache.mem += ie->scalecache.dst_w * ie->scalecache.dst_h;
843 im->cache->scaledmem += ie->scalecache.dst_w * ie->scalecache.dst_h;
844 im->cache->scaled =
845 eina_list_prepend(im->cache->scaled, ie);
846 ie->flags.alpha = im->flags.alpha;
847 ie->w = ie->scalecache.dst_w;
848 ie->h = ie->scalecache.dst_h;
849 evas_cache_image_surface_alloc(ie, ie->w, ie->h);
850 tctx = evas_common_draw_context_new();
851 evas_common_draw_context_set_render_op(tctx, _EVAS_RENDER_COPY);
852 if (ie->scalecache.smooth)
853 evas_common_scale_rgba_in_to_out_clip_smooth
854 ((RGBA_Image *)im, (RGBA_Image *)ie, tctx,
855 ie->scalecache.src_x, ie->scalecache.src_y,
856 ie->scalecache.src_w, ie->scalecache.src_h,
857 0, 0,
858 ie->scalecache.dst_w, ie->scalecache.dst_h);
859 else
860 evas_common_scale_rgba_in_to_out_clip_sample
861 ((RGBA_Image *)im, (RGBA_Image *)ie, tctx,
862 ie->scalecache.src_x, ie->scalecache.src_y,
863 ie->scalecache.src_w, ie->scalecache.src_h,
864 0, 0,
865 ie->scalecache.dst_w, ie->scalecache.dst_h);
866 evas_common_draw_context_free(tctx);
867 return 1;
868}
869
870static void
871_sc_flush(Evas_Cache_Image *cache)
872{
873 while (cache->scaledmem > (cache->limit >> 2))
874 {
875 Eina_List *l;
876 Image_Entry *ie;
877
878 printf("flush %i > %i\n", cache->scaledmem, cache->limit >> 2);
879 l = eina_list_last(cache->scaled);
880 while (l)
881 {
882 ie = l->data;
883 if (ie->scalecache.parent) break;
884 l = l->prev;
885 }
886 if (!l)
887 {
888 break;
889 }
890 ie->scalecache.parent->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
891 cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
892 cache->scaled =
893 eina_list_remove_list(cache->scaled, l);
894 ie->scalecache.parent->scalecache.others =
895 eina_list_remove(ie->scalecache.parent->scalecache.others, ie);
896 ie->scalecache.parent = NULL;
897 evas_cache_image_drop(ie);
898 }
899}
900
901#endif
902
734static void 903static void
735eng_image_draw(void *data, void *context, void *surface, void *image, 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 smooth) 904eng_image_draw(void *data, void *context, void *surface, void *image, 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 smooth)
736{ 905{
@@ -743,20 +912,72 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
743 evas_common_image_colorspace_normalize(im); 912 evas_common_image_colorspace_normalize(im);
744#ifdef BUILD_PTHREAD 913#ifdef BUILD_PTHREAD
745 if (cpunum > 1) 914 if (cpunum > 1)
746 evas_common_pipe_image_draw(im, surface, context, smooth, 915 {
747 src_x, src_y, src_w, src_h, 916 if (im->image.data)
748 dst_x, dst_y, dst_w, dst_h); 917 {
918 evas_common_pipe_image_draw(im, surface,
919 context, smooth,
920 src_x, src_y, src_w, src_h,
921 dst_x, dst_y, dst_w, dst_h);
922 }
923 }
749 else 924 else
750#endif 925#endif
751 { 926 {
752 if (smooth) 927#ifdef SCALECACHE
753 evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context, 928 Image_Entry *ie, *ie2;
754 src_x, src_y, src_w, src_h, 929 int ok;
755 dst_x, dst_y, dst_w, dst_h); 930
756 else 931 ie = (Image_Entry *)im;
757 evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context, 932 if ((src_w == dst_w) && (src_h == dst_h))
758 src_x, src_y, src_w, src_h, 933 {
759 dst_x, dst_y, dst_w, dst_h); 934 ie->scalecache.usage++;
935 if (smooth)
936 evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context,
937 src_x, src_y, src_w, src_h,
938 dst_x, dst_y, dst_w, dst_h);
939 else
940 evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context,
941 src_x, src_y, src_w, src_h,
942 dst_x, dst_y, dst_w, dst_h);
943 }
944 else
945 {
946 ok = 0;
947 _sc_clean(ie);
948 ie2 = _sc_find(ie, src_x, src_y, src_w, src_h, dst_w, dst_h, smooth);
949 if (ie2) ok = _sc_fill(ie, ie2);
950 else
951 {
952 ie2 = _sc_new(ie, src_x, src_y, src_w, src_h, dst_w, dst_h, smooth);
953 if (ie2) ok = _sc_fill(ie, ie2);
954 }
955 if ((ie2) && (ok))
956 evas_common_scale_rgba_in_to_out_clip_sample((RGBA_Image *)ie2,
957 surface, context,
958 0, 0, dst_w, dst_h,
959 dst_x, dst_y, dst_w, dst_h);
960 else
961 {
962 ie->scalecache.usage++;
963 evas_cache_image_load_data(ie);
964#endif
965 if (im->image.data)
966 {
967 if (smooth)
968 evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context,
969 src_x, src_y, src_w, src_h,
970 dst_x, dst_y, dst_w, dst_h);
971 else
972 evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context,
973 src_x, src_y, src_w, src_h,
974 dst_x, dst_y, dst_w, dst_h);
975 }
976#ifdef SCALECACHE
977 }
978 }
979 _sc_flush(ie->cache);
980#endif
760 evas_common_cpu_end_opt(); 981 evas_common_cpu_end_opt();
761 } 982 }
762} 983}