summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorDerek Foreman <derek.foreman.samsung@gmail.com>2018-07-31 17:02:12 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-07-31 17:03:16 -0400
commite7bcf0e690e75b13db022adaeeab1ab86c459540 (patch)
tree9660bfc48c7cebd1b41f13811667ae341d754b14 /src/lib
parent3524d48719e7815792a28bf624468b21d5030736 (diff)
evas: Defer render post callbacks added during async render
Summary: To take screenshots, Enlightenment makes a new snapshot object, performs a manual render, and uses the snapshot results. Turns out if this happens while an async render is in progress, the async render's completion triggers a render post callback on the snapshot object even though it's never been involved in a render. We need to defer new render post callbacks until any currently running render completes, then add them during that render's post. Fix T7156 Reviewers: devilhorns, zmike Reviewed By: devilhorns, zmike Subscribers: devilhorns, cedric, #committers, zmike Tags: #efl Maniphest Tasks: T7156 Differential Revision: https://phab.enlightenment.org/D6711
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c62
-rw-r--r--src/lib/evas/canvas/evas_render.c1
-rw-r--r--src/lib/evas/include/evas_private.h3
3 files changed, 63 insertions, 3 deletions
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index 0814b6fa5b..bb4face262 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -107,6 +107,7 @@ typedef struct
107 void *data; 107 void *data;
108 Evas_Callback_Type type; 108 Evas_Callback_Type type;
109 Efl_Event_Info_Type efl_event_type; 109 Efl_Event_Info_Type efl_event_type;
110 Evas_Callback_Priority priority;
110} Evas_Event_Cb_Wrapper_Info; 111} Evas_Event_Cb_Wrapper_Info;
111 112
112static int 113static int
@@ -563,6 +564,24 @@ evas_event_callback_add(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func,
563 func, data); 564 func, data);
564} 565}
565 566
567void
568_deferred_callbacks_process(Evas *eo_e, Evas_Public_Data *e)
569{
570 Evas_Event_Cb_Wrapper_Info *cb_info;
571 const Efl_Event_Description *desc;
572
573 while (e->deferred_callbacks)
574 {
575 cb_info = EINA_INLIST_CONTAINER_GET(e->deferred_callbacks,
576 Evas_Event_Cb_Wrapper_Info);
577 e->deferred_callbacks = eina_inlist_remove(e->deferred_callbacks,
578 e->deferred_callbacks);
579 desc = _legacy_evas_callback_table(cb_info->type);
580 efl_event_callback_priority_add(eo_e, desc, cb_info->priority, _eo_evas_cb, cb_info);
581 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info));
582 }
583}
584
566EAPI void 585EAPI void
567evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data) 586evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data)
568{ 587{
@@ -581,13 +600,22 @@ evas_event_callback_priority_add(Evas *eo_e, Evas_Callback_Type type, Evas_Callb
581 cb_info = calloc(1, sizeof(*cb_info)); 600 cb_info = calloc(1, sizeof(*cb_info));
582 cb_info->func.evas_cb = func; 601 cb_info->func.evas_cb = func;
583 cb_info->data = (void *)data; 602 cb_info->data = (void *)data;
603 cb_info->priority = priority;
584 cb_info->type = type; 604 cb_info->type = type;
585 cb_info->efl_event_type = _evas_event_efl_event_info_type(type); 605 cb_info->efl_event_type = _evas_event_efl_event_info_type(type);
586 606
587 desc = _legacy_evas_callback_table(type); 607 if ((e->rendering || e->inside_post_render) && type == EVAS_CALLBACK_RENDER_POST)
588 efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info); 608 {
609 e->deferred_callbacks = eina_inlist_append(e->deferred_callbacks,
610 EINA_INLIST_GET(cb_info));
611 }
612 else
613 {
614 desc = _legacy_evas_callback_table(type);
615 efl_event_callback_priority_add(eo_e, desc, priority, _eo_evas_cb, cb_info);
589 616
590 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info)); 617 e->callbacks = eina_inlist_append(e->callbacks, EINA_INLIST_GET(cb_info));
618 }
591} 619}
592 620
593EAPI void * 621EAPI void *
@@ -604,6 +632,20 @@ evas_event_callback_del(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb func)
604 632
605 if (!e->callbacks) return NULL; 633 if (!e->callbacks) return NULL;
606 634
635 if (type == EVAS_CALLBACK_RENDER_POST)
636 EINA_INLIST_REVERSE_FOREACH(e->deferred_callbacks, info)
637 {
638 if (info->func.evas_cb == func)
639 {
640 void *tmp = info->data;
641
642 e->deferred_callbacks =
643 eina_inlist_remove(e->deferred_callbacks, EINA_INLIST_GET(info));
644 free(info);
645 return tmp;
646 }
647 }
648
607 EINA_INLIST_REVERSE_FOREACH(e->callbacks, info) 649 EINA_INLIST_REVERSE_FOREACH(e->callbacks, info)
608 { 650 {
609 if ((info->func.evas_cb == func) && (info->type == type)) 651 if ((info->func.evas_cb == func) && (info->type == type))
@@ -634,6 +676,20 @@ evas_event_callback_del_full(Evas *eo_e, Evas_Callback_Type type, Evas_Event_Cb
634 676
635 if (!e->callbacks) return NULL; 677 if (!e->callbacks) return NULL;
636 678
679 if (type == EVAS_CALLBACK_RENDER_POST)
680 EINA_INLIST_REVERSE_FOREACH(e->deferred_callbacks, info)
681 {
682 if ((info->func.evas_cb == func) && (info->data == data))
683 {
684 void *tmp = info->data;
685
686 e->deferred_callbacks =
687 eina_inlist_remove(e->deferred_callbacks, EINA_INLIST_GET(info));
688 free(info);
689 return tmp;
690 }
691 }
692
637 EINA_INLIST_FOREACH(e->callbacks, info) 693 EINA_INLIST_FOREACH(e->callbacks, info)
638 { 694 {
639 if ((info->func.evas_cb == func) && (info->type == type) && (info->data == data)) 695 if ((info->func.evas_cb == func) && (info->type == type) && (info->data == data))
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index f03a6a5cab..0a915a19df 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -3838,6 +3838,7 @@ evas_render_wakeup(Evas *eo_e)
3838 post.updated_area = ret_updates; 3838 post.updated_area = ret_updates;
3839 _cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post); 3839 _cb_always_call(eo_e, EVAS_CALLBACK_RENDER_POST, &post);
3840 evas->inside_post_render = EINA_FALSE; 3840 evas->inside_post_render = EINA_FALSE;
3841 _deferred_callbacks_process(eo_e, evas);
3841 3842
3842 evas_render_updates_free(ret_updates); 3843 evas_render_updates_free(ret_updates);
3843 3844
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index bded8892b6..a63194df3f 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -860,6 +860,7 @@ struct _Evas_Public_Data
860 Eina_List *post_events; // free me on evas_free 860 Eina_List *post_events; // free me on evas_free
861 861
862 Eina_Inlist *callbacks; 862 Eina_Inlist *callbacks;
863 Eina_Inlist *deferred_callbacks;
863 864
864 int delete_grabs; 865 int delete_grabs;
865 int walking_grabs; 866 int walking_grabs;
@@ -1914,6 +1915,8 @@ void _efl_canvas_gesture_manager_callback_add_hook(Eo *gesture_manager, Eo *targ
1914void evas_focus_init(void); 1915void evas_focus_init(void);
1915void evas_focus_shutdown(void); 1916void evas_focus_shutdown(void);
1916 1917
1918void _deferred_callbacks_process(Evas *eo_e, Evas_Public_Data *e);
1919
1917extern Eina_Cow *evas_object_proxy_cow; 1920extern Eina_Cow *evas_object_proxy_cow;
1918extern Eina_Cow *evas_object_map_cow; 1921extern Eina_Cow *evas_object_map_cow;
1919extern Eina_Cow *evas_object_state_cow; 1922extern Eina_Cow *evas_object_state_cow;