evas/cserve2: Add scalecache support
authorPaulo Alcantara <pcacjr@profusion.mobi>
Tue, 27 Nov 2012 18:23:25 +0000 (18:23 +0000)
committerIván Briano <sachieru@gmail.com>
Tue, 27 Nov 2012 18:23:25 +0000 (18:23 +0000)
Signed-off-by: Paulo Alcantara <pcacjr@profusion.mobi>
Patch by: Paulo Alcantara <pcacjr@profusion.mobi>

SVN revision: 79754

17 files changed:
ChangeLog
NEWS
src/Makefile_Evas.am
src/bin/evas/evas_cserve2.h
src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_client.c
src/bin/evas/evas_cserve2_main.c
src/bin/evas/evas_cserve2_scale.c [new file with mode: 0644]
src/bin/evas/evas_cserve2_slave.c
src/lib/evas/cache2/evas_cache2.c
src/lib/evas/cache2/evas_cache2.h
src/lib/evas/canvas/evas_object_image.c
src/lib/evas/common/evas_image_main.c
src/lib/evas/cserve2/evas_cs2.h
src/lib/evas/cserve2/evas_cs2_client.c
src/lib/evas/include/evas_common.h
src/modules/evas/engines/software_generic/evas_engine.c

index a83354f..f7b2f30 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 
diff --git a/NEWS b/NEWS
index f35cd73..292adef 100644 (file)
--- a/NEWS
+++ b/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.
index dbb66a0..616c466 100644 (file)
@@ -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
index 3560387..af21cca 100644 (file)
@@ -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);
index 6ae8a42..97c9444 100644 (file)
@@ -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;
 }
 
index 5ced017..14a6cff 100644 (file)
@@ -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);
index 8b72ecc..5c57b72 100644 (file)
@@ -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();
diff --git a/src/bin/evas/evas_cserve2_scale.c b/src/bin/evas/evas_cserve2_scale.c
new file mode 100644 (file)
index 0000000..c986332
--- /dev/null
@@ -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);
+}
index 317bc14..5a06017 100644 (file)
@@ -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:
index 1b9d05c..6397f10 100644 (file)
    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)
 {
index 7028338..8fc300a 100644 (file)
@@ -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);
index f71f0e7..ca9d8e4 100644 (file)
@@ -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;
index a8f7317..05cc9aa 100644 (file)
@@ -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
 }
 
index fc83a92..7bd4c51 100644 (file)
@@ -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;
 };
index 004a5db..7024de9 100644 (file)
@@ -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))
index e4cfff9..cdc6a0e 100644 (file)
@@ -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)
 };
index 6d140b9..cf213d7 100644 (file)
@@ -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();
      }
 }