forked from enlightenment/efl
parent
5482c36015
commit
55f6c5f046
|
@ -14,6 +14,7 @@ evas_engine.c \
|
||||||
evas_soft16.h \
|
evas_soft16.h \
|
||||||
evas_soft16_dither_mask.c \
|
evas_soft16_dither_mask.c \
|
||||||
evas_soft16_main.c \
|
evas_soft16_main.c \
|
||||||
|
evas_soft16_image_cache.c \
|
||||||
evas_soft16_image_unscaled.c \
|
evas_soft16_image_unscaled.c \
|
||||||
evas_soft16_image_scaled_sampled.c \
|
evas_soft16_image_scaled_sampled.c \
|
||||||
evas_soft16_font.c \
|
evas_soft16_font.c \
|
||||||
|
@ -32,6 +33,7 @@ evas_engine.c \
|
||||||
evas_soft16.h \
|
evas_soft16.h \
|
||||||
evas_soft16_dither_mask.c \
|
evas_soft16_dither_mask.c \
|
||||||
evas_soft16_main.c \
|
evas_soft16_main.c \
|
||||||
|
evas_soft16_image_cache.c \
|
||||||
evas_soft16_image_unscaled.c \
|
evas_soft16_image_unscaled.c \
|
||||||
evas_soft16_image_scaled_sampled.c \
|
evas_soft16_image_scaled_sampled.c \
|
||||||
evas_soft16_font.c \
|
evas_soft16_font.c \
|
||||||
|
|
|
@ -491,16 +491,23 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
|
||||||
{
|
{
|
||||||
Soft16_Image *im_new;
|
Soft16_Image *im_new;
|
||||||
|
|
||||||
im_new = soft16_image_new(im->w, im->h, im->stride, im->have_alpha, im->pixels, 1);
|
im_new = soft16_image_new(im->w, im->h, im->stride, im->have_alpha,
|
||||||
if (!im_new) return im;
|
im->pixels, 1);
|
||||||
|
if (!im_new)
|
||||||
|
{
|
||||||
|
if (image_data) *image_data = NULL;
|
||||||
|
return im;
|
||||||
|
}
|
||||||
soft16_image_free(im);
|
soft16_image_free(im);
|
||||||
im = im_new;
|
im = im_new;
|
||||||
}
|
}
|
||||||
|
if (im->cache_key)
|
||||||
|
soft16_image_cache_del(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_data) *image_data = (DATA32 *) im->pixels;
|
if (image_data) *image_data = (DATA32 *) im->pixels;
|
||||||
|
|
||||||
return image;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -532,23 +539,19 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
|
||||||
static void
|
static void
|
||||||
eng_image_cache_flush(void *data)
|
eng_image_cache_flush(void *data)
|
||||||
{
|
{
|
||||||
int tmp_size;
|
soft16_image_cache_flush();
|
||||||
|
|
||||||
tmp_size = evas_common_image_get_cache();
|
|
||||||
evas_common_image_set_cache(0);
|
|
||||||
evas_common_image_set_cache(tmp_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_image_cache_set(void *data, int bytes)
|
eng_image_cache_set(void *data, int bytes)
|
||||||
{
|
{
|
||||||
evas_common_image_set_cache(bytes);
|
soft16_image_cache_size_set(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
eng_image_cache_get(void *data)
|
eng_image_cache_get(void *data)
|
||||||
{
|
{
|
||||||
return evas_common_image_get_cache();
|
return soft16_image_cache_size_get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
|
|
@ -58,6 +58,9 @@
|
||||||
#define pld(addr, off)
|
#define pld(addr, off)
|
||||||
#endif /* __ARMEL__ */
|
#endif /* __ARMEL__ */
|
||||||
|
|
||||||
|
#define IMG_BYTE_SIZE(stride, height, has_alpha) \
|
||||||
|
((stride) * (height) * (!(has_alpha) ? 2 : 3))
|
||||||
|
|
||||||
typedef struct _Soft16_Image Soft16_Image;
|
typedef struct _Soft16_Image Soft16_Image;
|
||||||
|
|
||||||
struct _Soft16_Image
|
struct _Soft16_Image
|
||||||
|
@ -75,9 +78,10 @@ struct _Soft16_Image
|
||||||
|
|
||||||
Evas_Image_Load_Opts lo; // load options
|
Evas_Image_Load_Opts lo; // load options
|
||||||
|
|
||||||
|
const char *cache_key;
|
||||||
|
|
||||||
unsigned char have_alpha : 1; // 1 if we have halpha
|
unsigned char have_alpha : 1; // 1 if we have halpha
|
||||||
unsigned char free_pixels : 1; // 1 if pixels should be freed
|
unsigned char free_pixels : 1; // 1 if pixels should be freed
|
||||||
unsigned char free_alpha : 1; // 1 if alpha mask should be freed
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,6 +89,7 @@ struct _Soft16_Image
|
||||||
*/
|
*/
|
||||||
Soft16_Image *soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, int copy);
|
Soft16_Image *soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, int copy);
|
||||||
void soft16_image_free(Soft16_Image *im);
|
void soft16_image_free(Soft16_Image *im);
|
||||||
|
void soft16_image_destroy(Soft16_Image *im);
|
||||||
Soft16_Image *soft16_image_load(const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo);
|
Soft16_Image *soft16_image_load(const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo);
|
||||||
void soft16_image_load_data(Soft16_Image *im);
|
void soft16_image_load_data(Soft16_Image *im);
|
||||||
void soft16_image_draw(Soft16_Image *src, Soft16_Image *dst, RGBA_Draw_Context *dc, 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, int smooth);
|
void soft16_image_draw(Soft16_Image *src, Soft16_Image *dst, RGBA_Draw_Context *dc, 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, int smooth);
|
||||||
|
@ -99,6 +104,17 @@ void soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst, RGBA
|
||||||
void soft16_image_convert_from_rgb(Soft16_Image *im, const DATA32 *src);
|
void soft16_image_convert_from_rgb(Soft16_Image *im, const DATA32 *src);
|
||||||
void soft16_image_convert_from_rgba(Soft16_Image *im, const DATA32 *src);
|
void soft16_image_convert_from_rgba(Soft16_Image *im, const DATA32 *src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image cache (evas_soft16_image_cache.c)
|
||||||
|
*/
|
||||||
|
void soft16_image_cache_flush(void);
|
||||||
|
int soft16_image_cache_size_get(void);
|
||||||
|
void soft16_image_cache_size_set(int limit);
|
||||||
|
|
||||||
|
Soft16_Image *soft16_image_cache_get(const char *cache_key);
|
||||||
|
void soft16_image_cache_put(Soft16_Image *im);
|
||||||
|
void soft16_image_cache_add(Soft16_Image *im, const char *cache_key);
|
||||||
|
void soft16_image_cache_del(Soft16_Image *im);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rectangle (evas_soft16_rectangle.c)
|
* Rectangle (evas_soft16_rectangle.c)
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
/**
|
||||||
|
* Software 16 image cache system.
|
||||||
|
*
|
||||||
|
* Images backed by files are registered in a hash table (_soft16_cache.hash)
|
||||||
|
* for fast lookup of existing, thus avoiding duplication of data.
|
||||||
|
*
|
||||||
|
* Images considered live, or in use, are those with im->references >
|
||||||
|
* 0, these are NOT accounted in the cache limits, but they're still
|
||||||
|
* available in the hash table for lookup.
|
||||||
|
*
|
||||||
|
* As soon as some image is not in use anymore (im->references == 0),
|
||||||
|
* it's put into cache and appended to a linked list
|
||||||
|
* (_soft16_cache.lru) if it fit into limits, if required, older
|
||||||
|
* elements will be removed to make room.
|
||||||
|
*
|
||||||
|
* Images that are tainted (pixels were modified), are removed from
|
||||||
|
* cache.
|
||||||
|
*
|
||||||
|
* Just payload size (pixels, with alpha) are accounted in
|
||||||
|
* calculation, shallow images (without real data), are accounted as
|
||||||
|
* regular images.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "evas_soft16.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifndef DEBUG_CACHE
|
||||||
|
//#define DEBUG_CACHE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEBUG_COLOR
|
||||||
|
#define DEBUG_COLOR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLOR
|
||||||
|
#define COLOR_CLEAR "\033[0m"
|
||||||
|
#define COLOR_RED "\033[31m"
|
||||||
|
#define COLOR_GREEN "\033[32m"
|
||||||
|
#define COLOR_YELLOW "\033[33m"
|
||||||
|
#define COLOR_BLUE "\033[34m"
|
||||||
|
#define COLOR_MAGENTA "\033[35m"
|
||||||
|
#define COLOR_CYAN "\033[36m"
|
||||||
|
#else
|
||||||
|
#define COLOR_CLEAR ""
|
||||||
|
#define COLOR_RED ""
|
||||||
|
#define COLOR_GREEN ""
|
||||||
|
#define COLOR_YELLOW ""
|
||||||
|
#define COLOR_BLUE ""
|
||||||
|
#define COLOR_MAGENTA ""
|
||||||
|
#define COLOR_CYAN ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_CACHE
|
||||||
|
static inline void
|
||||||
|
_dbg(const char *file, int line, const char *func, const char *color, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char msg[4096];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(msg, sizeof(msg), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
fprintf(stderr, "DBG: %s%s:%d:%s"COLOR_CLEAR" %s\n", color, file, line, func, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define dbg(fmt, ...) \
|
||||||
|
_dbg(__FILE__, __LINE__, __FUNCTION__, COLOR_CLEAR, fmt, ##__VA_ARGS__)
|
||||||
|
#define dbg_color(col, fmt, ...) \
|
||||||
|
_dbg(__FILE__, __LINE__, __FUNCTION__, col, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dbg(fmt, ...) do {} while (0)
|
||||||
|
#define dbg_color(col, fmt, ...) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _Soft16_Cache Soft16_Cache;
|
||||||
|
struct _Soft16_Cache {
|
||||||
|
Evas_Hash *hash; /**< every known image */
|
||||||
|
Evas_List *lru; /**< unused images, from older to newer */
|
||||||
|
int limit; /**< maximum size in bytes to keep with unused images */
|
||||||
|
int used; /**< current amount in bytes used by unused images */
|
||||||
|
};
|
||||||
|
static Soft16_Cache _soft16_cache = {NULL, NULL, 0, 0};
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
soft16_image_cache_destroy_image(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
_soft16_cache.hash = evas_hash_del(_soft16_cache.hash, im->cache_key, im);
|
||||||
|
evas_stringshare_del(im->cache_key);
|
||||||
|
soft16_image_destroy(im);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_cache_flush(void)
|
||||||
|
{
|
||||||
|
Evas_List *n;
|
||||||
|
|
||||||
|
dbg_color(COLOR_RED, "cache flush");
|
||||||
|
|
||||||
|
for (n = _soft16_cache.lru; n != NULL; n = n->next)
|
||||||
|
soft16_image_cache_destroy_image(n->data);
|
||||||
|
|
||||||
|
_soft16_cache.lru = evas_list_free(_soft16_cache.lru);
|
||||||
|
_soft16_cache.used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
soft16_image_cache_image_size_get(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
return IMG_BYTE_SIZE(im->stride, im->h, im->have_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
soft16_image_cache_free(int bytes)
|
||||||
|
{
|
||||||
|
Evas_List *n;
|
||||||
|
|
||||||
|
dbg_color(COLOR_RED, "BEG cache free %d bytes, used %d of %d...",
|
||||||
|
bytes, _soft16_cache.used, _soft16_cache.limit);
|
||||||
|
|
||||||
|
if (bytes >= _soft16_cache.used)
|
||||||
|
{
|
||||||
|
soft16_image_cache_flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = _soft16_cache.lru;
|
||||||
|
while (bytes > 0 && n != NULL)
|
||||||
|
{
|
||||||
|
Soft16_Image *im;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
im = n->data;
|
||||||
|
size = soft16_image_cache_image_size_get(im);
|
||||||
|
bytes -= size;
|
||||||
|
_soft16_cache.used -= size;
|
||||||
|
|
||||||
|
soft16_image_cache_destroy_image(im);
|
||||||
|
n = _soft16_cache.lru = evas_list_remove_list(_soft16_cache.lru, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(_soft16_cache.used >= 0);
|
||||||
|
dbg_color(COLOR_RED, "END cache is now %d of %d",
|
||||||
|
_soft16_cache.used, _soft16_cache.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
soft16_image_cache_size_get(void)
|
||||||
|
{
|
||||||
|
return _soft16_cache.limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_cache_size_set(int limit)
|
||||||
|
{
|
||||||
|
dbg("old: %d, new: %d, used: %d",
|
||||||
|
_soft16_cache.limit, limit, _soft16_cache.used);
|
||||||
|
|
||||||
|
if (limit < _soft16_cache.used && limit >= 0)
|
||||||
|
soft16_image_cache_free(_soft16_cache.used - limit);
|
||||||
|
|
||||||
|
_soft16_cache.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
soft16_image_cache_lru_del(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
Evas_List *n;
|
||||||
|
|
||||||
|
dbg_color(COLOR_YELLOW, "im=%p\n", im);
|
||||||
|
|
||||||
|
for (n = _soft16_cache.lru; n != NULL; n = n->next)
|
||||||
|
if (n->data == im)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!n)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_soft16_cache.lru = evas_list_remove_list(_soft16_cache.lru, n);
|
||||||
|
_soft16_cache.used -= soft16_image_cache_image_size_get(im);
|
||||||
|
dbg_color(COLOR_YELLOW, " found, remove from cache, stats %d of %d",
|
||||||
|
_soft16_cache.used, _soft16_cache.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
soft16_image_cache_lru_add(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
_soft16_cache.lru = evas_list_append(_soft16_cache.lru, im);
|
||||||
|
_soft16_cache.used += soft16_image_cache_image_size_get(im);
|
||||||
|
dbg_color(COLOR_YELLOW, " add to cache, stats %d of %d",
|
||||||
|
_soft16_cache.used, _soft16_cache.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STAT_GAP 2
|
||||||
|
|
||||||
|
Soft16_Image *
|
||||||
|
soft16_image_cache_get(const char *cache_key)
|
||||||
|
{
|
||||||
|
Soft16_Image *im;
|
||||||
|
|
||||||
|
dbg_color(COLOR_GREEN, "cache_key=[%s]", cache_key);
|
||||||
|
|
||||||
|
im = evas_hash_find(_soft16_cache.hash, cache_key);
|
||||||
|
if (im)
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
if ((t - im->laststat) > STAT_GAP)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(im->file, &st) < 0) return NULL;
|
||||||
|
if (st.st_mtime != im->timestamp) return NULL;
|
||||||
|
|
||||||
|
im->laststat = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg_color(COLOR_GREEN, " found %p, [%s][%s] %dx%d, refernces=%d",
|
||||||
|
im, im->file, im->key, im->w, im->h, im->references);
|
||||||
|
|
||||||
|
if (im->references == 0)
|
||||||
|
soft16_image_cache_lru_del(im);
|
||||||
|
|
||||||
|
im->references++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dbg_color(COLOR_GREEN, "not found!");
|
||||||
|
|
||||||
|
return im;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_cache_put(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
|
||||||
|
assert(im);
|
||||||
|
assert(im->cache_key);
|
||||||
|
assert(im->references == 0);
|
||||||
|
|
||||||
|
dbg_color(COLOR_CYAN, "BEG im=%p, cache_key=%s", im, im->cache_key);
|
||||||
|
|
||||||
|
size = soft16_image_cache_image_size_get(im);
|
||||||
|
dbg(" sizes: im=%d, used=%d, limit=%d", size,
|
||||||
|
_soft16_cache.used, _soft16_cache.limit);
|
||||||
|
|
||||||
|
if (size + _soft16_cache.used > _soft16_cache.limit)
|
||||||
|
{
|
||||||
|
if (size > _soft16_cache.limit)
|
||||||
|
{
|
||||||
|
dbg_color(COLOR_CYAN, " image doesn't fit in cache, destroy");
|
||||||
|
soft16_image_cache_del(im);
|
||||||
|
soft16_image_destroy(im);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
soft16_image_cache_free(_soft16_cache.used - size);
|
||||||
|
dbg(" freed cache space, now %d available",
|
||||||
|
_soft16_cache.limit - _soft16_cache.used);
|
||||||
|
}
|
||||||
|
|
||||||
|
soft16_image_cache_lru_add(im);
|
||||||
|
dbg_color(COLOR_CYAN, "END cache stats: used=%d, limit=%d",
|
||||||
|
_soft16_cache.used, _soft16_cache.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_cache_add(Soft16_Image *im, const char *cache_key)
|
||||||
|
{
|
||||||
|
assert(im);
|
||||||
|
assert(cache_key);
|
||||||
|
assert(im->cache_key == NULL);
|
||||||
|
|
||||||
|
dbg_color(COLOR_MAGENTA, "im=%p, cache_key=%s", im, cache_key);
|
||||||
|
|
||||||
|
im->cache_key = evas_stringshare_add(cache_key);
|
||||||
|
_soft16_cache.hash = evas_hash_add(_soft16_cache.hash, im->cache_key, im);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_cache_del(Soft16_Image *im)
|
||||||
|
{
|
||||||
|
assert(im);
|
||||||
|
assert(im->cache_key != NULL);
|
||||||
|
|
||||||
|
dbg_color(COLOR_MAGENTA, "im=%p, cache_key=%s", im, im->cache_key);
|
||||||
|
|
||||||
|
_soft16_cache.hash = evas_hash_del(_soft16_cache.hash, im->cache_key, im);
|
||||||
|
soft16_image_cache_lru_del(im);
|
||||||
|
|
||||||
|
evas_stringshare_del(im->cache_key);
|
||||||
|
im->cache_key = NULL;
|
||||||
|
}
|
|
@ -1,10 +1,5 @@
|
||||||
#include "evas_soft16.h"
|
#include "evas_soft16.h"
|
||||||
|
|
||||||
#define IMG_BYTE_SIZE(stride, height, has_alpha) \
|
|
||||||
((stride) * (height) * (!(has_alpha) ? 2 : 3))
|
|
||||||
|
|
||||||
static Evas_Hash *_soft16_image_cache_hash = NULL;
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
_calc_stride(int w)
|
_calc_stride(int w)
|
||||||
{
|
{
|
||||||
|
@ -109,50 +104,28 @@ soft16_image_cache_key_from_img(const Soft16_Image *im, char *buf,
|
||||||
void
|
void
|
||||||
soft16_image_free(Soft16_Image *im)
|
soft16_image_free(Soft16_Image *im)
|
||||||
{
|
{
|
||||||
if (!im) return;
|
if (!im)
|
||||||
|
return;
|
||||||
|
|
||||||
im->references--;
|
im->references--;
|
||||||
if (im->references > 0) return;
|
if (im->references > 0)
|
||||||
if (im->file)
|
return;
|
||||||
{
|
|
||||||
char buf[4096 + 1024];
|
if (im->cache_key)
|
||||||
soft16_image_cache_key_from_img(im, buf, sizeof(buf));
|
soft16_image_cache_put(im);
|
||||||
_soft16_image_cache_hash = evas_hash_del(_soft16_image_cache_hash,
|
else
|
||||||
buf, im);
|
soft16_image_destroy(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
soft16_image_destroy(Soft16_Image *im)
|
||||||
|
{
|
||||||
if (im->file) evas_stringshare_del(im->file);
|
if (im->file) evas_stringshare_del(im->file);
|
||||||
if (im->key) evas_stringshare_del(im->key);
|
if (im->key) evas_stringshare_del(im->key);
|
||||||
if (im->free_pixels) free(im->pixels);
|
if (im->free_pixels) free(im->pixels);
|
||||||
free(im);
|
free(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STAT_GAP 2
|
|
||||||
|
|
||||||
static Soft16_Image *
|
|
||||||
soft16_image_cache_get(const char *cache_key)
|
|
||||||
{
|
|
||||||
Soft16_Image *im;
|
|
||||||
|
|
||||||
im = evas_hash_find(_soft16_image_cache_hash, cache_key);
|
|
||||||
if (im)
|
|
||||||
{
|
|
||||||
time_t t;
|
|
||||||
|
|
||||||
t = time(NULL);
|
|
||||||
if ((t - im->laststat) > STAT_GAP)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(im->file, &st) < 0) return NULL;
|
|
||||||
if (st.st_mtime != im->timestamp) return NULL;
|
|
||||||
|
|
||||||
im->laststat = t;
|
|
||||||
}
|
|
||||||
im->references++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return im;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Soft16_Image *
|
static Soft16_Image *
|
||||||
soft16_image_load_new(const char *file, const char *key,
|
soft16_image_load_new(const char *file, const char *key,
|
||||||
Evas_Image_Load_Opts *lo)
|
Evas_Image_Load_Opts *lo)
|
||||||
|
@ -192,13 +165,17 @@ soft16_image_load(const char *file, const char *key, int *error,
|
||||||
char buf[4096 + 1024];
|
char buf[4096 + 1024];
|
||||||
|
|
||||||
*error = 0;
|
*error = 0;
|
||||||
if (!file) return NULL;
|
if (!file)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
soft16_image_cache_key(lo, key, file, buf, sizeof(buf));
|
soft16_image_cache_key(lo, key, file, buf, sizeof(buf));
|
||||||
im = soft16_image_cache_get(buf);
|
im = soft16_image_cache_get(buf);
|
||||||
if (im) return im;
|
if (im)
|
||||||
|
return im;
|
||||||
|
|
||||||
im = soft16_image_load_new(file, key, lo);
|
im = soft16_image_load_new(file, key, lo);
|
||||||
if (im) _soft16_image_cache_hash = evas_hash_add(_soft16_image_cache_hash, buf, im);
|
if (im)
|
||||||
|
soft16_image_cache_add(im, buf);
|
||||||
|
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +430,7 @@ soft16_image_alpha_set(Soft16_Image *im, int have_alpha)
|
||||||
if (im->have_alpha == have_alpha) return im;
|
if (im->have_alpha == have_alpha) return im;
|
||||||
im->have_alpha = have_alpha;
|
im->have_alpha = have_alpha;
|
||||||
|
|
||||||
if ((im->pixels) && (im->free_pixels))
|
if ((im->pixels) && (im->free_pixels) && (im->references == 1))
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
|
@ -469,6 +446,9 @@ soft16_image_alpha_set(Soft16_Image *im, int have_alpha)
|
||||||
im->alpha = (DATA8*)(im->pixels + size);
|
im->alpha = (DATA8*)(im->pixels + size);
|
||||||
memset(im->alpha, 0x1f, size);
|
memset(im->alpha, 0x1f, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (im->cache_key)
|
||||||
|
soft16_image_cache_remove(im);
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue