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:
Hermet Park 2018-12-07 19:38:48 +09:00
parent 4d6f20d714
commit fbe92aa67f
21 changed files with 541 additions and 230 deletions

View File

@ -63,8 +63,6 @@ struct _Ector_Renderer_Data
int r, g, b, a;
} color;
Ector_Renderer *mask;
Eina_Bool visibility : 1;
Eina_Bool finalized : 1;
};

View File

@ -127,31 +127,6 @@ _ector_renderer_color_get(const Eo *obj EINA_UNUSED,
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
_ector_renderer_crc_get(const Eo *obj EINA_UNUSED,
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);
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;
}
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"

View File

@ -72,22 +72,21 @@ abstract Ector.Renderer (Efl.Object)
a: int; [[The alpha component of the given color.]]
}
}
@property mask {
[[Rendering mask]]
set {
}
get {
}
values {
mask: Ector.Renderer; [[Rendering mask]]
}
}
@property crc {
[[Cyclic redundancy check]]
get {
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 {
[[Actual draw operation]]
return: bool; [[$true on success, $false otherwise]]
@ -97,7 +96,7 @@ abstract Ector.Renderer (Efl.Object)
@in mul_col: uint; [[Premultiplied color]]
}
}
prepare {
prepare @pure_virtual {
[[Prepare for rendering]]
return: bool; [[$true on success, $false otherwise]]
}

View File

@ -38,6 +38,9 @@ struct _Ector_Renderer_Software_Shape_Data
Shape_Rle_Data *shape_data;
Shape_Rle_Data *outline_data;
Ector_Buffer *mask;
int mask_op;
Ector_Software_Shape_Task *task;
Eina_Bool done;
@ -223,7 +226,7 @@ static void _outline_transform(Outline *outline, Eina_Matrix3 *m)
static Eina_Bool
_generate_outline(const Efl_Gfx_Path_Command *cmds, const double *pts, Outline * outline)
{
Eina_Bool close_path = EINA_FALSE;
Eina_Bool close_path = EINA_FALSE;
for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
{
switch (*cmds)
@ -661,16 +664,18 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
x = pd->surface->x + (int)pd->base->origin.x;
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_transform_set(pd->surface->rasterizer, pd->base->m);
// fill the span_data structure
if (pd->shape->fill)
{
ector_renderer_software_op_fill(pd->shape->fill);
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
x, y, mul_col, op,
pd->shape_data);
pd->shape_data,
pd->mask,
pd->mask_op);
}
else
{
@ -683,16 +688,22 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
pd->base->color.a);
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
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)
{
ector_renderer_software_op_fill(pd->shape->stroke.fill);
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
x, y, mul_col, op,
pd->outline_data);
pd->outline_data,
pd->mask,
pd->mask_op);
}
else
{
@ -705,7 +716,9 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj,
pd->public_shape->stroke.color.a);
ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
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;
}
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"

View File

@ -6,6 +6,7 @@ class Ector.Renderer.Software.Shape (Ector.Renderer.Software, Ector.Renderer.Sha
Ector.Renderer.prepare;
Ector.Renderer.draw;
Ector.Renderer.Software.op_fill;
Ector.Renderer.mask { set; }
Ector.Renderer.crc { get; }
Efl.Gfx.Path.path { set; }
Efl.Object.constructor;

View File

@ -76,8 +76,8 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff
{
unsigned pxs;
if (pd->generic->immutable)
fail("This buffer is immutable.");
//if (pd->generic->immutable)
// fail("This buffer is immutable.");
if (pd->internal.maps)
fail("Can not call pixels_set when the buffer is mapped.");

View File

@ -82,9 +82,11 @@ typedef struct _Span_Data
int offx, offy;
Clip_Data clip;
Ector_Software_Buffer_Base_Data *mask;
int mask_op;
Eina_Matrix3 inv;
Span_Data_Type type;
Eina_Bool fast_matrix ;
Eina_Bool fast_matrix;
uint32_t mul_col;
Efl_Gfx_Render_Op op;
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_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);

View File

@ -14,22 +14,100 @@
static void
_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
{
RGBA_Comp_Func_Solid comp_func;
Span_Data *data = (Span_Data *)(user_data);
Span_Data *sd = user_data;
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
color = DRAW_MUL4_SYM(data->color, data->mul_col);
comp_func = efl_draw_func_solid_span_get(data->op, color);
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
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--)
{
target = buffer + ((pix_stride * spans->y) + spans->x);
comp_func(target, spans->len, color, spans->coverage);
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++)
{
*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;
}
}
@ -267,13 +345,24 @@ _span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
static void
_adjust_span_fill_methods(Span_Data *spdata)
{
//Blending Function
switch(spdata->type)
{
case None:
spdata->unclipped_blend = 0;
spdata->unclipped_blend = NULL;
break;
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;
case LinearGradient:
case RadialGradient:
@ -539,17 +628,22 @@ ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer,
rasterizer->fill_data.type = RadialGradient;
}
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)
{
// check for NULL rle data
if (!rle) return;
rasterizer->fill_data.offx = x;
rasterizer->fill_data.offy = y;
rasterizer->fill_data.mul_col = mul_col;
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);
_adjust_span_fill_methods(&rasterizer->fill_data);

View File

@ -22,17 +22,75 @@ _invalidate_cb(void *data EINA_UNUSED, const Efl_Event *event)
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
_efl_canvas_vg_container_render_pre(Eo *obj EINA_UNUSED,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
Efl_Canvas_Vg_Node_Data *nd)
_efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
Efl_VG *obj EINA_UNUSED,
Efl_Canvas_Vg_Node_Data *nd,
Ector_Surface *surface,
Eina_Matrix3 *ptransform,
Ector_Buffer *mask,
int mask_op,
void *data)
{
Efl_Canvas_Vg_Container_Data *pd = data;
Eina_List *l;
Eo *child;
Efl_Canvas_Vg_Node_Data *child_nd;
Efl_VG *child;
Efl_Gfx_Change_Flag flag;
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;
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)
{
//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.
if (efl_isa(child, EFL_CANVAS_VG_GRADIENT_CLASS))
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)
{
child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
}
_evas_vg_render_pre(child, s, current);
child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
_evas_vg_render_pre(vg_pd, child, surface, ctransform, mask, mask_op);
}
}
@ -77,16 +152,23 @@ _efl_canvas_vg_container_efl_object_constructor(Eo *obj,
static void
_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);
efl_destructor(efl_super(obj, MY_CLASS));
}
static void
_efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo *obj EINA_UNUSED,
Efl_Canvas_Vg_Container_Data *pd,
Eina_Rect *r)
Efl_Canvas_Vg_Container_Data *pd,
Eina_Rect *r)
{
Eina_Rect s;
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;
}
//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(to_it);
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 *
_efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
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_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
EINA_LIST_FOREACH(pd->children, l, child)
{

View File

@ -4,14 +4,14 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
legacy_prefix: evas_vg_container;
methods {
child_get {
[[Get child of container]]
[[Get child of container]]
params {
@in name: string; [[Child node name]]
}
return: Efl.Canvas.Vg.Node; [[Child object]]
}
children_get {
[[Get all children of container]]
[[Get all children of container]]
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.interpolate;
Efl.Duplicate.duplicate;
Efl.Canvas.Vg.Node.mask { set; }
}
}

View File

@ -56,30 +56,33 @@ _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(const Eo *obj EIN
}
static void
_efl_canvas_vg_gradient_linear_render_pre(Eo *obj,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
Efl_Canvas_Vg_Node_Data *nd)
_efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
Efl_VG *obj,
Efl_Canvas_Vg_Node_Data *nd,
Ector_Surface *surface,
Eina_Matrix3 *ptransform,
Ector_Buffer *mask,
int mask_op,
void *data)
{
Efl_Canvas_Vg_Gradient_Linear_Data *pd = data;
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;
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)
{
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();
}
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_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
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_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);
ector_renderer_prepare(nd->renderer);
ector_renderer_mask_set(nd->renderer, mask, mask_op);
}
static Eo *

View File

@ -72,11 +72,14 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_focal_get(const Eo *obj E
}
static void
_efl_canvas_vg_gradient_radial_render_pre(Eo *obj,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
Efl_Canvas_Vg_Node_Data *nd)
_efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
Efl_VG *obj,
Efl_Canvas_Vg_Node_Data *nd,
Ector_Surface *surface,
Eina_Matrix3 *ptransform,
Ector_Buffer *mask,
int mask_op,
void *data)
{
Efl_Canvas_Vg_Gradient_Radial_Data *pd = data;
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;
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)
{
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();
}
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_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
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_focal_set(nd->renderer, pd->focal.x, pd->focal.y);
efl_gfx_gradient_radial_radius_set(nd->renderer, pd->radius);
ector_renderer_prepare(nd->renderer);
ector_renderer_mask_set(nd->renderer, mask, mask_op);
}
static Eo *

View File

@ -65,6 +65,14 @@ _efl_canvas_vg_node_transformation_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Vg_
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
_efl_canvas_vg_node_origin_set(Eo *obj,
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;
}
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
_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;
//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);
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 (pd->mask)
{
nd->mask = efl_duplicate(pd->mask);
efl_parent_set(nd->mask, node);
}
nd->x = pd->x;
nd->y = pd->y;
nd->r = pd->r;

View File

@ -42,13 +42,12 @@ abstract Efl.Canvas.Vg.Node (Efl.Object, Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.
}
}
@property mask {
[[Vector graphics object mask]]
[[Set Mask Node to this renderer]]
set {
}
get {
}
values {
m: Efl.Canvas.Vg.Node; [[Object mask]]
mask: Efl.Canvas.Vg.Node; [[Mask object]]
op: int; [[Masking Option. Reserved]]
}
}
}

View File

@ -371,37 +371,71 @@ _efl_canvas_vg_object_efl_object_finalize(Eo *obj, Efl_Canvas_Vg_Object_Data *pd
static void
_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)
{
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;
Eina_List *l;
vc = efl_data_scope_get(n, EFL_CANVAS_VG_CONTAINER_CLASS);
EINA_LIST_FOREACH(vc->children, l, child)
_evas_vg_render(obj, pd,
engine, output, context, surface, child,
clips, do_async);
EINA_LIST_FOREACH(cd->children, l, child)
_evas_vg_render(obj, pd, engine, output, context, child, clips, do_async);
}
else
{
Efl_Canvas_Vg_Node_Data *nd;
nd = efl_data_scope_get(n, EFL_CANVAS_VG_NODE_CLASS);
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));
Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(node, EFL_CANVAS_VG_NODE_CLASS);
ENFN->ector_renderer_draw(engine, output, context, nd->renderer, clips, do_async);
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.
static void *
_render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
void *engine, void *surface,
Efl_VG *root, int w, int h, void *key,
void *engine, Efl_VG *root, int w, int h, void *key,
void *buffer, Eina_Bool do_async)
{
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;
}
_evas_vg_render_pre(root, ector, NULL);
_evas_vg_render_pre(obj, root, ector, NULL, NULL, 0);
//initialize buffer
context = evas_common_draw_context_new();
evas_common_draw_context_set_render_op(context, _EVAS_RENDER_COPY);
evas_common_draw_context_set_color(context, 255, 255, 255, 255);
obj->layer->evas->engine.func->ector_begin(engine, buffer,
context, surface,
ector,
0, 0,
do_async);
ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_TRUE, do_async);
//draw on buffer
_evas_vg_render(obj, pd,
engine, buffer,
context, surface,
root, NULL,
context, root,
NULL,
do_async);
obj->layer->evas->engine.func->image_dirty_region(engine, buffer, 0, 0, w, h);
obj->layer->evas->engine.func->ector_end(engine, buffer,
context, surface,
ector,do_async);
ENFN->image_dirty_region(engine, buffer, 0, 0, w, h);
ENFN->ector_end(engine, buffer, context, ector, do_async);
evas_common_draw_context_free(context);
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);
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);
else
//cache reference was increased when we get the cache.
@ -534,20 +563,15 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
if (!buffer)
{
// render to the buffer
buffer = _render_to_buffer(obj, pd,
engine, surface,
user_entry->root,
w, h,
user_entry,
buffer,
buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
w, h, user_entry, buffer,
do_async);
}
else
{
// render to the buffer
if (pd->changed)
buffer = _render_to_buffer(obj, pd,
engine, surface,
buffer = _render_to_buffer(obj, pd, engine,
user_entry->root,
w, h,
user_entry,
@ -630,7 +654,7 @@ _efl_canvas_vg_object_render_pre(Evas_Object *eo_obj,
// FIXME: handle damage only on changed renderer.
s = evas_ector_get(obj->layer->evas);
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 */
/* if it just became visible or invisible */

View File

@ -78,43 +78,45 @@ _efl_canvas_vg_shape_stroke_marker_get(const Eo *obj EINA_UNUSED,
}
static void
_efl_canvas_vg_shape_render_pre(Eo *obj EINA_UNUSED,
Eina_Matrix3 *parent,
Ector_Surface *s,
void *data,
Efl_Canvas_Vg_Node_Data *nd)
_efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd,
Efl_VG *obj,
Efl_Canvas_Vg_Node_Data *nd,
Ector_Surface *surface,
Eina_Matrix3 *ptransform,
Ector_Buffer *mask,
int mask_op,
void *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;
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);
stroke_fill = _evas_vg_render_pre(pd->stroke.fill, s, current);
stroke_marker = _evas_vg_render_pre(pd->stroke.marker, s, current);
mask = _evas_vg_render_pre(nd->mask, s, current);
fill = _evas_vg_render_pre(vg_pd, pd->fill, surface, ctransform, mask, mask_op);
stroke_fill = _evas_vg_render_pre(vg_pd, pd->stroke.fill, surface, ctransform, mask, mask_op);
stroke_marker = _evas_vg_render_pre(vg_pd, pd->stroke.marker, surface, ctransform, mask, mask_op);
if (!nd->renderer)
{
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();
}
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_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a);
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_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);
efl_gfx_path_copy_from(nd->renderer, obj);
ector_renderer_prepare(nd->renderer);
ector_renderer_mask_set(nd->renderer, mask, mask_op);
}
static Eo *

View File

@ -57,12 +57,13 @@ struct _Efl_Canvas_Vg_Node_Data
Eina_Matrix3 *m;
Efl_Canvas_Vg_Interpolation *intp;
Efl_Canvas_Vg_Node *mask;
Ector_Renderer *renderer;
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;
double x, y;
@ -74,11 +75,25 @@ struct _Efl_Canvas_Vg_Node_Data
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
{
Eina_List *children;
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
@ -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);
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;
Efl_Canvas_Vg_Node_Data *child_nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
if (child_nd) child_nd->render_pre(child, m, s, child_nd->data, child_nd);
return child_nd;
Efl_Canvas_Vg_Node_Data *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);
return nd;
}
static inline void

View File

@ -1482,9 +1482,9 @@ struct _Evas_Func
void (*ector_destroy) (void *engine, Ector_Surface *surface);
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);
void (*ector_begin) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, int x, int y, 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_end) (void *engine, void *output, void *context, void *surface, Ector_Surface *ector, 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, Ector_Renderer *r, Eina_Array *clips, 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_destroy) (void *engine, void *surface);

View File

@ -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));
}
//FIXME: Currently Ector GL doens't work properly. Use software instead.
#include "../software_generic/evas_ector_software.h"
static Ector_Buffer *
eng_ector_buffer_new(void *engine, Evas *evas, int w, int h,
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
{
return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
evas_ector_gl_buffer_prepare(efl_added, engine, w, h, cspace, flags));
/* FIXME: This condition is tricky, this buffer could be used for masking
* 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
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *output,
void *context EINA_UNUSED, void *surface EINA_UNUSED,
Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
void *context EINA_UNUSED, Ector_Renderer *renderer,
Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
{
if (use_cairo|| !use_gl)
if (use_cairo || !use_gl)
{
int w, h;
Eina_Rectangle *r;
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);
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
eng_ector_begin(void *engine, void *output,
void *context EINA_UNUSED, void *surface EINA_UNUSED,
Ector_Surface *ector, int x, int y, Eina_Bool do_async EINA_UNUSED)
eng_ector_begin(void *engine, void *surface,
void *context EINA_UNUSED, Ector_Surface *ector,
int x, int y, Eina_Bool clear, Eina_Bool do_async EINA_UNUSED)
{
if (use_cairo|| !use_gl)
{
int w, h, stride;
Evas_GL_Image *glim = output;
Evas_GL_Image *glim = surface;
DATA32 *pixels;
int load_err;
glim = eng_image_data_get(engine, glim, EINA_TRUE, &pixels, &load_err,NULL);
eng_image_stride_get(engine, glim, &stride);
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
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
eng_ector_end(void *engine, void *output,
void *context EINA_UNUSED, void *surface EINA_UNUSED,
Ector_Surface *ector, Eina_Bool do_async EINA_UNUSED)
eng_ector_end(void *engine,
void *surface,
void *context EINA_UNUSED,
Ector_Surface *ector,
Eina_Bool do_async EINA_UNUSED)
{
if (use_cairo || !use_gl)
{
Evas_GL_Image *glim = output;
Evas_GL_Image *glim = surface;
DATA32 *pixels;
int load_err;

View File

@ -34,6 +34,8 @@ endforeach
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)
shared_module(mod_full_name, engine_src,
include_directories : config_dir + [engine_include_dir],

View File

@ -411,6 +411,7 @@ struct _Evas_Thread_Command_Ector_Surface
Ector_Surface *ector;
void *pixels;
int x, y;
Eina_Bool clear;
};
// 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 *
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)
{
Ector_Buffer *buf;
@ -4293,8 +4294,8 @@ _draw_thread_ector_draw(void *data)
static void
eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
void *context, void *remove EINA_UNUSED,
Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
void *context, Ector_Renderer *renderer,
Eina_Array *clips, Eina_Bool do_async)
{
RGBA_Image *dst = surface;
RGBA_Draw_Context *dc = context;
@ -4400,7 +4401,7 @@ _draw_thread_ector_surface_set(void *data)
x = ector_surface->x;
y = ector_surface->y;
// 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);
@ -4411,20 +4412,21 @@ _draw_thread_ector_surface_set(void *data)
static void
eng_ector_begin(void *engine EINA_UNUSED, void *surface,
void *context EINA_UNUSED, void *remove EINA_UNUSED,
Ector_Surface *ector, int x, int y, Eina_Bool do_async)
void *context EINA_UNUSED, Ector_Surface *ector,
int x, int y, Eina_Bool clear, Eina_Bool do_async)
{
if (do_async)
{
Evas_Thread_Command_Ector_Surface *nes;
nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
if (!nes) return ;
if (!nes) return;
nes->ector = ector;
nes->pixels = surface;
nes->x = x;
nes->y = y;
nes->clear = clear;
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;
h = sf->cache_entry.h;
// 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_surface_reference_point_set(ector, x, y);
@ -4447,9 +4449,11 @@ eng_ector_begin(void *engine EINA_UNUSED, void *surface,
}
static void
eng_ector_end(void *engine EINA_UNUSED, void *surface EINA_UNUSED,
void *context EINA_UNUSED, void *remove EINA_UNUSED,
Ector_Surface *ector, Eina_Bool do_async)
eng_ector_end(void *engine EINA_UNUSED,
void *surface EINA_UNUSED,
void *context EINA_UNUSED,
Ector_Surface *ector,
Eina_Bool do_async)
{
if (do_async)
{