summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHermet Park <hermetpark@gmail.com>2018-12-07 19:38:48 +0900
committerHermet Park <hermetpark@gmail.com>2018-12-07 19:50:08 +0900
commitfbe92aa67f18f8c0401cdc6d4440ed512c43b131 (patch)
tree0a681b5f232105491183dfdb4efcc5d5d7050689
parent4d6f20d714ea083471be163f67af518eced4028c (diff)
evas ector: add software implmentation for masking feature.
This implementation uses Ector_Buffer to generate mask image from vg container, and pass it to Ector engine. Ector renderer could blend this image as a mask. Yet only vg container works as a mask, we could extend shape to support masking later. Still vector gl drawing is not completed, We use software ector buffer to draw on it. This is on progessing.
-rw-r--r--src/lib/ector/ector_private.h2
-rw-r--r--src/lib/ector/ector_renderer.c34
-rw-r--r--src/lib/ector/ector_renderer.eo21
-rw-r--r--src/lib/ector/software/ector_renderer_software_shape.c36
-rw-r--r--src/lib/ector/software/ector_renderer_software_shape.eo1
-rw-r--r--src/lib/ector/software/ector_software_buffer.c4
-rw-r--r--src/lib/ector/software/ector_software_private.h11
-rw-r--r--src/lib/ector/software/ector_software_rasterizer.c122
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_container.c163
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_container.eo5
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c23
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c21
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_node.c41
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_node.eo7
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_object.c102
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_shape.c32
-rw-r--r--src/lib/evas/canvas/evas_vg_private.h30
-rw-r--r--src/lib/evas/include/evas_private.h6
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c82
-rw-r--r--src/modules/evas/engines/gl_generic/meson.build2
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c26
21 files changed, 541 insertions, 230 deletions
diff --git a/src/lib/ector/ector_private.h b/src/lib/ector/ector_private.h
index 1f483664e8..8604768e16 100644
--- a/src/lib/ector/ector_private.h
+++ b/src/lib/ector/ector_private.h
@@ -63,8 +63,6 @@ struct _Ector_Renderer_Data
63 int r, g, b, a; 63 int r, g, b, a;
64 } color; 64 } color;
65 65
66 Ector_Renderer *mask;
67
68 Eina_Bool visibility : 1; 66 Eina_Bool visibility : 1;
69 Eina_Bool finalized : 1; 67 Eina_Bool finalized : 1;
70}; 68};
diff --git a/src/lib/ector/ector_renderer.c b/src/lib/ector/ector_renderer.c
index 1c2026e4da..186e3233ab 100644
--- a/src/lib/ector/ector_renderer.c
+++ b/src/lib/ector/ector_renderer.c
@@ -127,31 +127,6 @@ _ector_renderer_color_get(const Eo *obj EINA_UNUSED,
127 if (a) *a = pd->color.a; 127 if (a) *a = pd->color.a;
128} 128}
129 129
130static void
131_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
132 Ector_Renderer_Data *pd,
133 Ector_Renderer *mask)
134{
135 efl_replace(&pd->mask, mask);
136}
137
138static Ector_Renderer *
139_ector_renderer_mask_get(const Eo *obj EINA_UNUSED,
140 Ector_Renderer_Data *pd)
141{
142 return pd->mask;
143}
144
145static Eina_Bool
146_ector_renderer_prepare(Eo *obj EINA_UNUSED,
147 Ector_Renderer_Data *pd)
148{
149 if (pd->mask)
150 ector_renderer_prepare(pd->mask);
151
152 return EINA_TRUE;
153}
154
155static unsigned int 130static unsigned int
156_ector_renderer_crc_get(const Eo *obj EINA_UNUSED, 131_ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
157 Ector_Renderer_Data *pd) 132 Ector_Renderer_Data *pd)
@@ -162,9 +137,16 @@ _ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
162 crc = eina_crc((void*) &pd->origin, sizeof(pd->origin), crc, EINA_FALSE); 137 crc = eina_crc((void*) &pd->origin, sizeof(pd->origin), crc, EINA_FALSE);
163 138
164 if (pd->m) crc = eina_crc((void*) pd->m, sizeof(Eina_Matrix3), crc, EINA_FALSE); 139 if (pd->m) crc = eina_crc((void*) pd->m, sizeof(Eina_Matrix3), crc, EINA_FALSE);
165 if (pd->mask) crc = _renderer_crc_get(pd->mask, crc);
166 140
167 return crc; 141 return crc;
168} 142}
169 143
144static void
145_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
146 Ector_Renderer_Data *pd EINA_UNUSED,
147 Ector_Buffer *mask EINA_UNUSED,
148 int op EINA_UNUSED)
149{
150}
151
170#include "ector_renderer.eo.c" 152#include "ector_renderer.eo.c"
diff --git a/src/lib/ector/ector_renderer.eo b/src/lib/ector/ector_renderer.eo
index de669c0cc7..844ec1adaa 100644
--- a/src/lib/ector/ector_renderer.eo
+++ b/src/lib/ector/ector_renderer.eo
@@ -72,22 +72,21 @@ abstract Ector.Renderer (Efl.Object)
72 a: int; [[The alpha component of the given color.]] 72 a: int; [[The alpha component of the given color.]]
73 } 73 }
74 } 74 }
75 @property mask {
76 [[Rendering mask]]
77 set {
78 }
79 get {
80 }
81 values {
82 mask: Ector.Renderer; [[Rendering mask]]
83 }
84 }
85 @property crc { 75 @property crc {
86 [[Cyclic redundancy check]] 76 [[Cyclic redundancy check]]
87 get { 77 get {
88 return: uint; [[CRC value]] 78 return: uint; [[CRC value]]
89 } 79 }
90 } 80 }
81 @property mask {
82 [[Set Mask Image to this Renderer]]
83 set {
84 }
85 values {
86 mask: Ector.Buffer; [[Mask Image Buffer]]
87 op: int; [[Masking option]]
88 }
89 }
91 draw @pure_virtual { 90 draw @pure_virtual {
92 [[Actual draw operation]] 91 [[Actual draw operation]]
93 return: bool; [[$true on success, $false otherwise]] 92 return: bool; [[$true on success, $false otherwise]]
@@ -97,7 +96,7 @@ abstract Ector.Renderer (Efl.Object)
97 @in mul_col: uint; [[Premultiplied color]] 96 @in mul_col: uint; [[Premultiplied color]]
98 } 97 }
99 } 98 }
100 prepare { 99 prepare @pure_virtual {
101 [[Prepare for rendering]] 100 [[Prepare for rendering]]
102 return: bool; [[$true on success, $false otherwise]] 101 return: bool; [[$true on success, $false otherwise]]
103 } 102 }
diff --git a/src/lib/ector/software/ector_renderer_software_shape.c b/src/lib/ector/software/ector_renderer_software_shape.c
index 6749d5fcb9..396e47283e 100644
--- a/src/lib/ector/software/ector_renderer_software_shape.c
+++ b/src/lib/ector/software/ector_renderer_software_shape.c
@@ -38,6 +38,9 @@ struct _Ector_Renderer_Software_Shape_Data
38 Shape_Rle_Data *shape_data; 38 Shape_Rle_Data *shape_data;
39 Shape_Rle_Data *outline_data; 39 Shape_Rle_Data *outline_data;
40 40
41 Ector_Buffer *mask;
42 int mask_op;
43
41 Ector_Software_Shape_Task *task; 44 Ector_Software_Shape_Task *task;
42 45
43 Eina_Bool done; 46 Eina_Bool done;
@@ -223,7 +226,7 @@ static void _outline_transform(Outline *outline, Eina_Matrix3 *m)
223static Eina_Bool 226static Eina_Bool
224_generate_outline(const Efl_Gfx_Path_Command *cmds, const double *pts, Outline * outline) 227_generate_outline(const Efl_Gfx_Path_Command *cmds, const double *pts, Outline * outline)
225{ 228{
226 Eina_Bool close_path = EINA_FALSE; 229 Eina_Bool close_path = EINA_FALSE;
227 for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++) 230 for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
228 { 231 {
229 switch (*cmds) 232 switch (*cmds)
@@ -661,16 +664,18 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
661 x = pd->surface->x + (int)pd->base->origin.x; 664 x = pd->surface->x + (int)pd->base->origin.x;
662 y = pd->surface->y + (int)pd->base->origin.y; 665 y = pd->surface->y + (int)pd->base->origin.y;
663 666
664 // fill the span_data structure
665 ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips); 667 ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips);
666 ector_software_rasterizer_transform_set(pd->surface->rasterizer, pd->base->m); 668 ector_software_rasterizer_transform_set(pd->surface->rasterizer, pd->base->m);
667 669
670 // fill the span_data structure
668 if (pd->shape->fill) 671 if (pd->shape->fill)
669 { 672 {
670 ector_renderer_software_op_fill(pd->shape->fill); 673 ector_renderer_software_op_fill(pd->shape->fill);
671 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer, 674 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
672 x, y, mul_col, op, 675 x, y, mul_col, op,
673 pd->shape_data); 676 pd->shape_data,
677 pd->mask,
678 pd->mask_op);
674 } 679 }
675 else 680 else
676 { 681 {
@@ -683,16 +688,22 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
683 pd->base->color.a); 688 pd->base->color.a);
684 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer, 689 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
685 x, y, mul_col, op, 690 x, y, mul_col, op,
686 pd->shape_data); 691 pd->shape_data,
692 pd->mask,
693 pd->mask_op);
687 } 694 }
688 } 695 }
689 696
697 if (!pd->outline_data) return EINA_TRUE;
698
690 if (pd->shape->stroke.fill) 699 if (pd->shape->stroke.fill)
691 { 700 {
692 ector_renderer_software_op_fill(pd->shape->stroke.fill); 701 ector_renderer_software_op_fill(pd->shape->stroke.fill);
693 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer, 702 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
694 x, y, mul_col, op, 703 x, y, mul_col, op,
695 pd->outline_data); 704 pd->outline_data,
705 pd->mask,
706 pd->mask_op);
696 } 707 }
697 else 708 else
698 { 709 {
@@ -705,7 +716,9 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
705 pd->public_shape->stroke.color.a); 716 pd->public_shape->stroke.color.a);
706 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer, 717 ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
707 x, y, mul_col, op, 718 x, y, mul_col, op,
708 pd->outline_data); 719 pd->outline_data,
720 pd->mask,
721 pd->mask_op);
709 } 722 }
710 } 723 }
711 724
@@ -831,4 +844,15 @@ _ector_renderer_software_shape_ector_renderer_crc_get(const Eo *obj,
831 return crc; 844 return crc;
832} 845}
833 846
847static void
848_ector_renderer_software_shape_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
849 Ector_Renderer_Software_Shape_Data *pd,
850 Ector_Buffer *mask,
851 int op)
852{
853 //Use ref/unref.
854 pd->mask = mask;
855 pd->mask_op = op;
856}
857
834#include "ector_renderer_software_shape.eo.c" 858#include "ector_renderer_software_shape.eo.c"
diff --git a/src/lib/ector/software/ector_renderer_software_shape.eo b/src/lib/ector/software/ector_renderer_software_shape.eo
index 97b15ca153..abe8344f3f 100644
--- a/src/lib/ector/software/ector_renderer_software_shape.eo
+++ b/src/lib/ector/software/ector_renderer_software_shape.eo
@@ -6,6 +6,7 @@ class Ector.Renderer.Software.Shape (Ector.Renderer.Software, Ector.Renderer.Sha
6 Ector.Renderer.prepare; 6 Ector.Renderer.prepare;
7 Ector.Renderer.draw; 7 Ector.Renderer.draw;
8 Ector.Renderer.Software.op_fill; 8 Ector.Renderer.Software.op_fill;
9 Ector.Renderer.mask { set; }
9 Ector.Renderer.crc { get; } 10 Ector.Renderer.crc { get; }
10 Efl.Gfx.Path.path { set; } 11 Efl.Gfx.Path.path { set; }
11 Efl.Object.constructor; 12 Efl.Object.constructor;
diff --git a/src/lib/ector/software/ector_software_buffer.c b/src/lib/ector/software/ector_software_buffer.c
index e8981281f5..e7d288e1e1 100644
--- a/src/lib/ector/software/ector_software_buffer.c
+++ b/src/lib/ector/software/ector_software_buffer.c
@@ -76,8 +76,8 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff
76{ 76{
77 unsigned pxs; 77 unsigned pxs;
78 78
79 if (pd->generic->immutable) 79 //if (pd->generic->immutable)
80 fail("This buffer is immutable."); 80// fail("This buffer is immutable.");
81 81
82 if (pd->internal.maps) 82 if (pd->internal.maps)
83 fail("Can not call pixels_set when the buffer is mapped."); 83 fail("Can not call pixels_set when the buffer is mapped.");
diff --git a/src/lib/ector/software/ector_software_private.h b/src/lib/ector/software/ector_software_private.h
index dad1f9948c..34ea0038b7 100644
--- a/src/lib/ector/software/ector_software_private.h
+++ b/src/lib/ector/software/ector_software_private.h
@@ -82,9 +82,11 @@ typedef struct _Span_Data
82 82
83 int offx, offy; 83 int offx, offy;
84 Clip_Data clip; 84 Clip_Data clip;
85 Ector_Software_Buffer_Base_Data *mask;
86 int mask_op;
85 Eina_Matrix3 inv; 87 Eina_Matrix3 inv;
86 Span_Data_Type type; 88 Span_Data_Type type;
87 Eina_Bool fast_matrix ; 89 Eina_Bool fast_matrix;
88 uint32_t mul_col; 90 uint32_t mul_col;
89 Efl_Gfx_Render_Op op; 91 Efl_Gfx_Render_Op op;
90 union { 92 union {
@@ -129,7 +131,12 @@ void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, S
129Shape_Rle_Data * ector_software_rasterizer_generate_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline); 131Shape_Rle_Data * ector_software_rasterizer_generate_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline);
130Shape_Rle_Data * ector_software_rasterizer_generate_stroke_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath); 132Shape_Rle_Data * ector_software_rasterizer_generate_stroke_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath);
131 133
132void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, int x, int y, uint32_t mul_col, Efl_Gfx_Render_Op op, Shape_Rle_Data* rle); 134void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
135 int x, int y, uint32_t mul_col,
136 Efl_Gfx_Render_Op op,
137 Shape_Rle_Data* rle,
138 Ector_Buffer *mask,
139 int mask_op);
133 140
134void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle); 141void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
135 142
diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c
index 25169be790..7a03bb69f2 100644
--- a/src/lib/ector/software/ector_software_rasterizer.c
+++ b/src/lib/ector/software/ector_software_rasterizer.c
@@ -14,22 +14,100 @@
14static void 14static void
15_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) 15_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
16{ 16{
17 RGBA_Comp_Func_Solid comp_func; 17 Span_Data *sd = user_data;
18 Span_Data *data = (Span_Data *)(user_data);
19 uint32_t color, *buffer, *target; 18 uint32_t color, *buffer, *target;
20 const int pix_stride = data->raster_buffer->stride / 4; 19 const int pix_stride = sd->raster_buffer->stride / 4;
21 20
22 // multiply the color with mul_col if any 21 // multiply the color with mul_col if any
23 color = DRAW_MUL4_SYM(data->color, data->mul_col); 22 color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
24 comp_func = efl_draw_func_solid_span_get(data->op, color); 23 RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
25 24
26 // move to the offset location 25 // move to the offset location
27 buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx); 26 buffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
27
28 while (count--)
29 {
30 target = buffer + ((pix_stride * spans->y) + spans->x);
31 comp_func(target, spans->len, color, spans->coverage);
32 ++spans;
33 }
34}
35
36static void
37_blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data)
38{
39 Span_Data *sd = user_data;
40 const int pix_stride = sd->raster_buffer->stride / 4;
41 Ector_Software_Buffer_Base_Data *mask = sd->mask;
42
43 // multiply the color with mul_col if any
44 uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
45 RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
46
47 // move to the offset location
48 uint32_t *buffer =
49 sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
50 uint32_t *mbuffer = mask->pixels.u32;
28 51
29 while (count--) 52 while (count--)
30 { 53 {
31 target = buffer + ((pix_stride * spans->y) + spans->x); 54 uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
32 comp_func(target, spans->len, color, spans->coverage); 55 uint32_t *mtarget =
56 mbuffer + ((mask->generic->w * spans->y) + spans->x);
57 uint32_t *temp = alloca(sizeof(uint32_t) * spans->len);
58 memset(temp, 0x00, sizeof(uint32_t) * spans->len);
59 comp_func(temp, spans->len, color, spans->coverage);
60
61 //masking
62 for (int i = 0; i < spans->len; i++)
63 {
64 *temp = draw_mul_256(((*mtarget)>>24), *temp);
65 int alpha = 255 - ((*temp) >> 24);
66 *target = *temp + draw_mul_256(alpha, *target);
67 ++temp;
68 ++mtarget;
69 ++target;
70 }
71 ++spans;
72 }
73}
74
75static void
76_blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data)
77{
78 Span_Data *sd = user_data;
79 const int pix_stride = sd->raster_buffer->stride / 4;
80 Ector_Software_Buffer_Base_Data *mask = sd->mask;
81
82 // multiply the color with mul_col if any
83 uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
84 RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
85
86 // move to the offset location
87 uint32_t *buffer =
88 sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
89 uint32_t *mbuffer = mask->pixels.u32;
90
91 while (count--)
92 {
93 uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
94 uint32_t *mtarget =
95 mbuffer + ((mask->generic->w * spans->y) + spans->x);
96 uint32_t *temp = alloca(sizeof(uint32_t) * spans->len);
97 memset(temp, 0x00, sizeof(uint32_t) * spans->len);
98 comp_func(temp, spans->len, color, spans->coverage);
99
100 //masking
101 for (int i = 0; i < spans->len; i++)
102 {
103 if (*mtarget)
104 *temp = draw_mul_256((255 - ((*mtarget)>>24)), *temp);
105 int alpha = 255 - ((*temp) >> 24);
106 *target = *temp + draw_mul_256(alpha, *target);
107 ++temp;
108 ++mtarget;
109 ++target;
110 }
33 ++spans; 111 ++spans;
34 } 112 }
35} 113}
@@ -267,13 +345,24 @@ _span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
267static void 345static void
268_adjust_span_fill_methods(Span_Data *spdata) 346_adjust_span_fill_methods(Span_Data *spdata)
269{ 347{
348 //Blending Function
270 switch(spdata->type) 349 switch(spdata->type)
271 { 350 {
272 case None: 351 case None:
273 spdata->unclipped_blend = 0; 352 spdata->unclipped_blend = NULL;
274 break; 353 break;
275 case Solid: 354 case Solid:
276 spdata->unclipped_blend = &_blend_color_argb; 355 {
356 if (spdata->mask)
357 {
358 if (spdata->mask_op == 2)
359 spdata->unclipped_blend = &_blend_color_argb_with_maskInvA;
360 else
361 spdata->unclipped_blend = &_blend_color_argb_with_maskA;
362 }
363 else
364 spdata->unclipped_blend = &_blend_color_argb;
365 }
277 break; 366 break;
278 case LinearGradient: 367 case LinearGradient:
279 case RadialGradient: 368 case RadialGradient:
@@ -539,17 +628,22 @@ ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer,
539 rasterizer->fill_data.type = RadialGradient; 628 rasterizer->fill_data.type = RadialGradient;
540} 629}
541 630
542void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, 631void
543 int x, int y, uint32_t mul_col, 632ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
544 Efl_Gfx_Render_Op op, Shape_Rle_Data* rle) 633 int x, int y, uint32_t mul_col,
634 Efl_Gfx_Render_Op op, Shape_Rle_Data* rle,
635 Ector_Buffer *mask,
636 int mask_op)
545{ 637{
546 // check for NULL rle data
547 if (!rle) return; 638 if (!rle) return;
548 639
549 rasterizer->fill_data.offx = x; 640 rasterizer->fill_data.offx = x;
550 rasterizer->fill_data.offy = y; 641 rasterizer->fill_data.offy = y;
551 rasterizer->fill_data.mul_col = mul_col; 642 rasterizer->fill_data.mul_col = mul_col;
552 rasterizer->fill_data.op = op; 643 rasterizer->fill_data.op = op;
644 rasterizer->fill_data.mask =
645 mask ? efl_data_scope_get(mask, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN) : NULL;
646 rasterizer->fill_data.mask_op = mask_op;
553 647
554 _setup_span_fill_matrix(rasterizer); 648 _setup_span_fill_matrix(rasterizer);
555 _adjust_span_fill_methods(&rasterizer->fill_data); 649 _adjust_span_fill_methods(&rasterizer->fill_data);
diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c
index ccb8bfbf76..addbf0cbc9 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_container.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_container.c
@@ -22,17 +22,75 @@ _invalidate_cb(void *data EINA_UNUSED, const Efl_Event *event)
22 efl_unref(child); 22 efl_unref(child);
23} 23}
24 24
25static Ector_Buffer *
26_prepare_mask(Evas_Object_Protected_Data *obj, //vector object
27 Efl_Canvas_Vg_Node* mask_obj,
28 Ector_Surface *surface,
29 Eina_Matrix3 *ptransform,
30 Ector_Buffer *mask,
31 int mask_op)
32{
33 Efl_Canvas_Vg_Container_Data *pd = efl_data_scope_get(mask_obj, MY_CLASS);
34 Efl_Canvas_Vg_Node_Data *nd =
35 efl_data_scope_get(mask_obj, EFL_CANVAS_VG_NODE_CLASS);
36 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return pd->mask.buffer;
37
38 //1. Mask Size
39 Eina_Rect mbound;
40 mbound.x = 0;
41 mbound.y = 0;
42 mbound.w = obj->cur->geometry.w;
43 mbound.h = obj->cur->geometry.h;
44
45// efl_gfx_path_bounds_get(mask, &mbound);
46
47 //2. Reusable ector buffer?
48 if (!pd->mask.buffer || (pd->mask.bound.w != mbound.w) ||
49 (pd->mask.bound.h != mbound.h))
50 {
51 if (pd->mask.pixels) free(pd->mask.pixels);
52 if (pd->mask.buffer) efl_unref(pd->mask.buffer);
53 pd->mask.pixels = calloc(sizeof(uint32_t), mbound.w * mbound.h);
54 pd->mask.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas,
55 mbound.w, mbound.h,
56 EFL_GFX_COLORSPACE_ARGB8888,
57 ECTOR_BUFFER_FLAG_DRAWABLE |
58 ECTOR_BUFFER_FLAG_CPU_READABLE |
59 ECTOR_BUFFER_FLAG_CPU_WRITABLE);
60 ector_buffer_pixels_set(pd->mask.buffer, pd->mask.pixels,
61 mbound.w, mbound.h, 0,
62 EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
63 pd->mask.bound.w = mbound.w;
64 pd->mask.bound.h = mbound.h;
65 pd->mask.vg_pd = obj;
66 }
67
68 pd->mask.bound.x = mbound.x;
69 pd->mask.bound.y = mbound.y;
70
71 if (!pd->mask.buffer) ERR("Mask Buffer is invalid");
72
73 pd->mask.dirty = EINA_TRUE;
74
75 //3. Prepare Drawing shapes...
76 _evas_vg_render_pre(obj, mask_obj, surface, ptransform, mask, mask_op);
77
78 return pd->mask.buffer;
79}
80
25static void 81static void
26_efl_canvas_vg_container_render_pre(Eo *obj EINA_UNUSED, 82_efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
27 Eina_Matrix3 *parent, 83 Efl_VG *obj EINA_UNUSED,
28 Ector_Surface *s, 84 Efl_Canvas_Vg_Node_Data *nd,
29 void *data, 85 Ector_Surface *surface,
30 Efl_Canvas_Vg_Node_Data *nd) 86 Eina_Matrix3 *ptransform,
87 Ector_Buffer *mask,
88 int mask_op,
89 void *data)
31{ 90{
32 Efl_Canvas_Vg_Container_Data *pd = data; 91 Efl_Canvas_Vg_Container_Data *pd = data;
33 Eina_List *l; 92 Eina_List *l;
34 Eo *child; 93 Efl_VG *child;
35 Efl_Canvas_Vg_Node_Data *child_nd;
36 Efl_Gfx_Change_Flag flag; 94 Efl_Gfx_Change_Flag flag;
37 95
38 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return; 96 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
@@ -40,20 +98,37 @@ _efl_canvas_vg_container_render_pre(Eo *obj EINA_UNUSED,
40 flag = nd->flags; 98 flag = nd->flags;
41 nd->flags = EFL_GFX_CHANGE_FLAG_NONE; 99 nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
42 100
43 EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd); 101 EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
102
103 //Container may have mask source.
104 if (pd->mask_src)
105 {
106 mask = _prepare_mask(vg_pd, pd->mask_src, surface, ptransform, mask,
107 mask_op);
108 mask_op = pd->mask.option;
109 }
44 110
45 EINA_LIST_FOREACH(pd->children, l, child) 111 EINA_LIST_FOREACH(pd->children, l, child)
46 { 112 {
113 //Don't need to update mask nodes.
114 if (efl_isa(child, MY_CLASS))
115 {
116 Efl_Canvas_Vg_Container_Data *child_cd =
117 efl_data_scope_get(child, MY_CLASS);
118 if (child_cd->mask.target) continue;
119 }
120
47 //Skip Gradients. they will be updated by Shape. 121 //Skip Gradients. they will be updated by Shape.
48 if (efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS)) 122 if (efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
49 continue; 123 continue;
50 124
125 Efl_Canvas_Vg_Node_Data *child_nd =
126 efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
127
51 if (flag & EFL_GFX_CHANGE_FLAG_MATRIX) 128 if (flag & EFL_GFX_CHANGE_FLAG_MATRIX)
52 { 129 child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
53 child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS); 130
54 child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX; 131 _evas_vg_render_pre(vg_pd, child, surface, ctransform, mask, mask_op);
55 }
56 _evas_vg_render_pre(child, s, current);
57 } 132 }
58} 133}
59 134
@@ -77,16 +152,23 @@ _efl_canvas_vg_container_efl_object_constructor(Eo *obj,
77 152
78static void 153static void
79_efl_canvas_vg_container_efl_object_destructor(Eo *obj, 154_efl_canvas_vg_container_efl_object_destructor(Eo *obj,
80 Efl_Canvas_Vg_Container_Data *pd EINA_UNUSED) 155 Efl_Canvas_Vg_Container_Data *pd)
81{ 156{
82 efl_destructor(efl_super(obj, MY_CLASS)); 157 //Destroy mask surface
158 if (pd->mask.buffer) efl_unref(pd->mask.buffer);
159 if (pd->mask.pixels) free(pd->mask.pixels);
160
161 efl_unref(pd->mask_src);
162 eina_list_free(pd->mask.target);
83 eina_hash_free(pd->names); 163 eina_hash_free(pd->names);
164
165 efl_destructor(efl_super(obj, MY_CLASS));
84} 166}
85 167
86static void 168static void
87_efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo *obj EINA_UNUSED, 169_efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo *obj EINA_UNUSED,
88 Efl_Canvas_Vg_Container_Data *pd, 170 Efl_Canvas_Vg_Container_Data *pd,
89 Eina_Rect *r) 171 Eina_Rect *r)
90{ 172{
91 Eina_Rect s; 173 Eina_Rect s;
92 Eina_Bool first = EINA_TRUE; 174 Eina_Bool first = EINA_TRUE;
@@ -162,12 +244,51 @@ _efl_canvas_vg_container_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Contain
162 if (!r) break; 244 if (!r) break;
163 } 245 }
164 246
247 //Interpolates Mask
248 Efl_Canvas_Vg_Container_Data *fromd = efl_data_scope_get(from, MY_CLASS);
249 Efl_Canvas_Vg_Container_Data *tod = efl_data_scope_get(to, MY_CLASS);
250
251 if (fromd->mask_src && tod->mask_src && pd->mask_src)
252 {
253 if (!efl_gfx_path_interpolate(pd->mask_src,
254 fromd->mask_src, tod->mask_src, pos_map))
255 return EINA_FALSE;
256 }
257
165 eina_iterator_free(from_it); 258 eina_iterator_free(from_it);
166 eina_iterator_free(to_it); 259 eina_iterator_free(to_it);
167 260
168 return r; 261 return r;
169} 262}
170 263
264static void
265_efl_canvas_vg_container_efl_canvas_vg_node_mask_set(Eo *obj,
266 Efl_Canvas_Vg_Container_Data *pd,
267 Efl_Canvas_Vg_Node *mask,
268 int op)
269{
270 if (pd->mask_src == mask) return;
271
272 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(mask, MY_CLASS));
273
274 if (pd->mask_src)
275 {
276 Efl_Canvas_Vg_Container_Data *pd2 =
277 efl_data_scope_get(pd->mask_src, MY_CLASS);
278 pd2->mask.target = eina_list_remove(pd2->mask.target, obj);
279 }
280
281 if (mask)
282 {
283 Efl_Canvas_Vg_Container_Data *pd2 = efl_data_scope_get(mask, MY_CLASS);
284 pd2->mask.target = eina_list_append(pd2->mask.target, obj);
285 }
286
287 pd->mask.option = op;
288 efl_replace(&pd->mask_src, mask);
289 _efl_canvas_vg_node_changed(obj);
290}
291
171EOLIAN static Efl_VG * 292EOLIAN static Efl_VG *
172_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj, 293_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
173 Efl_Canvas_Vg_Container_Data *pd) 294 Efl_Canvas_Vg_Container_Data *pd)
@@ -180,6 +301,14 @@ _efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
180 efl_event_callback_add(container, EFL_EVENT_INVALIDATE, _invalidate_cb, NULL); 301 efl_event_callback_add(container, EFL_EVENT_INVALIDATE, _invalidate_cb, NULL);
181 efl_parent_set(container, efl_parent_get(obj)); 302 efl_parent_set(container, efl_parent_get(obj));
182 303
304 //Copy Mask
305 if (pd->mask_src)
306 {
307 Eo * mask_src = efl_duplicate(pd->mask_src);
308 efl_parent_set(mask_src, container);
309 efl_canvas_vg_node_mask_set(container, mask_src, pd->mask.option);
310 }
311
183 //Copy Children 312 //Copy Children
184 EINA_LIST_FOREACH(pd->children, l, child) 313 EINA_LIST_FOREACH(pd->children, l, child)
185 { 314 {
diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.eo b/src/lib/evas/canvas/efl_canvas_vg_container.eo
index f89d584d86..4060441d44 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_container.eo
+++ b/src/lib/evas/canvas/efl_canvas_vg_container.eo
@@ -4,14 +4,14 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
4 legacy_prefix: evas_vg_container; 4 legacy_prefix: evas_vg_container;
5 methods { 5 methods {
6 child_get { 6 child_get {
7 [[Get child of container]] 7 [[Get child of container]]
8 params { 8 params {
9 @in name: string; [[Child node name]] 9 @in name: string; [[Child node name]]
10 } 10 }
11 return: Efl.Canvas.Vg.Node; [[Child object]] 11 return: Efl.Canvas.Vg.Node; [[Child object]]
12 } 12 }
13 children_get { 13 children_get {
14 [[Get all children of container]] 14 [[Get all children of container]]
15 return: iterator<Efl.Canvas.Vg.Node> @owned @warn_unused; [[Iterator to children]] 15 return: iterator<Efl.Canvas.Vg.Node> @owned @warn_unused; [[Iterator to children]]
16 } 16 }
17 } 17 }
@@ -21,5 +21,6 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
21 Efl.Gfx.Path.bounds_get; 21 Efl.Gfx.Path.bounds_get;
22 Efl.Gfx.Path.interpolate; 22 Efl.Gfx.Path.interpolate;
23 Efl.Duplicate.duplicate; 23 Efl.Duplicate.duplicate;
24 Efl.Canvas.Vg.Node.mask { set; }
24 } 25 }
25} 26}
diff --git a/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c b/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c
index 391f9c81b5..fa35d29153 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c
@@ -56,30 +56,33 @@ _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(const Eo *obj EIN
56} 56}
57 57
58static void 58static void
59_efl_canvas_vg_gradient_linear_render_pre(Eo *obj, 59_efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
60 Eina_Matrix3 *parent, 60 Efl_VG *obj,
61 Ector_Surface *s, 61 Efl_Canvas_Vg_Node_Data *nd,
62 void *data, 62 Ector_Surface *surface,
63 Efl_Canvas_Vg_Node_Data *nd) 63 Eina_Matrix3 *ptransform,
64 Ector_Buffer *mask,
65 int mask_op,
66 void *data)
64{ 67{
65 Efl_Canvas_Vg_Gradient_Linear_Data *pd = data; 68 Efl_Canvas_Vg_Gradient_Linear_Data *pd = data;
66 Efl_Canvas_Vg_Gradient_Data *gd; 69 Efl_Canvas_Vg_Gradient_Data *gd;
67 70
68 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ; 71 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
69 72
70 nd->flags = EFL_GFX_CHANGE_FLAG_NONE; 73 nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
71 74
72 gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS); 75 gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
73 EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd); 76 EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
74 77
75 if (!nd->renderer) 78 if (!nd->renderer)
76 { 79 {
77 efl_domain_current_push(EFL_ID_DOMAIN_SHARED); 80 efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
78 nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN); 81 nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN);
79 efl_domain_current_pop(); 82 efl_domain_current_pop();
80 } 83 }
81 84
82 ector_renderer_transformation_set(nd->renderer, current); 85 ector_renderer_transformation_set(nd->renderer, ctransform);
83 ector_renderer_origin_set(nd->renderer, nd->x, nd->y); 86 ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
84 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); 87 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
85 ector_renderer_visibility_set(nd->renderer, nd->visibility); 88 ector_renderer_visibility_set(nd->renderer, nd->visibility);
@@ -87,8 +90,8 @@ _efl_canvas_vg_gradient_linear_render_pre(Eo *obj,
87 efl_gfx_gradient_spread_set(nd->renderer, gd->spread); 90 efl_gfx_gradient_spread_set(nd->renderer, gd->spread);
88 efl_gfx_gradient_linear_start_set(nd->renderer, pd->start.x, pd->start.y); 91 efl_gfx_gradient_linear_start_set(nd->renderer, pd->start.x, pd->start.y);
89 efl_gfx_gradient_linear_end_set(nd->renderer, pd->end.x, pd->end.y); 92 efl_gfx_gradient_linear_end_set(nd->renderer, pd->end.x, pd->end.y);
90
91 ector_renderer_prepare(nd->renderer); 93 ector_renderer_prepare(nd->renderer);
94 ector_renderer_mask_set(nd->renderer, mask, mask_op);
92} 95}
93 96
94static Eo * 97static Eo *
diff --git a/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c b/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c
index 6a72b7e4da..9ff537e2ed 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c
@@ -72,11 +72,14 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_focal_get(const Eo *obj E
72} 72}
73 73
74static void 74static void
75_efl_canvas_vg_gradient_radial_render_pre(Eo *obj, 75_efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
76 Eina_Matrix3 *parent, 76 Efl_VG *obj,
77 Ector_Surface *s, 77 Efl_Canvas_Vg_Node_Data *nd,
78 void *data, 78 Ector_Surface *surface,
79 Efl_Canvas_Vg_Node_Data *nd) 79 Eina_Matrix3 *ptransform,
80 Ector_Buffer *mask,
81 int mask_op,
82 void *data)
80{ 83{
81 Efl_Canvas_Vg_Gradient_Radial_Data *pd = data; 84 Efl_Canvas_Vg_Gradient_Radial_Data *pd = data;
82 Efl_Canvas_Vg_Gradient_Data *gd; 85 Efl_Canvas_Vg_Gradient_Data *gd;
@@ -86,16 +89,16 @@ _efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
86 nd->flags = EFL_GFX_CHANGE_FLAG_NONE; 89 nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
87 90
88 gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS); 91 gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
89 EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd); 92 EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
90 93
91 if (!nd->renderer) 94 if (!nd->renderer)
92 { 95 {
93 efl_domain_current_push(EFL_ID_DOMAIN_SHARED); 96 efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
94 nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN); 97 nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN);
95 efl_domain_current_pop(); 98 efl_domain_current_pop();
96 } 99 }
97 100
98 ector_renderer_transformation_set(nd->renderer, current); 101 ector_renderer_transformation_set(nd->renderer, ctransform);
99 ector_renderer_origin_set(nd->renderer, nd->x, nd->y); 102 ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
100 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); 103 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
101 ector_renderer_visibility_set(nd->renderer, nd->visibility); 104 ector_renderer_visibility_set(nd->renderer, nd->visibility);
@@ -104,8 +107,8 @@ _efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
104 efl_gfx_gradient_radial_center_set(nd->renderer, pd->center.x, pd->center.y); 107 efl_gfx_gradient_radial_center_set(nd->renderer, pd->center.x, pd->center.y);
105 efl_gfx_gradient_radial_focal_set(nd->renderer, pd->focal.x, pd->focal.y); 108 efl_gfx_gradient_radial_focal_set(nd->renderer, pd->focal.x, pd->focal.y);
106 efl_gfx_gradient_radial_radius_set(nd->renderer, pd->radius); 109 efl_gfx_gradient_radial_radius_set(nd->renderer, pd->radius);
107
108 ector_renderer_prepare(nd->renderer); 110 ector_renderer_prepare(nd->renderer);
111 ector_renderer_mask_set(nd->renderer, mask, mask_op);
109} 112}
110 113
111static Eo * 114static Eo *
diff --git a/src/lib/evas/canvas/efl_canvas_vg_node.c b/src/lib/evas/canvas/efl_canvas_vg_node.c
index e7ef736528..dc2c4a3a09 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_node.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_node.c
@@ -66,6 +66,14 @@ _efl_canvas_vg_node_transformation_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_
66} 66}
67 67
68static void 68static void
69_efl_canvas_vg_node_mask_set(Eo *obj EINA_UNUSED,
70 Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
71 Efl_Canvas_Vg_Node *mask EINA_UNUSED,
72 int op EINA_UNUSED)
73{
74}
75
76static void
69_efl_canvas_vg_node_origin_set(Eo *obj, 77_efl_canvas_vg_node_origin_set(Eo *obj,
70 Efl_Canvas_Vg_Node_Data *pd, 78 Efl_Canvas_Vg_Node_Data *pd,
71 double x, double y) 79 double x, double y)
@@ -166,25 +174,6 @@ _efl_canvas_vg_node_efl_gfx_color_color_get(const Eo *obj EINA_UNUSED,
166 if (a) *a = pd->a; 174 if (a) *a = pd->a;
167} 175}
168 176
169static void
170_efl_canvas_vg_node_mask_set(Eo *obj EINA_UNUSED,
171 Efl_Canvas_Vg_Node_Data *pd,
172 Efl_VG *r)
173{
174 Efl_VG *tmp = pd->mask;
175
176 pd->mask = efl_ref(r);
177 efl_unref(tmp);
178
179 _efl_canvas_vg_node_changed(obj);
180}
181
182static Efl_VG*
183_efl_canvas_vg_node_mask_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Node_Data *pd)
184{
185 return pd->mask;
186}
187
188static Eina_Size2D 177static Eina_Size2D
189_efl_canvas_vg_node_efl_gfx_entity_size_get(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED) 178_efl_canvas_vg_node_efl_gfx_entity_size_get(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED)
190{ 179{
@@ -711,14 +700,6 @@ _efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Node_Data *p
711 700
712 pd->visibility = pos_map >= 0.5 ? tod->visibility : fromd->visibility; 701 pd->visibility = pos_map >= 0.5 ? tod->visibility : fromd->visibility;
713 702
714 //Interpolates Mask
715 if (fromd->mask && tod->mask && pd->mask)
716 {
717 if (!efl_gfx_path_interpolate(pd->mask,
718 fromd->mask, tod->mask, pos_map))
719 return EINA_FALSE;
720 }
721
722 _efl_canvas_vg_node_changed(obj); 703 _efl_canvas_vg_node_changed(obj);
723 704
724 return EINA_TRUE; 705 return EINA_TRUE;
@@ -750,12 +731,6 @@ _efl_canvas_vg_node_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Node_Da
750 if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3)); 731 if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3));
751 } 732 }
752 733
753 if (pd->mask)
754 {
755 nd->mask = efl_duplicate(pd->mask);
756 efl_parent_set(nd->mask, node);
757 }
758
759 nd->x = pd->x; 734 nd->x = pd->x;
760 nd->y = pd->y; 735 nd->y = pd->y;
761 nd->r = pd->r; 736 nd->r = pd->r;
diff --git a/src/lib/evas/canvas/efl_canvas_vg_node.eo b/src/lib/evas/canvas/efl_canvas_vg_node.eo
index 6b720c2c53..361fe741d7 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_node.eo
+++ b/src/lib/evas/canvas/efl_canvas_vg_node.eo
@@ -42,13 +42,12 @@ abstract Efl.Canvas.Vg.Node (Efl.Object, Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.
42 } 42 }
43 } 43 }
44 @property mask { 44 @property mask {
45 [[Vector graphics object mask]] 45 [[Set Mask Node to this renderer]]
46 set { 46 set {
47 } 47 }
48 get {
49 }
50 values { 48 values {
51 m: Efl.Canvas.Vg.Node; [[Object mask]] 49 mask: Efl.Canvas.Vg.Node; [[Mask object]]
50 op: int; [[Masking Option. Reserved]]
52 } 51 }
53 } 52 }
54 } 53 }
diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c
index a227c6bd9f..ac45c6d791 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_object.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_object.c
@@ -371,37 +371,71 @@ _efl_canvas_vg_object_efl_object_finalize(Eo *obj, Efl_Canvas_Vg_Object_Data *pd
371 371
372static void 372static void
373_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, 373_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
374 void *engine, void *output, void *context, void *surface, Efl_VG *n, 374 void *engine, void *output, void *context, Efl_VG *node,
375 Eina_Array *clips, Eina_Bool do_async) 375 Eina_Array *clips, Eina_Bool do_async)
376{ 376{
377 if (efl_isa(n, EFL_CANVAS_VG_CONTAINER_CLASS)) 377 if (efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS))
378 { 378 {
379 Efl_Canvas_Vg_Container_Data *vc; 379 Efl_Canvas_Vg_Container_Data *cd =
380 efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS);
381
382 //Update Mask Image
383 if (cd->mask_src)
384 {
385 Efl_Canvas_Vg_Container_Data *cd2 =
386 efl_data_scope_get(cd->mask_src, EFL_CANVAS_VG_CONTAINER_CLASS);
387
388 if (cd2->mask.buffer && cd2->mask.dirty)
389 {
390 Ector_Surface *ector = evas_ector_get(obj->layer->evas);
391 if (!ector) return;
392
393 ENFN->ector_end(engine, output, context, ector, EINA_FALSE);
394
395 //Need a better approach.
396 ector_buffer_pixels_set(ector, cd2->mask.pixels, cd2->mask.bound.w, cd2->mask.bound.h, 0,
397 EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
398 ector_surface_reference_point_set(ector, -cd2->mask.bound.x, -cd2->mask.bound.y);
399
400 //Draw Mask Image.
401 Efl_VG *child;
402 Eina_List *l;
403 EINA_LIST_FOREACH(cd2->children, l, child)
404 _evas_vg_render(obj, pd, engine, output, context, child,
405 clips, EINA_FALSE);
406
407 cd2->mask.dirty = EINA_FALSE;
408#if 0
409 FILE *fp = fopen("./test.raw", "w+");
410 fwrite(cd2->mask.pixels, cd2->mask.bound.w * cd2->mask.bound.h, sizeof(uint32_t), fp);
411 fclose(fp);
412 ERR("size = %d x %d", cd2->mask.bound.w, cd2->mask.bound.h);
413#endif
414 //Restore previous ector context
415 ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async);
416 }
417 }
418
419 if (cd->mask.target) return; //Don't draw mask itself.
420
380 Efl_VG *child; 421 Efl_VG *child;
381 Eina_List *l; 422 Eina_List *l;
382 423
383 vc = efl_data_scope_get(n, EFL_CANVAS_VG_CONTAINER_CLASS); 424 EINA_LIST_FOREACH(cd->children, l, child)
384 425 _evas_vg_render(obj, pd, engine, output, context, child, clips, do_async);
385 EINA_LIST_FOREACH(vc->children, l, child)
386 _evas_vg_render(obj, pd,
387 engine, output, context, surface, child,
388 clips, do_async);
389 } 426 }
390 else 427 else
391 { 428 {
392 Efl_Canvas_Vg_Node_Data *nd; 429 Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(node, EFL_CANVAS_VG_NODE_CLASS);
393 nd = efl_data_scope_get(n, EFL_CANVAS_VG_NODE_CLASS); 430 ENFN->ector_renderer_draw(engine, output, context, nd->renderer, clips, do_async);
394 obj->layer->evas->engine.func->ector_renderer_draw(engine, output, context, surface, nd->renderer, clips, do_async); 431 if (do_async) eina_array_push(&pd->cleanup, efl_ref(nd->renderer));
395 if (do_async)
396 eina_array_push(&pd->cleanup, efl_ref(nd->renderer));
397 } 432 }
398} 433}
399 434
400//renders a vg_tree to an offscreen buffer and push it to the cache. 435//renders a vg_tree to an offscreen buffer and push it to the cache.
401static void * 436static void *
402_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, 437_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
403 void *engine, void *surface, 438 void *engine, Efl_VG *root, int w, int h, void *key,
404 Efl_VG *root, int w, int h, void *key,
405 void *buffer, Eina_Bool do_async) 439 void *buffer, Eina_Bool do_async)
406{ 440{
407 Ector_Surface *ector; 441 Ector_Surface *ector;
@@ -420,29 +454,24 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
420 buffer_created = EINA_TRUE; 454 buffer_created = EINA_TRUE;
421 } 455 }
422 456
423 _evas_vg_render_pre(root, ector, NULL); 457 _evas_vg_render_pre(obj, root, ector, NULL, NULL, 0);
424 458
425 //initialize buffer 459 //initialize buffer
426 context = evas_common_draw_context_new(); 460 context = evas_common_draw_context_new();
427 evas_common_draw_context_set_render_op(context, _EVAS_RENDER_COPY); 461 evas_common_draw_context_set_render_op(context, _EVAS_RENDER_COPY);
428 evas_common_draw_context_set_color(context, 255, 255, 255, 255); 462 evas_common_draw_context_set_color(context, 255, 255, 255, 255);
429 obj->layer->evas->engine.func->ector_begin(engine, buffer, 463
430 context, surface, 464 ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_TRUE, do_async);
431 ector, 465
432 0, 0,
433 do_async);
434 //draw on buffer 466 //draw on buffer
435 _evas_vg_render(obj, pd, 467 _evas_vg_render(obj, pd,
436 engine, buffer, 468 engine, buffer,
437 context, surface, 469 context, root,
438 root, NULL, 470 NULL,
439 do_async); 471 do_async);
440 472
441 obj->layer->evas->engine.func->image_dirty_region(engine, buffer, 0, 0, w, h); 473 ENFN->image_dirty_region(engine, buffer, 0, 0, w, h);
442 obj->layer->evas->engine.func->ector_end(engine, buffer, 474 ENFN->ector_end(engine, buffer, context, ector, do_async);
443 context, surface,
444 ector,do_async);
445
446 evas_common_draw_context_free(context); 475 evas_common_draw_context_free(context);
447 476
448 if (buffer_created) 477 if (buffer_created)
@@ -498,7 +527,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
498 void *buffer = ENFN->ector_surface_cache_get(engine, root); 527 void *buffer = ENFN->ector_surface_cache_get(engine, root);
499 528
500 if (!buffer) 529 if (!buffer)
501 buffer = _render_to_buffer(obj, pd, engine, surface, root, w, h, root, NULL, 530 buffer = _render_to_buffer(obj, pd, engine, root, w, h, root, NULL,
502 do_async); 531 do_async);
503 else 532 else
504 //cache reference was increased when we get the cache. 533 //cache reference was increased when we get the cache.
@@ -534,20 +563,15 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
534 if (!buffer) 563 if (!buffer)
535 { 564 {
536 // render to the buffer 565 // render to the buffer
537 buffer = _render_to_buffer(obj, pd, 566 buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
538 engine, surface, 567 w, h, user_entry, buffer,
539 user_entry->root,
540 w, h,
541 user_entry,
542 buffer,
543 do_async); 568 do_async);
544 } 569 }
545 else 570 else
546 { 571 {
547 // render to the buffer 572 // render to the buffer
548 if (pd->changed) 573 if (pd->changed)
549 buffer = _render_to_buffer(obj, pd, 574 buffer = _render_to_buffer(obj, pd, engine,
550 engine, surface,
551 user_entry->root, 575 user_entry->root,
552 w, h, 576 w, h,
553 user_entry, 577 user_entry,
@@ -630,7 +654,7 @@ _efl_canvas_vg_object_render_pre(Evas_Object *eo_obj,
630 // FIXME: handle damage only on changed renderer. 654 // FIXME: handle damage only on changed renderer.
631 s = evas_ector_get(obj->layer->evas); 655 s = evas_ector_get(obj->layer->evas);
632 if (pd->root && s) 656 if (pd->root && s)
633 _evas_vg_render_pre(pd->root, s, NULL); 657 _evas_vg_render_pre(obj, pd->root, s, NULL, NULL, 0);
634 658
635 /* now figure what changed and add draw rects */ 659 /* now figure what changed and add draw rects */
636 /* if it just became visible or invisible */ 660 /* if it just became visible or invisible */
diff --git a/src/lib/evas/canvas/efl_canvas_vg_shape.c b/src/lib/evas/canvas/efl_canvas_vg_shape.c
index d55009afcb..106efeccfb 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_shape.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_shape.c
@@ -78,43 +78,45 @@ _efl_canvas_vg_shape_stroke_marker_get(const Eo *obj EINA_UNUSED,
78} 78}
79 79
80static void 80static void
81_efl_canvas_vg_shape_render_pre(Eo *obj EINA_UNUSED, 81_efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd,
82 Eina_Matrix3 *parent, 82 Efl_VG *obj,
83 Ector_Surface *s, 83 Efl_Canvas_Vg_Node_Data *nd,
84 void *data, 84 Ector_Surface *surface,
85 Efl_Canvas_Vg_Node_Data *nd) 85 Eina_Matrix3 *ptransform,
86 Ector_Buffer *mask,
87 int mask_op,
88 void *data)
86{ 89{
87 Efl_Canvas_Vg_Shape_Data *pd = data; 90 Efl_Canvas_Vg_Shape_Data *pd = data;
88 Efl_Canvas_Vg_Node_Data *fill, *stroke_fill, *stroke_marker, *mask; 91 Efl_Canvas_Vg_Node_Data *fill, *stroke_fill, *stroke_marker;
89 92
90 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return; 93 if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
91 94
92 nd->flags = EFL_GFX_CHANGE_FLAG_NONE; 95 nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
93 96
94 EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd); 97 EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
95 98
96 fill = _evas_vg_render_pre(pd->fill, s, current); 99 fill = _evas_vg_render_pre(vg_pd, pd->fill, surface, ctransform, mask, mask_op);
97 stroke_fill = _evas_vg_render_pre(pd->stroke.fill, s, current); 100 stroke_fill = _evas_vg_render_pre(vg_pd, pd->stroke.fill, surface, ctransform, mask, mask_op);
98 stroke_marker = _evas_vg_render_pre(pd->stroke.marker, s, current); 101 stroke_marker = _evas_vg_render_pre(vg_pd, pd->stroke.marker, surface, ctransform, mask, mask_op);
99 mask = _evas_vg_render_pre(nd->mask, s, current);
100 102
101 if (!nd->renderer) 103 if (!nd->renderer)
102 { 104 {
103 efl_domain_current_push(EFL_ID_DOMAIN_SHARED); 105 efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
104 nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_SHAPE_MIXIN); 106 nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_SHAPE_MIXIN);
105 efl_domain_current_pop(); 107 efl_domain_current_pop();
106 } 108 }
107 109 ector_renderer_transformation_set(nd->renderer, ctransform);
108 ector_renderer_transformation_set(nd->renderer, current);
109 ector_renderer_origin_set(nd->renderer, nd->x, nd->y); 110 ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
110 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); 111 ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
111 ector_renderer_visibility_set(nd->renderer, nd->visibility); 112 ector_renderer_visibility_set(nd->renderer, nd->visibility);
112 ector_renderer_mask_set(nd->renderer, mask ? mask->renderer : NULL);
113 ector_renderer_shape_fill_set(nd->renderer, fill ? fill->renderer : NULL); 113 ector_renderer_shape_fill_set(nd->renderer, fill ? fill->renderer : NULL);
114 ector_renderer_shape_stroke_fill_set(nd->renderer, stroke_fill ? stroke_fill->renderer : NULL); 114 ector_renderer_shape_stroke_fill_set(nd->renderer, stroke_fill ? stroke_fill->renderer : NULL);
115 ector_renderer_shape_stroke_marker_set(nd->renderer, stroke_marker ? stroke_marker->renderer : NULL); 115 ector_renderer_shape_stroke_marker_set(nd->renderer, stroke_marker ? stroke_marker->renderer : NULL);
116 efl_gfx_path_copy_from(nd->renderer, obj); 116 efl_gfx_path_copy_from(nd->renderer, obj);
117 ector_renderer_prepare(nd->renderer); 117 ector_renderer_prepare(nd->renderer);
118 ector_renderer_mask_set(nd->renderer, mask, mask_op);
119
118} 120}
119 121
120static Eo * 122static Eo *
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
index a4d11d06cb..10b8b49b25 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -57,12 +57,13 @@ struct _Efl_Canvas_Vg_Node_Data
57 Eina_Matrix3 *m; 57 Eina_Matrix3 *m;
58 Efl_Canvas_Vg_Interpolation *intp; 58 Efl_Canvas_Vg_Interpolation *intp;
59 59
60 Efl_Canvas_Vg_Node *mask;
61 Ector_Renderer *renderer; 60 Ector_Renderer *renderer;
62 61
63 Efl_VG *vg_obj; //...Not necessary!! 62 Efl_VG *vg_obj; //...Not necessary!!
64 63
65 void (*render_pre)(Eo *obj, Eina_Matrix3 *parent, Ector_Surface *s, void *data, Efl_Canvas_Vg_Node_Data *nd); 64 void (*render_pre)(Evas_Object_Protected_Data *vg_pd, Efl_VG *node,
65 Efl_Canvas_Vg_Node_Data *nd, Ector_Surface *surface,
66 Eina_Matrix3 *ptransform, Ector_Buffer *mask, int mask_op, void *data);
66 void *data; 67 void *data;
67 68
68 double x, y; 69 double x, y;
@@ -74,11 +75,25 @@ struct _Efl_Canvas_Vg_Node_Data
74 Eina_Bool parenting : 1; 75 Eina_Bool parenting : 1;
75}; 76};
76 77
78typedef struct _Vg_Mask
79{
80 Evas_Object_Protected_Data *vg_pd; //Vector Object (for accessing backend engine)
81 Ector_Buffer *buffer; //Mask Ector Buffer
82 void *pixels; //Mask pixel buffer (actual data)
83 Eina_Rect bound; //Mask boundary
84 Eina_List *target; //Mask target
85 int option; //Mask option
86 Eina_Bool dirty : 1; //Need to update mask image.
87} Vg_Mask;
88
77struct _Efl_Canvas_Vg_Container_Data 89struct _Efl_Canvas_Vg_Container_Data
78{ 90{
79 Eina_List *children; 91 Eina_List *children;
80
81 Eina_Hash *names; 92 Eina_Hash *names;
93
94 //Masking feature.
95 Efl_Canvas_Vg_Node *mask_src; //Mask Source
96 Vg_Mask mask; //Mask source data
82}; 97};
83 98
84struct _Efl_Canvas_Vg_Gradient_Data 99struct _Efl_Canvas_Vg_Gradient_Data
@@ -112,13 +127,12 @@ Eina_Bool evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_ent
112void efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj); 127void efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj);
113 128
114static inline Efl_Canvas_Vg_Node_Data * 129static inline Efl_Canvas_Vg_Node_Data *
115_evas_vg_render_pre(Efl_VG *child, Ector_Surface *s, Eina_Matrix3 *m) 130_evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child, Ector_Surface *surface, Eina_Matrix3 *transform, Ector_Buffer *mask, int mask_op)
116{ 131{
117 if (!child) return NULL; 132 if (!child) return NULL;
118 133 Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
119 Efl_Canvas_Vg_Node_Data *child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS); 134 if (nd) nd->render_pre(vg_pd, child, nd, surface, transform, mask, mask_op, nd->data);
120 if (child_nd) child_nd->render_pre(child, m, s, child_nd->data, child_nd); 135 return nd;
121 return child_nd;
122} 136}
123 137
124static inline void 138static inline void
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 34dffee36b..3d5020fdd6 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1482,9 +1482,9 @@ struct _Evas_Func
1482 void (*ector_destroy) (void *engine, Ector_Surface *surface); 1482 void (*ector_destroy) (void *engine, Ector_Surface *surface);
1483 Ector_Buffer *(*ector_buffer_wrap) (void *engine, Evas *e, void *engine_image); 1483 Ector_Buffer *(*ector_buffer_wrap) (void *engine, Evas *e, void *engine_image);
1484 Ector_Buffer *(*ector_buffer_new) (void *engine, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags); 1484 Ector_Buffer *(*ector_buffer_new) (void *engine, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags);
1485 void (*ector_begin) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, int x, int y, Eina_Bool do_async); 1485 void (*ector_begin) (void *engine, void *output, void *context, Ector_Surface *ector, int x, int y, Eina_Bool clear, Eina_Bool do_async);
1486 void (*ector_renderer_draw) (void *engine, void *output, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async); 1486 void (*ector_renderer_draw) (void *engine, void *output, void *context, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
1487 void (*ector_end) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, Eina_Bool do_async); 1487 void (*ector_end) (void *engine, void *output, void *context, Ector_Surface *ector, Eina_Bool do_async);
1488 1488
1489 void *(*ector_surface_create) (void *engine, int w, int h, int *error); 1489 void *(*ector_surface_create) (void *engine, int w, int h, int *error);
1490 void (*ector_surface_destroy) (void *engine, void *surface); 1490 void (*ector_surface_destroy) (void *engine, void *surface);
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 5d0771a058..96b0e41a94 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -2509,25 +2509,72 @@ eng_ector_buffer_wrap(void *engine EINA_UNUSED, Evas *evas, void *engine_image)
2509 evas_ector_buffer_engine_image_set(efl_added, evas, im)); 2509 evas_ector_buffer_engine_image_set(efl_added, evas, im));
2510} 2510}
2511 2511
2512//FIXME: Currently Ector GL doens't work properly. Use software instead.
2513#include "../software_generic/evas_ector_software.h"
2514
2512static Ector_Buffer * 2515static Ector_Buffer *
2513eng_ector_buffer_new(void *engine, Evas *evas, int w, int h, 2516eng_ector_buffer_new(void *engine, Evas *evas, int w, int h,
2514 Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags) 2517 Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
2515{ 2518{
2516 return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas, 2519 /* FIXME: This condition is tricky, this buffer could be used for masking
2517 evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags)); 2520 * buffer by vector, Require to use software drawing.
2521 */
2522 if (flags != (ECTOR_BUFFER_FLAG_DRAWABLE | ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE))
2523 {
2524 return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
2525 evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags));
2526 }
2527 else
2528 {
2529 Ector_Buffer *buf;
2530 Image_Entry *ie;
2531 void *pixels;
2532 int pxs;
2533
2534 if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
2535 pxs = 4;
2536 else if (cspace == EFL_GFX_COLORSPACE_GRY8)
2537 pxs = 1;
2538 else
2539 {
2540 ERR("Unsupported colorspace: %d", (int) cspace);
2541 return NULL;
2542 }
2543
2544 // alloc buffer
2545 ie = evas_cache_image_copied_data(evas_common_image_cache_get(), w, h,
2546 NULL, EINA_TRUE, cspace);
2547 if (!ie) return NULL;
2548 pixels = ((RGBA_Image *) ie)->image.data;
2549 memset(pixels, 0, w * h * pxs);
2550
2551 if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED))
2552 {
2553 evas_cache_image_drop(ie);
2554 return NULL;
2555 }
2556
2557 buf = efl_add_ref(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL,
2558 evas_ector_buffer_engine_image_set(efl_added, engine, ie));
2559 efl_domain_current_pop();
2560
2561 evas_cache_image_drop(ie);
2562
2563 return buf;
2564 }
2518} 2565}
2519 2566
2520static void 2567static void
2521eng_ector_renderer_draw(void *engine EINA_UNUSED, void *output, 2568eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
2522 void *context EINA_UNUSED, void *surface EINA_UNUSED, 2569 void *context EINA_UNUSED, Ector_Renderer *renderer,
2523 Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED) 2570 Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
2524{ 2571{
2525 if (use_cairo|| !use_gl) 2572 if (use_cairo || !use_gl)
2526 { 2573 {
2527 int w, h; 2574 int w, h;
2528 Eina_Rectangle *r; 2575 Eina_Rectangle *r;
2529 Eina_Array *c = eina_array_new(4); 2576 Eina_Array *c = eina_array_new(4);
2530 Evas_GL_Image *glimg = output; 2577 Evas_GL_Image *glimg = surface;
2531 2578
2532 eng_image_size_get(engine, glimg, &w, &h); 2579 eng_image_size_get(engine, glimg, &w, &h);
2533 eina_array_push(c, eina_rectangle_new(0, 0, w, h)); 2580 eina_array_push(c, eina_rectangle_new(0, 0, w, h));
@@ -2603,21 +2650,22 @@ eng_ector_surface_cache_drop(void *engine, void *key)
2603} 2650}
2604 2651
2605static void 2652static void
2606eng_ector_begin(void *engine, void *output, 2653eng_ector_begin(void *engine, void *surface,
2607 void *context EINA_UNUSED, void *surface EINA_UNUSED, 2654 void *context EINA_UNUSED, Ector_Surface *ector,
2608 Ector_Surface *ector, int x, int y, Eina_Bool do_async EINA_UNUSED) 2655 int x, int y, Eina_Bool clear, Eina_Bool do_async EINA_UNUSED)
2609{ 2656{
2610 if (use_cairo|| !use_gl) 2657 if (use_cairo|| !use_gl)
2611 { 2658 {
2612 int w, h, stride; 2659 int w, h, stride;
2613 Evas_GL_Image *glim = output; 2660 Evas_GL_Image *glim = surface;
2614 DATA32 *pixels; 2661 DATA32 *pixels;
2615 int load_err; 2662 int load_err;
2616 2663
2617 glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL); 2664 glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL);
2618 eng_image_stride_get(engine, glim, &stride); 2665 eng_image_stride_get(engine, glim, &stride);
2619 eng_image_size_get(engine, glim, &w, &h); 2666 eng_image_size_get(engine, glim, &w, &h);
2620 memset(pixels, 0, stride * h); 2667
2668 if (clear) memset(pixels, 0, stride * h);
2621 2669
2622 // it just uses the software backend to draw for now 2670 // it just uses the software backend to draw for now
2623 ector_buffer_pixels_set(ector, pixels, w, h, stride, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); 2671 ector_buffer_pixels_set(ector, pixels, w, h, stride, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
@@ -2630,13 +2678,15 @@ eng_ector_begin(void *engine, void *output,
2630} 2678}
2631 2679
2632static void 2680static void
2633eng_ector_end(void *engine, void *output, 2681eng_ector_end(void *engine,
2634 void *context EINA_UNUSED, void *surface EINA_UNUSED, 2682 void *surface,
2635 Ector_Surface *ector, Eina_Bool do_async EINA_UNUSED) 2683 void *context EINA_UNUSED,
2684 Ector_Surface *ector,
2685 Eina_Bool do_async EINA_UNUSED)
2636{ 2686{
2637 if (use_cairo || !use_gl) 2687 if (use_cairo || !use_gl)
2638 { 2688 {
2639 Evas_GL_Image *glim = output; 2689 Evas_GL_Image *glim = surface;
2640 DATA32 *pixels; 2690 DATA32 *pixels;
2641 int load_err; 2691 int load_err;
2642 2692
diff --git a/src/modules/evas/engines/gl_generic/meson.build b/src/modules/evas/engines/gl_generic/meson.build
index cbc467b7ab..8926f24127 100644
--- a/src/modules/evas/engines/gl_generic/meson.build
+++ b/src/modules/evas/engines/gl_generic/meson.build
@@ -34,6 +34,8 @@ endforeach
34 34
35engine_deps = [gl_common] 35engine_deps = [gl_common]
36 36
37engine_include_dir = include_directories(join_paths('..','software_generic'))
38
37if get_option('evas-modules') == 'shared' and not evas_force_static.contains(engine) 39if get_option('evas-modules') == 'shared' and not evas_force_static.contains(engine)
38 shared_module(mod_full_name, engine_src, 40 shared_module(mod_full_name, engine_src,
39 include_directories : config_dir + [engine_include_dir], 41 include_directories : config_dir + [engine_include_dir],
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 51d24c2ca1..7007f3a2fd 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -411,6 +411,7 @@ struct _Evas_Thread_Command_Ector_Surface
411 Ector_Surface *ector; 411 Ector_Surface *ector;
412 void *pixels; 412 void *pixels;
413 int x, y; 413 int x, y;
414 Eina_Bool clear;
414}; 415};
415 416
416// declare here as it is re-used 417// declare here as it is re-used
@@ -4237,7 +4238,7 @@ eng_ector_buffer_wrap(void *data, Evas *e EINA_UNUSED, void *engine_image)
4237} 4238}
4238 4239
4239static Ector_Buffer * 4240static Ector_Buffer *
4240eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int width, int height, 4241eng_ector_buffer_new(void *data, Evas *evas, int width, int height,
4241 Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED) 4242 Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED)
4242{ 4243{
4243 Ector_Buffer *buf; 4244 Ector_Buffer *buf;
@@ -4293,8 +4294,8 @@ _draw_thread_ector_draw(void *data)
4293 4294
4294static void 4295static void
4295eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface, 4296eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
4296 void *context, void *remove EINA_UNUSED, 4297 void *context, Ector_Renderer *renderer,
4297 Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async) 4298 Eina_Array *clips, Eina_Bool do_async)
4298{ 4299{
4299 RGBA_Image *dst = surface; 4300 RGBA_Image *dst = surface;
4300 RGBA_Draw_Context *dc = context; 4301 RGBA_Draw_Context *dc = context;
@@ -4400,7 +4401,7 @@ _draw_thread_ector_surface_set(void *data)
4400 x = ector_surface->x; 4401 x = ector_surface->x;
4401 y = ector_surface->y; 4402 y = ector_surface->y;
4402 // clear the surface before giving to ector 4403 // clear the surface before giving to ector
4403 memset(pixels, 0, (w * h * 4)); 4404 if (ector_surface->clear) memset(pixels, 0, (w * h * 4));
4404 } 4405 }
4405 4406
4406 ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); 4407 ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
@@ -4411,20 +4412,21 @@ _draw_thread_ector_surface_set(void *data)
4411 4412
4412static void 4413static void
4413eng_ector_begin(void *engine EINA_UNUSED, void *surface, 4414eng_ector_begin(void *engine EINA_UNUSED, void *surface,
4414 void *context EINA_UNUSED, void *remove EINA_UNUSED, 4415 void *context EINA_UNUSED, Ector_Surface *ector,
4415 Ector_Surface *ector, int x, int y, Eina_Bool do_async) 4416 int x, int y, Eina_Bool clear, Eina_Bool do_async)
4416{ 4417{
4417 if (do_async) 4418 if (do_async)
4418 { 4419 {
4419 Evas_Thread_Command_Ector_Surface *nes; 4420 Evas_Thread_Command_Ector_Surface *nes;
4420 4421
4421 nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface)); 4422 nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
4422 if (!nes) return ; 4423 if (!nes) return;
4423 4424
4424 nes->ector = ector; 4425 nes->ector = ector;
4425 nes->pixels = surface; 4426 nes->pixels = surface;
4426 nes->x = x; 4427 nes->x = x;
4427 nes->y = y; 4428 nes->y = y;
4429 nes->clear = clear;
4428 4430
4429 QCMD(_draw_thread_ector_surface_set, nes); 4431 QCMD(_draw_thread_ector_surface_set, nes);
4430 } 4432 }
@@ -4439,7 +4441,7 @@ eng_ector_begin(void *engine EINA_UNUSED, void *surface,
4439 w = sf->cache_entry.w; 4441 w = sf->cache_entry.w;
4440 h = sf->cache_entry.h; 4442 h = sf->cache_entry.h;
4441 // clear the surface before giving to ector 4443 // clear the surface before giving to ector
4442 memset(pixels, 0, (w * h * 4)); 4444 if (clear) memset(pixels, 0, (w * h * 4));
4443 4445
4444 ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); 4446 ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
4445 ector_surface_reference_point_set(ector, x, y); 4447 ector_surface_reference_point_set(ector, x, y);
@@ -4447,9 +4449,11 @@ eng_ector_begin(void *engine EINA_UNUSED, void *surface,
4447} 4449}
4448 4450
4449static void 4451static void
4450eng_ector_end(void *engine EINA_UNUSED, void *surface EINA_UNUSED, 4452eng_ector_end(void *engine EINA_UNUSED,
4451 void *context EINA_UNUSED, void *remove EINA_UNUSED, 4453 void *surface EINA_UNUSED,
4452 Ector_Surface *ector, Eina_Bool do_async) 4454 void *context EINA_UNUSED,
4455 Ector_Surface *ector,
4456 Eina_Bool do_async)
4453{ 4457{
4454 if (do_async) 4458 if (do_async)
4455 { 4459 {