forked from enlightenment/efl
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
This commit is contained in:
parent
21f07b9fa9
commit
a9227fd530
|
@ -38,6 +38,8 @@ extern "C" {
|
|||
|
||||
#include <Efl.h>
|
||||
|
||||
typedef struct _Evas_Object_Pointer_Data Evas_Object_Pointer_Data;
|
||||
|
||||
EOAPI const Eina_List *efl_input_device_children_get(const Eo *obj);
|
||||
|
||||
EOAPI void efl_input_device_evas_set(Eo *obj, Evas *e);
|
||||
|
@ -46,6 +48,9 @@ EOAPI Evas *efl_input_device_evas_get(const Eo *obj);
|
|||
EOAPI void efl_input_device_subclass_set(Eo *obj, Evas_Device_Subclass sub_clas);
|
||||
EOAPI Evas_Device_Subclass efl_input_device_subclass_get(const Eo *obj);
|
||||
|
||||
EOAPI void efl_input_device_grab_register(Eo *obj, Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
|
||||
EOAPI void efl_input_device_grab_unregister(Eo *obj, Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
|
||||
|
||||
typedef struct _Efl_Input_Pointer_Data Efl_Input_Pointer_Data;
|
||||
typedef struct _Efl_Input_Key_Data Efl_Input_Key_Data;
|
||||
typedef struct _Efl_Input_Hold_Data Efl_Input_Hold_Data;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "Evas.h"
|
||||
#define EFL_INTERNAL_UNSTABLE
|
||||
#include "Evas_Internal.h"
|
||||
#include "evas_common_private.h"
|
||||
#include "evas_private.h"
|
||||
|
||||
#define MY_CLASS EFL_INPUT_DEVICE_CLASS
|
||||
|
||||
|
@ -16,6 +18,9 @@ struct _Efl_Input_Device_Data
|
|||
Eo *evas; /* Evas */
|
||||
Efl_Input_Device *source; /* ref */
|
||||
Eina_List *children; /* ref'ed by efl_parent, not by this list */
|
||||
Eina_Hash *grabs; /* Hash of all the object that might grab this device.
|
||||
We expect thousand of them to be registered here,
|
||||
that is why we use a hash. */
|
||||
unsigned int id;
|
||||
Efl_Input_Device_Type klass;
|
||||
unsigned int subclass; // Evas_Device_Subclass (unused)
|
||||
|
@ -71,6 +76,12 @@ _efl_input_device_efl_object_destructor(Eo *obj, Efl_Input_Device_Data *pd)
|
|||
}
|
||||
efl_unref(pd->source);
|
||||
|
||||
if (pd->grabs)
|
||||
{
|
||||
eina_hash_free(pd->grabs);
|
||||
pd->grabs = NULL;
|
||||
}
|
||||
|
||||
return efl_destructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
|
@ -279,11 +290,42 @@ _efl_input_device_subclass_set(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
|
|||
|
||||
EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_subclass_set, EFL_FUNC_CALL(sub_clas), Evas_Device_Subclass sub_clas);
|
||||
|
||||
static void
|
||||
_grab_del(void *data)
|
||||
{
|
||||
Evas_Object_Pointer_Data *pdata = data;
|
||||
|
||||
evas_object_pointer_grab_del(pdata->obj, pdata);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_input_device_grab_register(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
|
||||
Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata)
|
||||
{
|
||||
if (!pd->grabs) pd->grabs = eina_hash_pointer_new(_grab_del);
|
||||
eina_hash_add(pd->grabs, &grab, pdata);
|
||||
}
|
||||
|
||||
EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_grab_register, EFL_FUNC_CALL(grab, pdata),
|
||||
Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
|
||||
|
||||
static void
|
||||
_efl_input_device_grab_unregister(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd,
|
||||
Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata)
|
||||
{
|
||||
eina_hash_del(pd->grabs, &grab, pdata);
|
||||
}
|
||||
|
||||
EOAPI EFL_VOID_FUNC_BODYV(efl_input_device_grab_unregister, EFL_FUNC_CALL(grab, pdata),
|
||||
Efl_Canvas_Object *grab, Evas_Object_Pointer_Data *pdata);
|
||||
|
||||
#define EFL_INPUT_DEVICE_EXTRA_OPS \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_evas_get, _efl_input_device_evas_get), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_evas_set, _efl_input_device_evas_set), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_subclass_get, _efl_input_device_subclass_get), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_subclass_set, _efl_input_device_subclass_set), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_children_get, _efl_input_device_children_get), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_grab_register, _efl_input_device_grab_register), \
|
||||
EFL_OBJECT_OP_FUNC(efl_input_device_grab_unregister, _efl_input_device_grab_unregister),
|
||||
|
||||
#include "efl_input_device.eo.c"
|
||||
|
|
|
@ -81,9 +81,9 @@ _init_cow(void)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Evas_Object_Pointer_Data *
|
||||
_evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
|
||||
Efl_Input_Device *pointer)
|
||||
Evas_Object_Pointer_Data *
|
||||
evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
|
||||
Efl_Input_Device *pointer)
|
||||
{
|
||||
Evas_Object_Pointer_Data *pdata;
|
||||
|
||||
|
@ -95,22 +95,6 @@ _evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *pdata);
|
||||
|
||||
static void
|
||||
_evas_device_del_cb(void *data, const Efl_Event *ev)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj;
|
||||
Evas_Object_Pointer_Data *pdata;
|
||||
|
||||
obj = efl_data_scope_safe_get(data, MY_CLASS);
|
||||
EINA_SAFETY_ON_NULL_RETURN(obj);
|
||||
pdata = _evas_object_pointer_data_find(obj, ev->object);
|
||||
if (!pdata) return;
|
||||
_evas_object_pointer_grab_del(obj, pdata);
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
|
||||
Evas_Object_Pointer_Data *pdata)
|
||||
|
@ -138,9 +122,9 @@ _evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
|
||||
Evas_Object_Pointer_Data *pdata)
|
||||
void
|
||||
evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
|
||||
Evas_Object_Pointer_Data *pdata)
|
||||
{
|
||||
if ((pdata->mouse_grabbed > 0) && (obj->layer) && (obj->layer->evas))
|
||||
pdata->evas_pdata->seat->mouse_grabbed -= pdata->mouse_grabbed;
|
||||
|
@ -151,11 +135,12 @@ _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
|
|||
if (obj->proxy->is_proxy && obj->proxy->src_events)
|
||||
_evas_object_proxy_grab_del(obj, pdata);
|
||||
}
|
||||
efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL,
|
||||
_evas_device_del_cb, obj->object);
|
||||
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
|
||||
events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata));
|
||||
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
|
||||
if (obj->events->pointer_grabs)
|
||||
{
|
||||
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
|
||||
events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata));
|
||||
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
|
||||
}
|
||||
|
||||
free(pdata);
|
||||
}
|
||||
|
@ -170,14 +155,13 @@ _evas_object_pointer_data_add(Evas_Pointer_Data *evas_pdata,
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
|
||||
pdata->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
|
||||
pdata->evas_pdata = evas_pdata;
|
||||
pdata->obj = obj;
|
||||
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
|
||||
events->pointer_grabs = eina_inlist_append(events->pointer_grabs,
|
||||
EINA_INLIST_GET(pdata));
|
||||
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
|
||||
|
||||
efl_event_callback_priority_add(evas_pdata->pointer, EFL_EVENT_DEL,
|
||||
EFL_CALLBACK_PRIORITY_BEFORE,
|
||||
_evas_device_del_cb, obj->object);
|
||||
efl_input_device_grab_register(evas_pdata->pointer, obj->object, pdata);
|
||||
return pdata;
|
||||
}
|
||||
|
||||
|
@ -187,7 +171,7 @@ _evas_object_pointer_data_get(Evas_Pointer_Data *evas_pdata,
|
|||
{
|
||||
Evas_Object_Pointer_Data *pdata;
|
||||
|
||||
pdata = _evas_object_pointer_data_find(obj, evas_pdata->pointer);
|
||||
pdata = evas_object_pointer_data_find(obj, evas_pdata->pointer);
|
||||
|
||||
//The pointer does not exist yet - create one.
|
||||
if (!pdata)
|
||||
|
@ -1068,29 +1052,39 @@ _efl_canvas_object_efl_object_invalidate(Eo *eo_obj, Evas_Object_Protected_Data
|
|||
evas_object_hide(eo_obj);
|
||||
|
||||
if (obj->events)
|
||||
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
|
||||
{
|
||||
Evas_Public_Data *edata = NULL;
|
||||
{
|
||||
Eina_Inlist *pointer_grabs;
|
||||
|
||||
if (!efl_invalidated_get(evas_object_evas_get(eo_obj)))
|
||||
edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
|
||||
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
|
||||
{
|
||||
Evas_Public_Data *edata = NULL;
|
||||
|
||||
EINA_LIST_FREE (events->focused_by_seats, dev)
|
||||
{
|
||||
event_id = _evas_event_counter;
|
||||
efl_event_callback_del(dev, EFL_EVENT_INVALIDATE,
|
||||
_evas_focus_device_invalidate_cb, obj);
|
||||
if (edata) eina_hash_del_by_key(edata->focused_objects, &dev);
|
||||
_evas_focus_dispatch_event(obj, dev, EINA_FALSE);
|
||||
if ((obj->layer) && (obj->layer->evas))
|
||||
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
|
||||
}
|
||||
EINA_INLIST_FREE(events->pointer_grabs, pdata)
|
||||
_evas_object_pointer_grab_del(obj, pdata);
|
||||
EINA_LIST_FREE(events->events_whitelist, dev)
|
||||
efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj);
|
||||
}
|
||||
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
|
||||
if (!efl_invalidated_get(evas_object_evas_get(eo_obj)))
|
||||
edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
|
||||
|
||||
EINA_LIST_FREE (events->focused_by_seats, dev)
|
||||
{
|
||||
event_id = _evas_event_counter;
|
||||
efl_event_callback_del(dev, EFL_EVENT_INVALIDATE,
|
||||
_evas_focus_device_invalidate_cb, obj);
|
||||
if (edata) eina_hash_del_by_key(edata->focused_objects, &dev);
|
||||
_evas_focus_dispatch_event(obj, dev, EINA_FALSE);
|
||||
if ((obj->layer) && (obj->layer->evas))
|
||||
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
|
||||
}
|
||||
pointer_grabs = events->pointer_grabs;
|
||||
events->pointer_grabs = NULL;
|
||||
EINA_LIST_FREE(events->events_whitelist, dev)
|
||||
efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj);
|
||||
}
|
||||
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
|
||||
|
||||
EINA_INLIST_FREE(pointer_grabs, pdata)
|
||||
{
|
||||
pointer_grabs = eina_inlist_remove(pointer_grabs, EINA_INLIST_GET(pdata));
|
||||
efl_input_device_grab_unregister(pdata->evas_pdata->pointer, eo_obj, pdata);
|
||||
}
|
||||
}
|
||||
|
||||
event_id = _evas_object_event_new();
|
||||
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_DEL, NULL, event_id, NULL);
|
||||
|
|
|
@ -77,6 +77,7 @@ typedef struct _Evas_Format Evas_Format;
|
|||
typedef struct _Evas_Map_Point Evas_Map_Point;
|
||||
typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
|
||||
typedef struct _Evas_Smart_Interfaces_Array Evas_Smart_Interfaces_Array;
|
||||
typedef enum _Evas_Object_Intercept_Cb_Type Evas_Object_Intercept_Cb_Type;
|
||||
typedef struct _Evas_Post_Callback Evas_Post_Callback;
|
||||
typedef struct _Evas_Coord_Touch_Point Evas_Coord_Touch_Point;
|
||||
typedef struct _Evas_Object_Proxy_Data Evas_Object_Proxy_Data;
|
||||
|
@ -1095,6 +1096,7 @@ struct _Evas_Object_Protected_State
|
|||
struct _Evas_Object_Pointer_Data {
|
||||
EINA_INLIST;
|
||||
|
||||
Evas_Object_Protected_Data *obj;
|
||||
Evas_Pointer_Data *evas_pdata;
|
||||
Evas_Object_Pointer_Mode pointer_mode;
|
||||
int mouse_grabbed;
|
||||
|
@ -1679,6 +1681,10 @@ void evas_object_inform_call_image_preloaded(Evas_Object *obj);
|
|||
void evas_object_inform_call_image_unloaded(Evas_Object *obj);
|
||||
void evas_object_inform_call_image_resize(Evas_Object *obj);
|
||||
void evas_object_intercept_cleanup(Evas_Object *obj);
|
||||
Evas_Object_Pointer_Data *evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
|
||||
Efl_Input_Device *pointer);
|
||||
void evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
|
||||
Evas_Object_Pointer_Data *pdata);
|
||||
void evas_object_grabs_cleanup(Evas_Object *obj, Evas_Object_Protected_Data *pd);
|
||||
void evas_key_grab_free(Evas_Object *obj, Evas_Object_Protected_Data *pd, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
|
||||
void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events, Eina_Bool source_invisible);
|
||||
|
|
Loading…
Reference in New Issue