forked from enlightenment/efl
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
This commit is contained in:
parent
1a897239c7
commit
72c25fd2fc
|
@ -386,7 +386,9 @@ AC_CHECK_HEADERS(pthread.h sched.h,
|
|||
)
|
||||
### disable pthreads by default for now - some wierd deadlock issue with
|
||||
# barriers (makes no sense)
|
||||
#build_pthreads="no"
|
||||
# disable pthread code - messes with scalecache (whihc really is a much
|
||||
# bigger general speedup
|
||||
build_pthreads="no"
|
||||
AC_MSG_CHECKING(whether to build pthread code)
|
||||
AC_ARG_ENABLE(pthreads,
|
||||
AC_HELP_STRING([--enable-pthreads], [enable threaded rendering]),
|
||||
|
|
|
@ -57,6 +57,9 @@ struct _Evas_Cache_Image
|
|||
int usage;
|
||||
int limit;
|
||||
int references;
|
||||
|
||||
Eina_List *scaled;
|
||||
int scaledmem;
|
||||
};
|
||||
|
||||
struct _Evas_Cache_Engine_Image_Func
|
||||
|
@ -126,6 +129,7 @@ EAPI Image_Entry* evas_cache_image_alone(Image_Entry *im);
|
|||
EAPI Image_Entry* evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h);
|
||||
EAPI void evas_cache_image_load_data(Image_Entry *im);
|
||||
EAPI void evas_cache_image_surface_alloc(Image_Entry *im, int w, int h);
|
||||
EAPI void evas_cache_image_surface_dealloc(Image_Entry *im);
|
||||
EAPI DATA32* evas_cache_image_pixels(Image_Entry *im);
|
||||
EAPI Image_Entry* evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace);
|
||||
EAPI Image_Entry* evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace);
|
||||
|
|
|
@ -192,7 +192,7 @@ evas_cache_engine_image_init(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_
|
|||
parent->references++;
|
||||
|
||||
new->brother = NULL;
|
||||
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,7 @@ evas_cache_engine_image_flush(Evas_Cache_Engine_Image *cache)
|
|||
eim = (Engine_Image_Entry *) cache->lru->last;
|
||||
_evas_cache_engine_image_dealloc(cache, eim);
|
||||
}
|
||||
evas_common_image_set_cache(evas_common_image_get_cache());
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -45,19 +45,38 @@ static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry
|
|||
|
||||
static void
|
||||
_evas_cache_image_make_dirty(Evas_Cache_Image *cache,
|
||||
Image_Entry *im)
|
||||
Image_Entry *ie)
|
||||
{
|
||||
im->flags.cached = 1;
|
||||
im->flags.dirty = 1;
|
||||
im->flags.activ = 0;
|
||||
im->flags.lru_nodata = 0;
|
||||
cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im));
|
||||
ie->flags.cached = 1;
|
||||
ie->flags.dirty = 1;
|
||||
ie->flags.activ = 0;
|
||||
ie->flags.lru_nodata = 0;
|
||||
cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(ie));
|
||||
|
||||
if (im->cache_key)
|
||||
if (ie->cache_key)
|
||||
{
|
||||
eina_stringshare_del(im->cache_key);
|
||||
im->cache_key = NULL;
|
||||
eina_stringshare_del(ie->cache_key);
|
||||
ie->cache_key = NULL;
|
||||
}
|
||||
|
||||
while (ie->scalecache.others)
|
||||
{
|
||||
Image_Entry *ie2;
|
||||
|
||||
ie2 = ie->scalecache.others->data;
|
||||
cache->usage -= cache->func.mem_size_get(ie2);
|
||||
if (ie2->scalecache.usage >= 6)
|
||||
{
|
||||
ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaled =
|
||||
eina_list_remove(ie->cache->scaled, ie2);
|
||||
}
|
||||
ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
|
||||
ie2->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -92,7 +111,6 @@ _evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
|
|||
im->flags.cached = 1;
|
||||
cache->inactiv = evas_hash_direct_add(cache->inactiv, key, im);
|
||||
cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
|
||||
cache->usage += cache->func.mem_size_get(im);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -108,7 +126,6 @@ _evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
|
|||
{
|
||||
im->flags.lru_nodata = 0;
|
||||
cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im));
|
||||
cache->usage -= cache->func.mem_size_get(im);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +177,24 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
|
|||
if (cache->func.debug)
|
||||
cache->func.debug("deleting", ie);
|
||||
|
||||
while (ie->scalecache.others)
|
||||
{
|
||||
Image_Entry *ie2;
|
||||
|
||||
ie2 = ie->scalecache.others->data;
|
||||
cache->usage -= cache->func.mem_size_get(ie2);
|
||||
if (ie2->scalecache.usage >= 6)
|
||||
{
|
||||
ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaled =
|
||||
eina_list_remove(ie->cache->scaled, ie2);
|
||||
}
|
||||
ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
|
||||
ie2->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie2);
|
||||
}
|
||||
|
||||
cache->func.destructor(ie);
|
||||
|
||||
_evas_cache_image_remove_activ(cache, ie);
|
||||
|
@ -251,7 +286,7 @@ _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
|
|||
wmin = w > 0 ? w : 1;
|
||||
hmin = h > 0 ? h : 1;
|
||||
if (ie->allocated.w == wmin && ie->allocated.h == hmin)
|
||||
return ;
|
||||
return;
|
||||
|
||||
#ifdef BUILD_ASYNC_PRELOAD
|
||||
pthread_mutex_lock(&mutex_surface_alloc);
|
||||
|
@ -382,6 +417,9 @@ evas_cache_image_init(const Evas_Cache_Image_Func *cb)
|
|||
|
||||
new->references = 1;
|
||||
|
||||
new->scaled = NULL;
|
||||
new->scaledmem = 0;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
@ -603,6 +641,20 @@ evas_cache_image_drop(Image_Entry *im)
|
|||
assert(im);
|
||||
assert(im->cache);
|
||||
|
||||
if (im->scalecache.parent)
|
||||
{
|
||||
im->scalecache.parent->cache->usage -= im->scalecache.parent->cache->func.mem_size_get(im);
|
||||
if (im->scalecache.usage >= 6)
|
||||
{
|
||||
im->scalecache.parent->scalecache.mem -= im->scalecache.dst_w * im->scalecache.dst_h;
|
||||
im->scalecache.parent->cache->scaledmem -= im->scalecache.dst_w * im->scalecache.dst_h;
|
||||
im->scalecache.parent->cache->scaled =
|
||||
eina_list_remove(im->scalecache.parent->cache->scaled, im);
|
||||
}
|
||||
im->scalecache.parent->scalecache.others =
|
||||
eina_list_remove(im->scalecache.parent->scalecache.others, im);
|
||||
}
|
||||
|
||||
im->references--;
|
||||
cache = im->cache;
|
||||
|
||||
|
@ -643,13 +695,31 @@ evas_cache_image_data_not_needed(Image_Entry *im)
|
|||
EAPI Image_Entry *
|
||||
evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
|
||||
{
|
||||
Image_Entry *im_dirty = im;
|
||||
Image_Entry *im_dirty = im, *ie = im;
|
||||
Evas_Cache_Image *cache;
|
||||
|
||||
assert(im);
|
||||
assert(im->cache);
|
||||
|
||||
cache = im->cache;
|
||||
while (ie->scalecache.others)
|
||||
{
|
||||
Image_Entry *ie2;
|
||||
|
||||
ie2 = ie->scalecache.others->data;
|
||||
cache->usage -= cache->func.mem_size_get(ie2);
|
||||
if (ie2->scalecache.usage >= 6)
|
||||
{
|
||||
ie->scalecache.mem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaledmem -= ie2->scalecache.dst_w * ie2->scalecache.dst_h;
|
||||
ie->cache->scaled =
|
||||
eina_list_remove(ie->cache->scaled, ie2);
|
||||
}
|
||||
ie->scalecache.others = eina_list_remove_list(ie->scalecache.others, ie->scalecache.others);
|
||||
ie2->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie2);
|
||||
}
|
||||
|
||||
if (!(im->flags.dirty))
|
||||
{
|
||||
if (im->references == 1) im_dirty = im;
|
||||
|
@ -815,6 +885,41 @@ evas_cache_image_surface_alloc(Image_Entry *im, int w, int h)
|
|||
cache->func.debug("surface-alloc", im);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_cache_image_surface_dealloc(Image_Entry *im)
|
||||
{
|
||||
Evas_Cache_Image *cache;
|
||||
|
||||
assert(im);
|
||||
assert(im->cache);
|
||||
|
||||
cache = im->cache;
|
||||
|
||||
if (!((RGBA_Image *)im)->image.data) return;
|
||||
if (!im->info.loader) return;
|
||||
if (!im->info.module) return;
|
||||
if (!im->flags.loaded) return;
|
||||
|
||||
im->flags.loaded = 0;
|
||||
|
||||
#ifdef BUILD_ASYNC_PRELOAD
|
||||
pthread_mutex_lock(&mutex_surface_alloc);
|
||||
#endif
|
||||
|
||||
printf("-------- actual dealloc %p\n", im);
|
||||
_evas_cache_image_remove_lru_nodata(cache, im);
|
||||
cache->func.surface_delete(im);
|
||||
im->allocated.w = 0;
|
||||
im->allocated.h = 0;
|
||||
|
||||
#ifdef BUILD_ASYNC_PRELOAD
|
||||
pthread_mutex_unlock(&mutex_surface_alloc);
|
||||
#endif
|
||||
|
||||
if (cache->func.debug)
|
||||
cache->func.debug("surface-dealloc", im);
|
||||
}
|
||||
|
||||
EAPI Image_Entry *
|
||||
evas_cache_image_size_set(Image_Entry *im, int w, int h)
|
||||
{
|
||||
|
@ -890,7 +995,6 @@ evas_cache_image_load_data(Image_Entry *im)
|
|||
{
|
||||
_evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
|
||||
im->flags.loaded = 0;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
|
|||
char *dot;
|
||||
int i;
|
||||
|
||||
if (ie->info.loader)
|
||||
{
|
||||
if (!evas_common_load_rgba_image_data_from_file(ie)) return 0;
|
||||
}
|
||||
dot = strrchr (ie->file, '.');
|
||||
if (dot)
|
||||
{
|
||||
|
|
|
@ -405,7 +405,36 @@ EAPI void
|
|||
evas_common_image_set_cache(int size)
|
||||
{
|
||||
if (eci != NULL)
|
||||
evas_cache_image_set(eci, size);
|
||||
{
|
||||
Evas_Cache_Image *cache = eci;
|
||||
|
||||
evas_cache_image_set(eci, size);
|
||||
while (cache->scaledmem > (cache->limit >> 2))
|
||||
{
|
||||
Eina_List *l;
|
||||
Image_Entry *ie;
|
||||
|
||||
l = eina_list_last(cache->scaled);
|
||||
while (l)
|
||||
{
|
||||
ie = l->data;
|
||||
if (ie->scalecache.parent) break;
|
||||
l = l->prev;
|
||||
}
|
||||
if (!l)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ie->scalecache.parent->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
cache->scaled =
|
||||
eina_list_remove_list(cache->scaled, l);
|
||||
ie->scalecache.parent->scalecache.others =
|
||||
eina_list_remove(ie->scalecache.parent->scalecache.others, ie);
|
||||
ie->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI int
|
||||
|
|
|
@ -271,9 +271,10 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
|
|||
/* scale to dst */
|
||||
dptr = dst_ptr;
|
||||
#ifdef DIRECT_SCALE
|
||||
if ((!src->cache_entry.flags.alpha) &&
|
||||
if ((dc->render_op == _EVAS_RENDER_COPY) ||
|
||||
((!src->cache_entry.flags.alpha) &&
|
||||
(!dst->cache_entry.flags.alpha) &&
|
||||
(!dc->mul.use))
|
||||
(!dc->mul.use)))
|
||||
{
|
||||
for (y = 0; y < dst_clip_h; y++)
|
||||
{
|
||||
|
|
|
@ -270,64 +270,70 @@ struct _Image_Entry_Flags
|
|||
|
||||
struct _Image_Entry
|
||||
{
|
||||
EINA_INLIST;
|
||||
|
||||
Evas_Cache_Image *cache;
|
||||
|
||||
const char *cache_key;
|
||||
|
||||
const char *file;
|
||||
const char *key;
|
||||
|
||||
const void *target;
|
||||
|
||||
time_t timestamp;
|
||||
time_t laststat;
|
||||
|
||||
int references;
|
||||
|
||||
unsigned char scale;
|
||||
|
||||
RGBA_Image_Loadopts load_opts;
|
||||
int space;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
struct
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
} allocated;
|
||||
|
||||
struct
|
||||
{
|
||||
void *module;
|
||||
void *loader;
|
||||
} info;
|
||||
|
||||
Image_Entry_Flags flags;
|
||||
EINA_INLIST;
|
||||
|
||||
Evas_Cache_Image *cache;
|
||||
|
||||
const char *cache_key;
|
||||
|
||||
const char *file;
|
||||
const char *key;
|
||||
|
||||
const void *target;
|
||||
|
||||
time_t timestamp;
|
||||
time_t laststat;
|
||||
|
||||
int references;
|
||||
|
||||
unsigned char scale;
|
||||
|
||||
RGBA_Image_Loadopts load_opts;
|
||||
int space;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
struct {
|
||||
int w;
|
||||
int h;
|
||||
} allocated;
|
||||
|
||||
struct {
|
||||
void *module;
|
||||
void *loader;
|
||||
} info;
|
||||
|
||||
Image_Entry_Flags flags;
|
||||
struct {
|
||||
int usage;
|
||||
int mem;
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_w, dst_h;
|
||||
int smooth;
|
||||
Image_Entry *parent;
|
||||
Eina_List *others;
|
||||
} scalecache;
|
||||
};
|
||||
|
||||
struct _Engine_Image_Entry
|
||||
{
|
||||
EINA_INLIST;
|
||||
|
||||
|
||||
/* Upper Engine data. */
|
||||
Image_Entry *src;
|
||||
|
||||
|
||||
/* Cache stuff. */
|
||||
Evas_Cache_Engine_Image *cache;
|
||||
const char *cache_key;
|
||||
|
||||
struct
|
||||
{
|
||||
Evas_Bool cached : 1;
|
||||
Evas_Bool activ : 1;
|
||||
Evas_Bool dirty : 1;
|
||||
Evas_Bool loaded : 1;
|
||||
Evas_Bool need_parent : 1;
|
||||
|
||||
struct {
|
||||
Evas_Bool cached : 1;
|
||||
Evas_Bool activ : 1;
|
||||
Evas_Bool dirty : 1;
|
||||
Evas_Bool loaded : 1;
|
||||
Evas_Bool need_parent : 1;
|
||||
} flags;
|
||||
|
||||
|
||||
int references;
|
||||
int w;
|
||||
int h;
|
||||
|
|
|
@ -731,6 +731,175 @@ eng_image_data_preload_cancel(void *data, void *image)
|
|||
evas_cache_image_preload_cancel(&im->cache_entry);
|
||||
}
|
||||
|
||||
#define SCALECACHE 1
|
||||
|
||||
#ifdef SCALECACHE
|
||||
static Image_Entry *
|
||||
_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)
|
||||
{
|
||||
Eina_List *l;
|
||||
Image_Entry *ie = NULL;
|
||||
|
||||
for (l = im->scalecache.others; l; l = l->next)
|
||||
{
|
||||
ie = l->data;
|
||||
if ((ie->scalecache.dst_w == dst_w) &&
|
||||
(ie->scalecache.dst_h == dst_h) &&
|
||||
(ie->scalecache.src_w == src_w) &&
|
||||
(ie->scalecache.src_h == src_h) &&
|
||||
(ie->scalecache.src_x == src_x) &&
|
||||
(ie->scalecache.src_y == src_y) &&
|
||||
(ie->scalecache.smooth == smooth))
|
||||
{
|
||||
if (l != ie->scalecache.others)
|
||||
{
|
||||
im->scalecache.others = eina_list_remove_list(im->scalecache.others, l);
|
||||
im->scalecache.others = eina_list_prepend(im->scalecache.others, ie);
|
||||
}
|
||||
ie->scalecache.usage++;
|
||||
return ie;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_sc_clean(Image_Entry *im)
|
||||
{
|
||||
while ((im->scalecache.mem > (im->cache->limit >> 2)) ||
|
||||
(eina_list_count(im->scalecache.others) > 40))
|
||||
{
|
||||
Eina_List *l;
|
||||
Image_Entry *ie;
|
||||
|
||||
printf("clean %i > %i\n", im->cache->scaledmem, im->cache->limit >> 2);
|
||||
l = eina_list_last(im->scalecache.others);
|
||||
ie = l->data;
|
||||
if (ie->scalecache.usage >= 6)
|
||||
{
|
||||
im->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
im->cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
im->cache->scaled =
|
||||
eina_list_remove(im->cache->scaled, ie);
|
||||
}
|
||||
im->scalecache.others = eina_list_remove_list(im->scalecache.others, l);
|
||||
ie->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie);
|
||||
}
|
||||
}
|
||||
|
||||
static Image_Entry *
|
||||
_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)
|
||||
{
|
||||
Image_Entry *ie;
|
||||
|
||||
ie = evas_cache_image_empty(im->cache);
|
||||
evas_cache_image_colorspace(ie, EVAS_COLORSPACE_ARGB8888);
|
||||
im->scalecache.usage++;
|
||||
im->scalecache.others = eina_list_prepend(im->scalecache.others, ie);
|
||||
ie->scalecache.src_x = src_x;
|
||||
ie->scalecache.src_y = src_y;
|
||||
ie->scalecache.src_w = src_w;
|
||||
ie->scalecache.src_h = src_h;
|
||||
ie->scalecache.dst_w = dst_w;
|
||||
ie->scalecache.dst_h = dst_h;
|
||||
ie->scalecache.smooth = smooth;
|
||||
ie->scalecache.parent = im;
|
||||
return ie;
|
||||
}
|
||||
|
||||
static int
|
||||
_sc_fill(Image_Entry *im, Image_Entry *ie)
|
||||
{
|
||||
RGBA_Draw_Context *tctx;
|
||||
|
||||
ie->scalecache.usage++;
|
||||
if (ie->scalecache.usage < 5) return 0;
|
||||
if (ie->scalecache.usage >= 6)
|
||||
{
|
||||
ie->scalecache.parent->scalecache.usage--;
|
||||
if (ie->scalecache.parent->scalecache.usage <= 0)
|
||||
{
|
||||
ie->scalecache.parent->scalecache.usage = 0;
|
||||
if ((im->info.loader) &&
|
||||
(im->flags.loaded) &&
|
||||
(im->info.module) &&
|
||||
(im->file) &&
|
||||
(((RGBA_Image*)im)->image.data));
|
||||
{
|
||||
evas_cache_image_surface_dealloc(im);
|
||||
}
|
||||
}
|
||||
im->cache->scaled =
|
||||
eina_list_remove(im->cache->scaled, ie);
|
||||
im->cache->scaled =
|
||||
eina_list_prepend(im->cache->scaled, ie);
|
||||
return 1;
|
||||
}
|
||||
im->scalecache.usage += 10;
|
||||
im->cache->func.load(im);
|
||||
ie->scalecache.usage = 6;
|
||||
im->scalecache.mem += ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
im->cache->scaledmem += ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
im->cache->scaled =
|
||||
eina_list_prepend(im->cache->scaled, ie);
|
||||
ie->flags.alpha = im->flags.alpha;
|
||||
ie->w = ie->scalecache.dst_w;
|
||||
ie->h = ie->scalecache.dst_h;
|
||||
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
|
||||
tctx = evas_common_draw_context_new();
|
||||
evas_common_draw_context_set_render_op(tctx, _EVAS_RENDER_COPY);
|
||||
if (ie->scalecache.smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth
|
||||
((RGBA_Image *)im, (RGBA_Image *)ie, tctx,
|
||||
ie->scalecache.src_x, ie->scalecache.src_y,
|
||||
ie->scalecache.src_w, ie->scalecache.src_h,
|
||||
0, 0,
|
||||
ie->scalecache.dst_w, ie->scalecache.dst_h);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_sample
|
||||
((RGBA_Image *)im, (RGBA_Image *)ie, tctx,
|
||||
ie->scalecache.src_x, ie->scalecache.src_y,
|
||||
ie->scalecache.src_w, ie->scalecache.src_h,
|
||||
0, 0,
|
||||
ie->scalecache.dst_w, ie->scalecache.dst_h);
|
||||
evas_common_draw_context_free(tctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_sc_flush(Evas_Cache_Image *cache)
|
||||
{
|
||||
while (cache->scaledmem > (cache->limit >> 2))
|
||||
{
|
||||
Eina_List *l;
|
||||
Image_Entry *ie;
|
||||
|
||||
printf("flush %i > %i\n", cache->scaledmem, cache->limit >> 2);
|
||||
l = eina_list_last(cache->scaled);
|
||||
while (l)
|
||||
{
|
||||
ie = l->data;
|
||||
if (ie->scalecache.parent) break;
|
||||
l = l->prev;
|
||||
}
|
||||
if (!l)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ie->scalecache.parent->scalecache.mem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
cache->scaledmem -= ie->scalecache.dst_w * ie->scalecache.dst_h;
|
||||
cache->scaled =
|
||||
eina_list_remove_list(cache->scaled, l);
|
||||
ie->scalecache.parent->scalecache.others =
|
||||
eina_list_remove(ie->scalecache.parent->scalecache.others, ie);
|
||||
ie->scalecache.parent = NULL;
|
||||
evas_cache_image_drop(ie);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
eng_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)
|
||||
{
|
||||
|
@ -743,20 +912,72 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
|
|||
evas_common_image_colorspace_normalize(im);
|
||||
#ifdef BUILD_PTHREAD
|
||||
if (cpunum > 1)
|
||||
evas_common_pipe_image_draw(im, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
{
|
||||
if (im->image.data)
|
||||
{
|
||||
evas_common_pipe_image_draw(im, surface,
|
||||
context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
#ifdef SCALECACHE
|
||||
Image_Entry *ie, *ie2;
|
||||
int ok;
|
||||
|
||||
ie = (Image_Entry *)im;
|
||||
if ((src_w == dst_w) && (src_h == dst_h))
|
||||
{
|
||||
ie->scalecache.usage++;
|
||||
if (smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
_sc_clean(ie);
|
||||
ie2 = _sc_find(ie, src_x, src_y, src_w, src_h, dst_w, dst_h, smooth);
|
||||
if (ie2) ok = _sc_fill(ie, ie2);
|
||||
else
|
||||
{
|
||||
ie2 = _sc_new(ie, src_x, src_y, src_w, src_h, dst_w, dst_h, smooth);
|
||||
if (ie2) ok = _sc_fill(ie, ie2);
|
||||
}
|
||||
if ((ie2) && (ok))
|
||||
evas_common_scale_rgba_in_to_out_clip_sample((RGBA_Image *)ie2,
|
||||
surface, context,
|
||||
0, 0, dst_w, dst_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
else
|
||||
{
|
||||
ie->scalecache.usage++;
|
||||
evas_cache_image_load_data(ie);
|
||||
#endif
|
||||
if (im->image.data)
|
||||
{
|
||||
if (smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
#ifdef SCALECACHE
|
||||
}
|
||||
}
|
||||
_sc_flush(ie->cache);
|
||||
#endif
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue