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