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)
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
21 @in type: const(Efl.Class); [[Efl class]] /* FIXME: Should probably be a more restricted type */ 21 @in type: const(Efl.Class); [[Efl class]] /* FIXME: Should probably be a more restricted type */
22 } 22 }
23 } 23 }
24 draw_image @pure_virtual {
25 [[ Draw image's buffer to surface buffer. ]]
26 params {
27 @in image: Ector.Buffer; [[Image buffer]]
28 @in x: int; [[Buffer position x]]
29 @in y: int; [[Buffer position y]]
30 @in alpha: int; [[Buffer alpha value]]
31 }
32 return: bool; [[True if drawing was successful]]
33 }
24 } 34 }
25} 35}
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 @@
5#include "sw_ft_raster.h" 5#include "sw_ft_raster.h"
6#include "sw_ft_stroker.h" 6#include "sw_ft_stroker.h"
7#include "../ector_private.h" 7#include "../ector_private.h"
8#include "draw.h"
8 9
9typedef struct _Ector_Software_Surface_Data Ector_Software_Surface_Data; 10typedef struct _Ector_Software_Surface_Data Ector_Software_Surface_Data;
10typedef struct _Ector_Software_Thread Ector_Software_Thread; 11typedef 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,
245 pd->y = y; 245 pd->y = y;
246} 246}
247 247
248static Eina_Bool
249_ector_software_surface_ector_surface_draw_image(Eo *obj EINA_UNUSED,
250 Ector_Software_Surface_Data *pd,
251 Ector_Buffer *buffer, int x, int y, int alpha)
252{
253 if (!buffer || !pd->rasterizer || !pd->rasterizer->fill_data.raster_buffer->pixels.u32)
254 return EINA_FALSE;
255
256 Ector_Software_Buffer_Base_Data *bd = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
257 const int pix_stride = pd->rasterizer->fill_data.raster_buffer->stride / 4;
258
259 uint32_t *src = bd->pixels.u32;
260 for (unsigned int local_y = 0; local_y < bd->generic->h; local_y++)
261 {
262 uint32_t *dst = pd->rasterizer->fill_data.raster_buffer->pixels.u32 + (x + ((local_y + y) * pix_stride));
263 for (unsigned int local_x = 0; local_x < bd->generic->w; local_x++)
264 {
265 *src = draw_mul_256(alpha, *src);
266 int inv_alpha = 255 - ((*src) >> 24);
267 *dst = *src + draw_mul_256(inv_alpha, *dst);
268 dst++;
269 src++;
270 }
271 }
272 return EINA_TRUE;
273}
248#include "ector_software_surface.eo.c" 274#include "ector_software_surface.eo.c"
249#include "ector_renderer_software.eo.c" 275#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
6 implements { 6 implements {
7 Ector.Surface.renderer_factory_new; 7 Ector.Surface.renderer_factory_new;
8 Ector.Surface.reference_point { set; } 8 Ector.Surface.reference_point { set; }
9 Ector.Surface.draw_image;
9 Efl.Object.destructor; 10 Efl.Object.destructor;
10 Efl.Object.constructor; 11 Efl.Object.constructor;
11 } 12 }
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
236_efl_canvas_vg_container_efl_object_destructor(Eo *obj, 236_efl_canvas_vg_container_efl_object_destructor(Eo *obj,
237 Efl_Canvas_Vg_Container_Data *pd) 237 Efl_Canvas_Vg_Container_Data *pd)
238{ 238{
239 if (pd->blend_pixels) free(pd->blend_pixels);
240 if (pd->blend_buffer) efl_unref(pd->blend_buffer);
241
239 //Destroy mask surface 242 //Destroy mask surface
240 if (pd->mask.buffer) efl_unref(pd->mask.buffer); 243 if (pd->mask.buffer) efl_unref(pd->mask.buffer);
241 if (pd->mask.pixels) free(pd->mask.pixels); 244 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
386static void 386static void
387_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, 387_evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd,
388 void *engine, void *output, void *context, Efl_VG *node, 388 void *engine, void *output, void *context, Efl_VG *node,
389 Eina_Array *clips, Eina_Bool do_async) 389 Eina_Array *clips, int w, int h, Ector_Surface *ector, Eina_Bool do_async)
390{ 390{
391 if (!efl_gfx_entity_visible_get(node)) return; 391 if (!efl_gfx_entity_visible_get(node)) return;
392 392
393 if (efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS)) 393 if (efl_isa(node, EFL_CANVAS_VG_CONTAINER_CLASS))
394 { 394 {
395 Efl_Canvas_Vg_Container_Data *cd = 395 Efl_VG *child;
396 efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS); 396 Eina_List *l;
397 Efl_Canvas_Vg_Container_Data *cd = efl_data_scope_get(node, EFL_CANVAS_VG_CONTAINER_CLASS);
397 398
398 if (cd->mask.target) return; //Don't draw mask itself. 399 if (cd->mask.target) return; //Don't draw mask itself.
399 400
400 Efl_VG *child; 401 int alpha = 255;
401 Eina_List *l; 402 efl_gfx_color_get(node, NULL, NULL, NULL, &alpha);
403
404 if (alpha < 255)
405 {
406 // Reuse buffer
407 if (!cd->blend_pixels)
408 cd->blend_pixels = calloc(w * h, sizeof(uint32_t*));
409 else
410 memset(cd->blend_pixels, 0, sizeof(uint32_t) * (w * h));
411
412 if (!cd->blend_buffer)
413 {
414 cd->blend_buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas,
415 w, h,
416 EFL_GFX_COLORSPACE_ARGB8888,
417 ECTOR_BUFFER_FLAG_DRAWABLE |
418 ECTOR_BUFFER_FLAG_CPU_READABLE |
419 ECTOR_BUFFER_FLAG_CPU_WRITABLE);
420 ector_buffer_pixels_set(cd->blend_buffer, cd->blend_pixels,
421 w, h, 0,
422 EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
423 }
424
425 // Buffer change
426 ector_buffer_pixels_set(ector, cd->blend_pixels,
427 w, h, 0,
428 EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
429 ector_surface_reference_point_set(ector, 0,0);
430
431 // Draw child node to changed buffer
432 EINA_LIST_FOREACH(cd->children, l, child)
433 _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
434
435 // Re-set original surface
436 ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async);
402 437
403 EINA_LIST_FOREACH(cd->children, l, child) 438 // Draw buffer to original surface.(Ector_Surface)
404 _evas_vg_render(obj, pd, engine, output, context, child, clips, do_async); 439 ector_surface_draw_image(ector, cd->blend_buffer, 0, 0, alpha);
440
441 }
442 else
443 {
444 if (cd->blend_pixels) free(cd->blend_pixels);
445 if (cd->blend_buffer) efl_unref(cd->blend_buffer);
446 EINA_LIST_FOREACH(cd->children, l, child)
447 _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async);
448 }
405 } 449 }
406 else 450 else
407 { 451 {
@@ -451,6 +495,7 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd
451 engine, buffer, 495 engine, buffer,
452 context, root, 496 context, root,
453 NULL, 497 NULL,
498 w, h, ector,
454 do_async); 499 do_async);
455 500
456 ENFN->image_dirty_region(engine, buffer, 0, 0, w, h); 501 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
94 //Masking feature. 94 //Masking feature.
95 Efl_Canvas_Vg_Node *mask_src; //Mask Source 95 Efl_Canvas_Vg_Node *mask_src; //Mask Source
96 Vg_Mask mask; //Mask source data 96 Vg_Mask mask; //Mask source data
97
98 //Layer transparency feature. This buffer is only valid when the layer has transparency.
99 Ector_Buffer *blend_buffer;
100 void *blend_pixels;
97}; 101};
98 102
99struct _Efl_Canvas_Vg_Gradient_Data 103struct _Efl_Canvas_Vg_Gradient_Data