2009-12-19 02:58:39 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
#include <assert.h>
|
|
|
|
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
#include "evas_cs2_private.h"
|
|
|
|
#endif
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2009-03-26 00:14:08 -07:00
|
|
|
#include "evas_private.h"
|
|
|
|
#include "evas_image_private.h"
|
|
|
|
|
2009-03-27 00:34:45 -07:00
|
|
|
#define SCALECACHE 1
|
2009-03-26 00:14:08 -07:00
|
|
|
|
2009-03-30 21:12:09 -07:00
|
|
|
#define MAX_SCALEITEMS 32
|
2009-03-26 00:14:08 -07:00
|
|
|
#define MIN_SCALE_USES 3
|
2009-05-06 05:36:06 -07:00
|
|
|
//#define MIN_SCALE_AGE_GAP 5000
|
|
|
|
#define MAX_SCALECACHE_DIM 3200
|
2009-03-26 20:50:03 -07:00
|
|
|
#define FLOP_ADD 4
|
|
|
|
#define MAX_FLOP_COUNT 16
|
|
|
|
#define FLOP_DEL 1
|
2009-05-06 05:36:06 -07:00
|
|
|
#define SCALE_CACHE_SIZE 4 * 1024 * 1024
|
|
|
|
//#define SCALE_CACHE_SIZE 0
|
2009-03-26 00:14:08 -07:00
|
|
|
|
2013-04-11 01:20:05 -07:00
|
|
|
typedef struct _ScaleitemKey ScaleitemKey;
|
2009-03-26 00:14:08 -07:00
|
|
|
typedef struct _Scaleitem Scaleitem;
|
|
|
|
|
2013-04-11 01:20:05 -07:00
|
|
|
struct _ScaleitemKey
|
|
|
|
{
|
|
|
|
int src_x, src_y;
|
|
|
|
unsigned int src_w, src_h;
|
|
|
|
unsigned int dst_w, dst_h;
|
|
|
|
Eina_Bool smooth : 1;
|
|
|
|
};
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
struct _Scaleitem
|
|
|
|
{
|
2009-03-26 05:47:44 -07:00
|
|
|
EINA_INLIST;
|
2009-03-26 00:14:08 -07:00
|
|
|
unsigned long long usage;
|
|
|
|
unsigned long long usage_count;
|
2009-03-26 05:47:44 -07:00
|
|
|
RGBA_Image *im, *parent_im;
|
2013-04-11 01:20:05 -07:00
|
|
|
Eina_List *item;
|
2010-09-18 16:07:31 -07:00
|
|
|
unsigned int flop;
|
|
|
|
unsigned int size_adjust;
|
2013-04-11 01:20:05 -07:00
|
|
|
|
|
|
|
ScaleitemKey key;
|
|
|
|
|
2009-05-06 05:36:06 -07:00
|
|
|
Eina_Bool forced_unload : 1;
|
|
|
|
Eina_Bool populate_me : 1;
|
2009-03-26 00:14:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
static unsigned long long use_counter = 0;
|
|
|
|
|
2013-10-10 01:44:24 -07:00
|
|
|
static SLK(cache_lock);
|
2009-03-26 05:47:44 -07:00
|
|
|
static Eina_Inlist *cache_list = NULL;
|
2010-09-18 16:07:31 -07:00
|
|
|
static unsigned int cache_size = 0;
|
2009-05-08 04:26:25 -07:00
|
|
|
static int init = 0;
|
|
|
|
|
2010-09-18 16:07:31 -07:00
|
|
|
static unsigned int max_cache_size = SCALE_CACHE_SIZE;
|
|
|
|
static unsigned int max_dimension = MAX_SCALECACHE_DIM;
|
|
|
|
static unsigned int max_flop_count = MAX_FLOP_COUNT;
|
|
|
|
static unsigned int max_scale_items = MAX_SCALEITEMS;
|
|
|
|
static unsigned int min_scale_uses = MIN_SCALE_USES;
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
|
2013-04-11 01:20:05 -07:00
|
|
|
static int
|
|
|
|
_evas_common_scalecache_key_hash(const void *key, int key_length EINA_UNUSED)
|
|
|
|
{
|
|
|
|
const ScaleitemKey *skey;
|
|
|
|
unsigned int tohash;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
skey = key;
|
|
|
|
|
|
|
|
tohash = (skey->src_x ^ skey->src_y) ^ ((skey->src_w ^ skey->src_h) ^ (skey->dst_w ^ skey->dst_h));
|
|
|
|
r = eina_hash_int32(&tohash, sizeof (int));
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
_evas_common_scalecache_key_length(const void *key EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return sizeof (ScaleitemKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_evas_common_scalecache_key_cmp(const void *key1, int key1_length EINA_UNUSED,
|
|
|
|
const void *key2, int key2_length EINA_UNUSED)
|
|
|
|
{
|
|
|
|
const ScaleitemKey *sk1 = key1;
|
|
|
|
const ScaleitemKey *sk2 = key2;
|
|
|
|
|
|
|
|
#define CMP_SKEY(Sk1, Sk2, Name) \
|
|
|
|
if (Sk1->Name != Sk2->Name) \
|
|
|
|
return Sk1->Name - Sk2->Name;
|
|
|
|
|
|
|
|
CMP_SKEY(sk1, sk2, src_w);
|
|
|
|
CMP_SKEY(sk1, sk2, src_h);
|
|
|
|
CMP_SKEY(sk1, sk2, dst_w);
|
|
|
|
CMP_SKEY(sk1, sk2, dst_h);
|
|
|
|
CMP_SKEY(sk1, sk2, src_x);
|
|
|
|
CMP_SKEY(sk1, sk2, src_y);
|
|
|
|
CMP_SKEY(sk1, sk2, smooth);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
void
|
|
|
|
evas_common_scalecache_init(void)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
2009-05-08 04:26:25 -07:00
|
|
|
const char *s;
|
|
|
|
|
|
|
|
init++;
|
|
|
|
if (init > 1) return;
|
2009-03-26 00:14:08 -07:00
|
|
|
use_counter = 0;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKI(cache_lock);
|
2009-05-08 04:26:25 -07:00
|
|
|
s = getenv("EVAS_SCALECACHE_SIZE");
|
|
|
|
if (s) max_cache_size = atoi(s) * 1024;
|
|
|
|
s = getenv("EVAS_SCALECACHE_MAX_DIMENSION");
|
|
|
|
if (s) max_dimension = atoi(s);
|
|
|
|
s = getenv("EVAS_SCALECACHE_MAX_FLOP_COUNT");
|
|
|
|
if (s) max_flop_count = atoi(s);
|
|
|
|
s = getenv("EVAS_SCALECACHE_MAX_ITEMS");
|
|
|
|
if (s) max_scale_items = atoi(s);
|
|
|
|
s = getenv("EVAS_SCALECACHE_MIN_USES");
|
|
|
|
if (s) min_scale_uses = atoi(s);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_scalecache_shutdown(void)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
2009-05-08 04:26:25 -07:00
|
|
|
init--;
|
2010-05-21 00:10:45 -07:00
|
|
|
if (init ==0)
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKD(cache_lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_rgba_image_scalecache_init(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2011-04-30 23:24:02 -07:00
|
|
|
// NOTE: this conflicts with evas image cache init and del of lock
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKI(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_rgba_image_scalecache_shutdown(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
evas_common_rgba_image_scalecache_dirty(ie);
|
2011-04-30 23:24:02 -07:00
|
|
|
// NOTE: this conflicts with evas image cache init and del of lock
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKD(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_rgba_image_scalecache_dirty(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
while (im->cache.list)
|
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
Scaleitem *sci = im->cache.list->data;
|
|
|
|
|
2009-03-26 05:47:44 -07:00
|
|
|
im->cache.list = eina_list_remove(im->cache.list, sci);
|
2013-01-17 14:14:05 -08:00
|
|
|
if ((sci->im) && (sci->im->cache_entry.references == 0))
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2009-03-26 05:47:44 -07:00
|
|
|
evas_common_rgba_image_free(&sci->im->cache_entry);
|
2013-01-17 14:14:05 -08:00
|
|
|
sci->im = NULL;
|
|
|
|
|
2009-05-06 05:36:06 -07:00
|
|
|
if (!sci->forced_unload)
|
2013-04-11 01:20:05 -07:00
|
|
|
cache_size -= sci->key.dst_w * sci->key.dst_h * 4;
|
2009-05-06 05:36:06 -07:00
|
|
|
else
|
|
|
|
cache_size -= sci->size_adjust;
|
2009-03-26 05:47:44 -07:00
|
|
|
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-03-26 05:47:44 -07:00
|
|
|
}
|
2013-01-17 14:14:05 -08:00
|
|
|
|
|
|
|
if (!sci->im)
|
|
|
|
free(sci);
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
2013-04-11 01:20:05 -07:00
|
|
|
eina_hash_free(im->cache.hash);
|
|
|
|
im->cache.hash = NULL;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_rgba_image_scalecache_orig_use(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
use_counter++;
|
|
|
|
// FIXME: if orig not loaded, reload
|
|
|
|
// FIXME: mark orig with current used counter
|
2009-03-26 05:47:44 -07:00
|
|
|
im->cache.orig_usage++;
|
|
|
|
im->cache.usage_count = use_counter;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
int size = 0;
|
|
|
|
Eina_List *l;
|
|
|
|
Scaleitem *sci;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
EINA_LIST_FOREACH(im->cache.list, l, sci)
|
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
if (sci->im) size += sci->key.dst_w * sci->key.dst_h * 4;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
return size;
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-01-17 14:14:05 -08:00
|
|
|
/* receives original Image_Entry */
|
2013-01-16 14:32:39 -08:00
|
|
|
void
|
2013-01-17 14:14:05 -08:00
|
|
|
evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie, Eina_Array *ret)
|
2013-01-16 14:32:39 -08:00
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
Eina_List *l;
|
|
|
|
Scaleitem *sci;
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2013-01-16 14:32:39 -08:00
|
|
|
EINA_LIST_FOREACH(im->cache.list, l, sci)
|
|
|
|
{
|
|
|
|
if (sci->im)
|
|
|
|
{
|
|
|
|
Image_Entry *scie = (Image_Entry *)sci->im;
|
2013-01-17 14:14:05 -08:00
|
|
|
assert(scie->references >= 0);
|
2013-01-16 14:32:39 -08:00
|
|
|
scie->references++;
|
2013-01-17 14:14:05 -08:00
|
|
|
eina_array_push(ret, scie);
|
2013-01-16 14:32:39 -08:00
|
|
|
}
|
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2013-01-16 14:32:39 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-01-17 14:14:05 -08:00
|
|
|
/* receives scaled Image_Entry */
|
2013-01-16 14:32:39 -08:00
|
|
|
void
|
2013-01-17 14:14:05 -08:00
|
|
|
evas_common_rgba_image_scalecache_item_unref(Image_Entry *scie)
|
2013-01-16 14:32:39 -08:00
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
2013-01-17 14:14:05 -08:00
|
|
|
scie->references--;
|
|
|
|
assert(scie->references >= 0);
|
2013-01-16 14:32:39 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
#ifdef SCALECACHE
|
2009-03-26 20:50:03 -07:00
|
|
|
static void
|
|
|
|
_sci_fix_newest(RGBA_Image *im)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Scaleitem *sci;
|
2010-06-27 22:21:05 -07:00
|
|
|
|
2009-03-26 20:50:03 -07:00
|
|
|
im->cache.newest_usage = 0;
|
|
|
|
im->cache.newest_usage_count = 0;
|
|
|
|
EINA_LIST_FOREACH(im->cache.list, l, sci)
|
|
|
|
{
|
|
|
|
if (sci->usage > im->cache.newest_usage)
|
|
|
|
im->cache.newest_usage = sci->usage;
|
|
|
|
if (sci->usage_count > im->cache.newest_usage_count)
|
|
|
|
im->cache.newest_usage_count = sci->usage_count;
|
|
|
|
}
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF("_sci_fix_newest! -> %i", im->cache.newest_usage);
|
2009-03-26 20:50:03 -07:00
|
|
|
}
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
static Scaleitem *
|
|
|
|
_sci_find(RGBA_Image *im,
|
2012-11-04 03:51:42 -08:00
|
|
|
RGBA_Draw_Context *dc EINA_UNUSED, int smooth,
|
2013-04-11 01:20:05 -07:00
|
|
|
int src_x, int src_y,
|
|
|
|
unsigned int src_w, unsigned int src_h,
|
|
|
|
unsigned int dst_w, unsigned int dst_h)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Scaleitem *sci;
|
2013-04-11 01:20:05 -07:00
|
|
|
ScaleitemKey key;
|
2009-05-13 05:20:14 -07:00
|
|
|
|
2013-04-11 01:20:05 -07:00
|
|
|
#define SET_SKEY(S, Name) \
|
|
|
|
S.Name = Name
|
|
|
|
|
|
|
|
if (im->cache.hash)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
SET_SKEY(key, src_w);
|
|
|
|
SET_SKEY(key, src_h);
|
|
|
|
SET_SKEY(key, dst_w);
|
|
|
|
SET_SKEY(key, dst_h);
|
|
|
|
SET_SKEY(key, src_x);
|
|
|
|
SET_SKEY(key, src_y);
|
|
|
|
SET_SKEY(key, smooth);
|
|
|
|
|
|
|
|
sci = eina_hash_find(im->cache.hash, &key);
|
|
|
|
if (sci)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
im->cache.list = eina_list_promote_list(im->cache.list, sci->item);
|
2009-03-26 00:14:08 -07:00
|
|
|
return sci;
|
|
|
|
}
|
|
|
|
}
|
2013-04-11 01:20:05 -07:00
|
|
|
|
2009-05-08 04:26:25 -07:00
|
|
|
if (eina_list_count(im->cache.list) > max_scale_items)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
|
|
|
l = eina_list_last(im->cache.list);
|
2013-04-11 01:20:05 -07:00
|
|
|
sci = eina_list_data_get(l);
|
|
|
|
|
|
|
|
eina_hash_del(im->cache.hash, &sci->key, sci);
|
2009-03-26 00:14:08 -07:00
|
|
|
im->cache.list = eina_list_remove_list(im->cache.list, l);
|
2009-03-26 20:50:03 -07:00
|
|
|
if ((sci->usage == im->cache.newest_usage) ||
|
|
|
|
(sci->usage_count == im->cache.newest_usage_count))
|
|
|
|
_sci_fix_newest(im);
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2009-03-26 05:47:44 -07:00
|
|
|
if (sci->im)
|
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
if (sci->im->cache_entry.references > 0) goto try_alloc;
|
|
|
|
|
2009-03-26 05:47:44 -07:00
|
|
|
evas_common_rgba_image_free(&sci->im->cache_entry);
|
2009-05-06 05:36:06 -07:00
|
|
|
if (!sci->forced_unload)
|
2013-04-11 01:20:05 -07:00
|
|
|
cache_size -= sci->key.dst_w * sci->key.dst_h * 4;
|
2009-05-06 05:36:06 -07:00
|
|
|
else
|
|
|
|
cache_size -= sci->size_adjust;
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF(" 1- %i", sci->dst_w * sci->dst_h * 4);
|
2009-03-26 05:47:44 -07:00
|
|
|
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
|
|
|
|
}
|
2009-05-13 05:20:14 -07:00
|
|
|
if (max_scale_items < 1) return NULL;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
|
|
|
else
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
try_alloc:
|
2009-05-13 05:20:14 -07:00
|
|
|
if (max_scale_items < 1) return NULL;
|
|
|
|
if (eina_list_count(im->cache.list) > (max_scale_items - 1))
|
|
|
|
return NULL;
|
2013-01-17 14:14:05 -08:00
|
|
|
|
2010-08-13 05:53:08 -07:00
|
|
|
sci = calloc(1, sizeof(Scaleitem));
|
2009-03-26 05:47:44 -07:00
|
|
|
sci->parent_im = im;
|
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
sci->usage = 0;
|
|
|
|
sci->usage_count = 0;
|
|
|
|
sci->populate_me = 0;
|
2013-04-11 01:20:05 -07:00
|
|
|
sci->key.smooth = smooth;
|
2009-05-09 20:06:49 -07:00
|
|
|
sci->forced_unload = 0;
|
2009-03-26 05:47:44 -07:00
|
|
|
sci->flop = 0;
|
2009-03-26 00:14:08 -07:00
|
|
|
sci->im = NULL;
|
2013-04-11 01:20:05 -07:00
|
|
|
sci->key.src_x = src_x;
|
|
|
|
sci->key.src_y = src_y;
|
|
|
|
sci->key.src_w = src_w;
|
|
|
|
sci->key.src_h = src_h;
|
|
|
|
sci->key.dst_w = dst_w;
|
|
|
|
sci->key.dst_h = dst_h;
|
|
|
|
if (!im->cache.hash)
|
|
|
|
im->cache.hash = eina_hash_new(_evas_common_scalecache_key_length,
|
|
|
|
_evas_common_scalecache_key_cmp,
|
|
|
|
_evas_common_scalecache_key_hash,
|
|
|
|
NULL,
|
|
|
|
3);
|
|
|
|
eina_hash_direct_add(im->cache.hash, &sci->key, sci);
|
2009-03-26 00:14:08 -07:00
|
|
|
im->cache.list = eina_list_prepend(im->cache.list, sci);
|
2013-04-11 01:20:05 -07:00
|
|
|
sci->item = im->cache.list;
|
2009-03-26 00:14:08 -07:00
|
|
|
return sci;
|
|
|
|
}
|
2009-03-26 05:47:44 -07:00
|
|
|
|
|
|
|
static void
|
2009-06-17 03:01:52 -07:00
|
|
|
_cache_prune(Scaleitem *notsci, Eina_Bool copies_only)
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
Eina_Inlist *next;
|
|
|
|
|
|
|
|
if (!cache_list) return;
|
|
|
|
|
|
|
|
next = cache_list;
|
|
|
|
while ((next) && (cache_size > max_cache_size))
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
Scaleitem *sci;
|
2013-01-16 14:32:39 -08:00
|
|
|
Image_Entry *scie;
|
|
|
|
|
2013-01-17 14:14:05 -08:00
|
|
|
sci = EINA_INLIST_CONTAINER_GET(next, Scaleitem);
|
|
|
|
|
|
|
|
if (copies_only)
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
while (!sci->parent_im->image.data)
|
2013-01-16 14:32:39 -08:00
|
|
|
{
|
2013-01-17 14:14:05 -08:00
|
|
|
next = EINA_INLIST_GET(sci)->next;
|
|
|
|
if (!next) return;
|
|
|
|
sci = EINA_INLIST_CONTAINER_GET(next, Scaleitem);
|
2013-01-16 14:32:39 -08:00
|
|
|
}
|
2009-03-26 05:47:44 -07:00
|
|
|
}
|
2013-01-17 14:14:05 -08:00
|
|
|
|
|
|
|
scie = (Image_Entry *)sci->im;
|
|
|
|
next = EINA_INLIST_GET(sci)->next;
|
|
|
|
|
|
|
|
if (sci == notsci) continue;
|
|
|
|
if ((!scie) || (scie->references > 0)) continue;
|
|
|
|
|
|
|
|
evas_common_rgba_image_free(scie);
|
|
|
|
sci->im = NULL;
|
|
|
|
sci->usage = 0;
|
|
|
|
sci->usage_count = 0;
|
|
|
|
sci->flop += FLOP_ADD;
|
|
|
|
|
|
|
|
if (!sci->forced_unload)
|
2013-04-11 01:20:05 -07:00
|
|
|
cache_size -= sci->key.dst_w * sci->key.dst_h * 4;
|
2013-01-17 14:14:05 -08:00
|
|
|
else
|
|
|
|
cache_size -= sci->size_adjust;
|
|
|
|
|
|
|
|
cache_list = eina_inlist_remove(cache_list, EINA_INLIST_GET(sci));
|
|
|
|
memset(sci, 0, sizeof(Eina_Inlist));
|
|
|
|
}
|
2009-03-26 05:47:44 -07:00
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
|
2009-04-09 06:20:00 -07:00
|
|
|
EAPI void
|
2010-09-18 16:07:31 -07:00
|
|
|
evas_common_rgba_image_scalecache_size_set(unsigned int size)
|
2009-04-09 06:20:00 -07:00
|
|
|
{
|
2009-05-09 20:06:49 -07:00
|
|
|
#ifdef SCALECACHE
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-04-09 06:20:00 -07:00
|
|
|
if (size != max_cache_size)
|
|
|
|
{
|
|
|
|
max_cache_size = size;
|
|
|
|
_cache_prune(NULL, 1);
|
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-05-09 20:06:49 -07:00
|
|
|
#endif
|
2009-04-09 06:20:00 -07:00
|
|
|
}
|
|
|
|
|
2010-09-18 16:07:31 -07:00
|
|
|
EAPI unsigned int
|
2009-04-09 06:20:00 -07:00
|
|
|
evas_common_rgba_image_scalecache_size_get(void)
|
|
|
|
{
|
2009-05-09 20:06:49 -07:00
|
|
|
#ifdef SCALECACHE
|
2009-04-09 06:20:00 -07:00
|
|
|
int t;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-04-09 06:20:00 -07:00
|
|
|
t = max_cache_size;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-04-09 06:20:00 -07:00
|
|
|
return t;
|
2009-05-09 20:06:49 -07:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
2009-04-09 06:20:00 -07:00
|
|
|
}
|
|
|
|
|
2013-01-16 14:32:39 -08:00
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_scalecache_prune(void)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2013-01-16 14:32:39 -08:00
|
|
|
_cache_prune(NULL, 0);
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2013-01-16 14:32:39 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-12-03 01:36:17 -08:00
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_scalecache_dump(void)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
int t;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2010-12-03 01:36:17 -08:00
|
|
|
t = max_cache_size;
|
|
|
|
max_cache_size = 0;
|
|
|
|
_cache_prune(NULL, 0);
|
|
|
|
max_cache_size = t;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2010-12-03 01:36:17 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-04-09 06:20:00 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_scalecache_flush(void)
|
|
|
|
{
|
2009-05-09 20:06:49 -07:00
|
|
|
#ifdef SCALECACHE
|
2009-04-09 06:20:00 -07:00
|
|
|
int t;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-04-09 06:20:00 -07:00
|
|
|
t = max_cache_size;
|
|
|
|
max_cache_size = 0;
|
|
|
|
_cache_prune(NULL, 1);
|
|
|
|
max_cache_size = t;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-05-09 20:06:49 -07:00
|
|
|
#endif
|
2009-04-09 06:20:00 -07:00
|
|
|
}
|
|
|
|
|
2015-07-11 21:17:08 -07:00
|
|
|
EAPI Eina_Bool
|
2012-11-04 03:51:42 -08:00
|
|
|
evas_common_rgba_image_scalecache_prepare(Image_Entry *ie, RGBA_Image *dst EINA_UNUSED,
|
2009-03-26 00:14:08 -07:00
|
|
|
RGBA_Draw_Context *dc, int smooth,
|
|
|
|
int src_region_x, int src_region_y,
|
|
|
|
int src_region_w, int src_region_h,
|
2012-11-04 03:51:42 -08:00
|
|
|
int dst_region_x EINA_UNUSED, int dst_region_y EINA_UNUSED,
|
2009-03-26 00:14:08 -07:00
|
|
|
int dst_region_w, int dst_region_h)
|
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
2011-05-01 06:25:23 -07:00
|
|
|
int locked = 0;
|
2011-05-02 01:24:27 -07:00
|
|
|
Eina_Lock_Result ret;
|
2009-03-26 00:14:08 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
Scaleitem *sci;
|
2015-07-11 21:17:08 -07:00
|
|
|
|
2009-03-26 05:47:44 -07:00
|
|
|
if ((dst_region_w == 0) || (dst_region_h == 0) ||
|
2015-07-11 21:17:08 -07:00
|
|
|
(src_region_w == 0) || (src_region_h == 0)) return EINA_TRUE;
|
2013-10-10 01:44:24 -07:00
|
|
|
// was having major lock issues here - SLKL was deadlocking. what was
|
2011-05-01 06:25:23 -07:00
|
|
|
// going on? it may have been an eina treads badness but this will stay here
|
|
|
|
// for now for debug
|
|
|
|
#if 1
|
2013-10-10 01:44:24 -07:00
|
|
|
ret = SLKT(im->cache.lock);
|
2011-05-01 06:25:23 -07:00
|
|
|
if (ret == EINA_FALSE) /* can't get image lock */
|
|
|
|
{
|
|
|
|
useconds_t slp = 1, slpt = 0;
|
|
|
|
|
|
|
|
while (slpt < 500000)
|
|
|
|
{
|
2011-06-02 12:20:39 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
Sleep(slp / 1000);
|
|
|
|
#else
|
2011-05-01 06:25:23 -07:00
|
|
|
usleep(slp);
|
2011-06-02 12:20:39 -07:00
|
|
|
#endif
|
2011-05-01 06:25:23 -07:00
|
|
|
slpt += slp;
|
|
|
|
slp++;
|
2013-10-10 01:44:24 -07:00
|
|
|
ret = SLKT(im->cache.lock);
|
2011-05-02 01:24:27 -07:00
|
|
|
if (ret == EINA_LOCK_DEADLOCK)
|
2011-05-01 06:25:23 -07:00
|
|
|
{
|
|
|
|
printf("WARNING: DEADLOCK on image %p (%s)\n", im, ie->file);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
locked = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ret == EINA_FALSE)
|
|
|
|
{
|
|
|
|
printf("WARNING: lock still there after %i usec\n", slpt);
|
|
|
|
printf("WARNING: stucklock on image %p (%s)\n", im, ie->file);
|
2013-10-10 01:44:24 -07:00
|
|
|
/* SLKDBG(im->cache.lock); */
|
2011-05-01 06:25:23 -07:00
|
|
|
}
|
|
|
|
}
|
2011-05-02 01:24:27 -07:00
|
|
|
else if (ret == EINA_LOCK_DEADLOCK)
|
2011-05-01 06:25:23 -07:00
|
|
|
{
|
|
|
|
printf("WARNING: DEADLOCK on image %p (%s)\n", im, ie->file);
|
|
|
|
}
|
|
|
|
else locked = 1;
|
|
|
|
#endif
|
2013-10-10 01:44:24 -07:00
|
|
|
if (!locked) { SLKL(im->cache.lock); locked = 1; }
|
2009-03-26 17:30:41 -07:00
|
|
|
use_counter++;
|
2009-03-26 00:14:08 -07:00
|
|
|
if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
|
|
|
|
{
|
2009-03-27 06:46:53 -07:00
|
|
|
// 1:1 scale.
|
|
|
|
im->cache.orig_usage++;
|
|
|
|
im->cache.usage_count = use_counter;
|
2013-10-10 01:44:24 -07:00
|
|
|
if (locked) SLKU(im->cache.lock);
|
2015-07-11 21:17:08 -07:00
|
|
|
return EINA_FALSE;
|
2009-03-27 06:46:53 -07:00
|
|
|
}
|
|
|
|
if ((!im->cache_entry.flags.alpha) && (!smooth))
|
|
|
|
{
|
|
|
|
// solid nearest scaling - it's actually the same speed cached or not,
|
|
|
|
// or in some cases faster not cached
|
2009-03-26 00:14:08 -07:00
|
|
|
im->cache.orig_usage++;
|
|
|
|
im->cache.usage_count = use_counter;
|
2013-10-10 01:44:24 -07:00
|
|
|
if (locked) SLKU(im->cache.lock);
|
2015-07-11 21:17:08 -07:00
|
|
|
return EINA_FALSE;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
sci = _sci_find(im, dc, smooth,
|
|
|
|
src_region_x, src_region_y, src_region_w, src_region_h,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-05-13 05:20:14 -07:00
|
|
|
if (!sci)
|
|
|
|
{
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
|
|
|
if (locked) SLKU(im->cache.lock);
|
2015-07-11 21:17:08 -07:00
|
|
|
return EINA_FALSE;
|
2009-05-13 05:20:14 -07:00
|
|
|
}
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF("%10i | %4i %4i %4ix%4i -> %4i %4i %4ix%4i | %i",
|
2009-03-26 00:14:08 -07:00
|
|
|
// (int)use_counter,
|
|
|
|
// src_region_x, src_region_y, src_region_w, src_region_h,
|
|
|
|
// dst_region_x, dst_region_y, dst_region_w, dst_region_h,
|
|
|
|
// smooth);
|
2009-05-08 04:26:25 -07:00
|
|
|
if ((sci->usage >= min_scale_uses)
|
2009-05-07 06:29:56 -07:00
|
|
|
&& (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC)
|
2009-03-26 20:50:03 -07:00
|
|
|
// && (sci->usage_count > (use_counter - MIN_SCALE_AGE_GAP))
|
|
|
|
)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
|
|
|
if (!sci->im)
|
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
if ((sci->key.dst_w < max_dimension) &&
|
|
|
|
(sci->key.dst_h < max_dimension))
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
2009-05-08 04:26:25 -07:00
|
|
|
if (sci->flop <= max_flop_count)
|
2009-03-26 05:47:44 -07:00
|
|
|
{
|
|
|
|
sci->populate_me = 1;
|
|
|
|
im->cache.populate_count++;
|
|
|
|
}
|
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
sci->usage++;
|
|
|
|
sci->usage_count = use_counter;
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-03-26 20:50:03 -07:00
|
|
|
if (sci->usage > im->cache.newest_usage)
|
|
|
|
im->cache.newest_usage = sci->usage;
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF("newset? %p %i > %i", im,
|
2009-03-26 20:50:03 -07:00
|
|
|
// (int)sci->usage,
|
|
|
|
// (int)im->cache.newest_usage);
|
|
|
|
if (sci->usage_count > im->cache.newest_usage_count)
|
|
|
|
im->cache.newest_usage_count = sci->usage_count;
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF(" -------------- used %8i#, %8i@", (int)sci->usage, (int)sci->usage_count);
|
2013-10-10 01:44:24 -07:00
|
|
|
if (locked) SLKU(im->cache.lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
2015-07-11 21:17:08 -07:00
|
|
|
if ((!im->image.data) && (sci->populate_me)) return EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SCALECACHE
|
2009-03-27 19:50:19 -07:00
|
|
|
//static int pops = 0;
|
|
|
|
//static int hits = 0;
|
|
|
|
//static int misses = 0;
|
|
|
|
//static int noscales = 0;
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
|
2013-01-16 08:07:46 -08:00
|
|
|
EAPI Eina_Bool
|
|
|
|
evas_common_rgba_image_scalecache_do_cbs(Image_Entry *ie, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc, int smooth,
|
|
|
|
int src_region_x, int src_region_y,
|
|
|
|
int src_region_w, int src_region_h,
|
|
|
|
int dst_region_x, int dst_region_y,
|
|
|
|
int dst_region_w, int dst_region_h,
|
|
|
|
Evas_Common_Scale_In_To_Out_Clip_Cb cb_sample,
|
|
|
|
Evas_Common_Scale_In_To_Out_Clip_Cb cb_smooth)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
|
|
|
#ifdef SCALECACHE
|
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
|
|
|
Scaleitem *sci;
|
2009-03-26 05:47:44 -07:00
|
|
|
int didpop = 0;
|
2009-05-06 05:36:06 -07:00
|
|
|
int dounload = 0;
|
2013-01-16 08:07:46 -08:00
|
|
|
Eina_Bool ret = EINA_FALSE;
|
2009-03-26 05:47:44 -07:00
|
|
|
/*
|
2009-03-26 00:14:08 -07:00
|
|
|
static int i = 0;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
if (i > 2000)
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
INF("p: %6i, h: %6i, m: %6i, n: %6i",
|
2009-03-26 00:14:08 -07:00
|
|
|
pops, hits, misses, noscales);
|
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
*/
|
2009-03-26 05:47:44 -07:00
|
|
|
if ((dst_region_w == 0) || (dst_region_h == 0) ||
|
2013-01-16 08:07:46 -08:00
|
|
|
(src_region_w == 0) || (src_region_h == 0)) return EINA_FALSE;
|
2009-03-26 00:14:08 -07:00
|
|
|
if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
|
|
|
|
{
|
2012-04-26 02:53:03 -07:00
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2012-05-03 14:01:31 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
2013-09-26 22:46:48 -07:00
|
|
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
2012-05-03 14:01:31 -07:00
|
|
|
evas_cache2_image_load_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->cache_entry);
|
|
|
|
}
|
2012-04-26 02:53:03 -07:00
|
|
|
evas_common_image_colorspace_normalize(im);
|
|
|
|
|
2009-03-27 19:50:19 -07:00
|
|
|
// noscales++;
|
2009-03-26 23:06:45 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
2013-01-16 08:07:46 -08:00
|
|
|
return cb_sample(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 23:06:45 -07:00
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
return EINA_FALSE;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-03-26 00:14:08 -07:00
|
|
|
sci = _sci_find(im, dc, smooth,
|
|
|
|
src_region_x, src_region_y, src_region_w, src_region_h,
|
|
|
|
dst_region_w, dst_region_h);
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-03-26 17:30:41 -07:00
|
|
|
if (!sci)
|
|
|
|
{
|
2012-04-26 02:53:03 -07:00
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2012-05-03 14:01:31 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_load_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->cache_entry);
|
|
|
|
}
|
2012-04-26 02:53:03 -07:00
|
|
|
evas_common_image_colorspace_normalize(im);
|
|
|
|
|
2009-03-27 19:50:19 -07:00
|
|
|
// misses++;
|
2009-03-27 07:11:27 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
|
|
|
if (smooth)
|
2013-01-16 08:07:46 -08:00
|
|
|
return cb_smooth(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-27 07:11:27 -07:00
|
|
|
else
|
2013-01-16 08:07:46 -08:00
|
|
|
return cb_sample(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-27 07:11:27 -07:00
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
return EINA_FALSE;
|
2009-03-26 17:30:41 -07:00
|
|
|
}
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2009-05-06 05:36:06 -07:00
|
|
|
if (sci->populate_me)
|
|
|
|
{
|
|
|
|
int size, osize, used;
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2009-05-06 05:36:06 -07:00
|
|
|
size = dst_region_w * dst_region_h;
|
2009-05-07 06:29:56 -07:00
|
|
|
if (((((dst_region_w > 640) || (dst_region_h > 640)) &&
|
|
|
|
(size > (480 * 480))) ||
|
|
|
|
(ie->scale_hint == EVAS_IMAGE_SCALE_HINT_STATIC)) &&
|
|
|
|
(ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC))
|
2009-05-06 05:36:06 -07:00
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Scaleitem *sci2;
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2009-05-06 05:36:06 -07:00
|
|
|
dounload = 1;
|
|
|
|
osize = sci->parent_im->cache_entry.w * sci->parent_im->cache_entry.h;
|
|
|
|
used = 0;
|
|
|
|
EINA_LIST_FOREACH(im->cache.list, l, sci2)
|
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
if (sci2->im) used += sci2->key.dst_w * sci2->key.dst_h;
|
2009-05-06 05:36:06 -07:00
|
|
|
}
|
|
|
|
if ((size < osize) && (used == 0))
|
|
|
|
sci->size_adjust = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osize -= used;
|
|
|
|
if (osize < 0) osize = 0;
|
|
|
|
size -= osize;
|
2013-01-16 08:07:46 -08:00
|
|
|
sci->size_adjust = size * 4;
|
2009-05-06 05:36:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size *= sizeof(DATA32);
|
|
|
|
if ((cache_size + size) > max_cache_size)
|
|
|
|
{
|
|
|
|
sci->populate_me = 0;
|
|
|
|
im->cache.populate_count--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-23 01:51:06 -07:00
|
|
|
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (sci->populate_me && (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
|
|
|
&& evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
|
|
|
{
|
|
|
|
RGBA_Image *im2 = (RGBA_Image *) evas_cache2_image_scale_load
|
|
|
|
(&im->cache_entry, src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h, dst_region_w, dst_region_h, smooth);
|
|
|
|
SLKL(cache_lock);
|
|
|
|
if (im2 != im)
|
|
|
|
{
|
|
|
|
sci->im = im2;
|
|
|
|
sci->populate_me = 0;
|
|
|
|
cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
|
|
|
|
didpop = 1;
|
|
|
|
}
|
|
|
|
SLKU(cache_lock);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-03-26 00:14:08 -07:00
|
|
|
if (sci->populate_me)
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF("##! populate!");
|
2009-03-26 00:14:08 -07:00
|
|
|
sci->im = evas_common_image_new
|
2009-03-27 06:46:53 -07:00
|
|
|
(dst_region_w, dst_region_h, im->cache_entry.flags.alpha);
|
2009-03-26 00:14:08 -07:00
|
|
|
if (sci->im)
|
|
|
|
{
|
|
|
|
static RGBA_Draw_Context *ct = NULL;
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2014-08-18 03:39:10 -07:00
|
|
|
SLKL(cache_lock);
|
2009-03-26 20:50:03 -07:00
|
|
|
im->cache.orig_usage++;
|
|
|
|
im->cache.usage_count = use_counter;
|
2009-03-26 05:47:44 -07:00
|
|
|
im->cache.populate_count--;
|
2009-03-27 19:50:19 -07:00
|
|
|
// pops++;
|
2009-03-26 00:14:08 -07:00
|
|
|
if (!ct)
|
|
|
|
{
|
2009-10-31 08:18:19 -07:00
|
|
|
// FIXME: static ct - never can free on shutdown? not a leak
|
2009-04-19 13:40:41 -07:00
|
|
|
// or real harm - just annoying valgrind bitch
|
2009-03-26 00:14:08 -07:00
|
|
|
ct = evas_common_draw_context_new();
|
|
|
|
evas_common_draw_context_set_render_op(ct, _EVAS_RENDER_COPY);
|
|
|
|
}
|
2016-07-11 05:45:39 -07:00
|
|
|
SLKU(cache_lock);
|
2014-08-18 03:39:10 -07:00
|
|
|
SLKU(im->cache.lock);
|
2016-07-11 05:45:39 -07:00
|
|
|
|
|
|
|
SLKL(cache_lock);
|
2009-03-26 20:50:03 -07:00
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2012-05-03 14:01:31 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_load_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->cache_entry);
|
|
|
|
}
|
2016-07-11 05:45:39 -07:00
|
|
|
SLKU(cache_lock);
|
|
|
|
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(im->cache.lock);
|
2016-07-11 05:45:39 -07:00
|
|
|
SLKL(cache_lock);
|
2009-03-26 20:50:03 -07:00
|
|
|
evas_common_image_colorspace_normalize(im);
|
2009-03-26 23:06:45 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
|
|
|
if (smooth)
|
2013-01-16 08:07:46 -08:00
|
|
|
ret = cb_smooth(im, sci->im, ct,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
0, 0,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 23:06:45 -07:00
|
|
|
else
|
2013-01-16 08:07:46 -08:00
|
|
|
ret = cb_sample(im, sci->im, ct,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
0, 0,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 23:06:45 -07:00
|
|
|
sci->populate_me = 0;
|
2013-01-16 08:07:46 -08:00
|
|
|
#if 0 // visual debug of cached images
|
2009-04-19 13:40:41 -07:00
|
|
|
{
|
|
|
|
int xx, yy;
|
|
|
|
DATA32 *pp;
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2009-04-19 13:40:41 -07:00
|
|
|
pp = sci->im->image.data;
|
|
|
|
for (yy = 0; yy < dst_region_h; yy++)
|
|
|
|
{
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2009-04-19 13:40:41 -07:00
|
|
|
for (xx = 0; xx < dst_region_w; xx++)
|
|
|
|
{
|
|
|
|
if (yy & 0x1)
|
|
|
|
{
|
2009-05-06 05:36:06 -07:00
|
|
|
if (xx & 0x1) *pp = 0x882288ff;
|
2009-04-19 13:40:41 -07:00
|
|
|
}
|
|
|
|
else
|
2013-01-16 08:07:46 -08:00
|
|
|
{
|
2009-05-06 05:36:06 -07:00
|
|
|
if (!(xx & 0x1)) *pp = 0x882288ff;
|
2013-01-16 08:07:46 -08:00
|
|
|
}
|
2009-04-19 13:40:41 -07:00
|
|
|
pp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
#endif
|
2009-03-26 23:06:45 -07:00
|
|
|
}
|
2009-05-06 05:36:06 -07:00
|
|
|
if (dounload)
|
|
|
|
{
|
|
|
|
sci->forced_unload = 1;
|
|
|
|
cache_size += sci->size_adjust;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-04-11 01:20:05 -07:00
|
|
|
cache_size += sci->key.dst_w * sci->key.dst_h * 4;
|
2009-05-06 05:36:06 -07:00
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
// INF(" + %i @ flop: %i (%ix%i)",
|
|
|
|
// sci->dst_w * sci->dst_h * 4, sci->flop,
|
2009-03-26 05:47:44 -07:00
|
|
|
// sci->dst_w, sci->dst_h);
|
|
|
|
cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-03-26 05:47:44 -07:00
|
|
|
didpop = 1;
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
|
|
|
}
|
2013-04-24 23:05:18 -07:00
|
|
|
if (sci->im && !ie->animated.animated)
|
2009-03-26 00:14:08 -07:00
|
|
|
{
|
2009-03-26 05:47:44 -07:00
|
|
|
if (!didpop)
|
|
|
|
{
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKL(cache_lock);
|
2009-03-26 05:47:44 -07:00
|
|
|
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
|
|
|
|
cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(cache_lock);
|
2009-03-26 05:47:44 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-09-18 16:07:31 -07:00
|
|
|
if (sci->flop >= FLOP_DEL) sci->flop -= FLOP_DEL;
|
2009-03-26 05:47:44 -07:00
|
|
|
}
|
2009-10-22 08:22:22 -07:00
|
|
|
// INF("use cached!");
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2013-01-16 08:07:46 -08:00
|
|
|
ret |= cb_sample(sci->im, dst, dc,
|
|
|
|
0, 0,
|
|
|
|
dst_region_w, dst_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-27 19:50:19 -07:00
|
|
|
// hits++;
|
2013-01-16 08:07:46 -08:00
|
|
|
// INF("check %p %i < %i",
|
2009-03-26 20:50:03 -07:00
|
|
|
// im,
|
2013-01-16 08:07:46 -08:00
|
|
|
// (int)im->cache.orig_usage,
|
2009-03-26 20:50:03 -07:00
|
|
|
// (int)im->cache.newest_usage);
|
2010-05-21 00:10:45 -07:00
|
|
|
/* while framequeuing is applied,
|
2013-01-16 08:07:46 -08:00
|
|
|
* original image data is loaded by the main thread
|
2010-05-21 00:10:45 -07:00
|
|
|
* just before enqueuing the rendering op into the pipe.
|
2013-01-16 08:07:46 -08:00
|
|
|
* so unloading the original image data here
|
2010-05-21 00:10:45 -07:00
|
|
|
* causes only speed-down side-effect and no memory usage gain;
|
|
|
|
* it will be loaded again for the very next rendering for this image.
|
|
|
|
*/
|
2010-12-14 02:22:06 -08:00
|
|
|
if (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC)
|
|
|
|
{
|
2013-01-16 08:07:46 -08:00
|
|
|
if ((dounload) ||
|
|
|
|
((im->cache_entry.flags.loaded) &&
|
|
|
|
((!im->cs.no_free)
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
|| (ie->data1)
|
|
|
|
#endif
|
2010-12-14 02:22:06 -08:00
|
|
|
) &&
|
|
|
|
(im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)))
|
2009-05-06 05:36:06 -07:00
|
|
|
{
|
2013-01-16 08:07:46 -08:00
|
|
|
if ((dounload) || (im->cache.orig_usage <
|
2010-12-14 02:22:06 -08:00
|
|
|
(im->cache.newest_usage / 20)))
|
|
|
|
{
|
2010-12-24 08:04:27 -08:00
|
|
|
//FIXME: imagedataunload - inform owners
|
2012-05-03 14:01:31 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_unload_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
2013-01-17 14:14:05 -08:00
|
|
|
/* FIXME: must be the _cache version, no? */
|
2012-05-03 14:01:31 -07:00
|
|
|
evas_common_rgba_image_unload(&im->cache_entry);
|
2010-12-14 02:22:06 -08:00
|
|
|
}
|
2009-05-06 05:36:06 -07:00
|
|
|
}
|
2009-03-26 20:50:03 -07:00
|
|
|
}
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-10 01:44:24 -07:00
|
|
|
SLKU(im->cache.lock);
|
2012-04-26 02:53:03 -07:00
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2012-05-03 14:01:31 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_load_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->cache_entry);
|
|
|
|
}
|
2012-04-26 02:53:03 -07:00
|
|
|
evas_common_image_colorspace_normalize(im);
|
2009-03-27 19:50:19 -07:00
|
|
|
// misses++;
|
2009-03-26 23:06:45 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
|
|
|
if (smooth)
|
2013-01-16 08:07:46 -08:00
|
|
|
ret |= cb_smooth(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 23:06:45 -07:00
|
|
|
else
|
2013-01-16 08:07:46 -08:00
|
|
|
ret |= cb_sample(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 23:06:45 -07:00
|
|
|
}
|
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2009-03-26 23:06:45 -07:00
|
|
|
RGBA_Image *im = (RGBA_Image *)ie;
|
2013-01-16 08:07:46 -08:00
|
|
|
|
2012-04-26 02:53:03 -07:00
|
|
|
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
2012-05-03 14:01:31 -07:00
|
|
|
{
|
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
if (evas_cserve2_use_get())
|
|
|
|
evas_cache2_image_load_data(&im->cache_entry);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
evas_cache_image_load_data(&im->cache_entry);
|
|
|
|
}
|
2012-04-26 02:53:03 -07:00
|
|
|
evas_common_image_colorspace_normalize(im);
|
2009-03-26 23:06:45 -07:00
|
|
|
if (im->image.data)
|
|
|
|
{
|
2009-03-26 00:14:08 -07:00
|
|
|
if (smooth)
|
2013-01-16 08:07:46 -08:00
|
|
|
return cb_smooth(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 00:14:08 -07:00
|
|
|
else
|
2013-01-16 08:07:46 -08:00
|
|
|
return cb_sample(im, dst, dc,
|
|
|
|
src_region_x, src_region_y,
|
|
|
|
src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y,
|
|
|
|
dst_region_w, dst_region_h);
|
2009-03-26 00:14:08 -07:00
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
|
|
|
|
return EINA_FALSE;
|
2009-03-26 00:14:08 -07:00
|
|
|
#endif
|
|
|
|
}
|
2013-01-16 08:07:46 -08:00
|
|
|
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
|
|
|
|
RGBA_Draw_Context *dc, int smooth,
|
|
|
|
int src_region_x, int src_region_y,
|
|
|
|
int src_region_w, int src_region_h,
|
|
|
|
int dst_region_x, int dst_region_y,
|
|
|
|
int dst_region_w, int dst_region_h)
|
|
|
|
{
|
|
|
|
evas_common_rgba_image_scalecache_do_cbs(
|
|
|
|
ie, dst, dc, smooth,
|
|
|
|
src_region_x, src_region_y, src_region_w, src_region_h,
|
|
|
|
dst_region_x, dst_region_y, dst_region_w, dst_region_h,
|
|
|
|
evas_common_scale_rgba_in_to_out_clip_sample,
|
|
|
|
evas_common_scale_rgba_in_to_out_clip_smooth);
|
2013-01-16 14:32:39 -08:00
|
|
|
evas_common_rgba_image_scalecache_prune();
|
2013-01-16 08:07:46 -08:00
|
|
|
}
|