Player: make the screenshot retrieval asynchronous

This commit is contained in:
Daniel Zaoui 2018-05-06 22:48:22 +03:00
parent 637285018f
commit d049f0cc2c
3 changed files with 100 additions and 76 deletions

View File

@ -117,18 +117,20 @@ static const char *_test_name = NULL;
static int _verbose = 0;
static Evas *(*_evas_new)(void) = NULL;
static int _ignore_evas_creation = 0;
static Eina_List *_evas_list = NULL;
static Eina_List *_cur_event_list = NULL;
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;
static void
_printf(int verbose, const char *fmt, ...)
{
@ -144,39 +146,29 @@ static void
_shot_do(Evas *e)
{
Ecore_Evas *ee_orig;
unsigned int *pixels;
int w, h;
Eina_Bool alpha;
if (!e) return;
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;
alpha = ecore_evas_alpha_get(ee_orig);
ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h);
if ((w < 1) || (h < 1)) return;
if (_dest_type == FTYPE_DIR)
if (!_disable_shots)
{
if (!_disable_shots)
void *e_data;
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)
{
int dir_name_len;
char *filename;
Evas_Object *o;
Ecore_Evas *ee;
_ignore_evas_creation++;
ee = ecore_evas_buffer_new(1, 1);
_ignore_evas_creation--;
o = evas_object_image_add(ecore_evas_get(ee));
evas_object_image_alpha_set(o, alpha);
evas_object_image_size_set(o, w, h);
evas_object_image_data_set(o, pixels);
dir_name_len = strlen(_dest) + 1; /* includes space of a '/' */
filename = malloc(strlen(_test_name) + strlen(IMAGE_FILENAME_EXT) +
@ -184,68 +176,58 @@ _shot_do(Evas *e)
sprintf(filename, "%s/%s%c%03d%s", _dest, _test_name,
SHOT_DELIMITER, _cur_shot_id, IMAGE_FILENAME_EXT);
_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);
ecore_evas_free(ee);
e_data = filename;
}
}
else if (_dest_type == FTYPE_EXU)
{
if (!_disable_shots)
else if (_dest_type == FTYPE_EXU)
{
Exactness_Image *ex_img = malloc(sizeof(*ex_img));
int nb_bytes = w * h * 4;
ex_img->w = w;
ex_img->h = h;
ex_img->alpha = alpha;
ex_img->pixels = malloc(nb_bytes);
memcpy(ex_img->pixels, pixels, nb_bytes);
_dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img);
_dest_unit->nb_shots++;
_printf(1, "Shot taken (in %s).\n", _dest);
e_data = ex_img;
}
efl_key_data_set(e, "_shot", e_data);
efl_key_data_set(e, "_snapshot", snapshot);
_shot_needed = EINA_TRUE;
}
if (_scan_objects)
if (_scan_objects && _dest_type == FTYPE_EXU)
{
Eina_Iterator *iter;
Eo *obj;
Exactness_Objects *e_objs = calloc(1, sizeof(*e_objs));
iter = eo_objects_iterator_new();
EINA_ITERATOR_FOREACH(iter, obj)
{
Eina_Iterator *iter;
Eo *obj;
Exactness_Objects *e_objs = calloc(1, sizeof(*e_objs));
iter = eo_objects_iterator_new();
EINA_ITERATOR_FOREACH(iter, obj)
if (!efl_isa(obj, EFL_CANVAS_OBJECT_CLASS) &&
!efl_isa(obj, EFL_CANVAS_SCENE_INTERFACE)) continue;
Exactness_Object *e_obj = calloc(1, sizeof(*e_obj));
Eo *parent = efl_parent_get(obj);
e_obj->id = (long long) obj;
if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS) ||
efl_isa(parent, EFL_CANVAS_SCENE_INTERFACE))
{
if (!efl_isa(obj, EFL_CANVAS_OBJECT_CLASS) &&
!efl_isa(obj, EFL_CANVAS_SCENE_INTERFACE)) continue;
Exactness_Object *e_obj = calloc(1, sizeof(*e_obj));
Eo *parent = efl_parent_get(obj);
e_obj->id = (long long) obj;
if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS) ||
efl_isa(parent, EFL_CANVAS_SCENE_INTERFACE))
{
e_obj->parent_id = (long long) efl_parent_get(obj);
}
else
{
e_obj->parent_id = 0;
}
e_obj->kl_name = eina_stringshare_add(efl_class_name_get(obj));
if (efl_isa(obj, EFL_CANVAS_OBJECT_CLASS))
{
Eina_Size2D sz = efl_gfx_entity_size_get(obj);
e_obj->w = sz.w;
e_obj->h = sz.h;
Eina_Position2D pos = efl_gfx_entity_position_get(obj);
e_obj->x = pos.x;
e_obj->y = pos.y;
}
e_objs->objs = eina_list_append(e_objs->objs, e_obj);
e_obj->parent_id = (long long) efl_parent_get(obj);
}
eina_iterator_free(iter);
_dest_unit->objs = eina_list_append(_dest_unit->objs, e_objs);
else
{
e_obj->parent_id = 0;
}
e_obj->kl_name = eina_stringshare_add(efl_class_name_get(obj));
if (efl_isa(obj, EFL_CANVAS_OBJECT_CLASS))
{
Eina_Size2D sz = efl_gfx_entity_size_get(obj);
e_obj->w = sz.w;
e_obj->h = sz.h;
Eina_Position2D pos = efl_gfx_entity_position_get(obj);
e_obj->x = pos.x;
e_obj->y = pos.y;
}
e_objs->objs = eina_list_append(e_objs->objs, e_obj);
}
eina_iterator_free(iter);
_dest_unit->objs = eina_list_append(_dest_unit->objs, e_objs);
}
}
@ -458,7 +440,8 @@ _feed_event_timer_cb(void *data EINA_UNUSED)
_cur_event_list = eina_list_next(_cur_event_list);
if (!_cur_event_list)
{ /* Finished reading all events */
ecore_main_loop_quit();
_exit_required = EINA_TRUE;
if (!_shot_needed) ecore_main_loop_quit();
}
else
{
@ -487,7 +470,7 @@ _stabilization_timer_cb(void *data EINA_UNUSED)
}
static void
_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
if (_stabilization_needed)
{
@ -495,6 +478,48 @@ _evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
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;
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();
}
}
static void
@ -830,7 +855,7 @@ _my_evas_new(int w EINA_UNUSED, int h EINA_UNUSED)
Evas *e;
if (!_evas_new) return NULL;
e = _evas_new();
if (e && !_ignore_evas_creation)
if (e)
{
_printf(1, "New Evas\n");
_evas_list = eina_list_append(_evas_list, e);

View File

@ -183,7 +183,6 @@ typedef struct
{
unsigned int w; /**< Width of the image */
unsigned int h; /**< Height of the image */
int alpha; /**< Alpha of the image */
void *pixels; /**< Pixels of the image */
} Exactness_Image;

View File

@ -267,7 +267,7 @@ exactness_unit_file_read(const char *filename)
Exactness_Image *ex_img = malloc(sizeof(*ex_img));
sprintf(entry, "images/%d", i + 1);
ex_img->pixels = eet_data_image_read(file, entry,
&ex_img->w, &ex_img->h, &ex_img->alpha,
&ex_img->w, &ex_img->h, NULL,
NULL, NULL, NULL);
unit->imgs = eina_list_append(unit->imgs, ex_img);
}
@ -310,7 +310,7 @@ exactness_unit_file_write(Exactness_Unit *unit, const char *filename)
char entry[16];
sprintf(entry, "images/%d", i++);
eet_data_image_write(file, entry,
ex_img->pixels, ex_img->w, ex_img->h, ex_img->alpha,
ex_img->pixels, ex_img->w, ex_img->h, 0xFF,
0, 100, EET_IMAGE_LOSSLESS);
}
eet_close(file);