pd->y = y;
}
+static Eina_Bool
+_ector_software_surface_ector_surface_draw_image(Eo *obj EINA_UNUSED,
+ Ector_Software_Surface_Data *pd,
+ Ector_Buffer *buffer, int x, int y, int alpha)
+{
+ if (!buffer || !pd->rasterizer || !pd->rasterizer->fill_data.raster_buffer->pixels.u32)
+ return EINA_FALSE;
+
+ Ector_Software_Buffer_Base_Data *bd = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+ const int pix_stride = pd->rasterizer->fill_data.raster_buffer->stride / 4;
+
+ uint32_t *src = bd->pixels.u32;
+ for (unsigned int local_y = 0; local_y < bd->generic->h; local_y++)
+ {
+ uint32_t *dst = pd->rasterizer->fill_data.raster_buffer->pixels.u32 + (x + ((local_y + y) * pix_stride));
+ for (unsigned int local_x = 0; local_x < bd->generic->w; local_x++)
+ {
+ *src = draw_mul_256(alpha, *src);
+ int inv_alpha = 255 - ((*src) >> 24);
+ *dst = *src + draw_mul_256(inv_alpha, *dst);
+ dst++;
+ src++;
+ }
+ }
+ return EINA_TRUE;
+}
#include "ector_software_surface.eo.c"
#include "ector_renderer_software.eo.c"
static void
_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
void *engine, void *output, void *context, Efl_VG *node,
- Eina_Array *clips, Eina_Bool do_async)
+ Eina_Array *clips, int w, int h, Ector_Surface *ector, Eina_Bool do_async)
{
if (!efl_gfx_entity_visible_get(node)) return;
if (efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS))
{
- Efl_Canvas_Vg_Container_Data *cd =
- efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS);
+ Efl_VG *child;
+ Eina_List *l;
+ Efl_Canvas_Vg_Container_Data *cd = efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS);
if (cd->mask.target) return; //Don't draw mask itself.
- Efl_VG *child;
- Eina_List *l;
+ int alpha = 255;
+ efl_gfx_color_get(node, NULL, NULL, NULL, &alpha);
+
+ if (alpha < 255)
+ {
+ // Reuse buffer
+ if (!cd->blend_pixels)
+ cd->blend_pixels = calloc(w * h, sizeof(uint32_t*));
+ else
+ memset(cd->blend_pixels, 0, sizeof(uint32_t) * (w * h));
+
+ if (!cd->blend_buffer)
+ {
+ cd->blend_buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas,
+ w, h,
+ EFL_GFX_COLORSPACE_ARGB8888,
+ ECTOR_BUFFER_FLAG_DRAWABLE |
+ ECTOR_BUFFER_FLAG_CPU_READABLE |
+ ECTOR_BUFFER_FLAG_CPU_WRITABLE);
+ ector_buffer_pixels_set(cd->blend_buffer, cd->blend_pixels,
+ w, h, 0,
+ EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
+ }
+
+ // Buffer change
+ ector_buffer_pixels_set(ector, cd->blend_pixels,
+ w, h, 0,
+ EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
+ ector_surface_reference_point_set(ector, 0,0);
+
+ // Draw child node to changed buffer
+ EINA_LIST_FOREACH(cd->children, l, child)
+ _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+
+ // Re-set original surface
+ ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async);
+
+ // Draw buffer to original surface.(Ector_Surface)
+ ector_surface_draw_image(ector, cd->blend_buffer, 0, 0, alpha);
- EINA_LIST_FOREACH(cd->children, l, child)
- _evas_vg_render(obj, pd, engine, output, context, child, clips, do_async);
+ }
+ else
+ {
+ if (cd->blend_pixels) free(cd->blend_pixels);
+ if (cd->blend_buffer) efl_unref(cd->blend_buffer);
+ EINA_LIST_FOREACH(cd->children, l, child)
+ _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
+ }
}
else
{
engine, buffer,
context, root,
NULL,
+ w, h, ector,
do_async);
ENFN->image_dirty_region(engine, buffer, 0, 0, w, h);