summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunsuChoi <jsuya.choi@samsung.com>2019-06-20 16:07:05 +0900
committerHermet Park <hermetpark@gmail.com>2019-06-20 16:07:05 +0900
commitc7b1a40b5ec2d63ce32be3d78e60ea1f3206140a (patch)
tree08ff2ad827d7258ae93cd3205f46a0fd75119dc2
parentc27c4692043140fef014dad3ff18c88c929772d8 (diff)
downloadefl-c7b1a40b5ec2d63ce32be3d78e60ea1f3206140a.tar.gz
ector: Fix precomp layer rendering issue when it has alpha value
Summary: When the precomp layer(parent layer) has alpha transparency and has more than 1 child layer and they overlap each other if vg object just propagate the alpha to child layer it will be applied twice in overlapped area. Even if the child layer does not have alpha transparency, parent alpha is applied to each child. Test Plan: N/A Reviewers: Hermet, smohanty Reviewed By: Hermet Subscribers: cedric, #reviewers, kimcinoo, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9072
-rw-r--r--src/lib/ector/ector_surface.eo10
-rw-r--r--src/lib/ector/software/ector_software_private.h1
-rw-r--r--src/lib/ector/software/ector_software_surface.c26
-rw-r--r--src/lib/ector/software/ector_software_surface.eo1
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_container.c3
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg_object.c59
-rw-r--r--src/lib/evas/canvas/evas_vg_private.h4
7 files changed, 97 insertions, 7 deletions
diff --git a/src/lib/ector/ector_surface.eo b/src/lib/ector/ector_surface.eo
index 0dcfff28ac..67a4813368 100644
--- a/src/lib/ector/ector_surface.eo
+++ b/src/lib/ector/ector_surface.eo
@@ -21,5 +21,15 @@ mixin @beta Ector.Surface extends Ector.Buffer
@in type: const(Efl.Class); [[Efl class]] /* FIXME: Should probably be a more restricted type */
}
}
+ draw_image @pure_virtual {
+ [[ Draw image's buffer to surface buffer. ]]
+ params {
+ @in image: Ector.Buffer; [[Image buffer]]
+ @in x: int; [[Buffer position x]]
+ @in y: int; [[Buffer position y]]
+ @in alpha: int; [[Buffer alpha value]]
+ }
+ return: bool; [[True if drawing was successful]]
+ }
}
}
diff --git a/src/lib/ector/software/ector_software_private.h b/src/lib/ector/software/ector_software_private.h
index 34ea0038b7..62d1c3f8fd 100644
--- a/src/lib/ector/software/ector_software_private.h
+++ b/src/lib/ector/software/ector_software_private.h
@@ -5,6 +5,7 @@
#include "sw_ft_raster.h"
#include "sw_ft_stroker.h"
#include "../ector_private.h"
+#include "draw.h"
typedef struct _Ector_Software_Surface_Data Ector_Software_Surface_Data;
typedef struct _Ector_Software_Thread Ector_Software_Thread;
diff --git a/src/lib/ector/software/ector_software_surface.c b/src/lib/ector/software/ector_software_surface.c
index 10cf9962fd..08a2786f16 100644
--- a/src/lib/ector/software/ector_software_surface.c
+++ b/src/lib/ector/software/ector_software_surface.c
@@ -245,5 +245,31 @@ _ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED,
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"
diff --git a/src/lib/ector/software/ector_software_surface.eo b/src/lib/ector/software/ector_software_surface.eo
index 77d6db28a3..62126401b8 100644
--- a/src/lib/ector/software/ector_software_surface.eo
+++ b/src/lib/ector/software/ector_software_surface.eo
@@ -6,6 +6,7 @@ class @beta Ector.Software.Surface extends Ector.Software.Buffer implements Ecto
implements {
Ector.Surface.renderer_factory_new;
Ector.Surface.reference_point { set; }
+ Ector.Surface.draw_image;
Efl.Object.destructor;
Efl.Object.constructor;
}
diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c
index 9598168956..2c55071a4d 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_container.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_container.c
@@ -236,6 +236,9 @@ static void
_efl_canvas_vg_container_efl_object_destructor(Eo *obj,
Efl_Canvas_Vg_Container_Data *pd)
{
+ if (pd->blend_pixels) free(pd->blend_pixels);
+ if (pd->blend_buffer) efl_unref(pd->blend_buffer);
+
//Destroy mask surface
if (pd->mask.buffer) efl_unref(pd->mask.buffer);
if (pd->mask.pixels) free(pd->mask.pixels);
diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c
index c4e7c2b861..026640a80a 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_object.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_object.c
@@ -386,22 +386,66 @@ _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, 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);
- EINA_LIST_FOREACH(cd->children, l, child)
- _evas_vg_render(obj, pd, engine, output, context, child, clips, do_async);
+ // Draw buffer to original surface.(Ector_Surface)
+ ector_surface_draw_image(ector, cd->blend_buffer, 0, 0, alpha);
+
+ }
+ 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
{
@@ -451,6 +495,7 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
engine, buffer,
context, root,
NULL,
+ w, h, ector,
do_async);
ENFN->image_dirty_region(engine, buffer, 0, 0, w, h);
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
index f4c47de4bb..73ff63e7d8 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -94,6 +94,10 @@ struct _Efl_Canvas_Vg_Container_Data
//Masking feature.
Efl_Canvas_Vg_Node *mask_src; //Mask Source
Vg_Mask mask; //Mask source data
+
+ //Layer transparency feature. This buffer is only valid when the layer has transparency.
+ Ector_Buffer *blend_buffer;
+ void *blend_pixels;
};
struct _Efl_Canvas_Vg_Gradient_Data