aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common/evas_image_scalecache.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common/evas_image_scalecache.c')
-rw-r--r--libraries/evas/src/lib/engines/common/evas_image_scalecache.c846
1 files changed, 846 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common/evas_image_scalecache.c b/libraries/evas/src/lib/engines/common/evas_image_scalecache.c
new file mode 100644
index 0000000..24a4f2d
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common/evas_image_scalecache.c
@@ -0,0 +1,846 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#ifdef HAVE_EVIL
6# include <Evil.h>
7#endif
8
9#include <assert.h>
10
11#include "evas_common.h"
12#include "evas_private.h"
13#include "evas_image_private.h"
14
15#define SCALECACHE 1
16
17#define MAX_SCALEITEMS 32
18#define MIN_SCALE_USES 3
19//#define MIN_SCALE_AGE_GAP 5000
20#define MAX_SCALECACHE_DIM 3200
21#define FLOP_ADD 4
22#define MAX_FLOP_COUNT 16
23#define FLOP_DEL 1
24#define SCALE_CACHE_SIZE 4 * 1024 * 1024
25//#define SCALE_CACHE_SIZE 0
26
27typedef struct _Scaleitem Scaleitem;
28
29struct _Scaleitem
30{
31 EINA_INLIST;
32 unsigned long long usage;
33 unsigned long long usage_count;
34 RGBA_Image *im, *parent_im;
35 int src_x, src_y;
36 unsigned int src_w, src_h;
37 unsigned int dst_w, dst_h;
38 unsigned int flop;
39 unsigned int size_adjust;
40#ifdef EVAS_FRAME_QUEUING
41 RWLK(lock);
42#endif
43 Eina_Bool forced_unload : 1;
44 Eina_Bool smooth : 1;
45 Eina_Bool populate_me : 1;
46};
47
48#ifdef SCALECACHE
49static unsigned long long use_counter = 0;
50
51#ifdef BUILD_PTHREAD
52static LK(cache_lock);
53#endif
54static Eina_Inlist *cache_list = NULL;
55static unsigned int cache_size = 0;
56static int init = 0;
57
58static unsigned int max_cache_size = SCALE_CACHE_SIZE;
59static unsigned int max_dimension = MAX_SCALECACHE_DIM;
60static unsigned int max_flop_count = MAX_FLOP_COUNT;
61static unsigned int max_scale_items = MAX_SCALEITEMS;
62static unsigned int min_scale_uses = MIN_SCALE_USES;
63#endif
64
65void
66evas_common_scalecache_init(void)
67{
68#ifdef SCALECACHE
69 const char *s;
70
71 init++;
72 if (init > 1) return;
73 use_counter = 0;
74 LKI(cache_lock);
75 s = getenv("EVAS_SCALECACHE_SIZE");
76 if (s) max_cache_size = atoi(s) * 1024;
77 s = getenv("EVAS_SCALECACHE_MAX_DIMENSION");
78 if (s) max_dimension = atoi(s);
79 s = getenv("EVAS_SCALECACHE_MAX_FLOP_COUNT");
80 if (s) max_flop_count = atoi(s);
81 s = getenv("EVAS_SCALECACHE_MAX_ITEMS");
82 if (s) max_scale_items = atoi(s);
83 s = getenv("EVAS_SCALECACHE_MIN_USES");
84 if (s) min_scale_uses = atoi(s);
85#endif
86}
87
88void
89evas_common_scalecache_shutdown(void)
90{
91#ifdef SCALECACHE
92 init--;
93 if (init ==0)
94 LKD(cache_lock);
95#endif
96}
97
98void
99evas_common_rgba_image_scalecache_init(Image_Entry *ie)
100{
101#ifdef SCALECACHE
102 RGBA_Image *im = (RGBA_Image *)ie;
103 // NOTE: this conflicts with evas image cache init and del of lock
104 LKI(im->cache.lock);
105#endif
106}
107
108void
109evas_common_rgba_image_scalecache_shutdown(Image_Entry *ie)
110{
111#ifdef SCALECACHE
112 RGBA_Image *im = (RGBA_Image *)ie;
113 evas_common_rgba_image_scalecache_dirty(ie);
114 // NOTE: this conflicts with evas image cache init and del of lock
115 LKD(im->cache.lock);
116#endif
117}
118
119void
120evas_common_rgba_image_scalecache_dirty(Image_Entry *ie)
121{
122#ifdef SCALECACHE
123 RGBA_Image *im = (RGBA_Image *)ie;
124 LKL(im->cache.lock);
125 while (im->cache.list)
126 {
127 Scaleitem *sci;
128 sci = im->cache.list->data;
129#ifdef EVAS_FRAME_QUEUING
130 WRLKL(sci->lock);
131#endif
132 im->cache.list = eina_list_remove(im->cache.list, sci);
133 if (sci->im)
134 {
135// INF(" 0- %i", sci->dst_w * sci->dst_h * 4);
136 LKL(cache_lock);
137 evas_common_rgba_image_free(&sci->im->cache_entry);
138 if (!sci->forced_unload)
139 cache_size -= sci->dst_w * sci->dst_h * 4;
140 else
141 cache_size -= sci->size_adjust;
142 cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
143 LKU(cache_lock);
144 }
145#ifdef EVAS_FRAME_QUEUING
146 RWLKU(sci->lock);
147 RWLKD(sci->lock);
148#endif
149 free(sci);
150 }
151 LKU(im->cache.lock);
152#endif
153}
154
155void
156evas_common_rgba_image_scalecache_orig_use(Image_Entry *ie)
157{
158#ifdef SCALECACHE
159 RGBA_Image *im = (RGBA_Image *)ie;
160 LKL(im->cache.lock);
161 use_counter++;
162 // FIXME: if orig not loaded, reload
163 // FIXME: mark orig with current used counter
164 im->cache.orig_usage++;
165 im->cache.usage_count = use_counter;
166 LKU(im->cache.lock);
167#endif
168}
169
170int
171evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie)
172{
173#ifdef SCALECACHE
174 RGBA_Image *im = (RGBA_Image *)ie;
175 int size = 0;
176 Eina_List *l;
177 Scaleitem *sci;
178 LKL(im->cache.lock);
179 EINA_LIST_FOREACH(im->cache.list, l, sci)
180 {
181 if (sci->im) size += sci->dst_w * sci->dst_h * 4;
182 }
183 LKU(im->cache.lock);
184 return size;
185#else
186 return 0;
187#endif
188}
189
190#ifdef SCALECACHE
191static void
192_sci_fix_newest(RGBA_Image *im)
193{
194 Eina_List *l;
195 Scaleitem *sci;
196
197 im->cache.newest_usage = 0;
198 im->cache.newest_usage_count = 0;
199 EINA_LIST_FOREACH(im->cache.list, l, sci)
200 {
201 if (sci->usage > im->cache.newest_usage)
202 im->cache.newest_usage = sci->usage;
203 if (sci->usage_count > im->cache.newest_usage_count)
204 im->cache.newest_usage_count = sci->usage_count;
205 }
206// INF("_sci_fix_newest! -> %i", im->cache.newest_usage);
207}
208
209static Scaleitem *
210_sci_find(RGBA_Image *im,
211 RGBA_Draw_Context *dc __UNUSED__, int smooth,
212 int src_region_x, int src_region_y,
213 unsigned int src_region_w, unsigned int src_region_h,
214 unsigned int dst_region_w, unsigned int dst_region_h)
215{
216 Eina_List *l;
217 Scaleitem *sci;
218
219 EINA_LIST_FOREACH(im->cache.list, l, sci)
220 {
221 if (
222 (sci->src_w == src_region_w) &&
223 (sci->src_h == src_region_h) &&
224 (sci->dst_w == dst_region_w) &&
225 (sci->dst_h == dst_region_h) &&
226 (sci->src_x == src_region_x) &&
227 (sci->src_y == src_region_y) &&
228 (sci->smooth == smooth)
229 )
230 {
231 if (im->cache.list != l)
232 {
233 im->cache.list = eina_list_remove_list(im->cache.list, l);
234 im->cache.list = eina_list_prepend(im->cache.list, sci);
235 }
236 return sci;
237 }
238 }
239 if (eina_list_count(im->cache.list) > max_scale_items)
240 {
241 l = eina_list_last(im->cache.list);
242 sci = l->data;
243#ifdef EVAS_FRAME_QUEUING
244 WRLKL(sci->lock);
245#endif
246 im->cache.list = eina_list_remove_list(im->cache.list, l);
247 if ((sci->usage == im->cache.newest_usage) ||
248 (sci->usage_count == im->cache.newest_usage_count))
249 _sci_fix_newest(im);
250 if (sci->im)
251 {
252 evas_common_rgba_image_free(&sci->im->cache_entry);
253 if (!sci->forced_unload)
254 cache_size -= sci->dst_w * sci->dst_h * 4;
255 else
256 cache_size -= sci->size_adjust;
257// INF(" 1- %i", sci->dst_w * sci->dst_h * 4);
258 cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
259 }
260#ifdef EVAS_FRAME_QUEUING
261 RWLKU(sci->lock);
262#endif
263 if (max_scale_items < 1) return NULL;
264 }
265 else
266 {
267 if (max_scale_items < 1) return NULL;
268
269 if (eina_list_count(im->cache.list) > (max_scale_items - 1))
270 return NULL;
271 sci = calloc(1, sizeof(Scaleitem));
272 sci->parent_im = im;
273#ifdef EVAS_FRAME_QUEUING
274 RWLKI(sci->lock);
275#endif
276 }
277 sci->usage = 0;
278 sci->usage_count = 0;
279 sci->populate_me = 0;
280 sci->smooth = smooth;
281 sci->forced_unload = 0;
282 sci->flop = 0;
283 sci->im = NULL;
284 sci->src_x = src_region_x;
285 sci->src_y = src_region_y;
286 sci->src_w = src_region_w;
287 sci->src_h = src_region_h;
288 sci->dst_w = dst_region_w;
289 sci->dst_h = dst_region_h;
290 im->cache.list = eina_list_prepend(im->cache.list, sci);
291 return sci;
292}
293
294static void
295_cache_prune(Scaleitem *notsci, Eina_Bool copies_only)
296{
297 Scaleitem *sci;
298 while (cache_size > max_cache_size)
299 {
300 if (!cache_list) break;
301 sci = (Scaleitem *)(cache_list);
302 if (copies_only)
303 {
304 while ((sci) && (!sci->parent_im->image.data))
305 sci = (Scaleitem *)(((Eina_Inlist *)sci)->next);
306 if (!sci) return;
307 }
308 if (sci == notsci) return;
309#ifdef EVAS_FRAME_QUEUING
310 WRLKL(sci->lock);
311#endif
312 if (sci->im)
313 {
314 evas_common_rgba_image_free(&sci->im->cache_entry);
315 sci->im = NULL;
316 sci->usage = 0;
317 sci->usage_count = 0;
318 sci->flop += FLOP_ADD;
319 if (!sci->forced_unload)
320 cache_size -= sci->dst_w * sci->dst_h * 4;
321 else
322 cache_size -= sci->size_adjust;
323// INF(" 2- %i", sci->dst_w * sci->dst_h * 4);
324 cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
325 memset(sci, 0, sizeof(Eina_Inlist));
326 }
327#ifdef EVAS_FRAME_QUEUING
328 RWLKU(sci->lock);
329#endif
330
331// INF("FLUSH %i > %i", cache_size, max_cache_size);
332 }
333}
334#endif
335
336EAPI void
337evas_common_rgba_image_scalecache_size_set(unsigned int size)
338{
339#ifdef SCALECACHE
340 LKL(cache_lock);
341 if (size != max_cache_size)
342 {
343 max_cache_size = size;
344 _cache_prune(NULL, 1);
345 }
346 LKU(cache_lock);
347#endif
348}
349
350EAPI unsigned int
351evas_common_rgba_image_scalecache_size_get(void)
352{
353#ifdef SCALECACHE
354 int t;
355 LKL(cache_lock);
356 t = max_cache_size;
357 LKU(cache_lock);
358 return t;
359#else
360 return 0;
361#endif
362}
363
364EAPI void
365evas_common_rgba_image_scalecache_dump(void)
366{
367#ifdef SCALECACHE
368 int t;
369 LKL(cache_lock);
370 t = max_cache_size;
371 max_cache_size = 0;
372 _cache_prune(NULL, 0);
373 max_cache_size = t;
374 LKU(cache_lock);
375#endif
376}
377
378EAPI void
379evas_common_rgba_image_scalecache_flush(void)
380{
381#ifdef SCALECACHE
382 int t;
383 LKL(cache_lock);
384 t = max_cache_size;
385 max_cache_size = 0;
386 _cache_prune(NULL, 1);
387 max_cache_size = t;
388 LKU(cache_lock);
389#endif
390}
391
392EAPI void
393evas_common_rgba_image_scalecache_prepare(Image_Entry *ie, RGBA_Image *dst __UNUSED__,
394 RGBA_Draw_Context *dc, int smooth,
395 int src_region_x, int src_region_y,
396 int src_region_w, int src_region_h,
397 int dst_region_x __UNUSED__, int dst_region_y __UNUSED__,
398 int dst_region_w, int dst_region_h)
399{
400#ifdef SCALECACHE
401 int locked = 0;
402 Eina_Lock_Result ret;
403 RGBA_Image *im = (RGBA_Image *)ie;
404 Scaleitem *sci;
405 if (!im->image.data) return;
406 if ((dst_region_w == 0) || (dst_region_h == 0) ||
407 (src_region_w == 0) || (src_region_h == 0)) return;
408 // was having major lock issues here - LKL was deadlocking. what was
409 // going on? it may have been an eina treads badness but this will stay here
410 // for now for debug
411#if 1
412 ret = LKT(im->cache.lock);
413 if (ret == EINA_FALSE) /* can't get image lock */
414 {
415 useconds_t slp = 1, slpt = 0;
416
417 while (slpt < 500000)
418 {
419#ifdef _WIN32
420 Sleep(slp / 1000);
421#else
422 usleep(slp);
423#endif
424 slpt += slp;
425 slp++;
426 ret = LKT(im->cache.lock);
427 if (ret == EINA_LOCK_DEADLOCK)
428 {
429 printf("WARNING: DEADLOCK on image %p (%s)\n", im, ie->file);
430 }
431 else
432 {
433 locked = 1;
434 break;
435 }
436 }
437 if (ret == EINA_FALSE)
438 {
439 printf("WARNING: lock still there after %i usec\n", slpt);
440 printf("WARNING: stucklock on image %p (%s)\n", im, ie->file);
441 LKDBG(im->cache.lock);
442 }
443 }
444 else if (ret == EINA_LOCK_DEADLOCK)
445 {
446 printf("WARNING: DEADLOCK on image %p (%s)\n", im, ie->file);
447 }
448 else locked = 1;
449#endif
450 if (!locked) { LKL(im->cache.lock); locked = 1; }
451 use_counter++;
452 if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
453 {
454 // 1:1 scale.
455 im->cache.orig_usage++;
456 im->cache.usage_count = use_counter;
457 if (locked) LKU(im->cache.lock);
458 return;
459 }
460 if ((!im->cache_entry.flags.alpha) && (!smooth))
461 {
462 // solid nearest scaling - it's actually the same speed cached or not,
463 // or in some cases faster not cached
464 im->cache.orig_usage++;
465 im->cache.usage_count = use_counter;
466 if (locked) LKU(im->cache.lock);
467 return;
468 }
469 LKL(cache_lock);
470 sci = _sci_find(im, dc, smooth,
471 src_region_x, src_region_y, src_region_w, src_region_h,
472 dst_region_w, dst_region_h);
473 if (!sci)
474 {
475 LKU(cache_lock);
476 if (locked) LKU(im->cache.lock);
477 return;
478 }
479// INF("%10i | %4i %4i %4ix%4i -> %4i %4i %4ix%4i | %i",
480// (int)use_counter,
481// src_region_x, src_region_y, src_region_w, src_region_h,
482// dst_region_x, dst_region_y, dst_region_w, dst_region_h,
483// smooth);
484 if ((sci->usage >= min_scale_uses)
485 && (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC)
486// && (sci->usage_count > (use_counter - MIN_SCALE_AGE_GAP))
487 )
488 {
489 if (!sci->im)
490 {
491 if ((sci->dst_w < max_dimension) &&
492 (sci->dst_h < max_dimension))
493 {
494 if (sci->flop <= max_flop_count)
495 {
496 sci->populate_me = 1;
497 im->cache.populate_count++;
498 }
499 }
500 }
501 }
502 sci->usage++;
503 sci->usage_count = use_counter;
504 LKU(cache_lock);
505 if (sci->usage > im->cache.newest_usage)
506 im->cache.newest_usage = sci->usage;
507// INF("newset? %p %i > %i", im,
508// (int)sci->usage,
509// (int)im->cache.newest_usage);
510 if (sci->usage_count > im->cache.newest_usage_count)
511 im->cache.newest_usage_count = sci->usage_count;
512// INF(" -------------- used %8i#, %8i@", (int)sci->usage, (int)sci->usage_count);
513 if (locked) LKU(im->cache.lock);
514#endif
515}
516
517#ifdef SCALECACHE
518//static int pops = 0;
519//static int hits = 0;
520//static int misses = 0;
521//static int noscales = 0;
522#endif
523
524EAPI void
525evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
526 RGBA_Draw_Context *dc, int smooth,
527 int src_region_x, int src_region_y,
528 int src_region_w, int src_region_h,
529 int dst_region_x, int dst_region_y,
530 int dst_region_w, int dst_region_h)
531{
532#ifdef SCALECACHE
533 RGBA_Image *im = (RGBA_Image *)ie;
534 Scaleitem *sci;
535 int didpop = 0;
536 int dounload = 0;
537/*
538 static int i = 0;
539
540 i++;
541 if (i > 2000)
542 {
543 INF("p: %6i, h: %6i, m: %6i, n: %6i",
544 pops, hits, misses, noscales);
545 i = 0;
546 }
547 */
548 if ((dst_region_w == 0) || (dst_region_h == 0) ||
549 (src_region_w == 0) || (src_region_h == 0)) return;
550 LKL(im->cache.lock);
551 if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
552 {
553#ifdef EVAS_FRAME_QUEUING
554 if (!evas_common_frameq_enabled())
555#endif
556 {
557 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
558 evas_cache_image_load_data(&im->cache_entry);
559 evas_common_image_colorspace_normalize(im);
560 }
561// noscales++;
562 LKU(im->cache.lock);
563 if (im->image.data)
564 {
565 evas_common_scale_rgba_in_to_out_clip_sample(im, dst, dc,
566 src_region_x, src_region_y,
567 src_region_w, src_region_h,
568 dst_region_x, dst_region_y,
569 dst_region_w, dst_region_h);
570 }
571 return;
572 }
573 LKL(cache_lock);
574 sci = _sci_find(im, dc, smooth,
575 src_region_x, src_region_y, src_region_w, src_region_h,
576 dst_region_w, dst_region_h);
577 LKU(cache_lock);
578 if (!sci)
579 {
580#ifdef EVAS_FRAME_QUEUING
581 if (!evas_common_frameq_enabled())
582#endif
583 {
584 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
585 evas_cache_image_load_data(&im->cache_entry);
586 evas_common_image_colorspace_normalize(im);
587 }
588// misses++;
589 LKU(im->cache.lock);
590 if (im->image.data)
591 {
592 if (smooth)
593 evas_common_scale_rgba_in_to_out_clip_smooth(im, dst, dc,
594 src_region_x, src_region_y,
595 src_region_w, src_region_h,
596 dst_region_x, dst_region_y,
597 dst_region_w, dst_region_h);
598 else
599 evas_common_scale_rgba_in_to_out_clip_sample(im, dst, dc,
600 src_region_x, src_region_y,
601 src_region_w, src_region_h,
602 dst_region_x, dst_region_y,
603 dst_region_w, dst_region_h);
604 }
605 return;
606 }
607 if (sci->populate_me)
608 {
609 int size, osize, used;
610
611 size = dst_region_w * dst_region_h;
612 if (((((dst_region_w > 640) || (dst_region_h > 640)) &&
613 (size > (480 * 480))) ||
614 (ie->scale_hint == EVAS_IMAGE_SCALE_HINT_STATIC)) &&
615 (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC))
616 {
617 Eina_List *l;
618 Scaleitem *sci2;
619
620 dounload = 1;
621 osize = sci->parent_im->cache_entry.w * sci->parent_im->cache_entry.h;
622 used = 0;
623 EINA_LIST_FOREACH(im->cache.list, l, sci2)
624 {
625 if (sci2->im) used += sci2->dst_w * sci2->dst_h;
626 }
627 if ((size < osize) && (used == 0))
628 sci->size_adjust = 0;
629 else
630 {
631 osize -= used;
632 if (osize < 0) osize = 0;
633 size -= osize;
634 sci->size_adjust = size * 4;
635 }
636 }
637 else
638 {
639 size *= sizeof(DATA32);
640 if ((cache_size + size) > max_cache_size)
641 {
642 sci->populate_me = 0;
643 im->cache.populate_count--;
644 }
645 }
646 }
647 if (sci->populate_me)
648 {
649// INF("##! populate!");
650 sci->im = evas_common_image_new
651 (dst_region_w, dst_region_h, im->cache_entry.flags.alpha);
652 if (sci->im)
653 {
654 static RGBA_Draw_Context *ct = NULL;
655
656 LKL(cache_lock);
657 im->cache.orig_usage++;
658 im->cache.usage_count = use_counter;
659 im->cache.populate_count--;
660// pops++;
661 if (!ct)
662 {
663 // FIXME: static ct - never can free on shutdown? not a leak
664 // or real harm - just annoying valgrind bitch
665 ct = evas_common_draw_context_new();
666 evas_common_draw_context_set_render_op(ct, _EVAS_RENDER_COPY);
667 }
668 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
669 evas_cache_image_load_data(&im->cache_entry);
670 evas_common_image_colorspace_normalize(im);
671 if (im->image.data)
672 {
673 if (smooth)
674 evas_common_scale_rgba_in_to_out_clip_smooth
675 (im, sci->im, ct,
676 src_region_x, src_region_y,
677 src_region_w, src_region_h,
678 0, 0,
679 dst_region_w, dst_region_h);
680 else
681 evas_common_scale_rgba_in_to_out_clip_sample
682 (im, sci->im, ct,
683 src_region_x, src_region_y,
684 src_region_w, src_region_h,
685 0, 0,
686 dst_region_w, dst_region_h);
687 sci->populate_me = 0;
688#if 0 // visual debug of cached images
689 {
690 int xx, yy;
691 DATA32 *pp;
692
693 pp = sci->im->image.data;
694 for (yy = 0; yy < dst_region_h; yy++)
695 {
696
697 for (xx = 0; xx < dst_region_w; xx++)
698 {
699 if (yy & 0x1)
700 {
701 if (xx & 0x1) *pp = 0x882288ff;
702 }
703 else
704 {
705 if (!(xx & 0x1)) *pp = 0x882288ff;
706 }
707 pp++;
708 }
709 }
710 }
711#endif
712 }
713 if (dounload)
714 {
715 sci->forced_unload = 1;
716 cache_size += sci->size_adjust;
717 }
718 else
719 {
720 cache_size += sci->dst_w * sci->dst_h * 4;
721 }
722// INF(" + %i @ flop: %i (%ix%i)",
723// sci->dst_w * sci->dst_h * 4, sci->flop,
724// sci->dst_w, sci->dst_h);
725 cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
726 _cache_prune(sci, 0);
727 LKU(cache_lock);
728 didpop = 1;
729 }
730 }
731 if (sci->im && !ie->flags.animated)
732 {
733 if (!didpop)
734 {
735 LKL(cache_lock);
736 cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
737 cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
738 LKU(cache_lock);
739 }
740 else
741 {
742 if (sci->flop >= FLOP_DEL) sci->flop -= FLOP_DEL;
743 }
744// INF("use cached!");
745#ifdef EVAS_FRAME_QUEUING
746 RDLKL(sci->lock);
747#endif
748 LKU(im->cache.lock);
749 evas_common_scale_rgba_in_to_out_clip_sample
750 (sci->im, dst, dc,
751 0, 0,
752 dst_region_w, dst_region_h,
753 dst_region_x, dst_region_y,
754 dst_region_w, dst_region_h);
755#ifdef EVAS_FRAME_QUEUING
756 RWLKU(sci->lock);
757#endif
758// hits++;
759// INF("check %p %i < %i",
760// im,
761// (int)im->cache.orig_usage,
762// (int)im->cache.newest_usage);
763#ifndef EVAS_FRAME_QUEUING
764 /* while framequeuing is applied,
765 * original image data is loaded by the main thread
766 * just before enqueuing the rendering op into the pipe.
767 * so unloading the original image data here
768 * causes only speed-down side-effect and no memory usage gain;
769 * it will be loaded again for the very next rendering for this image.
770 */
771 if (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC)
772 {
773 if ((dounload) ||
774 ((im->cache_entry.flags.loaded) &&
775 ((!im->cs.no_free)
776#ifdef EVAS_CSERVE
777 || (ie->data1)
778#endif
779 ) &&
780 (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)))
781 {
782 if ((dounload) || (im->cache.orig_usage <
783 (im->cache.newest_usage / 20)))
784 {
785 //FIXME: imagedataunload - inform owners
786 evas_common_rgba_image_unload(&im->cache_entry);
787 }
788 }
789 }
790#endif
791 }
792 else
793 {
794#ifdef EVAS_FRAME_QUEUING
795 if (!evas_common_frameq_enabled())
796#endif
797 {
798 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
799 evas_cache_image_load_data(&im->cache_entry);
800 evas_common_image_colorspace_normalize(im);
801 }
802// misses++;
803 LKU(im->cache.lock);
804 if (im->image.data)
805 {
806 if (smooth)
807 evas_common_scale_rgba_in_to_out_clip_smooth(im, dst, dc,
808 src_region_x, src_region_y,
809 src_region_w, src_region_h,
810 dst_region_x, dst_region_y,
811 dst_region_w, dst_region_h);
812 else
813 evas_common_scale_rgba_in_to_out_clip_sample(im, dst, dc,
814 src_region_x, src_region_y,
815 src_region_w, src_region_h,
816 dst_region_x, dst_region_y,
817 dst_region_w, dst_region_h);
818 }
819 }
820#else
821 RGBA_Image *im = (RGBA_Image *)ie;
822#ifdef EVAS_FRAME_QUEUING
823 if (!evas_common_frameq_enabled())
824#endif
825 {
826 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
827 evas_cache_image_load_data(&im->cache_entry);
828 evas_common_image_colorspace_normalize(im);
829 }
830 if (im->image.data)
831 {
832 if (smooth)
833 evas_common_scale_rgba_in_to_out_clip_smooth(im, dst, dc,
834 src_region_x, src_region_y,
835 src_region_w, src_region_h,
836 dst_region_x, dst_region_y,
837 dst_region_w, dst_region_h);
838 else
839 evas_common_scale_rgba_in_to_out_clip_sample(im, dst, dc,
840 src_region_x, src_region_y,
841 src_region_w, src_region_h,
842 dst_region_x, dst_region_y,
843 dst_region_w, dst_region_h);
844 }
845#endif
846}