diff --git a/src/bin/player.c b/src/bin/player.c index 0fd10b9..de1977e 100644 --- a/src/bin/player.c +++ b/src/bin/player.c @@ -145,28 +145,100 @@ _printf(int verbose, const char *fmt, ...) va_end(ap); } +static Exactness_Image * +_snapshot_shot_get(Evas *e) +{ + Exactness_Image *ex_img; + Evas_Object *snapshot; + void *pixels; + int w, h, nb_bytes; + + if (!e) return NULL; + + evas_output_size_get(e, &w, &h); + if ((w < 1) || (h < 1)) return NULL; + + snapshot = efl_key_data_get(e, "_snapshot"); + if (!snapshot) + { + snapshot = evas_object_image_filled_add(e); + if (snapshot) + { + evas_object_image_snapshot_set(snapshot, EINA_TRUE); + evas_object_geometry_set(snapshot, 0, 0, w, h); + efl_gfx_entity_visible_set(snapshot, EINA_TRUE); + efl_key_data_set(e, "_snapshot", snapshot); + } + return NULL; + } + + pixels = evas_object_image_data_get(snapshot, EINA_FALSE); + if (!pixels) 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 +_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + if (_shot_needed) + { + Evas_Event_Render_Post *post = event->info; + void *e_data = efl_key_data_get(event->object, "_shot"); + + // Nothing was updated, so let's not bother sending nothingness + if (post && !post->updated_area) return; + Exactness_Image *ex_shot = efl_key_data_get(event->object, "_last_shot"); + if (!ex_shot) ex_shot = _snapshot_shot_get(event->object); + if (!ex_shot) return; + + efl_key_data_set(event->object, "_last_shot", NULL); + + if (_dest_type == FTYPE_DIR) + { + char *filename = e_data; + Eo *o = evas_object_image_add(event->object); + evas_object_image_size_set(o, ex_shot->w, ex_shot->h); + evas_object_image_data_set(o, ex_shot->pixels); + _printf(1, "Shot taken (%s).\n", filename); + if (!evas_object_image_save(o, filename, NULL, NULL)) + { + printf("Cannot save widget to <%s>\n", filename); + } + free(filename); + } + else if (_dest_type == FTYPE_EXU) + { + Exactness_Image *ex_img = e_data; + memcpy(ex_img, ex_shot, sizeof(Exactness_Image)); + ex_shot->pixels = NULL; + _printf(1, "Shot taken (in %s).\n", _dest); + } + exactness_image_free(ex_shot); + efl_key_data_set(event->object, "_shot", NULL); + evas_object_del(efl_key_data_get(event->object, "_snapshot")); + efl_key_data_set(event->object, "_snapshot", NULL); + /* This part is needed when the shot is needed at the end of the scenario. + * As it is async, we need to wait for the shot termination. */ + _shot_needed = EINA_FALSE; + if (_exit_required) ecore_main_loop_quit(); + } +} + static void _shot_do(Evas *e) { - Ecore_Evas *ee_orig; - int w, h; - if (!e) return; - ee_orig = ecore_evas_ecore_evas_get(e); - - ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h); - if ((w < 1) || (h < 1)) return; - if (!_disable_shots) { void *e_data = NULL; - Evas_Object *snapshot = evas_object_image_filled_add(e); - if (!snapshot) return; - evas_object_image_snapshot_set(snapshot, EINA_TRUE); - - evas_object_geometry_set(snapshot, 0, 0, w, h); - efl_gfx_entity_visible_set(snapshot, EINA_TRUE); if (_dest_type == FTYPE_DIR) { @@ -184,15 +256,16 @@ _shot_do(Evas *e) else if (_dest_type == FTYPE_EXU) { Exactness_Image *ex_img = malloc(sizeof(*ex_img)); - ex_img->w = w; - ex_img->h = h; _dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img); _dest_unit->nb_shots++; e_data = ex_img; } efl_key_data_set(e, "_shot", e_data); - efl_key_data_set(e, "_snapshot", snapshot); _shot_needed = EINA_TRUE; + Efl_Event ev; + ev.info = NULL; + ev.object = e; + _evas_render_post_cb(NULL, &ev); } if (_scan_objects && _dest_type == FTYPE_EXU) @@ -234,34 +307,6 @@ _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) { @@ -490,12 +535,15 @@ _stabilization_timer_cb(void *data EINA_UNUSED) { Eina_List *itr; Evas *e; - Eina_Bool need_more = EINA_FALSE; +#define STAB_MAX 5 + static int need_more = STAB_MAX; EINA_LIST_FOREACH(_evas_list, itr, e) { 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 *cur_img = _snapshot_shot_get(e); + if (!last_img || exactness_image_compare(last_img, cur_img, NULL)) need_more = STAB_MAX; + if (need_more != STAB_MAX) printf("cur == last\n"); + else printf("cur != last\n"); exactness_image_free(last_img); efl_key_data_set(e, "_last_shot", cur_img); } @@ -503,9 +551,8 @@ _stabilization_timer_cb(void *data EINA_UNUSED) { 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); + evas_object_del(efl_key_data_get(e, "_snapshot")); + efl_key_data_set(e, "_snapshot", NULL); } } if (!need_more) @@ -516,56 +563,12 @@ _stabilization_timer_cb(void *data EINA_UNUSED) _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); } + need_more = STAB_MAX; + printf("end stab\n"); return ECORE_CALLBACK_CANCEL; } - else return ECORE_CALLBACK_RENEW; -} - -static void -_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event) -{ - if (_shot_needed) - { - Evas_Event_Render_Post *post = event->info; - void *e_data = efl_key_data_get(event->object, "_shot"); - Evas_Object *snapshot = efl_key_data_get(event->object, "_snapshot"); - void *pixels; - int w, h; - - // Nothing was updated, so let's not bother sending nothingness - if (!post->updated_area) return; - pixels = evas_object_image_data_get(snapshot, EINA_FALSE); - if (!pixels) return; - evas_object_geometry_get(snapshot, NULL, NULL, &w, &h); - - if (_dest_type == FTYPE_DIR) - { - char *filename = e_data; - Eo *o = evas_object_image_add(event->object); - evas_object_image_size_set(o, w, h); - evas_object_image_data_set(o, pixels); - _printf(1, "Shot taken (%s).\n", filename); - if (!evas_object_image_save(o, filename, NULL, NULL)) - { - printf("Cannot save widget to <%s>\n", filename); - } - free(filename); - } - else if (_dest_type == FTYPE_EXU) - { - int nb_bytes = w * h * 4; - Exactness_Image *ex_img = e_data; - ex_img->pixels = malloc(nb_bytes); - memcpy(ex_img->pixels, pixels, nb_bytes); - _printf(1, "Shot taken (in %s).\n", _dest); - } - efl_key_data_set(event->object, "_shot", NULL); - evas_object_del(snapshot); - /* This part is needed when the shot is needed at the end of the scenario. - * As it is async, we need to wait for the shot termination. */ - _shot_needed = EINA_FALSE; - if (_exit_required) ecore_main_loop_quit(); - } + need_more--; + return ECORE_CALLBACK_RENEW; } static void