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.
This commit is contained in:
parent
4d6f20d714
commit
fbe92aa67f
|
@ -63,8 +63,6 @@ struct _Ector_Renderer_Data
|
||||||
int r, g, b, a;
|
int r, g, b, a;
|
||||||
} color;
|
} color;
|
||||||
|
|
||||||
Ector_Renderer *mask;
|
|
||||||
|
|
||||||
Eina_Bool visibility : 1;
|
Eina_Bool visibility : 1;
|
||||||
Eina_Bool finalized : 1;
|
Eina_Bool finalized : 1;
|
||||||
};
|
};
|
||||||
|
|
|
@ -127,31 +127,6 @@ _ector_renderer_color_get(const Eo *obj EINA_UNUSED,
|
||||||
if (a) *a = pd->color.a;
|
if (a) *a = pd->color.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
|
|
||||||
Ector_Renderer_Data *pd,
|
|
||||||
Ector_Renderer *mask)
|
|
||||||
{
|
|
||||||
efl_replace(&pd->mask, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Ector_Renderer *
|
|
||||||
_ector_renderer_mask_get(const Eo *obj EINA_UNUSED,
|
|
||||||
Ector_Renderer_Data *pd)
|
|
||||||
{
|
|
||||||
return pd->mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_ector_renderer_prepare(Eo *obj EINA_UNUSED,
|
|
||||||
Ector_Renderer_Data *pd)
|
|
||||||
{
|
|
||||||
if (pd->mask)
|
|
||||||
ector_renderer_prepare(pd->mask);
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
_ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
|
_ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
|
||||||
Ector_Renderer_Data *pd)
|
Ector_Renderer_Data *pd)
|
||||||
|
@ -162,9 +137,16 @@ _ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
|
||||||
crc = eina_crc((void*) &pd->origin, sizeof(pd->origin), crc, EINA_FALSE);
|
crc = eina_crc((void*) &pd->origin, sizeof(pd->origin), crc, EINA_FALSE);
|
||||||
|
|
||||||
if (pd->m) crc = eina_crc((void*) pd->m, sizeof(Eina_Matrix3), crc, EINA_FALSE);
|
if (pd->m) crc = eina_crc((void*) pd->m, sizeof(Eina_Matrix3), crc, EINA_FALSE);
|
||||||
if (pd->mask) crc = _renderer_crc_get(pd->mask, crc);
|
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
|
||||||
|
Ector_Renderer_Data *pd EINA_UNUSED,
|
||||||
|
Ector_Buffer *mask EINA_UNUSED,
|
||||||
|
int op EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#include "ector_renderer.eo.c"
|
#include "ector_renderer.eo.c"
|
||||||
|
|
|
@ -72,22 +72,21 @@ abstract Ector.Renderer (Efl.Object)
|
||||||
a: int; [[The alpha component of the given color.]]
|
a: int; [[The alpha component of the given color.]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property mask {
|
|
||||||
[[Rendering mask]]
|
|
||||||
set {
|
|
||||||
}
|
|
||||||
get {
|
|
||||||
}
|
|
||||||
values {
|
|
||||||
mask: Ector.Renderer; [[Rendering mask]]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@property crc {
|
@property crc {
|
||||||
[[Cyclic redundancy check]]
|
[[Cyclic redundancy check]]
|
||||||
get {
|
get {
|
||||||
return: uint; [[CRC value]]
|
return: uint; [[CRC value]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@property mask {
|
||||||
|
[[Set Mask Image to this Renderer]]
|
||||||
|
set {
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
mask: Ector.Buffer; [[Mask Image Buffer]]
|
||||||
|
op: int; [[Masking option]]
|
||||||
|
}
|
||||||
|
}
|
||||||
draw @pure_virtual {
|
draw @pure_virtual {
|
||||||
[[Actual draw operation]]
|
[[Actual draw operation]]
|
||||||
return: bool; [[$true on success, $false otherwise]]
|
return: bool; [[$true on success, $false otherwise]]
|
||||||
|
@ -97,7 +96,7 @@ abstract Ector.Renderer (Efl.Object)
|
||||||
@in mul_col: uint; [[Premultiplied color]]
|
@in mul_col: uint; [[Premultiplied color]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prepare {
|
prepare @pure_virtual {
|
||||||
[[Prepare for rendering]]
|
[[Prepare for rendering]]
|
||||||
return: bool; [[$true on success, $false otherwise]]
|
return: bool; [[$true on success, $false otherwise]]
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct _Ector_Renderer_Software_Shape_Data
|
||||||
Shape_Rle_Data *shape_data;
|
Shape_Rle_Data *shape_data;
|
||||||
Shape_Rle_Data *outline_data;
|
Shape_Rle_Data *outline_data;
|
||||||
|
|
||||||
|
Ector_Buffer *mask;
|
||||||
|
int mask_op;
|
||||||
|
|
||||||
Ector_Software_Shape_Task *task;
|
Ector_Software_Shape_Task *task;
|
||||||
|
|
||||||
Eina_Bool done;
|
Eina_Bool done;
|
||||||
|
@ -661,16 +664,18 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
|
||||||
x = pd->surface->x + (int)pd->base->origin.x;
|
x = pd->surface->x + (int)pd->base->origin.x;
|
||||||
y = pd->surface->y + (int)pd->base->origin.y;
|
y = pd->surface->y + (int)pd->base->origin.y;
|
||||||
|
|
||||||
// fill the span_data structure
|
|
||||||
ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips);
|
ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips);
|
||||||
ector_software_rasterizer_transform_set(pd->surface->rasterizer, pd->base->m);
|
ector_software_rasterizer_transform_set(pd->surface->rasterizer, pd->base->m);
|
||||||
|
|
||||||
|
// fill the span_data structure
|
||||||
if (pd->shape->fill)
|
if (pd->shape->fill)
|
||||||
{
|
{
|
||||||
ector_renderer_software_op_fill(pd->shape->fill);
|
ector_renderer_software_op_fill(pd->shape->fill);
|
||||||
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
||||||
x, y, mul_col, op,
|
x, y, mul_col, op,
|
||||||
pd->shape_data);
|
pd->shape_data,
|
||||||
|
pd->mask,
|
||||||
|
pd->mask_op);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -683,16 +688,22 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
|
||||||
pd->base->color.a);
|
pd->base->color.a);
|
||||||
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
||||||
x, y, mul_col, op,
|
x, y, mul_col, op,
|
||||||
pd->shape_data);
|
pd->shape_data,
|
||||||
|
pd->mask,
|
||||||
|
pd->mask_op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pd->outline_data) return EINA_TRUE;
|
||||||
|
|
||||||
if (pd->shape->stroke.fill)
|
if (pd->shape->stroke.fill)
|
||||||
{
|
{
|
||||||
ector_renderer_software_op_fill(pd->shape->stroke.fill);
|
ector_renderer_software_op_fill(pd->shape->stroke.fill);
|
||||||
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
||||||
x, y, mul_col, op,
|
x, y, mul_col, op,
|
||||||
pd->outline_data);
|
pd->outline_data,
|
||||||
|
pd->mask,
|
||||||
|
pd->mask_op);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -705,7 +716,9 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
|
||||||
pd->public_shape->stroke.color.a);
|
pd->public_shape->stroke.color.a);
|
||||||
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
|
||||||
x, y, mul_col, op,
|
x, y, mul_col, op,
|
||||||
pd->outline_data);
|
pd->outline_data,
|
||||||
|
pd->mask,
|
||||||
|
pd->mask_op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,4 +844,15 @@ _ector_renderer_software_shape_ector_renderer_crc_get(const Eo *obj,
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ector_renderer_software_shape_ector_renderer_mask_set(Eo *obj EINA_UNUSED,
|
||||||
|
Ector_Renderer_Software_Shape_Data *pd,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int op)
|
||||||
|
{
|
||||||
|
//Use ref/unref.
|
||||||
|
pd->mask = mask;
|
||||||
|
pd->mask_op = op;
|
||||||
|
}
|
||||||
|
|
||||||
#include "ector_renderer_software_shape.eo.c"
|
#include "ector_renderer_software_shape.eo.c"
|
||||||
|
|
|
@ -6,6 +6,7 @@ class Ector.Renderer.Software.Shape (Ector.Renderer.Software, Ector.Renderer.Sha
|
||||||
Ector.Renderer.prepare;
|
Ector.Renderer.prepare;
|
||||||
Ector.Renderer.draw;
|
Ector.Renderer.draw;
|
||||||
Ector.Renderer.Software.op_fill;
|
Ector.Renderer.Software.op_fill;
|
||||||
|
Ector.Renderer.mask { set; }
|
||||||
Ector.Renderer.crc { get; }
|
Ector.Renderer.crc { get; }
|
||||||
Efl.Gfx.Path.path { set; }
|
Efl.Gfx.Path.path { set; }
|
||||||
Efl.Object.constructor;
|
Efl.Object.constructor;
|
||||||
|
|
|
@ -76,8 +76,8 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff
|
||||||
{
|
{
|
||||||
unsigned pxs;
|
unsigned pxs;
|
||||||
|
|
||||||
if (pd->generic->immutable)
|
//if (pd->generic->immutable)
|
||||||
fail("This buffer is immutable.");
|
// fail("This buffer is immutable.");
|
||||||
|
|
||||||
if (pd->internal.maps)
|
if (pd->internal.maps)
|
||||||
fail("Can not call pixels_set when the buffer is mapped.");
|
fail("Can not call pixels_set when the buffer is mapped.");
|
||||||
|
|
|
@ -82,9 +82,11 @@ typedef struct _Span_Data
|
||||||
|
|
||||||
int offx, offy;
|
int offx, offy;
|
||||||
Clip_Data clip;
|
Clip_Data clip;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask;
|
||||||
|
int mask_op;
|
||||||
Eina_Matrix3 inv;
|
Eina_Matrix3 inv;
|
||||||
Span_Data_Type type;
|
Span_Data_Type type;
|
||||||
Eina_Bool fast_matrix ;
|
Eina_Bool fast_matrix;
|
||||||
uint32_t mul_col;
|
uint32_t mul_col;
|
||||||
Efl_Gfx_Render_Op op;
|
Efl_Gfx_Render_Op op;
|
||||||
union {
|
union {
|
||||||
|
@ -129,7 +131,12 @@ void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, S
|
||||||
Shape_Rle_Data * ector_software_rasterizer_generate_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline);
|
Shape_Rle_Data * ector_software_rasterizer_generate_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline);
|
||||||
Shape_Rle_Data * ector_software_rasterizer_generate_stroke_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath);
|
Shape_Rle_Data * ector_software_rasterizer_generate_stroke_rle_data(Ector_Software_Thread *thread, Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath);
|
||||||
|
|
||||||
void 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);
|
void 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,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op);
|
||||||
|
|
||||||
void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
|
void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
|
||||||
|
|
||||||
|
|
|
@ -14,22 +14,100 @@
|
||||||
static void
|
static void
|
||||||
_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
|
_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
{
|
{
|
||||||
RGBA_Comp_Func_Solid comp_func;
|
Span_Data *sd = user_data;
|
||||||
Span_Data *data = (Span_Data *)(user_data);
|
|
||||||
uint32_t color, *buffer, *target;
|
uint32_t color, *buffer, *target;
|
||||||
const int pix_stride = data->raster_buffer->stride / 4;
|
const int pix_stride = sd->raster_buffer->stride / 4;
|
||||||
|
|
||||||
// multiply the color with mul_col if any
|
// multiply the color with mul_col if any
|
||||||
color = DRAW_MUL4_SYM(data->color, data->mul_col);
|
color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
comp_func = efl_draw_func_solid_span_get(data->op, color);
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
|
||||||
// move to the offset location
|
// move to the offset location
|
||||||
buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
|
buffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
target = buffer + ((pix_stride * spans->y) + spans->x);
|
||||||
|
comp_func(target, spans->len, color, spans->coverage);
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
const int pix_stride = sd->raster_buffer->stride / 4;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
// multiply the color with mul_col if any
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
|
||||||
|
// move to the offset location
|
||||||
|
uint32_t *buffer =
|
||||||
|
sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
|
||||||
|
uint32_t *mbuffer = mask->pixels.u32;
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
target = buffer + ((pix_stride * spans->y) + spans->x);
|
uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
|
||||||
comp_func(target, spans->len, color, spans->coverage);
|
uint32_t *mtarget =
|
||||||
|
mbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
uint32_t *temp = alloca(sizeof(uint32_t) * spans->len);
|
||||||
|
memset(temp, 0x00, sizeof(uint32_t) * spans->len);
|
||||||
|
comp_func(temp, spans->len, color, spans->coverage);
|
||||||
|
|
||||||
|
//masking
|
||||||
|
for (int i = 0; i < spans->len; i++)
|
||||||
|
{
|
||||||
|
*temp = draw_mul_256(((*mtarget)>>24), *temp);
|
||||||
|
int alpha = 255 - ((*temp) >> 24);
|
||||||
|
*target = *temp + draw_mul_256(alpha, *target);
|
||||||
|
++temp;
|
||||||
|
++mtarget;
|
||||||
|
++target;
|
||||||
|
}
|
||||||
|
++spans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data)
|
||||||
|
{
|
||||||
|
Span_Data *sd = user_data;
|
||||||
|
const int pix_stride = sd->raster_buffer->stride / 4;
|
||||||
|
Ector_Software_Buffer_Base_Data *mask = sd->mask;
|
||||||
|
|
||||||
|
// multiply the color with mul_col if any
|
||||||
|
uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
|
||||||
|
RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
|
||||||
|
|
||||||
|
// move to the offset location
|
||||||
|
uint32_t *buffer =
|
||||||
|
sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
|
||||||
|
uint32_t *mbuffer = mask->pixels.u32;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
|
||||||
|
uint32_t *mtarget =
|
||||||
|
mbuffer + ((mask->generic->w * spans->y) + spans->x);
|
||||||
|
uint32_t *temp = alloca(sizeof(uint32_t) * spans->len);
|
||||||
|
memset(temp, 0x00, sizeof(uint32_t) * spans->len);
|
||||||
|
comp_func(temp, spans->len, color, spans->coverage);
|
||||||
|
|
||||||
|
//masking
|
||||||
|
for (int i = 0; i < spans->len; i++)
|
||||||
|
{
|
||||||
|
if (*mtarget)
|
||||||
|
*temp = draw_mul_256((255 - ((*mtarget)>>24)), *temp);
|
||||||
|
int alpha = 255 - ((*temp) >> 24);
|
||||||
|
*target = *temp + draw_mul_256(alpha, *target);
|
||||||
|
++temp;
|
||||||
|
++mtarget;
|
||||||
|
++target;
|
||||||
|
}
|
||||||
++spans;
|
++spans;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,13 +345,24 @@ _span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
|
||||||
static void
|
static void
|
||||||
_adjust_span_fill_methods(Span_Data *spdata)
|
_adjust_span_fill_methods(Span_Data *spdata)
|
||||||
{
|
{
|
||||||
|
//Blending Function
|
||||||
switch(spdata->type)
|
switch(spdata->type)
|
||||||
{
|
{
|
||||||
case None:
|
case None:
|
||||||
spdata->unclipped_blend = 0;
|
spdata->unclipped_blend = NULL;
|
||||||
break;
|
break;
|
||||||
case Solid:
|
case Solid:
|
||||||
spdata->unclipped_blend = &_blend_color_argb;
|
{
|
||||||
|
if (spdata->mask)
|
||||||
|
{
|
||||||
|
if (spdata->mask_op == 2)
|
||||||
|
spdata->unclipped_blend = &_blend_color_argb_with_maskInvA;
|
||||||
|
else
|
||||||
|
spdata->unclipped_blend = &_blend_color_argb_with_maskA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
spdata->unclipped_blend = &_blend_color_argb;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LinearGradient:
|
case LinearGradient:
|
||||||
case RadialGradient:
|
case RadialGradient:
|
||||||
|
@ -539,17 +628,22 @@ ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer,
|
||||||
rasterizer->fill_data.type = RadialGradient;
|
rasterizer->fill_data.type = RadialGradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
|
void
|
||||||
int x, int y, uint32_t mul_col,
|
ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
|
||||||
Efl_Gfx_Render_Op op, Shape_Rle_Data* rle)
|
int x, int y, uint32_t mul_col,
|
||||||
|
Efl_Gfx_Render_Op op, Shape_Rle_Data* rle,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op)
|
||||||
{
|
{
|
||||||
// check for NULL rle data
|
|
||||||
if (!rle) return;
|
if (!rle) return;
|
||||||
|
|
||||||
rasterizer->fill_data.offx = x;
|
rasterizer->fill_data.offx = x;
|
||||||
rasterizer->fill_data.offy = y;
|
rasterizer->fill_data.offy = y;
|
||||||
rasterizer->fill_data.mul_col = mul_col;
|
rasterizer->fill_data.mul_col = mul_col;
|
||||||
rasterizer->fill_data.op = op;
|
rasterizer->fill_data.op = op;
|
||||||
|
rasterizer->fill_data.mask =
|
||||||
|
mask ? efl_data_scope_get(mask, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN) : NULL;
|
||||||
|
rasterizer->fill_data.mask_op = mask_op;
|
||||||
|
|
||||||
_setup_span_fill_matrix(rasterizer);
|
_setup_span_fill_matrix(rasterizer);
|
||||||
_adjust_span_fill_methods(&rasterizer->fill_data);
|
_adjust_span_fill_methods(&rasterizer->fill_data);
|
||||||
|
|
|
@ -22,17 +22,75 @@ _invalidate_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
||||||
efl_unref(child);
|
efl_unref(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Ector_Buffer *
|
||||||
|
_prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
||||||
|
Efl_Canvas_Vg_Node* mask_obj,
|
||||||
|
Ector_Surface *surface,
|
||||||
|
Eina_Matrix3 *ptransform,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op)
|
||||||
|
{
|
||||||
|
Efl_Canvas_Vg_Container_Data *pd = efl_data_scope_get(mask_obj, MY_CLASS);
|
||||||
|
Efl_Canvas_Vg_Node_Data *nd =
|
||||||
|
efl_data_scope_get(mask_obj, EFL_CANVAS_VG_NODE_CLASS);
|
||||||
|
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return pd->mask.buffer;
|
||||||
|
|
||||||
|
//1. Mask Size
|
||||||
|
Eina_Rect mbound;
|
||||||
|
mbound.x = 0;
|
||||||
|
mbound.y = 0;
|
||||||
|
mbound.w = obj->cur->geometry.w;
|
||||||
|
mbound.h = obj->cur->geometry.h;
|
||||||
|
|
||||||
|
// efl_gfx_path_bounds_get(mask, &mbound);
|
||||||
|
|
||||||
|
//2. Reusable ector buffer?
|
||||||
|
if (!pd->mask.buffer || (pd->mask.bound.w != mbound.w) ||
|
||||||
|
(pd->mask.bound.h != mbound.h))
|
||||||
|
{
|
||||||
|
if (pd->mask.pixels) free(pd->mask.pixels);
|
||||||
|
if (pd->mask.buffer) efl_unref(pd->mask.buffer);
|
||||||
|
pd->mask.pixels = calloc(sizeof(uint32_t), mbound.w * mbound.h);
|
||||||
|
pd->mask.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas,
|
||||||
|
mbound.w, mbound.h,
|
||||||
|
EFL_GFX_COLORSPACE_ARGB8888,
|
||||||
|
ECTOR_BUFFER_FLAG_DRAWABLE |
|
||||||
|
ECTOR_BUFFER_FLAG_CPU_READABLE |
|
||||||
|
ECTOR_BUFFER_FLAG_CPU_WRITABLE);
|
||||||
|
ector_buffer_pixels_set(pd->mask.buffer, pd->mask.pixels,
|
||||||
|
mbound.w, mbound.h, 0,
|
||||||
|
EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
||||||
|
pd->mask.bound.w = mbound.w;
|
||||||
|
pd->mask.bound.h = mbound.h;
|
||||||
|
pd->mask.vg_pd = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
pd->mask.bound.x = mbound.x;
|
||||||
|
pd->mask.bound.y = mbound.y;
|
||||||
|
|
||||||
|
if (!pd->mask.buffer) ERR("Mask Buffer is invalid");
|
||||||
|
|
||||||
|
pd->mask.dirty = EINA_TRUE;
|
||||||
|
|
||||||
|
//3. Prepare Drawing shapes...
|
||||||
|
_evas_vg_render_pre(obj, mask_obj, surface, ptransform, mask, mask_op);
|
||||||
|
|
||||||
|
return pd->mask.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_container_render_pre(Eo *obj EINA_UNUSED,
|
_efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
|
||||||
Eina_Matrix3 *parent,
|
Efl_VG *obj EINA_UNUSED,
|
||||||
Ector_Surface *s,
|
Efl_Canvas_Vg_Node_Data *nd,
|
||||||
void *data,
|
Ector_Surface *surface,
|
||||||
Efl_Canvas_Vg_Node_Data *nd)
|
Eina_Matrix3 *ptransform,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Container_Data *pd = data;
|
Efl_Canvas_Vg_Container_Data *pd = data;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
Eo *child;
|
Efl_VG *child;
|
||||||
Efl_Canvas_Vg_Node_Data *child_nd;
|
|
||||||
Efl_Gfx_Change_Flag flag;
|
Efl_Gfx_Change_Flag flag;
|
||||||
|
|
||||||
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
|
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
|
||||||
|
@ -40,20 +98,37 @@ _efl_canvas_vg_container_render_pre(Eo *obj EINA_UNUSED,
|
||||||
flag = nd->flags;
|
flag = nd->flags;
|
||||||
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
||||||
|
|
||||||
EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd);
|
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||||
|
|
||||||
|
//Container may have mask source.
|
||||||
|
if (pd->mask_src)
|
||||||
|
{
|
||||||
|
mask = _prepare_mask(vg_pd, pd->mask_src, surface, ptransform, mask,
|
||||||
|
mask_op);
|
||||||
|
mask_op = pd->mask.option;
|
||||||
|
}
|
||||||
|
|
||||||
EINA_LIST_FOREACH(pd->children, l, child)
|
EINA_LIST_FOREACH(pd->children, l, child)
|
||||||
{
|
{
|
||||||
|
//Don't need to update mask nodes.
|
||||||
|
if (efl_isa(child, MY_CLASS))
|
||||||
|
{
|
||||||
|
Efl_Canvas_Vg_Container_Data *child_cd =
|
||||||
|
efl_data_scope_get(child, MY_CLASS);
|
||||||
|
if (child_cd->mask.target) continue;
|
||||||
|
}
|
||||||
|
|
||||||
//Skip Gradients. they will be updated by Shape.
|
//Skip Gradients. they will be updated by Shape.
|
||||||
if (efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
|
if (efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Efl_Canvas_Vg_Node_Data *child_nd =
|
||||||
|
efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
|
||||||
|
|
||||||
if (flag & EFL_GFX_CHANGE_FLAG_MATRIX)
|
if (flag & EFL_GFX_CHANGE_FLAG_MATRIX)
|
||||||
{
|
child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
|
||||||
child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
|
|
||||||
child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
|
_evas_vg_render_pre(vg_pd, child, surface, ctransform, mask, mask_op);
|
||||||
}
|
|
||||||
_evas_vg_render_pre(child, s, current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,16 +152,23 @@ _efl_canvas_vg_container_efl_object_constructor(Eo *obj,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_container_efl_object_destructor(Eo *obj,
|
_efl_canvas_vg_container_efl_object_destructor(Eo *obj,
|
||||||
Efl_Canvas_Vg_Container_Data *pd EINA_UNUSED)
|
Efl_Canvas_Vg_Container_Data *pd)
|
||||||
{
|
{
|
||||||
efl_destructor(efl_super(obj, MY_CLASS));
|
//Destroy mask surface
|
||||||
|
if (pd->mask.buffer) efl_unref(pd->mask.buffer);
|
||||||
|
if (pd->mask.pixels) free(pd->mask.pixels);
|
||||||
|
|
||||||
|
efl_unref(pd->mask_src);
|
||||||
|
eina_list_free(pd->mask.target);
|
||||||
eina_hash_free(pd->names);
|
eina_hash_free(pd->names);
|
||||||
|
|
||||||
|
efl_destructor(efl_super(obj, MY_CLASS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo *obj EINA_UNUSED,
|
_efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo *obj EINA_UNUSED,
|
||||||
Efl_Canvas_Vg_Container_Data *pd,
|
Efl_Canvas_Vg_Container_Data *pd,
|
||||||
Eina_Rect *r)
|
Eina_Rect *r)
|
||||||
{
|
{
|
||||||
Eina_Rect s;
|
Eina_Rect s;
|
||||||
Eina_Bool first = EINA_TRUE;
|
Eina_Bool first = EINA_TRUE;
|
||||||
|
@ -162,12 +244,51 @@ _efl_canvas_vg_container_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Contain
|
||||||
if (!r) break;
|
if (!r) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Interpolates Mask
|
||||||
|
Efl_Canvas_Vg_Container_Data *fromd = efl_data_scope_get(from, MY_CLASS);
|
||||||
|
Efl_Canvas_Vg_Container_Data *tod = efl_data_scope_get(to, MY_CLASS);
|
||||||
|
|
||||||
|
if (fromd->mask_src && tod->mask_src && pd->mask_src)
|
||||||
|
{
|
||||||
|
if (!efl_gfx_path_interpolate(pd->mask_src,
|
||||||
|
fromd->mask_src, tod->mask_src, pos_map))
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
eina_iterator_free(from_it);
|
eina_iterator_free(from_it);
|
||||||
eina_iterator_free(to_it);
|
eina_iterator_free(to_it);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_canvas_vg_container_efl_canvas_vg_node_mask_set(Eo *obj,
|
||||||
|
Efl_Canvas_Vg_Container_Data *pd,
|
||||||
|
Efl_Canvas_Vg_Node *mask,
|
||||||
|
int op)
|
||||||
|
{
|
||||||
|
if (pd->mask_src == mask) return;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(mask, MY_CLASS));
|
||||||
|
|
||||||
|
if (pd->mask_src)
|
||||||
|
{
|
||||||
|
Efl_Canvas_Vg_Container_Data *pd2 =
|
||||||
|
efl_data_scope_get(pd->mask_src, MY_CLASS);
|
||||||
|
pd2->mask.target = eina_list_remove(pd2->mask.target, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
{
|
||||||
|
Efl_Canvas_Vg_Container_Data *pd2 = efl_data_scope_get(mask, MY_CLASS);
|
||||||
|
pd2->mask.target = eina_list_append(pd2->mask.target, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
pd->mask.option = op;
|
||||||
|
efl_replace(&pd->mask_src, mask);
|
||||||
|
_efl_canvas_vg_node_changed(obj);
|
||||||
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_VG *
|
EOLIAN static Efl_VG *
|
||||||
_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
|
_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
|
||||||
Efl_Canvas_Vg_Container_Data *pd)
|
Efl_Canvas_Vg_Container_Data *pd)
|
||||||
|
@ -180,6 +301,14 @@ _efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
|
||||||
efl_event_callback_add(container, EFL_EVENT_INVALIDATE, _invalidate_cb, NULL);
|
efl_event_callback_add(container, EFL_EVENT_INVALIDATE, _invalidate_cb, NULL);
|
||||||
efl_parent_set(container, efl_parent_get(obj));
|
efl_parent_set(container, efl_parent_get(obj));
|
||||||
|
|
||||||
|
//Copy Mask
|
||||||
|
if (pd->mask_src)
|
||||||
|
{
|
||||||
|
Eo * mask_src = efl_duplicate(pd->mask_src);
|
||||||
|
efl_parent_set(mask_src, container);
|
||||||
|
efl_canvas_vg_node_mask_set(container, mask_src, pd->mask.option);
|
||||||
|
}
|
||||||
|
|
||||||
//Copy Children
|
//Copy Children
|
||||||
EINA_LIST_FOREACH(pd->children, l, child)
|
EINA_LIST_FOREACH(pd->children, l, child)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,14 +4,14 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
|
||||||
legacy_prefix: evas_vg_container;
|
legacy_prefix: evas_vg_container;
|
||||||
methods {
|
methods {
|
||||||
child_get {
|
child_get {
|
||||||
[[Get child of container]]
|
[[Get child of container]]
|
||||||
params {
|
params {
|
||||||
@in name: string; [[Child node name]]
|
@in name: string; [[Child node name]]
|
||||||
}
|
}
|
||||||
return: Efl.Canvas.Vg.Node; [[Child object]]
|
return: Efl.Canvas.Vg.Node; [[Child object]]
|
||||||
}
|
}
|
||||||
children_get {
|
children_get {
|
||||||
[[Get all children of container]]
|
[[Get all children of container]]
|
||||||
return: iterator<Efl.Canvas.Vg.Node> @owned @warn_unused; [[Iterator to children]]
|
return: iterator<Efl.Canvas.Vg.Node> @owned @warn_unused; [[Iterator to children]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,5 +21,6 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
|
||||||
Efl.Gfx.Path.bounds_get;
|
Efl.Gfx.Path.bounds_get;
|
||||||
Efl.Gfx.Path.interpolate;
|
Efl.Gfx.Path.interpolate;
|
||||||
Efl.Duplicate.duplicate;
|
Efl.Duplicate.duplicate;
|
||||||
|
Efl.Canvas.Vg.Node.mask { set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,30 +56,33 @@ _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(const Eo *obj EIN
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_gradient_linear_render_pre(Eo *obj,
|
_efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
|
||||||
Eina_Matrix3 *parent,
|
Efl_VG *obj,
|
||||||
Ector_Surface *s,
|
Efl_Canvas_Vg_Node_Data *nd,
|
||||||
void *data,
|
Ector_Surface *surface,
|
||||||
Efl_Canvas_Vg_Node_Data *nd)
|
Eina_Matrix3 *ptransform,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Gradient_Linear_Data *pd = data;
|
Efl_Canvas_Vg_Gradient_Linear_Data *pd = data;
|
||||||
Efl_Canvas_Vg_Gradient_Data *gd;
|
Efl_Canvas_Vg_Gradient_Data *gd;
|
||||||
|
|
||||||
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ;
|
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
|
||||||
|
|
||||||
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
||||||
|
|
||||||
gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
|
gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
|
||||||
EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd);
|
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||||
|
|
||||||
if (!nd->renderer)
|
if (!nd->renderer)
|
||||||
{
|
{
|
||||||
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
||||||
nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN);
|
nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN);
|
||||||
efl_domain_current_pop();
|
efl_domain_current_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
ector_renderer_transformation_set(nd->renderer, current);
|
ector_renderer_transformation_set(nd->renderer, ctransform);
|
||||||
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
||||||
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
||||||
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
||||||
|
@ -87,8 +90,8 @@ _efl_canvas_vg_gradient_linear_render_pre(Eo *obj,
|
||||||
efl_gfx_gradient_spread_set(nd->renderer, gd->spread);
|
efl_gfx_gradient_spread_set(nd->renderer, gd->spread);
|
||||||
efl_gfx_gradient_linear_start_set(nd->renderer, pd->start.x, pd->start.y);
|
efl_gfx_gradient_linear_start_set(nd->renderer, pd->start.x, pd->start.y);
|
||||||
efl_gfx_gradient_linear_end_set(nd->renderer, pd->end.x, pd->end.y);
|
efl_gfx_gradient_linear_end_set(nd->renderer, pd->end.x, pd->end.y);
|
||||||
|
|
||||||
ector_renderer_prepare(nd->renderer);
|
ector_renderer_prepare(nd->renderer);
|
||||||
|
ector_renderer_mask_set(nd->renderer, mask, mask_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eo *
|
static Eo *
|
||||||
|
|
|
@ -72,11 +72,14 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_focal_get(const Eo *obj E
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
|
_efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
|
||||||
Eina_Matrix3 *parent,
|
Efl_VG *obj,
|
||||||
Ector_Surface *s,
|
Efl_Canvas_Vg_Node_Data *nd,
|
||||||
void *data,
|
Ector_Surface *surface,
|
||||||
Efl_Canvas_Vg_Node_Data *nd)
|
Eina_Matrix3 *ptransform,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Gradient_Radial_Data *pd = data;
|
Efl_Canvas_Vg_Gradient_Radial_Data *pd = data;
|
||||||
Efl_Canvas_Vg_Gradient_Data *gd;
|
Efl_Canvas_Vg_Gradient_Data *gd;
|
||||||
|
@ -86,16 +89,16 @@ _efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
|
||||||
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
||||||
|
|
||||||
gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
|
gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
|
||||||
EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd);
|
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||||
|
|
||||||
if (!nd->renderer)
|
if (!nd->renderer)
|
||||||
{
|
{
|
||||||
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
||||||
nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN);
|
nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN);
|
||||||
efl_domain_current_pop();
|
efl_domain_current_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
ector_renderer_transformation_set(nd->renderer, current);
|
ector_renderer_transformation_set(nd->renderer, ctransform);
|
||||||
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
||||||
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
||||||
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
||||||
|
@ -104,8 +107,8 @@ _efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
|
||||||
efl_gfx_gradient_radial_center_set(nd->renderer, pd->center.x, pd->center.y);
|
efl_gfx_gradient_radial_center_set(nd->renderer, pd->center.x, pd->center.y);
|
||||||
efl_gfx_gradient_radial_focal_set(nd->renderer, pd->focal.x, pd->focal.y);
|
efl_gfx_gradient_radial_focal_set(nd->renderer, pd->focal.x, pd->focal.y);
|
||||||
efl_gfx_gradient_radial_radius_set(nd->renderer, pd->radius);
|
efl_gfx_gradient_radial_radius_set(nd->renderer, pd->radius);
|
||||||
|
|
||||||
ector_renderer_prepare(nd->renderer);
|
ector_renderer_prepare(nd->renderer);
|
||||||
|
ector_renderer_mask_set(nd->renderer, mask, mask_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eo *
|
static Eo *
|
||||||
|
|
|
@ -65,6 +65,14 @@ _efl_canvas_vg_node_transformation_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_
|
||||||
return pd->m;
|
return pd->m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_canvas_vg_node_mask_set(Eo *obj EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
|
||||||
|
Efl_Canvas_Vg_Node *mask EINA_UNUSED,
|
||||||
|
int op EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_node_origin_set(Eo *obj,
|
_efl_canvas_vg_node_origin_set(Eo *obj,
|
||||||
Efl_Canvas_Vg_Node_Data *pd,
|
Efl_Canvas_Vg_Node_Data *pd,
|
||||||
|
@ -166,25 +174,6 @@ _efl_canvas_vg_node_efl_gfx_color_color_get(const Eo *obj EINA_UNUSED,
|
||||||
if (a) *a = pd->a;
|
if (a) *a = pd->a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_efl_canvas_vg_node_mask_set(Eo *obj EINA_UNUSED,
|
|
||||||
Efl_Canvas_Vg_Node_Data *pd,
|
|
||||||
Efl_VG *r)
|
|
||||||
{
|
|
||||||
Efl_VG *tmp = pd->mask;
|
|
||||||
|
|
||||||
pd->mask = efl_ref(r);
|
|
||||||
efl_unref(tmp);
|
|
||||||
|
|
||||||
_efl_canvas_vg_node_changed(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Efl_VG*
|
|
||||||
_efl_canvas_vg_node_mask_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Node_Data *pd)
|
|
||||||
{
|
|
||||||
return pd->mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Size2D
|
static Eina_Size2D
|
||||||
_efl_canvas_vg_node_efl_gfx_entity_size_get(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED)
|
_efl_canvas_vg_node_efl_gfx_entity_size_get(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -711,14 +700,6 @@ _efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Node_Data *p
|
||||||
|
|
||||||
pd->visibility = pos_map >= 0.5 ? tod->visibility : fromd->visibility;
|
pd->visibility = pos_map >= 0.5 ? tod->visibility : fromd->visibility;
|
||||||
|
|
||||||
//Interpolates Mask
|
|
||||||
if (fromd->mask && tod->mask && pd->mask)
|
|
||||||
{
|
|
||||||
if (!efl_gfx_path_interpolate(pd->mask,
|
|
||||||
fromd->mask, tod->mask, pos_map))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_efl_canvas_vg_node_changed(obj);
|
_efl_canvas_vg_node_changed(obj);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -750,12 +731,6 @@ _efl_canvas_vg_node_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Node_Da
|
||||||
if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3));
|
if (nd->m) memcpy(nd->m, pd->m, sizeof(Eina_Matrix3));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pd->mask)
|
|
||||||
{
|
|
||||||
nd->mask = efl_duplicate(pd->mask);
|
|
||||||
efl_parent_set(nd->mask, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
nd->x = pd->x;
|
nd->x = pd->x;
|
||||||
nd->y = pd->y;
|
nd->y = pd->y;
|
||||||
nd->r = pd->r;
|
nd->r = pd->r;
|
||||||
|
|
|
@ -42,13 +42,12 @@ abstract Efl.Canvas.Vg.Node (Efl.Object, Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property mask {
|
@property mask {
|
||||||
[[Vector graphics object mask]]
|
[[Set Mask Node to this renderer]]
|
||||||
set {
|
set {
|
||||||
}
|
}
|
||||||
get {
|
|
||||||
}
|
|
||||||
values {
|
values {
|
||||||
m: Efl.Canvas.Vg.Node; [[Object mask]]
|
mask: Efl.Canvas.Vg.Node; [[Mask object]]
|
||||||
|
op: int; [[Masking Option. Reserved]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,37 +371,71 @@ _efl_canvas_vg_object_efl_object_finalize(Eo *obj, Efl_Canvas_Vg_Object_Data *pd
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
||||||
void *engine, void *output, void *context, void *surface, Efl_VG *n,
|
void *engine, void *output, void *context, Efl_VG *node,
|
||||||
Eina_Array *clips, Eina_Bool do_async)
|
Eina_Array *clips, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
if (efl_isa(n, EFL_CANVAS_VG_CONTAINER_CLASS))
|
if (efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS))
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Container_Data *vc;
|
Efl_Canvas_Vg_Container_Data *cd =
|
||||||
|
efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS);
|
||||||
|
|
||||||
|
//Update Mask Image
|
||||||
|
if (cd->mask_src)
|
||||||
|
{
|
||||||
|
Efl_Canvas_Vg_Container_Data *cd2 =
|
||||||
|
efl_data_scope_get(cd->mask_src, EFL_CANVAS_VG_CONTAINER_CLASS);
|
||||||
|
|
||||||
|
if (cd2->mask.buffer && cd2->mask.dirty)
|
||||||
|
{
|
||||||
|
Ector_Surface *ector = evas_ector_get(obj->layer->evas);
|
||||||
|
if (!ector) return;
|
||||||
|
|
||||||
|
ENFN->ector_end(engine, output, context, ector, EINA_FALSE);
|
||||||
|
|
||||||
|
//Need a better approach.
|
||||||
|
ector_buffer_pixels_set(ector, cd2->mask.pixels, cd2->mask.bound.w, cd2->mask.bound.h, 0,
|
||||||
|
EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
||||||
|
ector_surface_reference_point_set(ector, -cd2->mask.bound.x, -cd2->mask.bound.y);
|
||||||
|
|
||||||
|
//Draw Mask Image.
|
||||||
|
Efl_VG *child;
|
||||||
|
Eina_List *l;
|
||||||
|
EINA_LIST_FOREACH(cd2->children, l, child)
|
||||||
|
_evas_vg_render(obj, pd, engine, output, context, child,
|
||||||
|
clips, EINA_FALSE);
|
||||||
|
|
||||||
|
cd2->mask.dirty = EINA_FALSE;
|
||||||
|
#if 0
|
||||||
|
FILE *fp = fopen("./test.raw", "w+");
|
||||||
|
fwrite(cd2->mask.pixels, cd2->mask.bound.w * cd2->mask.bound.h, sizeof(uint32_t), fp);
|
||||||
|
fclose(fp);
|
||||||
|
ERR("size = %d x %d", cd2->mask.bound.w, cd2->mask.bound.h);
|
||||||
|
#endif
|
||||||
|
//Restore previous ector context
|
||||||
|
ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cd->mask.target) return; //Don't draw mask itself.
|
||||||
|
|
||||||
Efl_VG *child;
|
Efl_VG *child;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
|
|
||||||
vc = efl_data_scope_get(n, EFL_CANVAS_VG_CONTAINER_CLASS);
|
EINA_LIST_FOREACH(cd->children, l, child)
|
||||||
|
_evas_vg_render(obj, pd, engine, output, context, child, clips, do_async);
|
||||||
EINA_LIST_FOREACH(vc->children, l, child)
|
|
||||||
_evas_vg_render(obj, pd,
|
|
||||||
engine, output, context, surface, child,
|
|
||||||
clips, do_async);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Node_Data *nd;
|
Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(node, EFL_CANVAS_VG_NODE_CLASS);
|
||||||
nd = efl_data_scope_get(n, EFL_CANVAS_VG_NODE_CLASS);
|
ENFN->ector_renderer_draw(engine, output, context, nd->renderer, clips, do_async);
|
||||||
obj->layer->evas->engine.func->ector_renderer_draw(engine, output, context, surface, nd->renderer, clips, do_async);
|
if (do_async) eina_array_push(&pd->cleanup, efl_ref(nd->renderer));
|
||||||
if (do_async)
|
|
||||||
eina_array_push(&pd->cleanup, efl_ref(nd->renderer));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//renders a vg_tree to an offscreen buffer and push it to the cache.
|
//renders a vg_tree to an offscreen buffer and push it to the cache.
|
||||||
static void *
|
static void *
|
||||||
_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
|
||||||
void *engine, void *surface,
|
void *engine, Efl_VG *root, int w, int h, void *key,
|
||||||
Efl_VG *root, int w, int h, void *key,
|
|
||||||
void *buffer, Eina_Bool do_async)
|
void *buffer, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
Ector_Surface *ector;
|
Ector_Surface *ector;
|
||||||
|
@ -420,29 +454,24 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
|
||||||
buffer_created = EINA_TRUE;
|
buffer_created = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_evas_vg_render_pre(root, ector, NULL);
|
_evas_vg_render_pre(obj, root, ector, NULL, NULL, 0);
|
||||||
|
|
||||||
//initialize buffer
|
//initialize buffer
|
||||||
context = evas_common_draw_context_new();
|
context = evas_common_draw_context_new();
|
||||||
evas_common_draw_context_set_render_op(context, _EVAS_RENDER_COPY);
|
evas_common_draw_context_set_render_op(context, _EVAS_RENDER_COPY);
|
||||||
evas_common_draw_context_set_color(context, 255, 255, 255, 255);
|
evas_common_draw_context_set_color(context, 255, 255, 255, 255);
|
||||||
obj->layer->evas->engine.func->ector_begin(engine, buffer,
|
|
||||||
context, surface,
|
ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_TRUE, do_async);
|
||||||
ector,
|
|
||||||
0, 0,
|
|
||||||
do_async);
|
|
||||||
//draw on buffer
|
//draw on buffer
|
||||||
_evas_vg_render(obj, pd,
|
_evas_vg_render(obj, pd,
|
||||||
engine, buffer,
|
engine, buffer,
|
||||||
context, surface,
|
context, root,
|
||||||
root, NULL,
|
NULL,
|
||||||
do_async);
|
do_async);
|
||||||
|
|
||||||
obj->layer->evas->engine.func->image_dirty_region(engine, buffer, 0, 0, w, h);
|
ENFN->image_dirty_region(engine, buffer, 0, 0, w, h);
|
||||||
obj->layer->evas->engine.func->ector_end(engine, buffer,
|
ENFN->ector_end(engine, buffer, context, ector, do_async);
|
||||||
context, surface,
|
|
||||||
ector,do_async);
|
|
||||||
|
|
||||||
evas_common_draw_context_free(context);
|
evas_common_draw_context_free(context);
|
||||||
|
|
||||||
if (buffer_created)
|
if (buffer_created)
|
||||||
|
@ -498,7 +527,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
void *buffer = ENFN->ector_surface_cache_get(engine, root);
|
void *buffer = ENFN->ector_surface_cache_get(engine, root);
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
buffer = _render_to_buffer(obj, pd, engine, surface, root, w, h, root, NULL,
|
buffer = _render_to_buffer(obj, pd, engine, root, w, h, root, NULL,
|
||||||
do_async);
|
do_async);
|
||||||
else
|
else
|
||||||
//cache reference was increased when we get the cache.
|
//cache reference was increased when we get the cache.
|
||||||
|
@ -534,20 +563,15 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
// render to the buffer
|
// render to the buffer
|
||||||
buffer = _render_to_buffer(obj, pd,
|
buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
|
||||||
engine, surface,
|
w, h, user_entry, buffer,
|
||||||
user_entry->root,
|
|
||||||
w, h,
|
|
||||||
user_entry,
|
|
||||||
buffer,
|
|
||||||
do_async);
|
do_async);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// render to the buffer
|
// render to the buffer
|
||||||
if (pd->changed)
|
if (pd->changed)
|
||||||
buffer = _render_to_buffer(obj, pd,
|
buffer = _render_to_buffer(obj, pd, engine,
|
||||||
engine, surface,
|
|
||||||
user_entry->root,
|
user_entry->root,
|
||||||
w, h,
|
w, h,
|
||||||
user_entry,
|
user_entry,
|
||||||
|
@ -630,7 +654,7 @@ _efl_canvas_vg_object_render_pre(Evas_Object *eo_obj,
|
||||||
// FIXME: handle damage only on changed renderer.
|
// FIXME: handle damage only on changed renderer.
|
||||||
s = evas_ector_get(obj->layer->evas);
|
s = evas_ector_get(obj->layer->evas);
|
||||||
if (pd->root && s)
|
if (pd->root && s)
|
||||||
_evas_vg_render_pre(pd->root, s, NULL);
|
_evas_vg_render_pre(obj, pd->root, s, NULL, NULL, 0);
|
||||||
|
|
||||||
/* now figure what changed and add draw rects */
|
/* now figure what changed and add draw rects */
|
||||||
/* if it just became visible or invisible */
|
/* if it just became visible or invisible */
|
||||||
|
|
|
@ -78,43 +78,45 @@ _efl_canvas_vg_shape_stroke_marker_get(const Eo *obj EINA_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_canvas_vg_shape_render_pre(Eo *obj EINA_UNUSED,
|
_efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd,
|
||||||
Eina_Matrix3 *parent,
|
Efl_VG *obj,
|
||||||
Ector_Surface *s,
|
Efl_Canvas_Vg_Node_Data *nd,
|
||||||
void *data,
|
Ector_Surface *surface,
|
||||||
Efl_Canvas_Vg_Node_Data *nd)
|
Eina_Matrix3 *ptransform,
|
||||||
|
Ector_Buffer *mask,
|
||||||
|
int mask_op,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
Efl_Canvas_Vg_Shape_Data *pd = data;
|
Efl_Canvas_Vg_Shape_Data *pd = data;
|
||||||
Efl_Canvas_Vg_Node_Data *fill, *stroke_fill, *stroke_marker, *mask;
|
Efl_Canvas_Vg_Node_Data *fill, *stroke_fill, *stroke_marker;
|
||||||
|
|
||||||
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
|
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
|
||||||
|
|
||||||
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
|
||||||
|
|
||||||
EFL_CANVAS_VG_COMPUTE_MATRIX(current, parent, nd);
|
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||||
|
|
||||||
fill = _evas_vg_render_pre(pd->fill, s, current);
|
fill = _evas_vg_render_pre(vg_pd, pd->fill, surface, ctransform, mask, mask_op);
|
||||||
stroke_fill = _evas_vg_render_pre(pd->stroke.fill, s, current);
|
stroke_fill = _evas_vg_render_pre(vg_pd, pd->stroke.fill, surface, ctransform, mask, mask_op);
|
||||||
stroke_marker = _evas_vg_render_pre(pd->stroke.marker, s, current);
|
stroke_marker = _evas_vg_render_pre(vg_pd, pd->stroke.marker, surface, ctransform, mask, mask_op);
|
||||||
mask = _evas_vg_render_pre(nd->mask, s, current);
|
|
||||||
|
|
||||||
if (!nd->renderer)
|
if (!nd->renderer)
|
||||||
{
|
{
|
||||||
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
||||||
nd->renderer = ector_surface_renderer_factory_new(s, ECTOR_RENDERER_SHAPE_MIXIN);
|
nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_SHAPE_MIXIN);
|
||||||
efl_domain_current_pop();
|
efl_domain_current_pop();
|
||||||
}
|
}
|
||||||
|
ector_renderer_transformation_set(nd->renderer, ctransform);
|
||||||
ector_renderer_transformation_set(nd->renderer, current);
|
|
||||||
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
|
||||||
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
|
||||||
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
ector_renderer_visibility_set(nd->renderer, nd->visibility);
|
||||||
ector_renderer_mask_set(nd->renderer, mask ? mask->renderer : NULL);
|
|
||||||
ector_renderer_shape_fill_set(nd->renderer, fill ? fill->renderer : NULL);
|
ector_renderer_shape_fill_set(nd->renderer, fill ? fill->renderer : NULL);
|
||||||
ector_renderer_shape_stroke_fill_set(nd->renderer, stroke_fill ? stroke_fill->renderer : NULL);
|
ector_renderer_shape_stroke_fill_set(nd->renderer, stroke_fill ? stroke_fill->renderer : NULL);
|
||||||
ector_renderer_shape_stroke_marker_set(nd->renderer, stroke_marker ? stroke_marker->renderer : NULL);
|
ector_renderer_shape_stroke_marker_set(nd->renderer, stroke_marker ? stroke_marker->renderer : NULL);
|
||||||
efl_gfx_path_copy_from(nd->renderer, obj);
|
efl_gfx_path_copy_from(nd->renderer, obj);
|
||||||
ector_renderer_prepare(nd->renderer);
|
ector_renderer_prepare(nd->renderer);
|
||||||
|
ector_renderer_mask_set(nd->renderer, mask, mask_op);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eo *
|
static Eo *
|
||||||
|
|
|
@ -57,12 +57,13 @@ struct _Efl_Canvas_Vg_Node_Data
|
||||||
Eina_Matrix3 *m;
|
Eina_Matrix3 *m;
|
||||||
Efl_Canvas_Vg_Interpolation *intp;
|
Efl_Canvas_Vg_Interpolation *intp;
|
||||||
|
|
||||||
Efl_Canvas_Vg_Node *mask;
|
|
||||||
Ector_Renderer *renderer;
|
Ector_Renderer *renderer;
|
||||||
|
|
||||||
Efl_VG *vg_obj; //...Not necessary!!
|
Efl_VG *vg_obj; //...Not necessary!!
|
||||||
|
|
||||||
void (*render_pre)(Eo *obj, Eina_Matrix3 *parent, Ector_Surface *s, void *data, Efl_Canvas_Vg_Node_Data *nd);
|
void (*render_pre)(Evas_Object_Protected_Data *vg_pd, Efl_VG *node,
|
||||||
|
Efl_Canvas_Vg_Node_Data *nd, Ector_Surface *surface,
|
||||||
|
Eina_Matrix3 *ptransform, Ector_Buffer *mask, int mask_op, void *data);
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
double x, y;
|
double x, y;
|
||||||
|
@ -74,11 +75,25 @@ struct _Efl_Canvas_Vg_Node_Data
|
||||||
Eina_Bool parenting : 1;
|
Eina_Bool parenting : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _Vg_Mask
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *vg_pd; //Vector Object (for accessing backend engine)
|
||||||
|
Ector_Buffer *buffer; //Mask Ector Buffer
|
||||||
|
void *pixels; //Mask pixel buffer (actual data)
|
||||||
|
Eina_Rect bound; //Mask boundary
|
||||||
|
Eina_List *target; //Mask target
|
||||||
|
int option; //Mask option
|
||||||
|
Eina_Bool dirty : 1; //Need to update mask image.
|
||||||
|
} Vg_Mask;
|
||||||
|
|
||||||
struct _Efl_Canvas_Vg_Container_Data
|
struct _Efl_Canvas_Vg_Container_Data
|
||||||
{
|
{
|
||||||
Eina_List *children;
|
Eina_List *children;
|
||||||
|
|
||||||
Eina_Hash *names;
|
Eina_Hash *names;
|
||||||
|
|
||||||
|
//Masking feature.
|
||||||
|
Efl_Canvas_Vg_Node *mask_src; //Mask Source
|
||||||
|
Vg_Mask mask; //Mask source data
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Efl_Canvas_Vg_Gradient_Data
|
struct _Efl_Canvas_Vg_Gradient_Data
|
||||||
|
@ -112,13 +127,12 @@ Eina_Bool evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_ent
|
||||||
void efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj);
|
void efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj);
|
||||||
|
|
||||||
static inline Efl_Canvas_Vg_Node_Data *
|
static inline Efl_Canvas_Vg_Node_Data *
|
||||||
_evas_vg_render_pre(Efl_VG *child, Ector_Surface *s, Eina_Matrix3 *m)
|
_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)
|
||||||
{
|
{
|
||||||
if (!child) return NULL;
|
if (!child) return NULL;
|
||||||
|
Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
|
||||||
Efl_Canvas_Vg_Node_Data *child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
|
if (nd) nd->render_pre(vg_pd, child, nd, surface, transform, mask, mask_op, nd->data);
|
||||||
if (child_nd) child_nd->render_pre(child, m, s, child_nd->data, child_nd);
|
return nd;
|
||||||
return child_nd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -1482,9 +1482,9 @@ struct _Evas_Func
|
||||||
void (*ector_destroy) (void *engine, Ector_Surface *surface);
|
void (*ector_destroy) (void *engine, Ector_Surface *surface);
|
||||||
Ector_Buffer *(*ector_buffer_wrap) (void *engine, Evas *e, void *engine_image);
|
Ector_Buffer *(*ector_buffer_wrap) (void *engine, Evas *e, void *engine_image);
|
||||||
Ector_Buffer *(*ector_buffer_new) (void *engine, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags);
|
Ector_Buffer *(*ector_buffer_new) (void *engine, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags);
|
||||||
void (*ector_begin) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, int x, int y, Eina_Bool do_async);
|
void (*ector_begin) (void *engine, void *output, void *context, Ector_Surface *ector, int x, int y, Eina_Bool clear, Eina_Bool do_async);
|
||||||
void (*ector_renderer_draw) (void *engine, void *output, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
|
void (*ector_renderer_draw) (void *engine, void *output, void *context, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
|
||||||
void (*ector_end) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, Eina_Bool do_async);
|
void (*ector_end) (void *engine, void *output, void *context, Ector_Surface *ector, Eina_Bool do_async);
|
||||||
|
|
||||||
void *(*ector_surface_create) (void *engine, int w, int h, int *error);
|
void *(*ector_surface_create) (void *engine, int w, int h, int *error);
|
||||||
void (*ector_surface_destroy) (void *engine, void *surface);
|
void (*ector_surface_destroy) (void *engine, void *surface);
|
||||||
|
|
|
@ -2509,25 +2509,72 @@ eng_ector_buffer_wrap(void *engine EINA_UNUSED, Evas *evas, void *engine_image)
|
||||||
evas_ector_buffer_engine_image_set(efl_added, evas, im));
|
evas_ector_buffer_engine_image_set(efl_added, evas, im));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: Currently Ector GL doens't work properly. Use software instead.
|
||||||
|
#include "../software_generic/evas_ector_software.h"
|
||||||
|
|
||||||
static Ector_Buffer *
|
static Ector_Buffer *
|
||||||
eng_ector_buffer_new(void *engine, Evas *evas, int w, int h,
|
eng_ector_buffer_new(void *engine, Evas *evas, int w, int h,
|
||||||
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
|
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
|
||||||
{
|
{
|
||||||
return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
|
/* FIXME: This condition is tricky, this buffer could be used for masking
|
||||||
evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags));
|
* buffer by vector, Require to use software drawing.
|
||||||
|
*/
|
||||||
|
if (flags != (ECTOR_BUFFER_FLAG_DRAWABLE | ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE))
|
||||||
|
{
|
||||||
|
return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
|
||||||
|
evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ector_Buffer *buf;
|
||||||
|
Image_Entry *ie;
|
||||||
|
void *pixels;
|
||||||
|
int pxs;
|
||||||
|
|
||||||
|
if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
|
||||||
|
pxs = 4;
|
||||||
|
else if (cspace == EFL_GFX_COLORSPACE_GRY8)
|
||||||
|
pxs = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("Unsupported colorspace: %d", (int) cspace);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alloc buffer
|
||||||
|
ie = evas_cache_image_copied_data(evas_common_image_cache_get(), w, h,
|
||||||
|
NULL, EINA_TRUE, cspace);
|
||||||
|
if (!ie) return NULL;
|
||||||
|
pixels = ((RGBA_Image *) ie)->image.data;
|
||||||
|
memset(pixels, 0, w * h * pxs);
|
||||||
|
|
||||||
|
if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED))
|
||||||
|
{
|
||||||
|
evas_cache_image_drop(ie);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = efl_add_ref(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL,
|
||||||
|
evas_ector_buffer_engine_image_set(efl_added, engine, ie));
|
||||||
|
efl_domain_current_pop();
|
||||||
|
|
||||||
|
evas_cache_image_drop(ie);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *output,
|
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
|
||||||
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
void *context EINA_UNUSED, Ector_Renderer *renderer,
|
||||||
Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
|
Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
if (use_cairo|| !use_gl)
|
if (use_cairo || !use_gl)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
Eina_Rectangle *r;
|
Eina_Rectangle *r;
|
||||||
Eina_Array *c = eina_array_new(4);
|
Eina_Array *c = eina_array_new(4);
|
||||||
Evas_GL_Image *glimg = output;
|
Evas_GL_Image *glimg = surface;
|
||||||
|
|
||||||
eng_image_size_get(engine, glimg, &w, &h);
|
eng_image_size_get(engine, glimg, &w, &h);
|
||||||
eina_array_push(c, eina_rectangle_new(0, 0, w, h));
|
eina_array_push(c, eina_rectangle_new(0, 0, w, h));
|
||||||
|
@ -2603,21 +2650,22 @@ eng_ector_surface_cache_drop(void *engine, void *key)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_begin(void *engine, void *output,
|
eng_ector_begin(void *engine, void *surface,
|
||||||
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
Ector_Surface *ector, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
int x, int y, Eina_Bool clear, Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
if (use_cairo|| !use_gl)
|
if (use_cairo|| !use_gl)
|
||||||
{
|
{
|
||||||
int w, h, stride;
|
int w, h, stride;
|
||||||
Evas_GL_Image *glim = output;
|
Evas_GL_Image *glim = surface;
|
||||||
DATA32 *pixels;
|
DATA32 *pixels;
|
||||||
int load_err;
|
int load_err;
|
||||||
|
|
||||||
glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL);
|
glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL);
|
||||||
eng_image_stride_get(engine, glim, &stride);
|
eng_image_stride_get(engine, glim, &stride);
|
||||||
eng_image_size_get(engine, glim, &w, &h);
|
eng_image_size_get(engine, glim, &w, &h);
|
||||||
memset(pixels, 0, stride * h);
|
|
||||||
|
if (clear) memset(pixels, 0, stride * h);
|
||||||
|
|
||||||
// it just uses the software backend to draw for now
|
// it just uses the software backend to draw for now
|
||||||
ector_buffer_pixels_set(ector, pixels, w, h, stride, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_end(void *engine, void *output,
|
eng_ector_end(void *engine,
|
||||||
void *context EINA_UNUSED, void *surface EINA_UNUSED,
|
void *surface,
|
||||||
Ector_Surface *ector, Eina_Bool do_async EINA_UNUSED)
|
void *context EINA_UNUSED,
|
||||||
|
Ector_Surface *ector,
|
||||||
|
Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
if (use_cairo || !use_gl)
|
if (use_cairo || !use_gl)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *glim = output;
|
Evas_GL_Image *glim = surface;
|
||||||
DATA32 *pixels;
|
DATA32 *pixels;
|
||||||
int load_err;
|
int load_err;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ endforeach
|
||||||
|
|
||||||
engine_deps = [gl_common]
|
engine_deps = [gl_common]
|
||||||
|
|
||||||
|
engine_include_dir = include_directories(join_paths('..','software_generic'))
|
||||||
|
|
||||||
if get_option('evas-modules') == 'shared' and not evas_force_static.contains(engine)
|
if get_option('evas-modules') == 'shared' and not evas_force_static.contains(engine)
|
||||||
shared_module(mod_full_name, engine_src,
|
shared_module(mod_full_name, engine_src,
|
||||||
include_directories : config_dir + [engine_include_dir],
|
include_directories : config_dir + [engine_include_dir],
|
||||||
|
|
|
@ -411,6 +411,7 @@ struct _Evas_Thread_Command_Ector_Surface
|
||||||
Ector_Surface *ector;
|
Ector_Surface *ector;
|
||||||
void *pixels;
|
void *pixels;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
Eina_Bool clear;
|
||||||
};
|
};
|
||||||
|
|
||||||
// declare here as it is re-used
|
// declare here as it is re-used
|
||||||
|
@ -4237,7 +4238,7 @@ eng_ector_buffer_wrap(void *data, Evas *e EINA_UNUSED, void *engine_image)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Ector_Buffer *
|
static Ector_Buffer *
|
||||||
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int width, int height,
|
eng_ector_buffer_new(void *data, Evas *evas, int width, int height,
|
||||||
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED)
|
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Ector_Buffer *buf;
|
Ector_Buffer *buf;
|
||||||
|
@ -4293,8 +4294,8 @@ _draw_thread_ector_draw(void *data)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
|
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
|
||||||
void *context, void *remove EINA_UNUSED,
|
void *context, Ector_Renderer *renderer,
|
||||||
Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
|
Eina_Array *clips, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
RGBA_Image *dst = surface;
|
RGBA_Image *dst = surface;
|
||||||
RGBA_Draw_Context *dc = context;
|
RGBA_Draw_Context *dc = context;
|
||||||
|
@ -4400,7 +4401,7 @@ _draw_thread_ector_surface_set(void *data)
|
||||||
x = ector_surface->x;
|
x = ector_surface->x;
|
||||||
y = ector_surface->y;
|
y = ector_surface->y;
|
||||||
// clear the surface before giving to ector
|
// clear the surface before giving to ector
|
||||||
memset(pixels, 0, (w * h * 4));
|
if (ector_surface->clear) memset(pixels, 0, (w * h * 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
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)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_begin(void *engine EINA_UNUSED, void *surface,
|
eng_ector_begin(void *engine EINA_UNUSED, void *surface,
|
||||||
void *context EINA_UNUSED, void *remove EINA_UNUSED,
|
void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
Ector_Surface *ector, int x, int y, Eina_Bool do_async)
|
int x, int y, Eina_Bool clear, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
if (do_async)
|
if (do_async)
|
||||||
{
|
{
|
||||||
Evas_Thread_Command_Ector_Surface *nes;
|
Evas_Thread_Command_Ector_Surface *nes;
|
||||||
|
|
||||||
nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
|
nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
|
||||||
if (!nes) return ;
|
if (!nes) return;
|
||||||
|
|
||||||
nes->ector = ector;
|
nes->ector = ector;
|
||||||
nes->pixels = surface;
|
nes->pixels = surface;
|
||||||
nes->x = x;
|
nes->x = x;
|
||||||
nes->y = y;
|
nes->y = y;
|
||||||
|
nes->clear = clear;
|
||||||
|
|
||||||
QCMD(_draw_thread_ector_surface_set, nes);
|
QCMD(_draw_thread_ector_surface_set, nes);
|
||||||
}
|
}
|
||||||
|
@ -4439,7 +4441,7 @@ eng_ector_begin(void *engine EINA_UNUSED, void *surface,
|
||||||
w = sf->cache_entry.w;
|
w = sf->cache_entry.w;
|
||||||
h = sf->cache_entry.h;
|
h = sf->cache_entry.h;
|
||||||
// clear the surface before giving to ector
|
// clear the surface before giving to ector
|
||||||
memset(pixels, 0, (w * h * 4));
|
if (clear) memset(pixels, 0, (w * h * 4));
|
||||||
|
|
||||||
ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
|
||||||
ector_surface_reference_point_set(ector, x, y);
|
ector_surface_reference_point_set(ector, x, y);
|
||||||
|
@ -4447,9 +4449,11 @@ eng_ector_begin(void *engine EINA_UNUSED, void *surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_end(void *engine EINA_UNUSED, void *surface EINA_UNUSED,
|
eng_ector_end(void *engine EINA_UNUSED,
|
||||||
void *context EINA_UNUSED, void *remove EINA_UNUSED,
|
void *surface EINA_UNUSED,
|
||||||
Ector_Surface *ector, Eina_Bool do_async)
|
void *context EINA_UNUSED,
|
||||||
|
Ector_Surface *ector,
|
||||||
|
Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
if (do_async)
|
if (do_async)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue