summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Bail <cedric.bail@free.fr>2019-10-31 13:20:52 -0400
committerMike Blumenkrantz <zmike@samsung.com>2019-10-31 13:29:56 -0400
commita9227fd5306ba68d020623121f3efd3f17857c76 (patch)
tree27774a9df1f0419ad17720c0e5e38860c1387af6
parent21f07b9fa980ffa181a0e88865236fc0c5bac9e7 (diff)
evas: move watching over destruction of device to custom logic due to high use.
Summary: This specific EFL_EVENT_DEL handler was registered thousand of time alone on an Evas device. Potential solution are to improve handling of this kind of large scale callback logic or just not take that path. I find it easier to have a custom code in this case to handle the destruction of Evas device and avoid this thousand of callback. Depends on D10492 Reviewers: zmike, raster, bu5hm4n, Hermet Reviewed By: zmike Subscribers: #reviewers, #committers Tags: #efl Maniphest Tasks: T8321 Differential Revision: https://phab.enlightenment.org/D10493
-rw-r--r--src/lib/evas/Evas_Internal.h5
-rw-r--r--src/lib/evas/canvas/efl_input_device.c42
-rw-r--r--src/lib/evas/canvas/evas_object_main.c98
-rw-r--r--src/lib/evas/include/evas_private.h6
4 files changed, 99 insertions, 52 deletions
diff --git a/src/lib/evas/Evas_Internal.h b/src/lib/evas/Evas_Internal.h
index 782742f5d9..d631cdcde5 100644
--- a/src/lib/evas/Evas_Internal.h
+++ b/src/lib/evas/Evas_Internal.h
@@ -38,6 +38,8 @@ extern "C" {
38 38
39#include <Efl.h> 39#include <Efl.h>
40 40
41typedef struct _Evas_Object_Pointer_Data Evas_Object_Pointer_Data;
42
41EOAPI const Eina_List *efl_input_device_children_get(const Eo *obj); 43EOAPI const Eina_List *efl_input_device_children_get(const Eo *obj);
42 44
43EOAPI void efl_input_device_evas_set(Eo *obj, Evas *e); 45EOAPI void efl_input_device_evas_set(Eo *obj, Evas *e);
@@ -46,6 +48,9 @@ EOAPI Evas *efl_input_device_evas_get(const Eo *obj);
46EOAPI void efl_input_device_subclass_set(Eo *obj, Evas_Device_Subclass sub_clas); 48EOAPI void efl_input_device_subclass_set(Eo *obj, Evas_Device_Subclass sub_clas);
47EOAPI Evas_Device_Subclass efl_input_device_subclass_get(const Eo *obj); 49EOAPI Evas_Device_Subclass efl_input_device_subclass_get(const Eo *obj);
48 50
51EOAPI void efl_input_device_grab_register(Eo *obj, Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
52EOAPI void efl_input_device_grab_unregister(Eo *obj, Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
53
49typedef struct _Efl_Input_Pointer_Data Efl_Input_Pointer_Data; 54typedef struct _Efl_Input_Pointer_Data Efl_Input_Pointer_Data;
50typedef struct _Efl_Input_Key_Data Efl_Input_Key_Data; 55typedef struct _Efl_Input_Key_Data Efl_Input_Key_Data;
51typedef struct _Efl_Input_Hold_Data Efl_Input_Hold_Data; 56typedef struct _Efl_Input_Hold_Data Efl_Input_Hold_Data;
diff --git a/src/lib/evas/canvas/efl_input_device.c b/src/lib/evas/canvas/efl_input_device.c
index 607ffd5f76..52eae92cbb 100644
--- a/src/lib/evas/canvas/efl_input_device.c
+++ b/src/lib/evas/canvas/efl_input_device.c
@@ -5,6 +5,8 @@
5#include "Evas.h" 5#include "Evas.h"
6#define EFL_INTERNAL_UNSTABLE 6#define EFL_INTERNAL_UNSTABLE
7#include "Evas_Internal.h" 7#include "Evas_Internal.h"
8#include "evas_common_private.h"
9#include "evas_private.h"
8 10
9#define MY_CLASS EFL_INPUT_DEVICE_CLASS 11#define MY_CLASS EFL_INPUT_DEVICE_CLASS
10 12
@@ -16,6 +18,9 @@ struct _Efl_Input_Device_Data
16 Eo *evas; /* Evas */ 18 Eo *evas; /* Evas */
17 Efl_Input_Device *source; /* ref */ 19 Efl_Input_Device *source; /* ref */
18 Eina_List *children; /* ref'ed by efl_parent, not by this list */ 20 Eina_List *children; /* ref'ed by efl_parent, not by this list */
21 Eina_Hash *grabs; /* Hash of all the object that might grab this device.
22 We expect thousand of them to be registered here,
23 that is why we use a hash. */
19 unsigned int id; 24 unsigned int id;
20 Efl_Input_Device_Type klass; 25 Efl_Input_Device_Type klass;
21 unsigned int subclass; // Evas_Device_Subclass (unused) 26 unsigned int subclass; // Evas_Device_Subclass (unused)
@@ -71,6 +76,12 @@ _efl_input_device_efl_object_destructor(Eo *obj, Efl_Input_Device_Data *pd)
71 } 76 }
72 efl_unref(pd->source); 77 efl_unref(pd->source);
73 78
79 if (pd->grabs)
80 {
81 eina_hash_free(pd->grabs);
82 pd->grabs = NULL;
83 }
84
74 return efl_destructor(efl_super(obj, MY_CLASS)); 85 return efl_destructor(efl_super(obj, MY_CLASS));
75} 86}
76 87
@@ -279,11 +290,42 @@ _efl_input_device_subclass_set(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
279 290
280EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_subclass_set, EFL_FUNC_CALL(sub_clas), Evas_Device_Subclass sub_clas); 291EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_subclass_set, EFL_FUNC_CALL(sub_clas), Evas_Device_Subclass sub_clas);
281 292
293static void
294_grab_del(void *data)
295{
296 Evas_Object_Pointer_Data *pdata = data;
297
298 evas_object_pointer_grab_del(pdata->obj, pdata);
299}
300
301static void
302_efl_input_device_grab_register(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
303 Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata)
304{
305 if (!pd->grabs) pd->grabs = eina_hash_pointer_new(_grab_del);
306 eina_hash_add(pd->grabs, &grab, pdata);
307}
308
309EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_grab_register, EFL_FUNC_CALL(grab, pdata),
310 Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
311
312static void
313_efl_input_device_grab_unregister(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
314 Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata)
315{
316 eina_hash_del(pd->grabs, &grab, pdata);
317}
318
319EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_grab_unregister, EFL_FUNC_CALL(grab, pdata),
320 Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
321
282#define EFL_INPUT_DEVICE_EXTRA_OPS \ 322#define EFL_INPUT_DEVICE_EXTRA_OPS \
283 EFL_OBJECT_OP_FUNC(efl_input_device_evas_get, _efl_input_device_evas_get), \ 323 EFL_OBJECT_OP_FUNC(efl_input_device_evas_get, _efl_input_device_evas_get), \
284 EFL_OBJECT_OP_FUNC(efl_input_device_evas_set, _efl_input_device_evas_set), \ 324 EFL_OBJECT_OP_FUNC(efl_input_device_evas_set, _efl_input_device_evas_set), \
285 EFL_OBJECT_OP_FUNC(efl_input_device_subclass_get, _efl_input_device_subclass_get), \ 325 EFL_OBJECT_OP_FUNC(efl_input_device_subclass_get, _efl_input_device_subclass_get), \
286 EFL_OBJECT_OP_FUNC(efl_input_device_subclass_set, _efl_input_device_subclass_set), \ 326 EFL_OBJECT_OP_FUNC(efl_input_device_subclass_set, _efl_input_device_subclass_set), \
287 EFL_OBJECT_OP_FUNC(efl_input_device_children_get, _efl_input_device_children_get), \ 327 EFL_OBJECT_OP_FUNC(efl_input_device_children_get, _efl_input_device_children_get), \
328 EFL_OBJECT_OP_FUNC(efl_input_device_grab_register, _efl_input_device_grab_register), \
329 EFL_OBJECT_OP_FUNC(efl_input_device_grab_unregister, _efl_input_device_grab_unregister),
288 330
289#include "efl_input_device.eo.c" 331#include "efl_input_device.eo.c"
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index 27ec6e2bfc..d5b20aed22 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -81,9 +81,9 @@ _init_cow(void)
81 return EINA_TRUE; 81 return EINA_TRUE;
82} 82}
83 83
84static Evas_Object_Pointer_Data * 84Evas_Object_Pointer_Data *
85_evas_object_pointer_data_find(Evas_Object_Protected_Data *obj, 85evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
86 Efl_Input_Device *pointer) 86 Efl_Input_Device *pointer)
87{ 87{
88 Evas_Object_Pointer_Data *pdata; 88 Evas_Object_Pointer_Data *pdata;
89 89
@@ -96,22 +96,6 @@ _evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
96} 96}
97 97
98static void 98static void
99_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *pdata);
100
101static void
102_evas_device_del_cb(void *data, const Efl_Event *ev)
103{
104 Evas_Object_Protected_Data *obj;
105 Evas_Object_Pointer_Data *pdata;
106
107 obj = efl_data_scope_safe_get(data, MY_CLASS);
108 EINA_SAFETY_ON_NULL_RETURN(obj);
109 pdata = _evas_object_pointer_data_find(obj, ev->object);
110 if (!pdata) return;
111 _evas_object_pointer_grab_del(obj, pdata);
112}
113
114static void
115_evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj, 99_evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
116 Evas_Object_Pointer_Data *pdata) 100 Evas_Object_Pointer_Data *pdata)
117{ 101{
@@ -138,9 +122,9 @@ _evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
138 } 122 }
139} 123}
140 124
141static void 125void
142_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, 126evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
143 Evas_Object_Pointer_Data *pdata) 127 Evas_Object_Pointer_Data *pdata)
144{ 128{
145 if ((pdata->mouse_grabbed > 0) && (obj->layer) && (obj->layer->evas)) 129 if ((pdata->mouse_grabbed > 0) && (obj->layer) && (obj->layer->evas))
146 pdata->evas_pdata->seat->mouse_grabbed -= pdata->mouse_grabbed; 130 pdata->evas_pdata->seat->mouse_grabbed -= pdata->mouse_grabbed;
@@ -151,11 +135,12 @@ _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
151 if (obj->proxy->is_proxy && obj->proxy->src_events) 135 if (obj->proxy->is_proxy && obj->proxy->src_events)
152 _evas_object_proxy_grab_del(obj, pdata); 136 _evas_object_proxy_grab_del(obj, pdata);
153 } 137 }
154 efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL, 138 if (obj->events->pointer_grabs)
155 _evas_device_del_cb, obj->object); 139 {
156 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) 140 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
157 events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata)); 141 events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata));
158 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events); 142 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
143 }
159 144
160 free(pdata); 145 free(pdata);
161} 146}
@@ -170,14 +155,13 @@ _evas_object_pointer_data_add(Evas_Pointer_Data *evas_pdata,
170 EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL); 155 EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
171 pdata->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB; 156 pdata->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
172 pdata->evas_pdata = evas_pdata; 157 pdata->evas_pdata = evas_pdata;
158 pdata->obj = obj;
173 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) 159 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
174 events->pointer_grabs = eina_inlist_append(events->pointer_grabs, 160 events->pointer_grabs = eina_inlist_append(events->pointer_grabs,
175 EINA_INLIST_GET(pdata)); 161 EINA_INLIST_GET(pdata));
176 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events); 162 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
177 163
178 efl_event_callback_priority_add(evas_pdata->pointer, EFL_EVENT_DEL, 164 efl_input_device_grab_register(evas_pdata->pointer, obj->object, pdata);
179 EFL_CALLBACK_PRIORITY_BEFORE,
180 _evas_device_del_cb, obj->object);
181 return pdata; 165 return pdata;
182} 166}
183 167
@@ -187,7 +171,7 @@ _evas_object_pointer_data_get(Evas_Pointer_Data *evas_pdata,
187{ 171{
188 Evas_Object_Pointer_Data *pdata; 172 Evas_Object_Pointer_Data *pdata;
189 173
190 pdata = _evas_object_pointer_data_find(obj, evas_pdata->pointer); 174 pdata = evas_object_pointer_data_find(obj, evas_pdata->pointer);
191 175
192 //The pointer does not exist yet - create one. 176 //The pointer does not exist yet - create one.
193 if (!pdata) 177 if (!pdata)
@@ -1068,29 +1052,39 @@ _efl_canvas_object_efl_object_invalidate(Eo *eo_obj, Evas_Object_Protected_Data
1068 evas_object_hide(eo_obj); 1052 evas_object_hide(eo_obj);
1069 1053
1070 if (obj->events) 1054 if (obj->events)
1071 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) 1055 {
1072 { 1056 Eina_Inlist *pointer_grabs;
1073 Evas_Public_Data *edata = NULL; 1057
1058 EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
1059 {
1060 Evas_Public_Data *edata = NULL;
1074 1061
1075 if (!efl_invalidated_get(evas_object_evas_get(eo_obj))) 1062 if (!efl_invalidated_get(evas_object_evas_get(eo_obj)))
1076 edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS); 1063 edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
1077 1064
1078 EINA_LIST_FREE (events->focused_by_seats, dev) 1065 EINA_LIST_FREE (events->focused_by_seats, dev)
1079 { 1066 {
1080 event_id = _evas_event_counter; 1067 event_id = _evas_event_counter;
1081 efl_event_callback_del(dev, EFL_EVENT_INVALIDATE, 1068 efl_event_callback_del(dev, EFL_EVENT_INVALIDATE,
1082 _evas_focus_device_invalidate_cb, obj); 1069 _evas_focus_device_invalidate_cb, obj);
1083 if (edata) eina_hash_del_by_key(edata->focused_objects, &dev); 1070 if (edata) eina_hash_del_by_key(edata->focused_objects, &dev);
1084 _evas_focus_dispatch_event(obj, dev, EINA_FALSE); 1071 _evas_focus_dispatch_event(obj, dev, EINA_FALSE);
1085 if ((obj->layer) && (obj->layer->evas)) 1072 if ((obj->layer) && (obj->layer->evas))
1086 _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); 1073 _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
1087 } 1074 }
1088 EINA_INLIST_FREE(events->pointer_grabs, pdata) 1075 pointer_grabs = events->pointer_grabs;
1089 _evas_object_pointer_grab_del(obj, pdata); 1076 events->pointer_grabs = NULL;
1090 EINA_LIST_FREE(events->events_whitelist, dev) 1077 EINA_LIST_FREE(events->events_whitelist, dev)
1091 efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj); 1078 efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj);
1092 } 1079 }
1093 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events); 1080 EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
1081
1082 EINA_INLIST_FREE(pointer_grabs, pdata)
1083 {
1084 pointer_grabs = eina_inlist_remove(pointer_grabs, EINA_INLIST_GET(pdata));
1085 efl_input_device_grab_unregister(pdata->evas_pdata->pointer, eo_obj, pdata);
1086 }
1087 }
1094 1088
1095 event_id = _evas_object_event_new(); 1089 event_id = _evas_object_event_new();
1096 evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_DEL, NULL, event_id, NULL); 1090 evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_DEL, NULL, event_id, NULL);
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 6906195db9..2081c3dc85 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -77,6 +77,7 @@ typedef struct _Evas_Format Evas_Format;
77typedef struct _Evas_Map_Point Evas_Map_Point; 77typedef struct _Evas_Map_Point Evas_Map_Point;
78typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array; 78typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
79typedef struct _Evas_Smart_Interfaces_Array Evas_Smart_Interfaces_Array; 79typedef struct _Evas_Smart_Interfaces_Array Evas_Smart_Interfaces_Array;
80typedef enum _Evas_Object_Intercept_Cb_Type Evas_Object_Intercept_Cb_Type;
80typedef struct _Evas_Post_Callback Evas_Post_Callback; 81typedef struct _Evas_Post_Callback Evas_Post_Callback;
81typedef struct _Evas_Coord_Touch_Point Evas_Coord_Touch_Point; 82typedef struct _Evas_Coord_Touch_Point Evas_Coord_Touch_Point;
82typedef struct _Evas_Object_Proxy_Data Evas_Object_Proxy_Data; 83typedef struct _Evas_Object_Proxy_Data Evas_Object_Proxy_Data;
@@ -1095,6 +1096,7 @@ struct _Evas_Object_Protected_State
1095struct _Evas_Object_Pointer_Data { 1096struct _Evas_Object_Pointer_Data {
1096 EINA_INLIST; 1097 EINA_INLIST;
1097 1098
1099 Evas_Object_Protected_Data *obj;
1098 Evas_Pointer_Data *evas_pdata; 1100 Evas_Pointer_Data *evas_pdata;
1099 Evas_Object_Pointer_Mode pointer_mode; 1101 Evas_Object_Pointer_Mode pointer_mode;
1100 int mouse_grabbed; 1102 int mouse_grabbed;
@@ -1679,6 +1681,10 @@ void evas_object_inform_call_image_preloaded(Evas_Object *obj);
1679void evas_object_inform_call_image_unloaded(Evas_Object *obj); 1681void evas_object_inform_call_image_unloaded(Evas_Object *obj);
1680void evas_object_inform_call_image_resize(Evas_Object *obj); 1682void evas_object_inform_call_image_resize(Evas_Object *obj);
1681void evas_object_intercept_cleanup(Evas_Object *obj); 1683void evas_object_intercept_cleanup(Evas_Object *obj);
1684Evas_Object_Pointer_Data *evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
1685 Efl_Input_Device *pointer);
1686void evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
1687 Evas_Object_Pointer_Data *pdata);
1682void evas_object_grabs_cleanup(Evas_Object *obj, Evas_Object_Protected_Data *pd); 1688void evas_object_grabs_cleanup(Evas_Object *obj, Evas_Object_Protected_Data *pd);
1683void evas_key_grab_free(Evas_Object *obj, Evas_Object_Protected_Data *pd, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers); 1689void evas_key_grab_free(Evas_Object *obj, Evas_Object_Protected_Data *pd, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
1684void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events, Eina_Bool source_invisible); 1690void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events, Eina_Bool source_invisible);