summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--NEWS1
-rw-r--r--src/Makefile_Evas.am1
-rw-r--r--src/bin/evas/evas_cserve2.h5
-rw-r--r--src/bin/evas/evas_cserve2_cache.c117
-rw-r--r--src/bin/evas/evas_cserve2_client.c33
-rw-r--r--src/bin/evas/evas_cserve2_main.c13
-rw-r--r--src/bin/evas/evas_cserve2_scale.c61
-rw-r--r--src/bin/evas/evas_cserve2_slave.c2
-rw-r--r--src/lib/evas/cache2/evas_cache2.c165
-rw-r--r--src/lib/evas/cache2/evas_cache2.h1
-rw-r--r--src/lib/evas/canvas/evas_object_image.c70
-rw-r--r--src/lib/evas/common/evas_image_main.c3
-rw-r--r--src/lib/evas/cserve2/evas_cs2.h4
-rw-r--r--src/lib/evas/cserve2/evas_cs2_client.c8
-rw-r--r--src/lib/evas/include/evas_common.h6
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c48
17 files changed, 503 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index a83354f..f7b2f30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
12012-11-22 Paulo Alcantara (pcacjr)
2 * Add scalecache support to Cserve2
3
12012-11-22 Sung W. Park (sung_) 42012-11-22 Sung W. Park (sung_)
2 5
3 * Fixed a bug where if an image object rendered using Evas GL 6 * Fixed a bug where if an image object rendered using Evas GL
diff --git a/NEWS b/NEWS
index f35cd73..292adef 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Additions:
11 * Add eina_tmpstr_add() and eina_tmpstr_del() 11 * Add eina_tmpstr_add() and eina_tmpstr_del()
12 * Add eina_thread API 12 * Add eina_thread API
13 * Add eina_list_last_data_get 13 * Add eina_list_last_data_get
14 * Add Cserve2 scalecache support
14 15
15Improvements: 16Improvements:
16 * Single EFL tree covering all EFL library components. 17 * Single EFL tree covering all EFL library components.
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index dbb66a0..616c466 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1727,6 +1727,7 @@ bin/evas/evas_cserve2_shm.c \
1727bin/evas/evas_cserve2_cache.c \ 1727bin/evas/evas_cserve2_cache.c \
1728bin/evas/evas_cserve2_requests.c \ 1728bin/evas/evas_cserve2_requests.c \
1729bin/evas/evas_cserve2_fonts.c \ 1729bin/evas/evas_cserve2_fonts.c \
1730bin/evas/evas_cserve2_scale.c \
1730bin/evas/evas_cserve2_main_loop_linux.c \ 1731bin/evas/evas_cserve2_main_loop_linux.c \
1731lib/evas/cserve2/evas_cs2_utils.h \ 1732lib/evas/cserve2/evas_cs2_utils.h \
1732lib/evas/cserve2/evas_cs2_utils.c 1733lib/evas/cserve2/evas_cs2_utils.c
diff --git a/src/bin/evas/evas_cserve2.h b/src/bin/evas/evas_cserve2.h
index 3560387..af21cca 100644
--- a/src/bin/evas/evas_cserve2.h
+++ b/src/bin/evas/evas_cserve2.h
@@ -109,6 +109,7 @@ struct _Slave_Msg_Image_Load {
109}; 109};
110 110
111struct _Slave_Msg_Image_Loaded { 111struct _Slave_Msg_Image_Loaded {
112 int w, h;
112 Eina_Bool alpha_sparse : 1; 113 Eina_Bool alpha_sparse : 1;
113}; 114};
114 115
@@ -275,6 +276,9 @@ size_t cserve2_shm_size_normalize(size_t size);
275 276
276void cserve2_command_run(Client *client, Message_Type type); 277void cserve2_command_run(Client *client, Message_Type type);
277 278
279void cserve2_scale_init(void);
280void cserve2_scale_shutdown(void);
281
278void cserve2_cache_init(void); 282void cserve2_cache_init(void);
279void cserve2_cache_shutdown(void); 283void cserve2_cache_shutdown(void);
280void cserve2_cache_client_new(Client *client); 284void cserve2_cache_client_new(Client *client);
@@ -282,6 +286,7 @@ void cserve2_cache_client_del(Client *client);
282int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid); 286int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
283void cserve2_cache_file_close(Client *client, unsigned int client_file_id); 287void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
284int cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg); 288int cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg);
289void 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);
285void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid); 290void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid);
286void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid); 291void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
287void cserve2_cache_image_unload(Client *client, unsigned int client_image_id); 292void cserve2_cache_image_unload(Client *client, unsigned int client_image_id);
diff --git a/src/bin/evas/evas_cserve2_cache.c b/src/bin/evas/evas_cserve2_cache.c
index 6ae8a42..97c9444 100644
--- a/src/bin/evas/evas_cserve2_cache.c
+++ b/src/bin/evas/evas_cserve2_cache.c
@@ -3,6 +3,7 @@
3#endif 3#endif
4 4
5#include <string.h> 5#include <string.h>
6#include <sys/mman.h>
6 7
7#ifdef DEBUG_LOAD_TIME 8#ifdef DEBUG_LOAD_TIME
8 #include <sys/time.h> 9 #include <sys/time.h>
@@ -65,6 +66,10 @@ struct _Image_Data {
65 int w, h; // w and h < -1 66 int w, h; // w and h < -1
66 int scale_down; // scale_down < -1 67 int scale_down; // scale_down < -1
67 int rx, ry, rw, rh; // rx, ry, rw, rh < -1 68 int rx, ry, rw, rh; // rx, ry, rw, rh < -1
69 int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
70 int scale_dst_w, scale_dst_h;
71 int scale_smooth;
72 int scale_hint;
68 Eina_Bool orientation; // orientation == 0 73 Eina_Bool orientation; // orientation == 0
69 } opts; 74 } opts;
70 Shm_Handle *shm; 75 Shm_Handle *shm;
@@ -179,7 +184,7 @@ static Eina_List *image_entries_lru = NULL;
179 184
180static Eina_List *font_shm_lru = NULL; 185static Eina_List *font_shm_lru = NULL;
181 186
182static int max_unused_mem_usage = 5 * 1024; /* in kbytes */ 187static int max_unused_mem_usage = 5 * 4 * 1024; /* in kbytes */
183static int unused_mem_usage = 0; 188static int unused_mem_usage = 0;
184static int max_font_usage = 10 * 4 * 1024; /* in kbytes */ 189static int max_font_usage = 10 * 4 * 1024; /* in kbytes */
185static int font_mem_usage = 0; 190static int font_mem_usage = 0;
@@ -474,6 +479,78 @@ _load_request_build(Image_Data *i, int *bufsize)
474 return buf; 479 return buf;
475} 480}
476 481
482static inline Eina_Bool
483_scaling_needed(Image_Data *entry, Slave_Msg_Image_Loaded *resp)
484{
485 return (((entry->opts.scale_dst_w) && (entry->opts.scale_dst_h)) &&
486 ((entry->opts.scale_dst_w != resp->w) ||
487 (entry->opts.scale_dst_h != resp->h)));
488}
489
490static int
491_scaling_do(Shm_Handle *scale_shm, Image_Data *entry)
492{
493 char *scale_map, *orig_map;
494 void *src_data, *dst_data;
495
496 scale_map = cserve2_shm_map(scale_shm);
497 if (scale_map == MAP_FAILED)
498 {
499 ERR("Failed to memory map file for scale image.");
500 return -1;
501 }
502
503 orig_map = cserve2_shm_map(entry->shm);
504 if (orig_map == MAP_FAILED)
505 {
506 ERR("Failed to memory map file for original image.");
507
508 cserve2_shm_unmap(scale_shm);
509 return -1;
510 }
511
512 src_data = orig_map + cserve2_shm_map_offset_get(entry->shm);
513 dst_data = scale_map + cserve2_shm_map_offset_get(scale_shm);
514
515 DBG("Scaling image ([%d,%d:%dx%d] --> [%d,%d:%dx%d])",
516 entry->opts.scale_src_x, entry->opts.scale_src_y,
517 entry->opts.scale_src_w, entry->opts.scale_src_h,
518 0, 0,
519 entry->opts.scale_dst_w, entry->opts.scale_dst_h);
520
521 cserve2_rgba_image_scale_do(src_data, dst_data,
522 entry->opts.scale_src_x, entry->opts.scale_src_y,
523 entry->opts.scale_src_w, entry->opts.scale_src_h,
524 0, 0,
525 entry->opts.scale_dst_w, entry->opts.scale_dst_h,
526 entry->file->alpha, entry->opts.scale_smooth);
527
528 cserve2_shm_unmap(entry->shm);
529 cserve2_shm_unmap(scale_shm);
530
531 return 0;
532}
533
534static int
535_scaling_prepare_and_do(Image_Data *orig)
536{
537 Shm_Handle *scale_shm;
538
539 DBG("Original image's shm path %s", cserve2_shm_name_get(orig->shm));
540
541 scale_shm =
542 cserve2_shm_request(orig->opts.scale_dst_w * orig->opts.scale_dst_h * 4);
543
544 DBG("Scale image's shm path %s", cserve2_shm_name_get(scale_shm));
545
546 if (_scaling_do(scale_shm, orig)) return -1;
547
548 cserve2_shm_unref(orig->shm); /* unreference old shm */
549 orig->shm = scale_shm; /* update shm */
550
551 return 0;
552}
553
477static Msg_Loaded * 554static Msg_Loaded *
478_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size) 555_load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size)
479{ 556{
@@ -485,6 +562,20 @@ _load_request_response(Image_Data *e, Slave_Msg_Image_Loaded *resp, int *size)
485 if (!e->doload) 562 if (!e->doload)
486 DBG("Entry %d loaded by speculative preload.", e->base.id); 563 DBG("Entry %d loaded by speculative preload.", e->base.id);
487 564
565 if (_scaling_needed(e, resp))
566 {
567 DBG("About to scale down image '%s%s'", e->file->path, e->file->key);
568
569 if (!_scaling_prepare_and_do(e))
570 DBG("Image '%s:%s' has been scaled down.",
571 e->file->path, e->file->key);
572 else
573 ERR("Failed to scale down image '%s%s'",
574 e->file->path, e->file->key);
575 }
576 else
577 DBG("No scaling needed for image '%s%s'", e->file->path, e->file->key);
578
488 return _image_loaded_msg_create(e, size); 579 return _image_loaded_msg_create(e, size);
489} 580}
490 581
@@ -500,10 +591,15 @@ _img_opts_id_get(Image_Data *im, char *buf, int size)
500{ 591{
501 uintptr_t image_id; 592 uintptr_t image_id;
502 593
503 snprintf(buf, size, "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:%d", 594 snprintf(buf, size,
595 "%u:%0.3f:%dx%d:%d:%d,%d+%dx%d:!([%d,%d:%dx%d]-[%dx%d:%d]):%d",
504 im->file_id, im->opts.dpi, im->opts.w, im->opts.h, 596 im->file_id, im->opts.dpi, im->opts.w, im->opts.h,
505 im->opts.scale_down, im->opts.rx, im->opts.ry, 597 im->opts.scale_down, im->opts.rx, im->opts.ry,
506 im->opts.rw, im->opts.rh, im->opts.orientation); 598 im->opts.rw, im->opts.rh,
599 im->opts.scale_src_x, im->opts.scale_src_y,
600 im->opts.scale_src_w, im->opts.scale_src_h,
601 im->opts.scale_dst_w, im->opts.scale_dst_h, im->opts.scale_smooth,
602 im->opts.orientation);
507 603
508 image_id = (uintptr_t)eina_hash_find(image_ids, buf); 604 image_id = (uintptr_t)eina_hash_find(image_ids, buf);
509 605
@@ -972,6 +1068,14 @@ _image_msg_new(Client *client, Msg_Setopts *msg)
972 im_entry->opts.ry = msg->opts.ry; 1068 im_entry->opts.ry = msg->opts.ry;
973 im_entry->opts.rw = msg->opts.rw; 1069 im_entry->opts.rw = msg->opts.rw;
974 im_entry->opts.rh = msg->opts.rh; 1070 im_entry->opts.rh = msg->opts.rh;
1071 im_entry->opts.scale_src_x = msg->opts.scale_src_x;
1072 im_entry->opts.scale_src_y = msg->opts.scale_src_y;
1073 im_entry->opts.scale_src_w = msg->opts.scale_src_w;
1074 im_entry->opts.scale_src_h = msg->opts.scale_src_h;
1075 im_entry->opts.scale_dst_w = msg->opts.scale_dst_w;
1076 im_entry->opts.scale_dst_h = msg->opts.scale_dst_h;
1077 im_entry->opts.scale_smooth = msg->opts.scale_smooth;
1078 im_entry->opts.scale_hint = msg->opts.scale_hint;
975 im_entry->opts.orientation = msg->opts.orientation; 1079 im_entry->opts.orientation = msg->opts.orientation;
976 1080
977 return im_entry; 1081 return im_entry;
@@ -2034,9 +2138,10 @@ cserve2_cache_image_opts_set(Client *client, Msg_Setopts *msg)
2034 fentry = entry->file; 2138 fentry = entry->file;
2035 fentry->images = eina_list_append(fentry->images, entry); 2139 fentry->images = eina_list_append(fentry->images, entry);
2036 2140
2037 entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD, 2141 if ((!entry->opts.scale_dst_w) && (!entry->opts.scale_dst_h))
2038 0, NULL, fentry->base.request, 2142 entry->base.request = cserve2_request_add(CSERVE2_REQ_IMAGE_SPEC_LOAD,
2039 &_load_funcs, entry); 2143 0, NULL, fentry->base.request,
2144 &_load_funcs, entry);
2040 return 0; 2145 return 0;
2041} 2146}
2042 2147
diff --git a/src/bin/evas/evas_cserve2_client.c b/src/bin/evas/evas_cserve2_client.c
index 5ced017..14a6cff 100644
--- a/src/bin/evas/evas_cserve2_client.c
+++ b/src/bin/evas/evas_cserve2_client.c
@@ -101,6 +101,10 @@ parse_input_setopts(int *size)
101 int w, h; 101 int w, h;
102 int scale; 102 int scale;
103 int rx, ry, rw, rh; 103 int rx, ry, rw, rh;
104 int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
105 int scale_dst_w, scale_dst_h;
106 int scale_smooth;
107 int scale_hint;
104 int orientation; 108 int orientation;
105 109
106 // reading file_id, image_id 110 // reading file_id, image_id
@@ -123,11 +127,30 @@ parse_input_setopts(int *size)
123 _read_line(line, sizeof(line)); 127 _read_line(line, sizeof(line));
124 sscanf(line, "%d %d %d %d", &rx, &ry, &rw, &rh); 128 sscanf(line, "%d %d %d %d", &rx, &ry, &rw, &rh);
125 129
130 // reading original image's source coord
131 _read_line(line, sizeof(line));
132 sscanf(line, "%d %d", &scale_src_x, &scale_src_y);
133
134 // reading original size
135 _read_line(line, sizeof(line));
136 sscanf(line, "%d %d", &scale_src_w, &scale_src_h);
137
138 // reading scale size
139 _read_line(line, sizeof(line));
140 sscanf(line, "%d %d", &scale_dst_w, &scale_dst_h);
141
142 // reading scale smooth
143 _read_line(line, sizeof(line));
144 sscanf(line, "%d", &scale_smooth);
145
146 // reading scale hint
147 _read_line(line, sizeof(line));
148 sscanf(line, "%d", &scale_hint);
149
126 // reading orientation 150 // reading orientation
127 _read_line(line, sizeof(line)); 151 _read_line(line, sizeof(line));
128 sscanf(line, "%d", &orientation); 152 sscanf(line, "%d", &orientation);
129 153
130
131 msg = calloc(1, sizeof(*msg)); 154 msg = calloc(1, sizeof(*msg));
132 155
133 msg->base.rid = _rid_count++; 156 msg->base.rid = _rid_count++;
@@ -142,6 +165,14 @@ parse_input_setopts(int *size)
142 msg->opts.ry = ry; 165 msg->opts.ry = ry;
143 msg->opts.rw = rw; 166 msg->opts.rw = rw;
144 msg->opts.rh = rh; 167 msg->opts.rh = rh;
168 msg->opts.scale_src_x = scale_src_x;
169 msg->opts.scale_src_y = scale_src_y;
170 msg->opts.scale_src_w = scale_src_w;
171 msg->opts.scale_src_h = scale_src_h;
172 msg->opts.scale_dst_w = scale_dst_w;
173 msg->opts.scale_dst_h = scale_dst_h;
174 msg->opts.scale_smooth = scale_smooth;
175 msg->opts.scale_hint = scale_hint;
145 msg->opts.orientation = !!orientation; 176 msg->opts.orientation = !!orientation;
146 177
147 *size = sizeof(*msg); 178 *size = sizeof(*msg);
diff --git a/src/bin/evas/evas_cserve2_main.c b/src/bin/evas/evas_cserve2_main.c
index 8b72ecc..5c57b72 100644
--- a/src/bin/evas/evas_cserve2_main.c
+++ b/src/bin/evas/evas_cserve2_main.c
@@ -105,7 +105,14 @@ _cserve2_client_setopts(Client *client)
105 INF("\tsize: %dx%d", msg->opts.w, msg->opts.h); 105 INF("\tsize: %dx%d", msg->opts.w, msg->opts.h);
106 INF("\tscale down: %d", msg->opts.scale_down); 106 INF("\tscale down: %d", msg->opts.scale_down);
107 INF("\tregion: %d,%d + %dx%d", 107 INF("\tregion: %d,%d + %dx%d",
108 msg->opts.rx, msg->opts.ry, msg->opts.rw, msg->opts.rh); 108 msg->opts.rx, msg->opts.ry, msg->opts.rw, msg->opts.rh);
109 INF("\toriginal image's source coord: %d,%d",
110 msg->opts.scale_src_x, msg->opts.scale_src_y);
111 INF("\toriginal image size: %dx%d",
112 msg->opts.scale_src_w, msg->opts.scale_src_h);
113 INF("\tscale size: %dx%d", msg->opts.scale_dst_w, msg->opts.scale_dst_h);
114 INF("\tscale smooth: %d", msg->opts.scale_smooth);
115 INF("\tscale hint: %d", msg->opts.scale_hint);
109 INF("\torientation: %d\n", msg->opts.orientation); 116 INF("\torientation: %d\n", msg->opts.orientation);
110 117
111 if (cserve2_cache_image_opts_set(client, msg) != 0) 118 if (cserve2_cache_image_opts_set(client, msg) != 0)
@@ -336,6 +343,8 @@ main(int argc EINA_UNUSED, const char *argv[] EINA_UNUSED)
336 343
337 cserve2_requests_init(); 344 cserve2_requests_init();
338 345
346 cserve2_scale_init();
347
339 cserve2_font_init(); 348 cserve2_font_init();
340 349
341 cserve2_cache_init(); 350 cserve2_cache_init();
@@ -350,6 +359,8 @@ main(int argc EINA_UNUSED, const char *argv[] EINA_UNUSED)
350 359
351 cserve2_font_shutdown(); 360 cserve2_font_shutdown();
352 361
362 cserve2_scale_shutdown();
363
353 cserve2_requests_shutdown(); 364 cserve2_requests_shutdown();
354 365
355 cserve2_slaves_shutdown(); 366 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
index 0000000..c986332
--- /dev/null
+++ b/src/bin/evas/evas_cserve2_scale.c
@@ -0,0 +1,61 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4void
5cserve2_scale_init(void)
6{
7 evas_common_cpu_init();
8 evas_common_blend_init();
9 evas_common_image_init();
10 evas_common_convert_init();
11 evas_common_scale_init();
12}
13
14void
15cserve2_scale_shutdown(void)
16{
17 evas_common_image_shutdown();
18}
19
20static inline void
21_cserve2_rgba_image_set(RGBA_Image *im, void *data, int w, int h, int alpha)
22{
23 memset(im, 0, sizeof *im);
24
25 im->ref = 1;
26 im->cache_entry.w = w;
27 im->cache_entry.h = h;
28 im->cache_entry.space = EVAS_COLORSPACE_ARGB8888;
29 im->cache_entry.flags.alpha = alpha;
30 im->image.data = data;
31 im->cache_entry.allocated.w = w;
32 im->cache_entry.allocated.h = h;
33}
34
35void
36cserve2_rgba_image_scale_do(void *src_data, void *dst_data,
37 int src_x, int src_y, int src_w, int src_h,
38 int dst_x, int dst_y, int dst_w, int dst_h,
39 int alpha, int smooth)
40{
41 RGBA_Image src, dst;
42 RGBA_Draw_Context ct;
43
44 _cserve2_rgba_image_set(&src, src_data, src_w, src_h, alpha);
45
46 _cserve2_rgba_image_set(&dst, dst_data, dst_w, dst_h, alpha);
47 dst.flags = RGBA_IMAGE_NOTHING;
48
49 memset(&ct, 0, sizeof(ct));
50 ct.sli.h = 1;
51 ct.render_op = _EVAS_RENDER_COPY;
52
53 if (smooth)
54 evas_common_scale_rgba_in_to_out_clip_smooth(&src, &dst, &ct,
55 src_x, src_y, src_w, src_h,
56 dst_x, dst_y, dst_w, dst_h);
57 else
58 evas_common_scale_rgba_in_to_out_clip_sample(&src, &dst, &ct,
59 src_x, src_y, src_w, src_h,
60 dst_x, dst_y, dst_w, dst_h);
61}
diff --git a/src/bin/evas/evas_cserve2_slave.c b/src/bin/evas/evas_cserve2_slave.c
index 317bc14..5a06017 100644
--- a/src/bin/evas/evas_cserve2_slave.c
+++ b/src/bin/evas/evas_cserve2_slave.c
@@ -349,6 +349,8 @@ image_load(const char *file, const char *key, const char *shmfile, Slave_Msg_Ima
349 if (!api->data_load(&ilp, file, key, &err)) 349 if (!api->data_load(&ilp, file, key, &err))
350 ret = err; 350 ret = err;
351 351
352 result->w = params->w;
353 result->h = params->h;
352 result->alpha_sparse = ilp.alpha_sparse; 354 result->alpha_sparse = ilp.alpha_sparse;
353 355
354done: 356done:
diff --git a/src/lib/evas/cache2/evas_cache2.c b/src/lib/evas/cache2/evas_cache2.c
index 1b9d05c..6397f10 100644
--- a/src/lib/evas/cache2/evas_cache2.c
+++ b/src/lib/evas/cache2/evas_cache2.c
@@ -25,6 +25,11 @@
25 Var = NULL; \ 25 Var = NULL; \
26} 26}
27 27
28/* Size of characters used to determine a string that'll be used for load
29 * options in hash keys.
30 */
31#define HKEY_LOAD_OPTS_STR_LEN 215
32
28static void _evas_cache_image_dirty_add(Image_Entry *im); 33static void _evas_cache_image_dirty_add(Image_Entry *im);
29static void _evas_cache_image_dirty_del(Image_Entry *im); 34static void _evas_cache_image_dirty_del(Image_Entry *im);
30static void _evas_cache_image_activ_add(Image_Entry *im); 35static 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,
567 size += eina_convert_xtoa(lo->region.w, hkey + size); 572 size += eina_convert_xtoa(lo->region.w, hkey + size);
568 hkey[size] = 'x'; 573 hkey[size] = 'x';
569 size += 1; 574 size += 1;
575
570 size += eina_convert_xtoa(lo->region.h, hkey + size); 576 size += eina_convert_xtoa(lo->region.h, hkey + size);
577 hkey[size++] = '!';
578 hkey[size++] = '(';
579
580 hkey[size] = '[';
581 size += 1;
582 size += eina_convert_xtoa(lo->scale_load.src_x, hkey + size);
583 hkey[size] = ',';
584 size += 1;
585 size += eina_convert_xtoa(lo->scale_load.src_y, hkey + size);
586 hkey[size] = ':';
587 size += 1;
588 size += eina_convert_xtoa(lo->scale_load.src_w, hkey + size);
589 hkey[size] = 'x';
590 size += 1;
591 size += eina_convert_xtoa(lo->scale_load.src_h, hkey + size);
592 hkey[size++] = ']';
593
594 hkey[size++] = '-';
595
596 hkey[size] = '[';
597 size += 1;
598 size += eina_convert_xtoa(lo->scale_load.dst_w, hkey + size);
599 hkey[size] = 'x';
600 size += 1;
601 size += eina_convert_xtoa(lo->scale_load.dst_h, hkey + size);
602 hkey[size] = ':';
603 size += 1;
604 size += eina_convert_xtoa(lo->scale_load.smooth, hkey + size);
605 hkey[size++] = ']';
606
607 hkey[size++] = ')';
571 608
572 if (lo->orientation) 609 if (lo->orientation)
573 { 610 {
@@ -591,7 +628,8 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RG
591 int stat_done = 0, stat_failed = 0; 628 int stat_done = 0, stat_failed = 0;
592 struct stat st; 629 struct stat st;
593 Image_Timestamp tstamp; 630 Image_Timestamp tstamp;
594 Evas_Image_Load_Opts prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 }, EINA_FALSE }; 631 Evas_Image_Load_Opts prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 },
632 { 0, 0, 0, 0, 0, 0, 0, 0 }, EINA_FALSE };
595 633
596 if ((!path) || ((!path) && (!key))) 634 if ((!path) || ((!path) && (!key)))
597 { 635 {
@@ -601,7 +639,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RG
601 639
602 pathlen = strlen(path); 640 pathlen = strlen(path);
603 keylen = key ? strlen(key) : 6; 641 keylen = key ? strlen(key) : 6;
604 size = pathlen + keylen + 132; 642 size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
605 hkey = alloca(sizeof(char) * size); 643 hkey = alloca(sizeof(char) * size);
606 644
607 _create_hash_key(hkey, path, pathlen, key, keylen, lo); 645 _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
614 (lo->dpi == 0.0) && 652 (lo->dpi == 0.0) &&
615 ((lo->w == 0) || (lo->h == 0)) && 653 ((lo->w == 0) || (lo->h == 0)) &&
616 ((lo->region.w == 0) || (lo->region.h == 0)) && 654 ((lo->region.w == 0) || (lo->region.h == 0)) &&
655 ((lo->scale_load.dst_w == 0) || (lo->scale_load.dst_h == 0)) &&
617 (lo->orientation == 0) 656 (lo->orientation == 0)
618 )) 657 ))
619 { 658 {
@@ -731,6 +770,128 @@ evas_cache2_image_open_wait(Image_Entry *im)
731 return EVAS_LOAD_ERROR_NONE; 770 return EVAS_LOAD_ERROR_NONE;
732} 771}
733 772
773static Image_Entry *
774_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)
775{
776 size_t pathlen, keylen, size;
777 char *hkey;
778 RGBA_Image_Loadopts lo;
779 Image_Entry *ret;
780
781 if (((!im->file) || ((!im->file) && (!im->key))) || (!im->data1) ||
782 ((src_w == dst_w) && (src_h == dst_h)) ||
783 ((!im->flags.alpha) && (!smooth))) return NULL;
784
785 pathlen = strlen(im->file);
786 keylen = im->key ? strlen(im->key) : 6;
787 size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
788 hkey = alloca(sizeof(char) * size);
789
790 memcpy(&lo, &im->load_opts, sizeof lo);
791 lo.scale_load.src_x = src_x;
792 lo.scale_load.src_y = src_y;
793 lo.scale_load.src_w = src_w;
794 lo.scale_load.src_h = src_h;
795 lo.scale_load.dst_w = dst_w;
796 lo.scale_load.dst_h = dst_h;
797 lo.scale_load.smooth = smooth;
798
799 if (!smooth)
800 {
801 lo.scale_load.smooth = 1;
802 _create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
803
804 ret = eina_hash_find(im->cache2->activ, hkey);
805 if (ret) goto found;
806
807 ret = eina_hash_find(im->cache2->inactiv, hkey);
808 if (ret) goto handle_inactiv;
809
810 lo.scale_load.smooth = smooth;
811 }
812
813 _create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
814
815 ret = eina_hash_find(im->cache2->activ, hkey);
816 if (ret) goto found;
817
818 ret = eina_hash_find(im->cache2->inactiv, hkey);
819
820 handle_inactiv:
821 if (!ret) return NULL;
822
823 /* Remove from lru and make it active again */
824 _evas_cache_image_lru_del(ret);
825 _evas_cache_image_activ_add(ret);
826
827 found:
828 evas_cache2_image_load_data(ret);
829
830 return ret;
831}
832
833EAPI Image_Entry *
834evas_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)
835{
836 size_t pathlen, keylen, size;
837 char *hkey;
838 RGBA_Image_Loadopts lo;
839 int error = EVAS_LOAD_ERROR_NONE;
840 Image_Entry *ret;
841
842 if (((!im->file) || ((!im->file) && (!im->key))) ||
843 ((src_w == 0) || (src_h == 0) || (dst_w == 0) || (dst_h == 0)) ||
844 (im->scale_hint == EVAS_IMAGE_SCALE_HINT_DYNAMIC)) goto parent_out;
845
846 if (((src_w == dst_w) && (src_h == dst_h)) ||
847 ((!im->flags.alpha) && (!smooth))) goto parent_out;
848
849 ret = _scaled_image_find(im, src_x, src_y, src_w, src_h,
850 dst_w, dst_h, smooth);
851 if (ret) return ret;
852
853 pathlen = strlen(im->file);
854 keylen = im->key ? strlen(im->key) : 6;
855 size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
856 hkey = alloca(sizeof(char) * size);
857
858 memcpy(&lo, &im->load_opts, sizeof lo);
859 lo.scale_load.src_x = src_x;
860 lo.scale_load.src_y = src_y;
861 lo.scale_load.src_w = src_w;
862 lo.scale_load.src_h = src_h;
863 lo.scale_load.dst_w = dst_w;
864 lo.scale_load.dst_h = dst_h;
865 lo.scale_load.smooth = smooth;
866 lo.scale_load.scale_hint = im->scale_hint;
867
868 _create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
869
870 ret = _evas_cache_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
871 &lo, &error);
872 if (error != EVAS_LOAD_ERROR_NONE)
873 {
874 ERR("Failed to create scale image entry with error code %d.", error);
875
876 if (ret) _evas_cache_image_entry_delete(im->cache2, ret);
877 goto parent_out;
878 }
879
880 evas_cserve2_image_load_wait(ret);
881 evas_cache2_image_load_data(ret);
882
883 ret->references++;
884 ret->w = dst_w;
885 ret->h = dst_h;
886
887 return ret;
888
889 parent_out:
890 evas_cache2_image_load_data(im);
891
892 return im;
893}
894
734EAPI void 895EAPI void
735evas_cache2_image_close(Image_Entry *im) 896evas_cache2_image_close(Image_Entry *im)
736{ 897{
diff --git a/src/lib/evas/cache2/evas_cache2.h b/src/lib/evas/cache2/evas_cache2.h
index 7028338..8fc300a 100644
--- a/src/lib/evas/cache2/evas_cache2.h
+++ b/src/lib/evas/cache2/evas_cache2.h
@@ -59,6 +59,7 @@ extern "C" {
59EAPI Evas_Cache2* evas_cache2_init(const Evas_Cache2_Image_Func *cb); 59EAPI Evas_Cache2* evas_cache2_init(const Evas_Cache2_Image_Func *cb);
60EAPI void evas_cache2_shutdown(Evas_Cache2 *cache); 60EAPI void evas_cache2_shutdown(Evas_Cache2 *cache);
61EAPI Image_Entry * evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error); 61EAPI Image_Entry * evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, RGBA_Image_Loadopts *lo, int *error);
62EAPI 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);
62EAPI int evas_cache2_image_open_wait(Image_Entry *im); 63EAPI int evas_cache2_image_open_wait(Image_Entry *im);
63EAPI void evas_cache2_image_close(Image_Entry *im); 64EAPI void evas_cache2_image_close(Image_Entry *im);
64EAPI int evas_cache2_image_load_data(Image_Entry *ie); 65EAPI int evas_cache2_image_load_data(Image_Entry *ie);
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index f71f0e7..ca9d8e4 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -12,6 +12,9 @@
12 12
13#include "evas_common.h" 13#include "evas_common.h"
14#include "evas_private.h" 14#include "evas_private.h"
15#ifdef EVAS_CSERVE2
16#include "../cserve2/evas_cs2_private.h"
17#endif
15#include "../common/evas_convert_color.h" 18#include "../common/evas_convert_color.h"
16#include "../common/evas_convert_colorspace.h" 19#include "../common/evas_convert_colorspace.h"
17#include "../common/evas_convert_yuv.h" 20#include "../common/evas_convert_yuv.h"
@@ -66,6 +69,12 @@ struct _Evas_Object_Image
66 struct { 69 struct {
67 short x, y, w, h; 70 short x, y, w, h;
68 } region; 71 } region;
72 struct {
73 int src_x, src_y, src_w, src_h;
74 int dst_w, dst_h;
75 int smooth;
76 int scale_hint;
77 } scale_load;
69 Eina_Bool orientation : 1; 78 Eina_Bool orientation : 1;
70 } load_opts; 79 } load_opts;
71 80
@@ -392,6 +401,14 @@ _image_file_set(Eo *eo_obj, void *_pd, va_list *list)
392 lo.region.y = o->load_opts.region.y; 401 lo.region.y = o->load_opts.region.y;
393 lo.region.w = o->load_opts.region.w; 402 lo.region.w = o->load_opts.region.w;
394 lo.region.h = o->load_opts.region.h; 403 lo.region.h = o->load_opts.region.h;
404 lo.scale_load.src_x = o->load_opts.scale_load.src_x;
405 lo.scale_load.src_y = o->load_opts.scale_load.src_y;
406 lo.scale_load.src_w = o->load_opts.scale_load.src_w;
407 lo.scale_load.src_h = o->load_opts.scale_load.src_h;
408 lo.scale_load.dst_w = o->load_opts.scale_load.dst_w;
409 lo.scale_load.dst_h = o->load_opts.scale_load.dst_h;
410 lo.scale_load.smooth = o->load_opts.scale_load.smooth;
411 lo.scale_load.scale_hint = o->load_opts.scale_load.scale_hint;
395 lo.orientation = o->load_opts.orientation; 412 lo.orientation = o->load_opts.orientation;
396 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output, 413 o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
397 o->cur.file, 414 o->cur.file,
@@ -3490,17 +3507,48 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
3490 (o->cur.border.t == 0) && 3507 (o->cur.border.t == 0) &&
3491 (o->cur.border.b == 0) && 3508 (o->cur.border.b == 0) &&
3492 (o->cur.border.fill != 0)) 3509 (o->cur.border.fill != 0))
3493 obj->layer->evas->engine.func->image_draw(output, 3510 {
3494 context, 3511#ifdef EVAS_CSERVE2
3495 surface, 3512 if (evas_cserve2_use_get())
3496 pixels, 3513 {
3497 0, 0, 3514 Image_Entry *ie;
3498 imagew, 3515 void *data = pixels;
3499 imageh, 3516 int w = imagew, h = imageh;
3500 obj->cur.geometry.x + ix + x, 3517
3501 obj->cur.geometry.y + iy + y, 3518 ie = evas_cache2_image_scale_load
3502 iw, ih, 3519 ((Image_Entry *)pixels,
3503 o->cur.smooth_scale); 3520 0, 0,
3521 imagew, imageh,
3522 iw, ih, o->cur.smooth_scale);
3523 if (ie != &((RGBA_Image *)pixels)->cache_entry)
3524 {
3525 data = ie;
3526 w = iw;
3527 h = ih;
3528 }
3529
3530 obj->layer->evas->engine.func->image_draw
3531 (output, context, surface, data,
3532 0, 0,
3533 w, h,
3534 obj->cur.geometry.x + ix + x,
3535 obj->cur.geometry.y + iy + y,
3536 iw, ih,
3537 o->cur.smooth_scale);
3538 }
3539 else
3540#endif
3541 {
3542 obj->layer->evas->engine.func->image_draw
3543 (output, context, surface, pixels,
3544 0, 0,
3545 imagew, imageh,
3546 obj->cur.geometry.x + ix + x,
3547 obj->cur.geometry.y + iy + y,
3548 iw, ih,
3549 o->cur.smooth_scale);
3550 }
3551 }
3504 else 3552 else
3505 { 3553 {
3506 int inx, iny, inw, inh, outx, outy, outw, outh; 3554 int inx, iny, inw, inh, outx, outy, outw, outh;
diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c
index a8f7317..05cc9aa 100644
--- a/src/lib/evas/common/evas_image_main.c
+++ b/src/lib/evas/common/evas_image_main.c
@@ -20,6 +20,7 @@
20 20
21static Evas_Cache_Image * eci = NULL; 21static Evas_Cache_Image * eci = NULL;
22#ifdef EVAS_CSERVE2 22#ifdef EVAS_CSERVE2
23#define EVAS_CSERVE2_SCALE_CACHE_SIZE (4 * 1024 * 1024)
23static Evas_Cache2 * eci2 = NULL; 24static Evas_Cache2 * eci2 = NULL;
24#endif 25#endif
25static int reference = 0; 26static int reference = 0;
@@ -743,7 +744,7 @@ evas_common_image_set_cache(unsigned int size)
743 evas_cache_image_set(eci, size); 744 evas_cache_image_set(eci, size);
744#ifdef EVAS_CSERVE2 745#ifdef EVAS_CSERVE2
745 if (eci2) 746 if (eci2)
746 evas_cache2_limit_set(eci2, size); 747 evas_cache2_limit_set(eci2, size + EVAS_CSERVE2_SCALE_CACHE_SIZE);
747#endif 748#endif
748} 749}
749 750
diff --git a/src/lib/evas/cserve2/evas_cs2.h b/src/lib/evas/cserve2/evas_cs2.h
index fc83a92..7bd4c51 100644
--- a/src/lib/evas/cserve2/evas_cs2.h
+++ b/src/lib/evas/cserve2/evas_cs2.h
@@ -76,6 +76,10 @@ struct _Msg_Setopts {
76 int w, h; 76 int w, h;
77 int scale_down; 77 int scale_down;
78 int rx, ry, rw, rh; 78 int rx, ry, rw, rh;
79 int scale_src_x, scale_src_y, scale_src_w, scale_src_h;
80 int scale_dst_w, scale_dst_h;
81 int scale_smooth;
82 int scale_hint;
79 Eina_Bool orientation; 83 Eina_Bool orientation;
80 } opts; 84 } opts;
81}; 85};
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c
index 004a5db..7024de9 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -561,6 +561,14 @@ _image_setopts_server_send(Image_Entry *ie)
561 msg.opts.ry = ie->load_opts.region.y; 561 msg.opts.ry = ie->load_opts.region.y;
562 msg.opts.rw = ie->load_opts.region.w; 562 msg.opts.rw = ie->load_opts.region.w;
563 msg.opts.rh = ie->load_opts.region.h; 563 msg.opts.rh = ie->load_opts.region.h;
564 msg.opts.scale_src_x = ie->load_opts.scale_load.src_x;
565 msg.opts.scale_src_y = ie->load_opts.scale_load.src_y;
566 msg.opts.scale_src_w = ie->load_opts.scale_load.src_w;
567 msg.opts.scale_src_h = ie->load_opts.scale_load.src_h;
568 msg.opts.scale_dst_w = ie->load_opts.scale_load.dst_w;
569 msg.opts.scale_dst_h = ie->load_opts.scale_load.dst_h;
570 msg.opts.scale_smooth = ie->load_opts.scale_load.smooth;
571 msg.opts.scale_hint = ie->load_opts.scale_load.scale_hint;
564 msg.opts.orientation = ie->load_opts.orientation; 572 msg.opts.orientation = ie->load_opts.orientation;
565 573
566 if (!_server_send(&msg, sizeof(msg), 0, NULL)) 574 if (!_server_send(&msg, sizeof(msg), 0, NULL))
diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h
index e4cfff9..cdc6a0e 100644
--- a/src/lib/evas/include/evas_common.h
+++ b/src/lib/evas/include/evas_common.h
@@ -500,6 +500,12 @@ struct _RGBA_Image_Loadopts
500 struct { 500 struct {
501 unsigned int x, y, w, h; 501 unsigned int x, y, w, h;
502 } region; 502 } region;
503 struct {
504 int src_x, src_y, src_w, src_h;
505 int dst_w, dst_h;
506 int smooth;
507 Evas_Image_Scale_Hint scale_hint;
508 } scale_load;
503 509
504 Eina_Bool orientation; // if EINA_TRUE => should honor orientation information provided by file (like jpeg exif info) 510 Eina_Bool orientation; // if EINA_TRUE => should honor orientation information provided by file (like jpeg exif info)
505}; 511};
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 6d140b9..cf213d7 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -923,22 +923,38 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
923 923
924image_loaded: 924image_loaded:
925#endif 925#endif
926 evas_common_rgba_image_scalecache_prepare(&im->cache_entry, surface, context, smooth, 926#ifdef EVAS_CSERVE2
927 src_x, src_y, src_w, src_h, 927 if (evas_cserve2_use_get())
928 dst_x, dst_y, dst_w, dst_h); 928 {
929 evas_common_rgba_image_scalecache_do(&im->cache_entry, surface, context, smooth, 929 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
930 src_x, src_y, src_w, src_h, 930 evas_cache2_image_load_data(&im->cache_entry);
931 dst_x, dst_y, dst_w, dst_h); 931
932/* 932 evas_common_image_colorspace_normalize(im);
933 if (smooth) 933
934 evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context, 934 if (smooth)
935 src_x, src_y, src_w, src_h, 935 evas_common_scale_rgba_in_to_out_clip_smooth
936 dst_x, dst_y, dst_w, dst_h); 936 (im, surface, context,
937 else 937 src_x, src_y, src_w, src_h,
938 evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context, 938 dst_x, dst_y, dst_w, dst_h);
939 src_x, src_y, src_w, src_h, 939 else
940 dst_x, dst_y, dst_w, dst_h); 940 evas_common_scale_rgba_in_to_out_clip_sample
941 */ 941 (im, surface, context,
942 src_x, src_y, src_w, src_h,
943 dst_x, dst_y, dst_w, dst_h);
944 }
945 else
946#endif
947 {
948 evas_common_rgba_image_scalecache_prepare
949 (&im->cache_entry, surface, context, smooth,
950 src_x, src_y, src_w, src_h,
951 dst_x, dst_y, dst_w, dst_h);
952 evas_common_rgba_image_scalecache_do
953 (&im->cache_entry, surface, context, smooth,
954 src_x, src_y, src_w, src_h,
955 dst_x, dst_y, dst_w, dst_h);
956 }
957
942 evas_common_cpu_end_opt(); 958 evas_common_cpu_end_opt();
943 } 959 }
944} 960}