evas/cserve2: Add scalecache support
Signed-off-by: Paulo Alcantara <pcacjr@profusion.mobi> Patch by: Paulo Alcantara <pcacjr@profusion.mobi> SVN revision: 79754
This commit is contained in:
parent
8ac3152e89
commit
f8f79f8599
|
@ -1,3 +1,6 @@
|
|||
2012-11-22 Paulo Alcantara (pcacjr)
|
||||
* Add scalecache support to Cserve2
|
||||
|
||||
2012-11-22 Sung W. Park (sung_)
|
||||
|
||||
* Fixed a bug where if an image object rendered using Evas GL
|
||||
|
|
1
NEWS
1
NEWS
|
@ -11,6 +11,7 @@ Additions:
|
|||
* Add eina_tmpstr_add() and eina_tmpstr_del()
|
||||
* Add eina_thread API
|
||||
* Add eina_list_last_data_get
|
||||
* Add Cserve2 scalecache support
|
||||
|
||||
Improvements:
|
||||
* Single EFL tree covering all EFL library components.
|
||||
|
|
|
@ -1727,6 +1727,7 @@ bin/evas/evas_cserve2_shm.c \
|
|||
bin/evas/evas_cserve2_cache.c \
|
||||
bin/evas/evas_cserve2_requests.c \
|
||||
bin/evas/evas_cserve2_fonts.c \
|
||||
bin/evas/evas_cserve2_scale.c \
|
||||
bin/evas/evas_cserve2_main_loop_linux.c \
|
||||
lib/evas/cserve2/evas_cs2_utils.h \
|
||||
lib/evas/cserve2/evas_cs2_utils.c
|
||||
|
|
|
@ -109,6 +109,7 @@ struct _Slave_Msg_Image_Load {
|
|||
};
|
||||
|
||||
struct _Slave_Msg_Image_Loaded {
|
||||
int w, h;
|
||||
Eina_Bool alpha_sparse : 1;
|
||||
};
|
||||
|
||||
|
@ -275,6 +276,9 @@ size_t cserve2_shm_size_normalize(size_t size);
|
|||
|
||||
void cserve2_command_run(Client *client, Message_Type type);
|
||||
|
||||
void cserve2_scale_init(void);
|
||||
void cserve2_scale_shutdown(void);
|
||||
|
||||
void cserve2_cache_init(void);
|
||||
void cserve2_cache_shutdown(void);
|
||||
void cserve2_cache_client_new(Client *client);
|
||||
|
@ -282,6 +286,7 @@ void cserve2_cache_client_del(Client *client);
|
|||
int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
|
||||
void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
|
||||
int cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg);
|
||||
void cserve2_rgba_image_scale_do(void *src_data, void *dst_data, 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 alpha, int smooth);
|
||||
void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid);
|
||||
void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
|
||||
void cserve2_cache_image_unload(Client *client, unsigned int client_image_id);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef DEBUG_LOAD_TIME
|
||||
#include <sys/time.h>
|
||||
|
@ -65,6 +66,10 @@ struct _Image_Data {
|
|||
int w, h; // w and h < -1
|
||||
int scale_down; // scale_down < -1
|
||||
int rx, ry, rw, rh; // rx, ry, rw, rh < -1
|
||||
int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
|
||||
int scale_dst_w, scale_dst_h;
|
||||
int scale_smooth;
|
||||
int scale_hint;
|
||||
Eina_Bool orientation; // orientation == 0
|
||||
} opts;
|
||||
Shm_Handle *shm;
|
||||
|
@ -179,7 +184,7 @@ static Eina_List *image_entries_lru = NULL;
|
|||
|
||||
static Eina_List *font_shm_lru = NULL;
|
||||
|
||||
static int max_unused_mem_usage = 5 * 1024; /* in kbytes */
|
||||
static int max_unused_mem_usage = 5 * 4 * 1024; /* in kbytes */
|
||||
static int unused_mem_usage = 0;
|
||||
static int max_font_usage = 10 * 4 * 1024; /* in kbytes */
|
||||
static int font_mem_usage = 0;
|
||||
|
@ -474,6 +479,78 @@ _load_request_build(Image_Data *i, int *bufsize)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_scaling_needed(Image_Data *entry, Slave_Msg_Image_Loaded *resp)
|
||||
{
|
||||
return (((entry->opts.scale_dst_w) && (entry->opts.scale_dst_h)) &&
|
||||
((entry->opts.scale_dst_w != resp->w) ||
|
||||
(entry->opts.scale_dst_h != resp->h)));
|
||||
}
|
||||
|
||||
static int
|
||||
_scaling_do(Shm_Handle *scale_shm, Image_Data *entry)
|
||||
{
|
||||
char *scale_map, *orig_map;
|
||||
void *src_data, *dst_data;
|
||||
|
||||
scale_map = cserve2_shm_map(scale_shm);
|
||||
if (scale_map == MAP_FAILED)
|
||||
{
|
||||
ERR("Failed to memory map file for scale image.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
orig_map = cserve2_shm_map(entry->shm);
|
||||
if (orig_map == MAP_FAILED)
|
||||
{
|
||||
ERR("Failed to memory map file for original image.");
|
||||
|
||||
cserve2_shm_unmap(scale_shm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
src_data = orig_map + cserve2_shm_map_offset_get(entry->shm);
|
||||
dst_data = scale_map + cserve2_shm_map_offset_get(scale_shm);
|
||||
|
||||
DBG("Scaling image ([%d,%d:%dx%d] --> [%d,%d:%dx%d])",
|
||||
entry->opts.scale_src_x, entry->opts.scale_src_y,
|
||||
entry->opts.scale_src_w, entry->opts.scale_src_h,
|
||||
0, 0,
|
||||
entry->opts.scale_dst_w, entry->opts.scale_dst_h);
|
||||
|
||||
cserve2_rgba_image_scale_do(src_data, dst_data,
|
||||
entry->opts.scale_src_x, entry->opts.scale_src_y,
|
||||
entry->opts.scale_src_w, entry->opts.scale_src_h,
|
||||
0, 0,
|
||||
entry->opts.scale_dst_w, entry->opts.scale_dst_h,
|
||||
entry->file->alpha, entry->opts.scale_smooth);
|
||||
|
||||
cserve2_shm_unmap(entry->shm);
|
||||
cserve2_shm_unmap(scale_shm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_scaling_prepare_and_do(Image_Data *orig)
|
||||
{
|
||||
Shm_Handle *scale_shm;
|
||||
|
||||
DBG("Original image's shm path %s", cserve2_shm_name_get(orig->shm));
|
||||
|
||||
scale_shm =
|
||||
cserve2_shm_request(orig->opts.scale_dst_w * orig->opts.scale_dst_h * 4);
|
||||
|
||||
DBG("Scale image's shm path %s", cserve2_shm_name_get(scale_shm));
|
||||
|
||||
if (_scaling_do(scale_shm, orig)) return -1;
|
||||
|
||||
cserve2_shm_unref(orig->shm); /* unreference old shm */
|
||||
orig->shm = scale_shm; /* update shm */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Msg_Loaded *
|
||||
_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size)
|
||||
{
|
||||
|
@ -485,6 +562,20 @@ _load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size)
|
|||
if (!e->doload)
|
||||
DBG("Entry %d loaded by speculative preload.", e->base.id);
|
||||
|
||||
if (_scaling_needed(e, resp))
|
||||
{
|
||||
DBG("About to scale down image '%s%s'", e->file->path, e->file->key);
|
||||
|
||||
if (!_scaling_prepare_and_do(e))
|
||||
DBG("Image '%s:%s' has been scaled down.",
|
||||
e->file->path, e->file->key);
|
||||
else
|
||||
ERR("Failed to scale down image '%s%s'",
|
||||
e->file->path, e->file->key);
|
||||
}
|
||||
else
|
||||
DBG("No scaling needed for image '%s%s'", e->file->path, e->file->key);
|
||||
|
||||
return _image_loaded_msg_create(e, size);
|
||||
}
|
||||
|
||||
|
@ -500,10 +591,15 @@ _img_opts_id_get(Image_Data *im, char *buf, int size)
|
|||
{
|
||||
uintptr_t image_id;
|
||||
|
||||
snprintf(buf, size, "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:%d",
|
||||
snprintf(buf, size,
|
||||
"%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:!([%d,%d:%dx%d]-[%dx%d:%d]):%d",
|
||||
im->file_id, im->opts.dpi, im->opts.w, im->opts.h,
|
||||
im->opts.scale_down, im->opts.rx, im->opts.ry,
|
||||
im->opts.rw, im->opts.rh, im->opts.orientation);
|
||||
im->opts.rw, im->opts.rh,
|
||||
im->opts.scale_src_x, im->opts.scale_src_y,
|
||||
im->opts.scale_src_w, im->opts.scale_src_h,
|
||||
im->opts.scale_dst_w, im->opts.scale_dst_h, im->opts.scale_smooth,
|
||||
im->opts.orientation);
|
||||
|
||||
image_id = (uintptr_t)eina_hash_find(image_ids, buf);
|
||||
|
||||
|
@ -972,6 +1068,14 @@ _image_msg_new(Client *client, Msg_Setopts *msg)
|
|||
im_entry->opts.ry = msg->opts.ry;
|
||||
im_entry->opts.rw = msg->opts.rw;
|
||||
im_entry->opts.rh = msg->opts.rh;
|
||||
im_entry->opts.scale_src_x = msg->opts.scale_src_x;
|
||||
im_entry->opts.scale_src_y = msg->opts.scale_src_y;
|
||||
im_entry->opts.scale_src_w = msg->opts.scale_src_w;
|
||||
im_entry->opts.scale_src_h = msg->opts.scale_src_h;
|
||||
im_entry->opts.scale_dst_w = msg->opts.scale_dst_w;
|
||||
im_entry->opts.scale_dst_h = msg->opts.scale_dst_h;
|
||||
im_entry->opts.scale_smooth = msg->opts.scale_smooth;
|
||||
im_entry->opts.scale_hint = msg->opts.scale_hint;
|
||||
im_entry->opts.orientation = msg->opts.orientation;
|
||||
|
||||
return im_entry;
|
||||
|
@ -2034,9 +2138,10 @@ cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg)
|
|||
fentry = entry->file;
|
||||
fentry->images = eina_list_append(fentry->images, entry);
|
||||
|
||||
entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD,
|
||||
0, NULL, fentry->base.request,
|
||||
&_load_funcs, entry);
|
||||
if ((!entry->opts.scale_dst_w) && (!entry->opts.scale_dst_h))
|
||||
entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD,
|
||||
0, NULL, fentry->base.request,
|
||||
&_load_funcs, entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,10 @@ parse_input_setopts(int *size)
|
|||
int w, h;
|
||||
int scale;
|
||||
int rx, ry, rw, rh;
|
||||
int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
|
||||
int scale_dst_w, scale_dst_h;
|
||||
int scale_smooth;
|
||||
int scale_hint;
|
||||
int orientation;
|
||||
|
||||
// reading file_id, image_id
|
||||
|
@ -123,11 +127,30 @@ parse_input_setopts(int *size)
|
|||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d %d %d %d", &rx, &ry, &rw, &rh);
|
||||
|
||||
// reading original image's source coord
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d %d", &scale_src_x, &scale_src_y);
|
||||
|
||||
// reading original size
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d %d", &scale_src_w, &scale_src_h);
|
||||
|
||||
// reading scale size
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d %d", &scale_dst_w, &scale_dst_h);
|
||||
|
||||
// reading scale smooth
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d", &scale_smooth);
|
||||
|
||||
// reading scale hint
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d", &scale_hint);
|
||||
|
||||
// reading orientation
|
||||
_read_line(line, sizeof(line));
|
||||
sscanf(line, "%d", &orientation);
|
||||
|
||||
|
||||
msg = calloc(1, sizeof(*msg));
|
||||
|
||||
msg->base.rid = _rid_count++;
|
||||
|
@ -142,6 +165,14 @@ parse_input_setopts(int *size)
|
|||
msg->opts.ry = ry;
|
||||
msg->opts.rw = rw;
|
||||
msg->opts.rh = rh;
|
||||
msg->opts.scale_src_x = scale_src_x;
|
||||
msg->opts.scale_src_y = scale_src_y;
|
||||
msg->opts.scale_src_w = scale_src_w;
|
||||
msg->opts.scale_src_h = scale_src_h;
|
||||
msg->opts.scale_dst_w = scale_dst_w;
|
||||
msg->opts.scale_dst_h = scale_dst_h;
|
||||
msg->opts.scale_smooth = scale_smooth;
|
||||
msg->opts.scale_hint = scale_hint;
|
||||
msg->opts.orientation = !!orientation;
|
||||
|
||||
*size = sizeof(*msg);
|
||||
|
|
|
@ -105,7 +105,14 @@ _cserve2_client_setopts(Client *client)
|
|||
INF("\tsize: %dx%d", msg->opts.w, msg->opts.h);
|
||||
INF("\tscale down: %d", msg->opts.scale_down);
|
||||
INF("\tregion: %d,%d + %dx%d",
|
||||
msg->opts.rx, msg->opts.ry, msg->opts.rw, msg->opts.rh);
|
||||
msg->opts.rx, msg->opts.ry, msg->opts.rw, msg->opts.rh);
|
||||
INF("\toriginal image's source coord: %d,%d",
|
||||
msg->opts.scale_src_x, msg->opts.scale_src_y);
|
||||
INF("\toriginal image size: %dx%d",
|
||||
msg->opts.scale_src_w, msg->opts.scale_src_h);
|
||||
INF("\tscale size: %dx%d", msg->opts.scale_dst_w, msg->opts.scale_dst_h);
|
||||
INF("\tscale smooth: %d", msg->opts.scale_smooth);
|
||||
INF("\tscale hint: %d", msg->opts.scale_hint);
|
||||
INF("\torientation: %d\n", msg->opts.orientation);
|
||||
|
||||
if (cserve2_cache_image_opts_set(client, msg) != 0)
|
||||
|
@ -336,6 +343,8 @@ main(int argc EINA_UNUSED, const char *argv[] EINA_UNUSED)
|
|||
|
||||
cserve2_requests_init();
|
||||
|
||||
cserve2_scale_init();
|
||||
|
||||
cserve2_font_init();
|
||||
|
||||
cserve2_cache_init();
|
||||
|
@ -350,6 +359,8 @@ main(int argc EINA_UNUSED, const char *argv[] EINA_UNUSED)
|
|||
|
||||
cserve2_font_shutdown();
|
||||
|
||||
cserve2_scale_shutdown();
|
||||
|
||||
cserve2_requests_shutdown();
|
||||
|
||||
cserve2_slaves_shutdown();
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
|
||||
void
|
||||
cserve2_scale_init(void)
|
||||
{
|
||||
evas_common_cpu_init();
|
||||
evas_common_blend_init();
|
||||
evas_common_image_init();
|
||||
evas_common_convert_init();
|
||||
evas_common_scale_init();
|
||||
}
|
||||
|
||||
void
|
||||
cserve2_scale_shutdown(void)
|
||||
{
|
||||
evas_common_image_shutdown();
|
||||
}
|
||||
|
||||
static inline void
|
||||
_cserve2_rgba_image_set(RGBA_Image *im, void *data, int w, int h, int alpha)
|
||||
{
|
||||
memset(im, 0, sizeof *im);
|
||||
|
||||
im->ref = 1;
|
||||
im->cache_entry.w = w;
|
||||
im->cache_entry.h = h;
|
||||
im->cache_entry.space = EVAS_COLORSPACE_ARGB8888;
|
||||
im->cache_entry.flags.alpha = alpha;
|
||||
im->image.data = data;
|
||||
im->cache_entry.allocated.w = w;
|
||||
im->cache_entry.allocated.h = h;
|
||||
}
|
||||
|
||||
void
|
||||
cserve2_rgba_image_scale_do(void *src_data, void *dst_data,
|
||||
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 alpha, int smooth)
|
||||
{
|
||||
RGBA_Image src, dst;
|
||||
RGBA_Draw_Context ct;
|
||||
|
||||
_cserve2_rgba_image_set(&src, src_data, src_w, src_h, alpha);
|
||||
|
||||
_cserve2_rgba_image_set(&dst, dst_data, dst_w, dst_h, alpha);
|
||||
dst.flags = RGBA_IMAGE_NOTHING;
|
||||
|
||||
memset(&ct, 0, sizeof(ct));
|
||||
ct.sli.h = 1;
|
||||
ct.render_op = _EVAS_RENDER_COPY;
|
||||
|
||||
if (smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth(&src, &dst, &ct,
|
||||
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(&src, &dst, &ct,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
|
@ -349,6 +349,8 @@ image_load(const char *file, const char *key, const char *shmfile, Slave_Msg_Ima
|
|||
if (!api->data_load(&ilp, file, key, &err))
|
||||
ret = err;
|
||||
|
||||
result->w = params->w;
|
||||
result->h = params->h;
|
||||
result->alpha_sparse = ilp.alpha_sparse;
|
||||
|
||||
done:
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
Var = NULL; \
|
||||
}
|
||||
|
||||
/* Size of characters used to determine a string that'll be used for load
|
||||
* options in hash keys.
|
||||
*/
|
||||
#define HKEY_LOAD_OPTS_STR_LEN 215
|
||||
|
||||
static void _evas_cache_image_dirty_add(Image_Entry *im);
|
||||
static void _evas_cache_image_dirty_del(Image_Entry *im);
|
||||
static void _evas_cache_image_activ_add(Image_Entry *im);
|
||||
|
@ -567,7 +572,39 @@ _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key,
|
|||
size += eina_convert_xtoa(lo->region.w, hkey + size);
|
||||
hkey[size] = 'x';
|
||||
size += 1;
|
||||
|
||||
size += eina_convert_xtoa(lo->region.h, hkey + size);
|
||||
hkey[size++] = '!';
|
||||
hkey[size++] = '(';
|
||||
|
||||
hkey[size] = '[';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.src_x, hkey + size);
|
||||
hkey[size] = ',';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.src_y, hkey + size);
|
||||
hkey[size] = ':';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.src_w, hkey + size);
|
||||
hkey[size] = 'x';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.src_h, hkey + size);
|
||||
hkey[size++] = ']';
|
||||
|
||||
hkey[size++] = '-';
|
||||
|
||||
hkey[size] = '[';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.dst_w, hkey + size);
|
||||
hkey[size] = 'x';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.dst_h, hkey + size);
|
||||
hkey[size] = ':';
|
||||
size += 1;
|
||||
size += eina_convert_xtoa(lo->scale_load.smooth, hkey + size);
|
||||
hkey[size++] = ']';
|
||||
|
||||
hkey[size++] = ')';
|
||||
|
||||
if (lo->orientation)
|
||||
{
|
||||
|
@ -591,7 +628,8 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RG
|
|||
int stat_done = 0, stat_failed = 0;
|
||||
struct stat st;
|
||||
Image_Timestamp tstamp;
|
||||
Evas_Image_Load_Opts prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 }, EINA_FALSE };
|
||||
Evas_Image_Load_Opts prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0 }, EINA_FALSE };
|
||||
|
||||
if ((!path) || ((!path) && (!key)))
|
||||
{
|
||||
|
@ -601,7 +639,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RG
|
|||
|
||||
pathlen = strlen(path);
|
||||
keylen = key ? strlen(key) : 6;
|
||||
size = pathlen + keylen + 132;
|
||||
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
||||
hkey = alloca(sizeof(char) * size);
|
||||
|
||||
_create_hash_key(hkey, path, pathlen, key, keylen, lo);
|
||||
|
@ -614,6 +652,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RG
|
|||
(lo->dpi == 0.0) &&
|
||||
((lo->w == 0) || (lo->h == 0)) &&
|
||||
((lo->region.w == 0) || (lo->region.h == 0)) &&
|
||||
((lo->scale_load.dst_w == 0) || (lo->scale_load.dst_h == 0)) &&
|
||||
(lo->orientation == 0)
|
||||
))
|
||||
{
|
||||
|
@ -731,6 +770,128 @@ evas_cache2_image_open_wait(Image_Entry *im)
|
|||
return EVAS_LOAD_ERROR_NONE;
|
||||
}
|
||||
|
||||
static Image_Entry *
|
||||
_scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth)
|
||||
{
|
||||
size_t pathlen, keylen, size;
|
||||
char *hkey;
|
||||
RGBA_Image_Loadopts lo;
|
||||
Image_Entry *ret;
|
||||
|
||||
if (((!im->file) || ((!im->file) && (!im->key))) || (!im->data1) ||
|
||||
((src_w == dst_w) && (src_h == dst_h)) ||
|
||||
((!im->flags.alpha) && (!smooth))) return NULL;
|
||||
|
||||
pathlen = strlen(im->file);
|
||||
keylen = im->key ? strlen(im->key) : 6;
|
||||
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
||||
hkey = alloca(sizeof(char) * size);
|
||||
|
||||
memcpy(&lo, &im->load_opts, sizeof lo);
|
||||
lo.scale_load.src_x = src_x;
|
||||
lo.scale_load.src_y = src_y;
|
||||
lo.scale_load.src_w = src_w;
|
||||
lo.scale_load.src_h = src_h;
|
||||
lo.scale_load.dst_w = dst_w;
|
||||
lo.scale_load.dst_h = dst_h;
|
||||
lo.scale_load.smooth = smooth;
|
||||
|
||||
if (!smooth)
|
||||
{
|
||||
lo.scale_load.smooth = 1;
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
|
||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||
if (ret) goto found;
|
||||
|
||||
ret = eina_hash_find(im->cache2->inactiv, hkey);
|
||||
if (ret) goto handle_inactiv;
|
||||
|
||||
lo.scale_load.smooth = smooth;
|
||||
}
|
||||
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
|
||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||
if (ret) goto found;
|
||||
|
||||
ret = eina_hash_find(im->cache2->inactiv, hkey);
|
||||
|
||||
handle_inactiv:
|
||||
if (!ret) return NULL;
|
||||
|
||||
/* Remove from lru and make it active again */
|
||||
_evas_cache_image_lru_del(ret);
|
||||
_evas_cache_image_activ_add(ret);
|
||||
|
||||
found:
|
||||
evas_cache2_image_load_data(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EAPI Image_Entry *
|
||||
evas_cache2_image_scale_load(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth)
|
||||
{
|
||||
size_t pathlen, keylen, size;
|
||||
char *hkey;
|
||||
RGBA_Image_Loadopts lo;
|
||||
int error = EVAS_LOAD_ERROR_NONE;
|
||||
Image_Entry *ret;
|
||||
|
||||
if (((!im->file) || ((!im->file) && (!im->key))) ||
|
||||
((src_w == 0) || (src_h == 0) || (dst_w == 0) || (dst_h == 0)) ||
|
||||
(im->scale_hint == EVAS_IMAGE_SCALE_HINT_DYNAMIC)) goto parent_out;
|
||||
|
||||
if (((src_w == dst_w) && (src_h == dst_h)) ||
|
||||
((!im->flags.alpha) && (!smooth))) goto parent_out;
|
||||
|
||||
ret = _scaled_image_find(im, src_x, src_y, src_w, src_h,
|
||||
dst_w, dst_h, smooth);
|
||||
if (ret) return ret;
|
||||
|
||||
pathlen = strlen(im->file);
|
||||
keylen = im->key ? strlen(im->key) : 6;
|
||||
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
||||
hkey = alloca(sizeof(char) * size);
|
||||
|
||||
memcpy(&lo, &im->load_opts, sizeof lo);
|
||||
lo.scale_load.src_x = src_x;
|
||||
lo.scale_load.src_y = src_y;
|
||||
lo.scale_load.src_w = src_w;
|
||||
lo.scale_load.src_h = src_h;
|
||||
lo.scale_load.dst_w = dst_w;
|
||||
lo.scale_load.dst_h = dst_h;
|
||||
lo.scale_load.smooth = smooth;
|
||||
lo.scale_load.scale_hint = im->scale_hint;
|
||||
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
|
||||
ret = _evas_cache_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
|
||||
&lo, &error);
|
||||
if (error != EVAS_LOAD_ERROR_NONE)
|
||||
{
|
||||
ERR("Failed to create scale image entry with error code %d.", error);
|
||||
|
||||
if (ret) _evas_cache_image_entry_delete(im->cache2, ret);
|
||||
goto parent_out;
|
||||
}
|
||||
|
||||
evas_cserve2_image_load_wait(ret);
|
||||
evas_cache2_image_load_data(ret);
|
||||
|
||||
ret->references++;
|
||||
ret->w = dst_w;
|
||||
ret->h = dst_h;
|
||||
|
||||
return ret;
|
||||
|
||||
parent_out:
|
||||
evas_cache2_image_load_data(im);
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_cache2_image_close(Image_Entry *im)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ extern "C" {
|
|||
EAPI Evas_Cache2* evas_cache2_init(const Evas_Cache2_Image_Func *cb);
|
||||
EAPI void evas_cache2_shutdown(Evas_Cache2 *cache);
|
||||
EAPI Image_Entry * evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error);
|
||||
EAPI Image_Entry *evas_cache2_image_scale_load(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth);
|
||||
EAPI int evas_cache2_image_open_wait(Image_Entry *im);
|
||||
EAPI void evas_cache2_image_close(Image_Entry *im);
|
||||
EAPI int evas_cache2_image_load_data(Image_Entry *ie);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#include "evas_common.h"
|
||||
#include "evas_private.h"
|
||||
#ifdef EVAS_CSERVE2
|
||||
#include "../cserve2/evas_cs2_private.h"
|
||||
#endif
|
||||
#include "../common/evas_convert_color.h"
|
||||
#include "../common/evas_convert_colorspace.h"
|
||||
#include "../common/evas_convert_yuv.h"
|
||||
|
@ -66,6 +69,12 @@ struct _Evas_Object_Image
|
|||
struct {
|
||||
short x, y, w, h;
|
||||
} region;
|
||||
struct {
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_w, dst_h;
|
||||
int smooth;
|
||||
int scale_hint;
|
||||
} scale_load;
|
||||
Eina_Bool orientation : 1;
|
||||
} load_opts;
|
||||
|
||||
|
@ -392,6 +401,14 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
|
|||
lo.region.y = o->load_opts.region.y;
|
||||
lo.region.w = o->load_opts.region.w;
|
||||
lo.region.h = o->load_opts.region.h;
|
||||
lo.scale_load.src_x = o->load_opts.scale_load.src_x;
|
||||
lo.scale_load.src_y = o->load_opts.scale_load.src_y;
|
||||
lo.scale_load.src_w = o->load_opts.scale_load.src_w;
|
||||
lo.scale_load.src_h = o->load_opts.scale_load.src_h;
|
||||
lo.scale_load.dst_w = o->load_opts.scale_load.dst_w;
|
||||
lo.scale_load.dst_h = o->load_opts.scale_load.dst_h;
|
||||
lo.scale_load.smooth = o->load_opts.scale_load.smooth;
|
||||
lo.scale_load.scale_hint = o->load_opts.scale_load.scale_hint;
|
||||
lo.orientation = o->load_opts.orientation;
|
||||
o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
|
||||
o->cur.file,
|
||||
|
@ -3490,17 +3507,48 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
|||
(o->cur.border.t == 0) &&
|
||||
(o->cur.border.b == 0) &&
|
||||
(o->cur.border.fill != 0))
|
||||
obj->layer->evas->engine.func->image_draw(output,
|
||||
context,
|
||||
surface,
|
||||
pixels,
|
||||
0, 0,
|
||||
imagew,
|
||||
imageh,
|
||||
obj->cur.geometry.x + ix + x,
|
||||
obj->cur.geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur.smooth_scale);
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
Image_Entry *ie;
|
||||
void *data = pixels;
|
||||
int w = imagew, h = imageh;
|
||||
|
||||
ie = evas_cache2_image_scale_load
|
||||
((Image_Entry *)pixels,
|
||||
0, 0,
|
||||
imagew, imageh,
|
||||
iw, ih, o->cur.smooth_scale);
|
||||
if (ie != &((RGBA_Image *)pixels)->cache_entry)
|
||||
{
|
||||
data = ie;
|
||||
w = iw;
|
||||
h = ih;
|
||||
}
|
||||
|
||||
obj->layer->evas->engine.func->image_draw
|
||||
(output, context, surface, data,
|
||||
0, 0,
|
||||
w, h,
|
||||
obj->cur.geometry.x + ix + x,
|
||||
obj->cur.geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur.smooth_scale);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
obj->layer->evas->engine.func->image_draw
|
||||
(output, context, surface, pixels,
|
||||
0, 0,
|
||||
imagew, imageh,
|
||||
obj->cur.geometry.x + ix + x,
|
||||
obj->cur.geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur.smooth_scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int inx, iny, inw, inh, outx, outy, outw, outh;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
static Evas_Cache_Image * eci = NULL;
|
||||
#ifdef EVAS_CSERVE2
|
||||
#define EVAS_CSERVE2_SCALE_CACHE_SIZE (4 * 1024 * 1024)
|
||||
static Evas_Cache2 * eci2 = NULL;
|
||||
#endif
|
||||
static int reference = 0;
|
||||
|
@ -743,7 +744,7 @@ evas_common_image_set_cache(unsigned int size)
|
|||
evas_cache_image_set(eci, size);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (eci2)
|
||||
evas_cache2_limit_set(eci2, size);
|
||||
evas_cache2_limit_set(eci2, size + EVAS_CSERVE2_SCALE_CACHE_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,10 @@ struct _Msg_Setopts {
|
|||
int w, h;
|
||||
int scale_down;
|
||||
int rx, ry, rw, rh;
|
||||
int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
|
||||
int scale_dst_w, scale_dst_h;
|
||||
int scale_smooth;
|
||||
int scale_hint;
|
||||
Eina_Bool orientation;
|
||||
} opts;
|
||||
};
|
||||
|
|
|
@ -561,6 +561,14 @@ _image_setopts_server_send(Image_Entry *ie)
|
|||
msg.opts.ry = ie->load_opts.region.y;
|
||||
msg.opts.rw = ie->load_opts.region.w;
|
||||
msg.opts.rh = ie->load_opts.region.h;
|
||||
msg.opts.scale_src_x = ie->load_opts.scale_load.src_x;
|
||||
msg.opts.scale_src_y = ie->load_opts.scale_load.src_y;
|
||||
msg.opts.scale_src_w = ie->load_opts.scale_load.src_w;
|
||||
msg.opts.scale_src_h = ie->load_opts.scale_load.src_h;
|
||||
msg.opts.scale_dst_w = ie->load_opts.scale_load.dst_w;
|
||||
msg.opts.scale_dst_h = ie->load_opts.scale_load.dst_h;
|
||||
msg.opts.scale_smooth = ie->load_opts.scale_load.smooth;
|
||||
msg.opts.scale_hint = ie->load_opts.scale_load.scale_hint;
|
||||
msg.opts.orientation = ie->load_opts.orientation;
|
||||
|
||||
if (!_server_send(&msg, sizeof(msg), 0, NULL))
|
||||
|
|
|
@ -500,6 +500,12 @@ struct _RGBA_Image_Loadopts
|
|||
struct {
|
||||
unsigned int x, y, w, h;
|
||||
} region;
|
||||
struct {
|
||||
int src_x, src_y, src_w, src_h;
|
||||
int dst_w, dst_h;
|
||||
int smooth;
|
||||
Evas_Image_Scale_Hint scale_hint;
|
||||
} scale_load;
|
||||
|
||||
Eina_Bool orientation; // if EINA_TRUE => should honor orientation information provided by file (like jpeg exif info)
|
||||
};
|
||||
|
|
|
@ -923,22 +923,38 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
|
|||
|
||||
image_loaded:
|
||||
#endif
|
||||
evas_common_rgba_image_scalecache_prepare(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
evas_common_rgba_image_scalecache_do(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
/*
|
||||
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 EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
evas_cache2_image_load_data(&im->cache_entry);
|
||||
|
||||
evas_common_image_colorspace_normalize(im);
|
||||
|
||||
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
|
||||
#endif
|
||||
{
|
||||
evas_common_rgba_image_scalecache_prepare
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
evas_common_rgba_image_scalecache_do
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue