summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHermet Park <hermet@hermet.pe.kr>2019-12-19 17:01:25 +0900
committerHermet Park <hermetpark@gmail.com>2019-12-19 17:01:25 +0900
commit8465904c19ea3de2c94c25259ca6a75d0241b4f1 (patch)
tree37769b373805a0d4ca62509b49c06ca98a76e1f6
parentfb301eea87bcade60bf7b2304c805f00147276e6 (diff)
ector software: catch up losing tasks among the threads.
Summary: ector sw uses thread pool internally to process rle job parallel. First of all, we lost task handles which allocated to each threads, we must free the task data after thread done. Secondly, tasks can be managed by one shape instance, the instance can't catch upon multiple instances alive. only last task can be attached to the shape instance. Thus, obvisouly the instance doesn't expect to handle multiple tasks at the same time, one instance only take care of one task on threading pool. Reviewers: jsuya, cedric, smohanty, kimcinoo Reviewed By: jsuya Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D10916
-rw-r--r--src/lib/ector/software/ector_renderer_software_shape.c55
1 files changed, 22 insertions, 33 deletions
diff --git a/src/lib/ector/software/ector_renderer_software_shape.c b/src/lib/ector/software/ector_renderer_software_shape.c
index 573774d..0db1ea2 100644
--- a/src/lib/ector/software/ector_renderer_software_shape.c
+++ b/src/lib/ector/software/ector_renderer_software_shape.c
@@ -42,8 +42,6 @@ struct _Ector_Renderer_Software_Shape_Data
42 Efl_Gfx_Vg_Composite_Method comp_method; 42 Efl_Gfx_Vg_Composite_Method comp_method;
43 43
44 Ector_Software_Shape_Task *task; 44 Ector_Software_Shape_Task *task;
45
46 Eina_Bool done;
47}; 45};
48 46
49typedef struct _Outline 47typedef struct _Outline
@@ -535,43 +533,37 @@ _generate_shape_data(Ector_Renderer_Software_Shape_Data *pd)
535static Ector_Software_Shape_Task * 533static Ector_Software_Shape_Task *
536_need_update_rle(Eo *obj, Ector_Renderer_Software_Shape_Data *pd) 534_need_update_rle(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
537{ 535{
538 Ector_Software_Shape_Task *r; 536 if (pd->task) return pd->task;
539 const Efl_Gfx_Path_Command *cmds;
540 const double *pts;
541 Efl_Gfx_Fill_Rule fill_rule;
542
543 if (!pd->done && pd->task) return pd->task;
544 537
545 if (!_generate_stroke_data(pd) && 538 if (!_generate_stroke_data(pd) &&
546 !_generate_shape_data(pd)) 539 !_generate_shape_data(pd))
547 return NULL; 540 return NULL;
548 541
542 const Efl_Gfx_Path_Command *cmds;
543 const double *pts;
549 efl_gfx_path_get(obj, &cmds, &pts); 544 efl_gfx_path_get(obj, &cmds, &pts);
550 fill_rule = efl_gfx_shape_fill_rule_get(obj);
551
552 if (!cmds) return NULL; 545 if (!cmds) return NULL;
553 546
554 r = pd->task; 547 Ector_Software_Shape_Task *task = malloc(sizeof(Ector_Software_Shape_Task));
555 if (!r) r = malloc(sizeof (Ector_Software_Shape_Task)); 548 if (!task) return NULL;
556 if (!r) return NULL;
557 549
558 r->pd = pd; 550 task->pd = pd;
559 r->cmds = cmds; 551 task->cmds = cmds;
560 r->pts = pts; 552 task->pts = pts;
561 r->fill_rule = fill_rule; 553 task->fill_rule = efl_gfx_shape_fill_rule_get(obj);
562 554
563 pd->done = EINA_FALSE; 555 pd->task = task;
564 pd->task = r;
565 556
566 return r; 557 return task;
567} 558}
568 559
569static void 560static void
570_done_rle(void *data) 561_done_rle(void *data)
571{ 562{
572 Ector_Software_Shape_Task *task = data; 563 Ector_Software_Shape_Task *task = data;
573 if (task && task->pd) 564 if (!task) return;
574 task->pd->done = EINA_TRUE; 565 if (task->pd) task->pd->task = NULL;
566 free(task);
575} 567}
576 568
577static void 569static void
@@ -635,30 +627,30 @@ static Eina_Bool
635_ector_renderer_software_shape_ector_renderer_prepare(Eo *obj, 627_ector_renderer_software_shape_ector_renderer_prepare(Eo *obj,
636 Ector_Renderer_Software_Shape_Data *pd) 628 Ector_Renderer_Software_Shape_Data *pd)
637{ 629{
638 Ector_Software_Shape_Task *task;
639
640 // FIXME: shouldn't this be moved to the software base object? 630 // FIXME: shouldn't this be moved to the software base object?
641 if (!pd->surface) 631 if (!pd->surface)
642 pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj); 632 pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
643 633
644 // Asynchronously lazy build of the RLE data for this shape 634 // Asynchronously lazy build of the RLE data for this shape
645 task = _need_update_rle(obj, pd); 635 if (!pd->task)
646 if (task) ector_software_schedule(_update_rle, _done_rle, task); 636 {
637 Ector_Software_Shape_Task *task = _need_update_rle(obj, pd);
638 if (task) ector_software_schedule(_update_rle, _done_rle, task);
639 }
647 640
648 return EINA_TRUE; 641 return EINA_TRUE;
649} 642}
650 643
651static Eina_Bool 644static Eina_Bool
652_ector_renderer_software_shape_ector_renderer_draw(Eo *obj, 645_ector_renderer_software_shape_ector_renderer_draw(Eo *obj EINA_UNUSED,
653 Ector_Renderer_Software_Shape_Data *pd, 646 Ector_Renderer_Software_Shape_Data *pd,
654 Efl_Gfx_Render_Op op, Eina_Array *clips, 647 Efl_Gfx_Render_Op op, Eina_Array *clips,
655 unsigned int mul_col) 648 unsigned int mul_col)
656{ 649{
657 Ector_Software_Shape_Task *task;
658 int x, y; 650 int x, y;
659 651
660 // check if RLE data are ready 652 // check if RLE data are ready
661 task = _need_update_rle(obj, pd); 653 Ector_Software_Shape_Task *task = pd->task;
662 if (task) ector_software_wait(_update_rle, _done_rle, task); 654 if (task) ector_software_wait(_update_rle, _done_rle, task);
663 655
664 // adjust the offset 656 // adjust the offset
@@ -757,8 +749,6 @@ _ector_renderer_software_shape_efl_object_constructor(Eo *obj, Ector_Renderer_So
757 obj = efl_constructor(efl_super(obj, MY_CLASS)); 749 obj = efl_constructor(efl_super(obj, MY_CLASS));
758 if (!obj) return NULL; 750 if (!obj) return NULL;
759 751
760 pd->task = NULL;
761 pd->done = EINA_FALSE;
762 pd->public_shape = efl_data_xref(obj, EFL_GFX_SHAPE_MIXIN, obj); 752 pd->public_shape = efl_data_xref(obj, EFL_GFX_SHAPE_MIXIN, obj);
763 pd->shape = efl_data_xref(obj, ECTOR_RENDERER_SHAPE_MIXIN, obj); 753 pd->shape = efl_data_xref(obj, ECTOR_RENDERER_SHAPE_MIXIN, obj);
764 pd->base = efl_data_xref(obj, ECTOR_RENDERER_CLASS, obj); 754 pd->base = efl_data_xref(obj, ECTOR_RENDERER_CLASS, obj);
@@ -771,14 +761,13 @@ _ector_renderer_software_shape_efl_object_destructor(Eo *obj, Ector_Renderer_Sof
771{ 761{
772 // FIXME: As base class, destructor can't call destructor of mixin class. 762 // FIXME: As base class, destructor can't call destructor of mixin class.
773 // Call explicit API to free shape data. 763 // Call explicit API to free shape data.
774 if (!pd->done && pd->task) 764 if (pd->task)
775 ector_software_wait(_update_rle, _done_rle, pd->task); 765 ector_software_wait(_update_rle, _done_rle, pd->task);
776 766
777 efl_gfx_path_reset(obj); 767 efl_gfx_path_reset(obj);
778 768
779 if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data); 769 if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
780 if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data); 770 if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
781 free(pd->task);
782 771
783 efl_data_xunref(pd->base->surface, pd->surface, obj); 772 efl_data_xunref(pd->base->surface, pd->surface, obj);
784 efl_data_xunref(obj, pd->base, obj); 773 efl_data_xunref(obj, pd->base, obj);