From 667171d1d9b4c3cbe4150b5e70882591e310c77b Mon Sep 17 00:00:00 2001 From: Daniel Zaoui Date: Wed, 16 May 2018 17:55:35 +0300 Subject: [PATCH] Player: improve the stabilization mechanism The goal is to support applications where editable entries are used. The problem is the text cursor that, even if we disable its animation through the theme overlay, triggers the render post event, which breaks all the previous method used to detect stability. Now, every 100ms, we compare the current canvas image with the previous saved shot. --- src/bin/player.c | 75 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/src/bin/player.c b/src/bin/player.c index 48a8f9d..65ba9ec 100644 --- a/src/bin/player.c +++ b/src/bin/player.c @@ -125,8 +125,6 @@ static int _cur_shot_id = 0; static Eina_Bool _shot_needed = EINA_FALSE; static Eina_Bool _scan_objects = EINA_FALSE, _disable_shots = EINA_FALSE; -static Eina_Bool _stabilization_needed = EINA_FALSE; -static Ecore_Timer *_stabilization_timer = NULL; static Eina_Bool _stabilization_timer_cb(void *); static Eina_Bool _exit_required = EINA_FALSE; @@ -231,6 +229,34 @@ _shot_do(Evas *e) } } +static Exactness_Image * +_sync_shot_get(Evas *e) +{ + Exactness_Image *ex_img; + Ecore_Evas *ee_orig; + unsigned int *pixels; + int w, h, nb_bytes; + + if (!e) return NULL; + + ee_orig = ecore_evas_ecore_evas_get(e); + + ecore_evas_manual_render(ee_orig); + pixels = (void *)ecore_evas_buffer_pixels_get(ee_orig); + if (!pixels) return NULL; + + ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h); + if ((w < 1) || (h < 1)) return NULL; + + ex_img = malloc(sizeof(*ex_img)); + nb_bytes = w * h * 4; + ex_img->w = w; + ex_img->h = h; + ex_img->pixels = malloc(nb_bytes); + memcpy(ex_img->pixels, pixels, nb_bytes); + return ex_img; +} + static void _feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data) { @@ -422,8 +448,7 @@ _feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data) { _printf(2, "%s stabilize\n", __func__); if (rect) evas_object_color_set(rect, 255, 165, 0, 255); - _stabilization_needed = EINA_TRUE; - _stabilization_timer = ecore_timer_add(1.0, _stabilization_timer_cb, NULL); + ecore_timer_add(0.1, _stabilization_timer_cb, NULL); break; } default: /* All non-input events are not handeled */ @@ -458,26 +483,42 @@ _feed_event_timer_cb(void *data EINA_UNUSED) static Eina_Bool _stabilization_timer_cb(void *data EINA_UNUSED) { - if (!_stabilization_needed) return ECORE_CALLBACK_CANCEL; - _stabilization_needed = EINA_FALSE; - if (_src_type != FTYPE_REMOTE) + Eina_List *itr; + Evas *e; + Eina_Bool need_more = EINA_FALSE; + EINA_LIST_FOREACH(_evas_list, itr, e) { - Exactness_Action *act = eina_list_data_get(_cur_event_list); - _printf(2, " %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0); - ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL); + Exactness_Image *last_img = efl_key_data_get(e, "_last_shot"); + Exactness_Image *cur_img = _sync_shot_get(e); + if (!last_img || exactness_image_compare(last_img, cur_img, NULL)) need_more = EINA_TRUE; + exactness_image_free(last_img); + efl_key_data_set(e, "_last_shot", cur_img); } - return ECORE_CALLBACK_CANCEL; + EINA_LIST_FOREACH(_evas_list, itr, e) + { + if (!need_more) + { + Exactness_Image *last_img = efl_key_data_get(e, "_last_shot"); + exactness_image_free(last_img); + efl_key_data_set(e, "_last_shot", NULL); + } + } + if (!need_more) + { + if (_src_type != FTYPE_REMOTE) + { + Exactness_Action *act = eina_list_data_get(_cur_event_list); + _printf(2, " %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0); + ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL); + } + return ECORE_CALLBACK_CANCEL; + } + else return ECORE_CALLBACK_RENEW; } static void _evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event) { - if (_stabilization_needed) - { - _printf(2, "Not stable yet...\n"); - ecore_timer_del(_stabilization_timer); - _stabilization_timer = ecore_timer_add(1.0, _stabilization_timer_cb, NULL); - } if (_shot_needed) { Evas_Event_Render_Post *post = event->info;