1. scale cache now allows you to hint at the object if its dynamic, static or
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 May 2009 13:29:56 +0000 (13:29 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 7 May 2009 13:29:56 +0000 (13:29 +0000)
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

21 files changed:
src/bin/evas_cserve_main.c
src/bin/evas_cserve_tool.c
src/lib/Evas.h
src/lib/canvas/evas_object_image.c
src/lib/cserve/evas_cs.h
src/lib/cserve/evas_cs_client.c
src/lib/cserve/evas_cs_server.c
src/lib/engines/common/evas_image_scalecache.c
src/lib/include/evas_common.h
src/lib/include/evas_private.h
src/modules/engines/cairo_x11/evas_engine.c
src/modules/engines/direct3d/evas_engine.c
src/modules/engines/directfb/evas_engine.c
src/modules/engines/gl_glew/evas_engine.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/quartz/evas_engine.c
src/modules/engines/software_16/evas_engine.c
src/modules/engines/software_16_sdl/evas_engine.c
src/modules/engines/software_generic/evas_engine.c
src/modules/engines/software_sdl/evas_engine.c
src/modules/engines/xrender_x11/evas_engine.c

index 6b9caf4..09574aa 100644 (file)
@@ -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;
index ffeb3f9..e2d532b 100644 (file)
@@ -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;
index 8363dba..4ae247b 100644 (file)
@@ -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);
index 214d388..e7a1923 100644 (file)
@@ -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);
index ea7fb87..5557c2d 100644 (file)
@@ -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);
index d04631d..c2db24d 100644 (file)
@@ -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
index 14e53cc..8f4e7b8 100644 (file)
@@ -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
index 76cf5ff..e001dac 100644 (file)
@@ -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;
index e63623b..20d5ad9 100644 (file)
@@ -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
index f263eab..7304966 100644 (file)
@@ -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
index 55073b0..57c3b9f 100644 (file)
@@ -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)
 {
index f93f770..6ff9021 100644 (file)
@@ -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);
index 24c5c1b..aff909b 100644 (file)
@@ -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;
index ae540bd..c242576 100644 (file)
@@ -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;
index f05cf98..8934e2d 100644 (file)
@@ -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;
index de7b3b9..4dc9d80 100644 (file)
@@ -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;
index 93e4af8..30e6758 100644 (file)
@@ -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 */
 };
 
index c15a13e..3341720 100644 (file)
@@ -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;
index 2517f50..566ddda 100644 (file)
@@ -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 */
 };
 
index ca62c93..13c7f5d 100644 (file)
@@ -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;
index 03644ea..1673685 100644 (file)
@@ -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;