From: raster Date: Thu, 7 May 2009 13:29:56 +0000 (+0000) Subject: 1. scale cache now allows you to hint at the object if its dynamic, static or X-Git-Tag: accepted/2.0/20130306.225542~242^2~2450 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c1e88b1e1c076173eae3e9f43714d3d74ba57c63;p=profile%2Fivi%2Fevas.git 1. scale cache now allows you to hint at the object if its dynamic, static or none (ie default) and the engines actually understand it and use it. 2. fixes to scalecache and cserver too. more toto's done and its now been stress tested by me - and i think cserve is ready to go gold. just enable it with export EVAS_CSERVE=1 in your env for any eflapps - and run evas_cserve (cmd-line options avalable plus cmd-line tol to query settings change on the fly and query statsitics and state) git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@40536 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/bin/evas_cserve_main.c b/src/bin/evas_cserve_main.c index 6b9caf4..09574aa 100644 --- a/src/bin/evas_cserve_main.c +++ b/src/bin/evas_cserve_main.c @@ -9,7 +9,6 @@ // fixme:'s // -// add ops to get internal cache state (both) // preload - make it work (both) // @@ -60,6 +59,8 @@ static int stat_res_interval = 2; static time_t t_now = 0; +static int server_id = 0; + static Evas_Cache_Image *cache = NULL; static Eina_Hash *active_images = NULL; @@ -74,6 +75,8 @@ static Mem *stat_mem = NULL; static int stat_mem_num = 0; static Eina_List *stat_mems = NULL; +static void cache_clean(void); + #ifndef _WIN32 static double get_time(void) @@ -435,6 +438,7 @@ img_new(const char *file, const char *key, RGBA_Image_Loadopts *load_opts, const img->stats.load1 = t; img->key = eina_stringshare_add(bufkey); img->file.modtime = st.st_mtime; + img->file.last_stat = t_now; img->file.file = eina_stringshare_add(file); if (key) img->file.key = eina_stringshare_add(key); img->load_opts.scale_down_by = load_opts->scale_down_by; @@ -447,9 +451,9 @@ img_new(const char *file, const char *key, RGBA_Image_Loadopts *load_opts, const img->ref = 1; img->active = 1; - img->usage = sizeof(Img) + strlen(img->key) + 1 + strlen(img->file.file) + 1; + img->usage = sizeof(Img) + strlen(img->key) + 1 + + strlen(img->file.file) + 1; if (img->file.key) img->usage += strlen(img->file.key) + 1; - // fixme: load img, get header eina_hash_direct_add(active_images, img->key, img); return img; } @@ -459,15 +463,19 @@ img_loaddata(Img *img) { double t; + if (img->mem) return; t = get_time(); evas_cache_image_load_data((Image_Entry *)img); t = get_time() - t; img->stats.load2 = t; if (img->image.data) msync(img->image.data, img->image.w * img->image.h * sizeof(DATA32), MS_SYNC | MS_INVALIDATE); + if (!img->active) cache_usage -= img->usage; img->usage += (4096 * (((img->image.w * img->image.h * sizeof(DATA32)) + 4095) / 4096)) + sizeof(Mem); + if (!img->active) cache_usage += img->usage; + cache_clean(); } static void @@ -484,7 +492,8 @@ img_free(Img *img) static void cache_clean(void) { - while ((cache_usage > ((cache_max_usage + cache_max_adjust) * 1024)) && (cache_images)) + while ((cache_usage > ((cache_max_usage + cache_max_adjust) * 1024)) && + (cache_images)) { Img *img; Eina_List *l; @@ -522,12 +531,20 @@ mem_cache_adjust(void) { int pval = cache_max_adjust; int max = 0; + int mem_used; if (mem_total <= 0) return; - if ((mem_free + mem_cached + mem_buffers) < mem_total) - cache_max_adjust += mem_total - (mem_free + mem_cached + mem_buffers); + mem_used = mem_total - mem_free - mem_cached - mem_buffers; +#if 0 // this lets the image cache to grow to fill all real free ram, if + // there is any (ie ram unused by disk cache) + if (mem_free < mem_total) + { + cache_max_adjust = mem_free; + return; + } +#endif - max = (mem_free / 8) - cache_max_usage; + max = ((mem_free + mem_cached + mem_buffers) / 8) - cache_max_usage; if (max < 0) max = 0; if (max > cache_max_usage) max = cache_max_usage; cache_max_adjust = max - cache_max_usage; @@ -541,15 +558,15 @@ static void img_cache(Img *img) { eina_hash_del(active_images, img->key, img); - img->active = 0; if (img->dead) { img_free(img); return; } cache_images = eina_list_prepend(cache_images, img); - img->cached = t_now; cache_usage += img->usage; + img->active = 0; + img->cached = t_now; if (cache_usage > ((cache_max_usage + cache_max_adjust) * 1024)) cache_clean(); } @@ -559,6 +576,7 @@ img_dead(Img *img) { if (img->active) return; cache_images = eina_list_remove(cache_images, img); + cache_usage -= img->usage; img_free(img); } @@ -573,6 +591,7 @@ img_ok(Img *img) ((t_now - img->file.last_stat) < stat_res_interval)) return 1; img->file.last_stat = t_now; ret = stat(img->file.file, &st); + img->file.last_stat = t_now; if (ret < 0) { img->dead = 1; @@ -624,9 +643,11 @@ img_load(const char *file, const char *key, RGBA_Image_Loadopts *load_opts) { if (img_ok(img)) { + cache_images = eina_list_remove_list(cache_images, l); + cache_usage -= img->usage; + img->active = 1; img->stats.load1saved++; img->ref++; - cache_images = eina_list_remove_list(cache_images, l); eina_hash_direct_add(active_images, img->key, img); stats_update(); return img; @@ -649,11 +670,17 @@ img_unload(Img *img) static void img_unloaddata(Img *img) { - if ((img->dref <= 0) && (img->useless)) + if ((img->dref <= 0) && (img->useless) && (img->mem)) { Image_Entry *ie = (Image_Entry *)img; + if (!img->active) cache_usage -= img->usage; + img->usage -= + (4096 * (((img->image.w * img->image.h * sizeof(DATA32)) + 4095) / 4096)) + + sizeof(Mem); + if (!img->active) cache_usage += img->usage; evas_cserve_mem_free(img->mem); + stat_mems = eina_list_remove(stat_mems, img->mem); img->mem = NULL; img->image.data = NULL; img->dref = 0; @@ -693,10 +720,23 @@ client_del(void *data, Client *c) images = data; EINA_LIST_FREE(images, img) { + img_unloaddata(img); img_unload(img); } } +static Eina_Bool +getinfo_hash_image_cb(const Eina_Hash *hash __UNUSED__, + const void *key __UNUSED__, + void *data, void *fdata __UNUSED__) +{ + Img *img = data; + Eina_List **list = fdata; + + *list = eina_list_append(*list, img); + return 1; +} + static int message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *data) { @@ -710,6 +750,7 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * memset(&msg, 0, sizeof(msg)); msg.pid = getpid(); + msg.server_id = server_id; rep = (Op_Init *)data; c->pid = rep->pid; c->func = client_del; @@ -770,8 +811,11 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Unload *)data; img = rep->handle; - c->data = eina_list_remove(c->data, img); - img_unload(img); + if ((img) && (rep->server_id == server_id)) + { + c->data = eina_list_remove(c->data, img); + img_unload(img); + } } break; case OP_LOADDATA: @@ -782,19 +826,26 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Loaddata *)data; img = rep->handle; - if (img->mem) - { - img->stats.load2saved++; - stats_update(); - } - else - img_loaddata(img); - memset(&msg, 0, sizeof(msg)); - if (img->mem) + if ((img) && (rep->server_id == server_id)) { - msg.mem.id = img->mem->id; - msg.mem.offset = img->mem->offset; - msg.mem.size = img->mem->size; + if (img->mem) + { + img->stats.load2saved++; + stats_update(); + } + else + { + img_loaddata(img); + } + memset(&msg, 0, sizeof(msg)); + if (img->mem) + { + msg.mem.id = img->mem->id; + msg.mem.offset = img->mem->offset; + msg.mem.size = img->mem->size; + } + else + msg.mem.id = msg.mem.offset = msg.mem.size = 0; } else msg.mem.id = msg.mem.offset = msg.mem.size = 0; @@ -808,8 +859,11 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Unloaddata *)data; img = rep->handle; - img->dref--; - img_unloaddata(img); + if ((img) && (rep->server_id == server_id)) + { + img->dref--; + img_unloaddata(img); + } } break; case OP_USELESSDATA: @@ -819,8 +873,11 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Unloaddata *)data; img = rep->handle; - img->dref--; - img_useless(img); + if ((img) && (rep->server_id == server_id)) + { + img->dref--; + img_useless(img); + } } break; case OP_PRELOAD: @@ -830,9 +887,11 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Preload *)data; img = rep->handle; - c->data = eina_list_remove(c->data, img); - printf("preload %p\n", img); - img_preload(img); + if ((img) && (rep->server_id == server_id)) + { + c->data = eina_list_remove(c->data, img); + img_preload(img); + } } case OP_FORCEDUNLOAD: { @@ -841,8 +900,11 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * rep = (Op_Forcedunload *)data; img = rep->handle; - c->data = eina_list_remove(c->data, img); - img_forcedunload(img); + if ((img) && (rep->server_id == server_id)) + { + c->data = eina_list_remove(c->data, img); + img_forcedunload(img); + } } break; case OP_GETCONFIG: @@ -863,6 +925,7 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * cache_max_usage = rep->cache_max_usage; cache_item_timeout = rep->cache_item_timeout; cache_item_timeout_check = rep->cache_item_timeout_check; + cache_timeout(t_now); cache_clean(); } break; @@ -882,18 +945,104 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char * break; case OP_GETINFO: { -// get a list of all images in active hash and cache list, and their info like -// file + key -// width, height and alpha flag -// refcount -// data loaded flag -// active ot cached -// last active timestamp -// dead -// mod time -// last checked mod time time -// memory footprint -// Op_Getstats_Reply msg; + Op_Getinfo_Reply *msg; + int len; + Eina_List *imgs = NULL, *l; + Img *img; + + len = sizeof(Op_Getinfo_Reply); + if (active_images) + eina_hash_foreach(active_images, getinfo_hash_image_cb, &imgs); + EINA_LIST_FOREACH(cache_images, l, img) + { + imgs = eina_list_append(imgs, img); + } + EINA_LIST_FOREACH(imgs, l, img) + { + len += sizeof(Op_Getinfo_Item); + if (img->file.file) len += strlen(img->file.file); + len++; + if (img->file.key) len += strlen(img->file.key); + len++; + } + msg = malloc(len); + if (msg) + { + unsigned char *p; + + memset(msg, 0, len); + p = (unsigned char *)msg; + msg->active.mem_total = 0; + msg->active.count = 0; + msg->cached.mem_total = 0; + msg->cached.count = 0; + p += sizeof(Op_Getinfo_Reply); + EINA_LIST_FOREACH(imgs, l, img) + { + Op_Getinfo_Item *itt, it; + + memset(&it, 0, sizeof(Op_Getinfo_Item)); + itt = (Op_Getinfo_Item *)p; + it.file_key_size = 0; + if (img->file.file) + { + strcpy(p + sizeof(Op_Getinfo_Item) + it.file_key_size, img->file.file); + it.file_key_size += strlen(img->file.file); + } + p[sizeof(Op_Getinfo_Item) + it.file_key_size] = 0; + it.file_key_size += 1; + if (img->file.key) + { + strcpy(p + sizeof(Op_Getinfo_Item) + it.file_key_size, img->file.key); + it.file_key_size += strlen(img->file.key); + } + p[sizeof(Op_Getinfo_Item) + it.file_key_size] = 0; + it.file_key_size += 1; + + it.w = img->image.w; + it.h = img->image.h; + it.file_mod_time = img->file.modtime; + it.file_checked_time = img->file.last_stat; + if (!img->active) + it.cached_time = img->cached; + else + it.cached_time = 0; + it.refcount = img->ref; + it.data_refcount = img->dref; + it.memory_footprint = img->usage; + it.head_load_time = img->stats.load1; + it.data_load_time = img->stats.load2; + it.alpha = img->image.alpha; + if (img->image.data) + it.data_loaded = 1; + else + it.data_loaded = 0; + it.active = img->active; + if (it.active) + { + msg->active.count++; + msg->active.mem_total += img->usage; + } + else + { + msg->cached.count++; + msg->cached.mem_total += img->usage; + } + it.dead = img->dead; + it.useless = img->useless; + memcpy(itt, &it, sizeof(Op_Getinfo_Item)); + p += sizeof(Op_Getinfo_Item) + it.file_key_size; + } + msg->active.mem_total = + (msg->active.mem_total + 1023) / 1024; + msg->cached.mem_total = + (msg->cached.mem_total + 1023) / 1024; + evas_cserve_client_send(c, OP_GETINFO, len, msg); + free(msg); + } + else + evas_cserve_client_send(c, OP_GETINFO, 0, NULL); + if (imgs) eina_list_free(imgs); } break; default: @@ -1003,7 +1152,14 @@ main(int argc, char **argv) { Server *s; time_t last_check, t, t_next; - + pid_t pid; + + t = time(NULL); + pid = getpid(); + t ^= (pid << 24) | (pid << 16) | (pid << 8) | (pid); + srand(t); + server_id = rand(); + parse_args(argc, argv); eina_init(); @@ -1052,7 +1208,8 @@ main(int argc, char **argv) if (exit_flag) break; t = time(NULL); t_next = t - last_check; - if ((t_next) >= cache_item_timeout_check) + if ((cache_item_timeout_check > 0) && + ((t_next) >= cache_item_timeout_check)) { t_next = cache_item_timeout_check; @@ -1076,7 +1233,7 @@ main(int argc, char **argv) evas_cserve_mem_free(stat_mem); stat_mem = NULL; } - + if (s) evas_cserve_server_del(s); evas_shutdown(); eina_shutdown(); return 0; diff --git a/src/bin/evas_cserve_tool.c b/src/bin/evas_cserve_tool.c index ffeb3f9..e2d532b 100644 --- a/src/bin/evas_cserve_tool.c +++ b/src/bin/evas_cserve_tool.c @@ -23,6 +23,7 @@ main(int argc, char **argv) "\tgetconfig Get configuration values\n" "\tsetconfig CSIZE CTIME CTIMECHECK Set the config values\n" "\tgetstats Get current cache statistics\n" + "\tgetinfo Get current cache content info\n" ); exit(0); } @@ -35,6 +36,7 @@ main(int argc, char **argv) printf("ERROR: cannot fetch config.\n"); exit(-1); } + printf("-REPLY-\n"); printf("csize: %i\n", config.cache_max_usage); printf("ctime: %i\n", config.cache_item_timeout); printf("ctimecheck: %i\n", config.cache_item_timeout_check); @@ -65,6 +67,7 @@ main(int argc, char **argv) printf("ERROR: cannot fetch stats.\n"); exit(-1); } + printf("-REPLY-\n"); printf("saved_memory: %i Kb\n", stats.saved_memory / 1024); printf("wasted_memory: %i Kb\n", stats.wasted_memory / 1024); printf("saved_memory_peak: %i Kb\n", stats.saved_memory_peak / 1024); @@ -73,28 +76,80 @@ main(int argc, char **argv) printf("saved_time_image_data_load: %1.3f sec\n", stats.saved_time_image_data_load); printf("-OK-\n"); } - } -/* - { - Image_Entry *ie; - RGBA_Image_Loadopts lopt = { 0, 0.0, 0, 0}; - - ie = malloc(sizeof(Image_Entry)); - if (evas_cserve_image_load(ie, argv[1], NULL, &lopt)) + else if ((!strcmp(argv[i], "getinfo"))) { - printf("load ok\n"); - if (evas_cserve_image_data_load(ie)) + Op_Getinfo_Reply *info; + Op_Getinfo_Item *itt; + unsigned char *p; + int i, j; + + info = evas_cserve_info_get(); + if (!info) { - Mem *m; + printf("ERROR: cannot fetch info.\n"); + exit(-1); + } + j = info->active.count + info->cached.count; + printf("-REPLY-\n"); + printf("active_count: %i\n", info->active.count); + printf("active_memory: %i Kb\n", info->active.mem_total); + printf("cache_count: %i\n", info->cached.count); + printf("cache_memory: %i Kb\n", info->cached.mem_total); + p = (unsigned char *)info; + p += sizeof(Op_Getinfo_Reply); + for (i = 0; i < j; i++) + { + Op_Getinfo_Item it; + char *file, *key, buf[512]; + struct tm *ltm; - m = ie->data2; - printf("first pixel: %08x\n", *((int *)m->data)); - printf("load data ok\n"); -// evas_cserve_image_free(ie); + itt = (Op_Getinfo_Item *)p; + memcpy(&it, itt, sizeof(Op_Getinfo_Item)); + file = p + sizeof(Op_Getinfo_Item); + key = file + strlen(file) + 1; + printf("-IMAGE- [#%i]\n", i); + printf(" file : %s\n", file); + printf(" key : %s\n", key); + printf(" size : %i x %i\n", it.w, it.h); + printf(" active : %i\n", (int)it.active); + printf(" memory used: %i bytes (%i Kb)\n", it.memory_footprint, (it.memory_footprint + 1023) / 1024); + printf(" has alpha : %i\n", (int)it.alpha); + printf(" data loaded: %i\n", (int)it.data_loaded); + printf(" dead : %i\n", (int)it.dead); + printf(" useless : %i\n", (int)it.useless); + printf(" image refs : %i\n", it.refcount); + printf(" data refs : %i\n", it.data_refcount); + printf(" header load: %1.5f sec\n", it.head_load_time); + printf(" data load : %1.5f sec\n", it.data_load_time); + if (it.cached_time == 0) + printf(" cached at : N/A\n"); + else + { + ltm = localtime(&(it.cached_time)); + if (ltm) + { + strftime(buf, sizeof(buf), "%Y.%m.%d %T", ltm); + printf(" cached at : %s\n", buf); + } + } + ltm = localtime(&(it.file_mod_time)); + if (ltm) + { + strftime(buf, sizeof(buf), "%Y.%m.%d %T", ltm); + printf(" file mod at: %s\n", buf); + } + ltm = localtime(&(it.file_checked_time)); + if (ltm) + { + strftime(buf, sizeof(buf), "%Y.%m.%d %T", ltm); + printf(" file check : %s\n", buf); + } + p += sizeof(Op_Getinfo_Item) + it.file_key_size; } + free(info); + printf("-OK-\n"); } } - */ evas_cserve_shutdown(); evas_shutdown(); return 0; diff --git a/src/lib/Evas.h b/src/lib/Evas.h index 8363dba..4ae247b 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -296,6 +296,13 @@ typedef enum _Evas_Border_Fill_Mode EVAS_BORDER_FILL_SOLID = 2 } Evas_Border_Fill_Mode; +typedef enum _Evas_Image_Scale_Hint +{ + EVAS_IMAGE_SCALE_HINT_NONE = 0, + EVAS_IMAGE_SCALE_HINT_DYNAMIC = 1, + EVAS_IMAGE_SCALE_HINT_STATIC = 2 +} Evas_Image_Scale_Hint; + struct _Evas_Engine_Info /** Generic engine information. Generic info is useless */ { int magic; /**< Magic number */ @@ -599,6 +606,8 @@ extern "C" { EAPI Evas_Colorspace evas_object_image_colorspace_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; EAPI void evas_object_image_native_surface_set (Evas_Object *obj, Evas_Native_Surface *surf) EINA_ARG_NONNULL(1, 2); EAPI Evas_Native_Surface *evas_object_image_native_surface_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; + EAPI void evas_object_image_scale_hint_set (Evas_Object *obj, Evas_Image_Scale_Hint hint) EINA_ARG_NONNULL(1); + EAPI Evas_Image_Scale_Hint evas_object_image_scale_hint_get (const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; /* image cache */ EAPI void evas_image_cache_flush (Evas *e) EINA_ARG_NONNULL(1); diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c index 214d388..e7a1923 100644 --- a/src/lib/canvas/evas_object_image.c +++ b/src/lib/canvas/evas_object_image.c @@ -53,6 +53,8 @@ struct _Evas_Object_Image void *get_pixels_data; } func; + Evas_Image_Scale_Hint scale_hint; + void *engine_data; unsigned char changed : 1; @@ -1809,6 +1811,42 @@ evas_object_image_native_surface_get(const Evas_Object *obj) * */ EAPI void +evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint) +{ + Evas_Object_Image *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Image *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); + return; + MAGIC_CHECK_END(); + o->scale_hint = hint; +} + +EAPI Evas_Image_Scale_Hint +evas_object_image_scale_hint_get(const Evas_Object *obj) +{ + Evas_Object_Image *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return EVAS_IMAGE_SCALE_HINT_NONE; + MAGIC_CHECK_END(); + o = (Evas_Object_Image *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); + return EVAS_IMAGE_SCALE_HINT_NONE; + MAGIC_CHECK_END(); + return o->scale_hint; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + * + */ +EAPI void evas_image_cache_flush(Evas *e) { MAGIC_CHECK(e, Evas, MAGIC_EVAS); @@ -2137,6 +2175,9 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su } o->dirty_pixels = 0; } + obj->layer->evas->engine.func->image_scale_hint_set(output, + o->engine_data, + o->scale_hint); o->engine_data = obj->layer->evas->engine.func->image_border_set(output, o->engine_data, o->cur.border.l, o->cur.border.r, o->cur.border.t, o->cur.border.b); diff --git a/src/lib/cserve/evas_cs.h b/src/lib/cserve/evas_cs.h index ea7fb87..5557c2d 100644 --- a/src/lib/cserve/evas_cs.h +++ b/src/lib/cserve/evas_cs.h @@ -63,6 +63,7 @@ struct _Server int (*func) (void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *data); void *data; pid_t pid; + int server_id; }; struct _Client @@ -116,6 +117,7 @@ enum typedef struct { pid_t pid; + int server_id; } Op_Init; typedef struct { @@ -128,6 +130,7 @@ typedef struct typedef struct { void *handle; + int server_id; struct { int id; int offset; @@ -141,14 +144,17 @@ typedef struct typedef struct { void *handle; + int server_id; } Op_Unload; typedef struct { void *handle; + int server_id; } Op_Unloaddata; typedef struct { void *handle; + int server_id; } Op_Loaddata; typedef struct { @@ -161,6 +167,7 @@ typedef struct typedef struct { void *handle; + int server_id; } Op_Preload; typedef struct { @@ -174,6 +181,7 @@ typedef struct typedef struct { void *handle; + int server_id; } Op_Forcedunload; typedef struct { @@ -196,6 +204,31 @@ typedef struct double saved_time_image_header_load; double saved_time_image_data_load; } Op_Getstats_Reply; +typedef struct +{ + struct { + int mem_total; + int count; + } active, cached; +} Op_Getinfo_Reply; // + N active Info Items + N cached items +typedef struct +{ + int file_key_size; + int w, h; + time_t file_mod_time; + time_t file_checked_time; + time_t cached_time; + int refcount; + int data_refcount; + int memory_footprint; + double head_load_time; + double data_load_time; + Eina_Bool alpha : 1; + Eina_Bool data_loaded : 1; + Eina_Bool active : 1; + Eina_Bool dead : 1; + Eina_Bool useless : 1; +} Op_Getinfo_Item; // + "file""key" // for clients to connect to cserve @@ -210,6 +243,7 @@ EAPI void evas_cserve_image_free(Image_Entry *ie); EAPI Eina_Bool evas_cserve_config_get(Op_Getconfig_Reply *config); EAPI Eina_Bool evas_cserve_config_set(Op_Setconfig *config); EAPI Eina_Bool evas_cserve_stats_get(Op_Getstats_Reply *stats); +EAPI Op_Getinfo_Reply *evas_cserve_info_get(void); // for the server EAPI Server *evas_cserve_server_add(void); diff --git a/src/lib/cserve/evas_cs_client.c b/src/lib/cserve/evas_cs_client.c index d04631d..c2db24d 100644 --- a/src/lib/cserve/evas_cs_client.c +++ b/src/lib/cserve/evas_cs_client.c @@ -3,6 +3,9 @@ #ifdef EVAS_CSERVE +static Server *cserve = NULL; +static int csrve_init = 0; + static void pipe_handler(int x, siginfo_t *info, void *data) { @@ -85,12 +88,16 @@ server_send(Server *s, int opcode, int size, unsigned char *data) if (num < 0) { pipe_handle(0); + if (cserve) server_disconnect(cserve); + cserve = NULL; return 0; } num = write(s->fd, data, size); if (num < 0) { pipe_handle(0); + if (cserve) server_disconnect(cserve); + cserve = NULL; return 0; } pipe_handle(0); @@ -100,22 +107,38 @@ server_send(Server *s, int opcode, int size, unsigned char *data) static unsigned char * server_read(Server *s, int *opcode, int *size) { - int ints[2], num; + int ints[2], num, left; unsigned char *data; num = read(s->fd, ints, sizeof(int) * 2); - if (num != (sizeof(int) * 2)) return NULL; + if (num != (sizeof(int) * 2)) + { + if (cserve) server_disconnect(cserve); + cserve = NULL; + return NULL; + } *size = ints[0]; *opcode = ints[1]; if ((*size < 0) || (*size > (1024 * 1024))) return NULL; data = malloc(*size); if (!data) return NULL; num = read(s->fd, data, *size); - if (num != *size) + if (num < 0) { free(data); return NULL; } + left = *size - num; + while (left > 0) + { + num = read(s->fd, data + (*size - left), left); + if (num < 0) + { + free(data); + return NULL; + } + left -= num; + } return data; } @@ -127,20 +150,21 @@ server_init(Server *s) int size; msg.pid = getpid(); + msg.server_id = 0; if (!server_send(s, OP_INIT, sizeof(msg), (unsigned char *)(&msg))) return 0; rep = (Op_Init *)server_read(s, &opcode, &size); - if (rep) + if ((rep) && (opcode == OP_INIT) && (size == sizeof(Op_Init))) { s->pid = rep->pid; + s->server_id = rep->server_id; free(rep); + return 1; } - return 1; + if (rep) free(rep); + return 0; } -static Server *cserve = NULL; -static int csrve_init = 0; - EAPI Eina_Bool evas_cserve_init(void) { @@ -150,7 +174,7 @@ evas_cserve_init(void) if (!cserve) return 0; if (!server_init(cserve)) { - server_disconnect(cserve); + if (cserve) server_disconnect(cserve); cserve = NULL; return 0; } @@ -182,7 +206,7 @@ server_reinit(void) { if (!server_init(cserve)) { - server_disconnect(cserve); + if (cserve) server_disconnect(cserve); cserve = NULL; } } @@ -241,7 +265,10 @@ evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_ ie->flags.alpha = rep->image.alpha; ie->data1 = rep->handle; } + if (rep) free(rep); if (ie->data1 == NULL) return 0; + if (cserve) + ie->server_id = cserve->server_id; return 1; } @@ -256,18 +283,31 @@ evas_cserve_image_data_load(Image_Entry *ie) else return 0; if (!cserve) return 0; if (ie->data1 == NULL) return 0; + if (cserve->server_id != ie->server_id) + { + ie->data1 = NULL; + if (!evas_cserve_image_load(ie, ie->file, ie->key, &(ie->load_opts))) + return 0; + } memset(&msg, 0, sizeof(msg)); msg.handle = ie->data1; + msg.server_id = cserve->server_id; if (!server_send(cserve, OP_LOADDATA, sizeof(msg), (unsigned char *)(&msg))) return 0; if (!cserve) return 0; rep = (Op_Loaddata_Reply *)server_read(cserve, &opcode, &size); if ((rep) && (opcode == OP_LOADDATA) && (size == sizeof(Op_Loaddata_Reply))) { - if (rep->mem.size <= 0) return 0; + if (rep->mem.size <= 0) + { + free(rep); + return 0; + } ie->data2 = evas_cserve_mem_open(cserve->pid, rep->mem.id, NULL, rep->mem.size, 0); + free(rep); return 1; } + if (rep) free(rep); return 0; } @@ -282,8 +322,13 @@ evas_cserve_image_free(Image_Entry *ie) if (ie->data1 == NULL) return; memset(&msg, 0, sizeof(msg)); msg.handle = ie->data1; + msg.server_id = cserve->server_id; if (ie->data2) evas_cserve_image_unload(ie); - server_send(cserve, OP_UNLOAD, sizeof(msg), (unsigned char *)(&msg)); + if (cserve) + { + if (ie->server_id == cserve->server_id) + server_send(cserve, OP_UNLOAD, sizeof(msg), (unsigned char *)(&msg)); + } ie->data1 = NULL; } @@ -298,9 +343,11 @@ evas_cserve_image_unload(Image_Entry *ie) if (ie->data1 == NULL) return; memset(&msg, 0, sizeof(msg)); msg.handle = ie->data1; + msg.server_id = cserve->server_id; if (ie->data2) evas_cserve_mem_close(ie->data2); ie->data2 = NULL; - server_send(cserve, OP_UNLOADDATA, sizeof(msg), (unsigned char *)(&msg)); + if (ie->server_id == cserve->server_id) + server_send(cserve, OP_UNLOADDATA, sizeof(msg), (unsigned char *)(&msg)); } EAPI void @@ -314,9 +361,11 @@ evas_cserve_image_useless(Image_Entry *ie) if (ie->data1 == NULL) return; memset(&msg, 0, sizeof(msg)); msg.handle = ie->data1; + msg.server_id = cserve->server_id; if (ie->data2) evas_cserve_mem_close(ie->data2); ie->data2 = NULL; - server_send(cserve, OP_USELESSDATA, sizeof(msg), (unsigned char *)(&msg)); + if (ie->server_id == cserve->server_id) + server_send(cserve, OP_USELESSDATA, sizeof(msg), (unsigned char *)(&msg)); } EAPI Eina_Bool @@ -333,8 +382,10 @@ evas_cserve_config_get(Op_Getconfig_Reply *config) if ((rep) && (opcode == OP_GETCONFIG) && (size == sizeof(Op_Getconfig_Reply))) { memcpy(config, rep, sizeof(Op_Getconfig_Reply)); + free(rep); return 1; } + if (rep) free(rep); return 0; } @@ -362,9 +413,30 @@ evas_cserve_stats_get(Op_Getstats_Reply *stats) if ((rep) && (opcode == OP_GETSTATS) && (size == sizeof(Op_Getstats_Reply))) { memcpy(stats, rep, sizeof(Op_Getstats_Reply)); + free(rep); return 1; } + if (rep) free(rep); return 0; } +EAPI Op_Getinfo_Reply * +evas_cserve_info_get(void) +{ + Op_Getinfo_Reply *rep; + int opcode; + int size; + if (csrve_init > 0) server_reinit(); + else return NULL; + if (!cserve) return NULL; + if (!server_send(cserve, OP_GETINFO, 0, NULL)) return NULL; + rep = (Op_Getinfo_Reply *)server_read(cserve, &opcode, &size); + if ((rep) && (opcode == OP_GETINFO) && (size >= sizeof(Op_Getinfo_Reply))) + { + return rep; + } + if (rep) free(rep); + return NULL; +} + #endif diff --git a/src/lib/cserve/evas_cs_server.c b/src/lib/cserve/evas_cs_server.c index 14e53cc..8f4e7b8 100644 --- a/src/lib/cserve/evas_cs_server.c +++ b/src/lib/cserve/evas_cs_server.c @@ -60,7 +60,15 @@ evas_cserve_server_add(void) EAPI void evas_cserve_server_del(Server *s) { - /* FIXME: del clients! */ + Client *c; + + EINA_LIST_FREE(s->clients, c) + { + close(c->fd); + if (c->buf) free(c->buf); + if (c->inbuf) free(c->inbuf); + free(c); + } close(s->fd); unlink(s->socket_path); free(s->socket_path); @@ -102,7 +110,7 @@ client_flush(Client *c) c->dead = 1; return; } - if (num != c->bufsize) + if (num < c->bufsize) { unsigned char *buf; @@ -130,11 +138,11 @@ client_buf_add(Client *c, unsigned char *data, int size) { int newsize; unsigned char *buf; - - newsize = c->bufalloc + size; + + newsize = c->bufsize + size; if (newsize > c->bufalloc) { - c->bufalloc + newsize + 1024; + c->bufalloc = newsize + 16384; buf = realloc(c->buf, c->bufalloc); if (buf) c->buf = buf; else return; @@ -148,9 +156,16 @@ client_write(Client *c, unsigned char *data, int size) { int num; - num = write(c->fd, data, size); - if (num != size) - client_buf_add(c, data + num, size - num); + if (!c->buf) + { + num = write(c->fd, data, size); + if (num != size) + client_buf_add(c, data + num, size - num); + } + else + { + client_buf_add(c, data, size); + } } EAPI void diff --git a/src/lib/engines/common/evas_image_scalecache.c b/src/lib/engines/common/evas_image_scalecache.c index 76cf5ff..e001dac 100644 --- a/src/lib/engines/common/evas_image_scalecache.c +++ b/src/lib/engines/common/evas_image_scalecache.c @@ -250,7 +250,7 @@ _cache_prune(Scaleitem *notsci, Evas_Bool copies_only) if (copies_only) { while ((sci) && (!sci->parent_im->image.data)) - sci = ((Eina_Inlist *)sci)->next; + sci = (Scaleitem *)(((Eina_Inlist *)sci)->next); if (!sci) return; } if (sci == notsci) return; @@ -352,6 +352,7 @@ evas_common_rgba_image_scalecache_prepare(Image_Entry *ie, RGBA_Image *dst, // dst_region_x, dst_region_y, dst_region_w, dst_region_h, // smooth); if ((sci->usage >= MIN_SCALE_USES) + && (ie->scale_hint != EVAS_IMAGE_SCALE_HINT_DYNAMIC) // && (sci->usage_count > (use_counter - MIN_SCALE_AGE_GAP)) ) { @@ -475,8 +476,10 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst, int size, osize, used; size = dst_region_w * dst_region_h; - if (((dst_region_w > 640) || (dst_region_h > 640)) && - (size > (480 * 480))) + 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)) { Eina_List *l; Scaleitem *sci2; diff --git a/src/lib/include/evas_common.h b/src/lib/include/evas_common.h index e63623b..20d5ad9 100644 --- a/src/lib/include/evas_common.h +++ b/src/lib/include/evas_common.h @@ -471,7 +471,9 @@ struct _Image_Entry #endif Image_Entry_Flags flags; + Evas_Image_Scale_Hint scale_hint; void *data1, *data2; + int server_id; }; struct _Engine_Image_Entry diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index f263eab..7304966 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -682,6 +682,8 @@ struct _Evas_Func /* void (*image_rotation_set) (void *data, void *image); */ + void (*image_scale_hint_set) (void *data, void *image, int hint); + int (*image_scale_hint_get) (void *data, void *image); }; struct _Evas_Image_Load_Func diff --git a/src/modules/engines/cairo_x11/evas_engine.c b/src/modules/engines/cairo_x11/evas_engine.c index 55073b0..57c3b9f 100644 --- a/src/modules/engines/cairo_x11/evas_engine.c +++ b/src/modules/engines/cairo_x11/evas_engine.c @@ -95,7 +95,9 @@ static void *eng_image_native_get(void *data, void *image); static void eng_image_cache_flush(void *data); static void eng_image_cache_set(void *data, int bytes); static int eng_image_cache_get(void *data); - +static void eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint); +static int eng_image_scale_hint_get(void *data __UNUSED__, void *image); + static void *eng_font_load(void *data, char *name, int size); static void *eng_font_memory_load(void *data, char *name, int size, const void *fdata, int fdata_size); static void *eng_font_add(void *data, void *font, char *name, int size); @@ -239,7 +241,10 @@ static Evas_Func eng_func = eng_font_cache_get, eng_font_hinting_set, - eng_font_hinting_can_hint + eng_font_hinting_can_hint, + + eng_image_scale_hint_set, + eng_image_scale_hint_get }; static void * @@ -1257,6 +1262,17 @@ eng_image_cache_get(void *data) return evas_common_image_get_cache(); } +static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + static void * eng_font_load(void *data, char *name, int size) { diff --git a/src/modules/engines/direct3d/evas_engine.c b/src/modules/engines/direct3d/evas_engine.c index f93f770..6ff9021 100644 --- a/src/modules/engines/direct3d/evas_engine.c +++ b/src/modules/engines/direct3d/evas_engine.c @@ -376,6 +376,17 @@ eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + +static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text) { Render_Engine *re = (Render_Engine *)data; @@ -558,6 +569,10 @@ module_open(Evas_Module *em) ORD(image_border_get); ORD(font_draw); ORD(font_free); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* ORD(gradient2_color_np_stop_insert); ORD(gradient2_clear); diff --git a/src/modules/engines/directfb/evas_engine.c b/src/modules/engines/directfb/evas_engine.c index 24c5c1b..aff909b 100644 --- a/src/modules/engines/directfb/evas_engine.c +++ b/src/modules/engines/directfb/evas_engine.c @@ -1600,6 +1600,17 @@ evas_engine_dfb_image_comment_get(void *data __UNUSED__, void *image, char *key return im->info.comment; } +static void +evas_engine_dfb_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +evas_engine_dfb_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + EAPI int module_open(Evas_Module *em) { @@ -1648,6 +1659,8 @@ module_open(Evas_Module *em) ORD(rectangle_draw); ORD(polygon_draw); ORD(gradient_draw); + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/gl_glew/evas_engine.c b/src/modules/engines/gl_glew/evas_engine.c index ae540bd..c242576 100644 --- a/src/modules/engines/gl_glew/evas_engine.c +++ b/src/modules/engines/gl_glew/evas_engine.c @@ -884,6 +884,17 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + +static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text) { Render_Engine *re; @@ -984,6 +995,10 @@ module_open(Evas_Module *em) ORD(image_native_set); ORD(image_native_get); ORD(font_draw); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index f05cf98..8934e2d 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/src/modules/engines/gl_x11/evas_engine.c @@ -1014,6 +1014,17 @@ eng_image_draw(void *data, void *context, void *surface __UNUSED__, void *image, } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + +static void eng_font_draw(void *data, void *context, void *surface __UNUSED__, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const char *text) { Render_Engine *re; @@ -1169,6 +1180,10 @@ module_open(Evas_Module *em) ORD(image_native_set); ORD(image_native_get); ORD(font_draw); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/quartz/evas_engine.c b/src/modules/engines/quartz/evas_engine.c index de7b3b9..4dc9d80 100644 --- a/src/modules/engines/quartz/evas_engine.c +++ b/src/modules/engines/quartz/evas_engine.c @@ -1101,6 +1101,18 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, CGContextDrawImage(re->ctx, CGRectMake(dst_x, dst_y, dst_w, dst_h), im->cgim); } +static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + + #pragma mark Text Manipulation & Drawing static Evas_Quartz_Font * @@ -1491,6 +1503,9 @@ module_open(Evas_Module *em) ORD(rectangle_draw); ORD(setup); + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out our api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/software_16/evas_engine.c b/src/modules/engines/software_16/evas_engine.c index 93e4af8..30e6758 100644 --- a/src/modules/engines/software_16/evas_engine.c +++ b/src/modules/engines/software_16/evas_engine.c @@ -648,6 +648,17 @@ eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image, } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + +static void eng_image_cache_flush(void *data __UNUSED__) { evas_cache_image_flush(evas_common_soft16_image_cache_get()); @@ -959,7 +970,9 @@ static Evas_Func func = eng_font_cache_get, /* font hinting functions */ eng_font_hinting_set, - eng_font_hinting_can_hint + eng_font_hinting_can_hint, + eng_image_scale_hint_set, + eng_image_scale_hint_get /* FUTURE software generic calls go here */ }; diff --git a/src/modules/engines/software_16_sdl/evas_engine.c b/src/modules/engines/software_16_sdl/evas_engine.c index c15a13e..3341720 100644 --- a/src/modules/engines/software_16_sdl/evas_engine.c +++ b/src/modules/engines/software_16_sdl/evas_engine.c @@ -822,6 +822,18 @@ evas_engine_sdl16_image_draw(void *data __UNUSED__, void *context, void *surface } static void +evas_engine_sdl16_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +evas_engine_sdl16_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + + +static void evas_engine_sdl16_image_cache_flush(void *data) { Render_Engine *re = (Render_Engine*) data; @@ -1058,6 +1070,10 @@ module_open(Evas_Module *em) ORD(line_draw); ORD(rectangle_draw); ORD(polygon_draw); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c index 2517f50..566ddda 100644 --- a/src/modules/engines/software_generic/evas_engine.c +++ b/src/modules/engines/software_generic/evas_engine.c @@ -778,6 +778,26 @@ eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image, } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ + Image_Entry *im; + + if (!image) return; + im = image; + im->scale_hint = hint; +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + Image_Entry *im; + + if (!image) return EVAS_IMAGE_SCALE_HINT_NONE; + im = image; + return im->scale_hint; +} + +static void eng_image_cache_flush(void *data __UNUSED__) { int tmp_size; @@ -1087,7 +1107,9 @@ static Evas_Func func = eng_font_cache_get, /* font hinting functions */ eng_font_hinting_set, - eng_font_hinting_can_hint + eng_font_hinting_can_hint, + eng_image_scale_hint_set, + eng_image_scale_hint_get /* FUTURE software generic calls go here */ }; diff --git a/src/modules/engines/software_sdl/evas_engine.c b/src/modules/engines/software_sdl/evas_engine.c index ca62c93..13c7f5d 100644 --- a/src/modules/engines/software_sdl/evas_engine.c +++ b/src/modules/engines/software_sdl/evas_engine.c @@ -622,6 +622,17 @@ evas_engine_sdl_image_draw(void *data, void *context, void *surface, void *image } static void +evas_engine_sdl_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +evas_engine_sdl_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + +static void evas_engine_sdl_image_cache_flush(void *data) { Render_Engine *re = (Render_Engine*) data; @@ -856,6 +867,10 @@ EAPI int module_open(Evas_Module *em) ORD(rectangle_draw); ORD(polygon_draw); ORD(gradient_draw); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out own api */ em->functions = (void *)(&func); return 1; diff --git a/src/modules/engines/xrender_x11/evas_engine.c b/src/modules/engines/xrender_x11/evas_engine.c index 03644ea..1673685 100644 --- a/src/modules/engines/xrender_x11/evas_engine.c +++ b/src/modules/engines/xrender_x11/evas_engine.c @@ -1326,6 +1326,18 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, } static void +eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint) +{ +} + +static int +eng_image_scale_hint_get(void *data __UNUSED__, void *image) +{ + return EVAS_IMAGE_SCALE_HINT_NONE; +} + + +static void eng_image_cache_flush(void *data) { Render_Engine *re; @@ -1479,6 +1491,10 @@ module_open(Evas_Module *em) ORD(image_cache_set); ORD(image_cache_get); ORD(font_draw); + + ORD(image_scale_hint_set); + ORD(image_scale_hint_get); + /* now advertise out own api */ em->functions = (void *)(&func); return 1;