summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@yahoo.com>2018-06-10 11:58:40 +0300
committerDaniel Zaoui <daniel.zaoui@yahoo.com>2018-06-10 11:58:40 +0300
commit49e455f481387d2d6ad24c8b318276fcb2f41b24 (patch)
treeeeb25fe97590d4fb1dd799a9fe3260b220bb4bb6
parente59cca6fcee294ef640dc57b2a9f74f83d61918e (diff)
Player: try to stabilize screenshotting
Buffer evas cannot be used when the application is shown on the screen. It means the _sync_shot_get function cannot work always. That is a problem when the stabilization feature is used. That's why we need to use snapshot no matter the case. The problem is that snapshot seems to sit on the canvas and therefore doesn't forward the events, such as mouse down... So we need to create a snapshot only when needed. Additionally, stabilization feature needed to be finished. The threshold to guarantee the stabilization was not implemented.
-rw-r--r--src/bin/player.c199
1 files changed, 101 insertions, 98 deletions
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, ...)
145 va_end(ap); 145 va_end(ap);
146} 146}
147 147
148static Exactness_Image *
149_snapshot_shot_get(Evas *e)
150{
151 Exactness_Image *ex_img;
152 Evas_Object *snapshot;
153 void *pixels;
154 int w, h, nb_bytes;
155
156 if (!e) return NULL;
157
158 evas_output_size_get(e, &w, &h);
159 if ((w < 1) || (h < 1)) return NULL;
160
161 snapshot = efl_key_data_get(e, "_snapshot");
162 if (!snapshot)
163 {
164 snapshot = evas_object_image_filled_add(e);
165 if (snapshot)
166 {
167 evas_object_image_snapshot_set(snapshot, EINA_TRUE);
168 evas_object_geometry_set(snapshot, 0, 0, w, h);
169 efl_gfx_entity_visible_set(snapshot, EINA_TRUE);
170 efl_key_data_set(e, "_snapshot", snapshot);
171 }
172 return NULL;
173 }
174
175 pixels = evas_object_image_data_get(snapshot, EINA_FALSE);
176 if (!pixels) return NULL;
177
178 ex_img = malloc(sizeof(*ex_img));
179 nb_bytes = w * h * 4;
180 ex_img->w = w;
181 ex_img->h = h;
182 ex_img->pixels = malloc(nb_bytes);
183 memcpy(ex_img->pixels, pixels, nb_bytes);
184 return ex_img;
185}
186
148static void 187static void
149_shot_do(Evas *e) 188_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event)
150{ 189{
151 Ecore_Evas *ee_orig; 190 if (_shot_needed)
152 int w, h; 191 {
192 Evas_Event_Render_Post *post = event->info;
193 void *e_data = efl_key_data_get(event->object, "_shot");
153 194
154 if (!e) return; 195 // Nothing was updated, so let's not bother sending nothingness
196 if (post && !post->updated_area) return;
197 Exactness_Image *ex_shot = efl_key_data_get(event->object, "_last_shot");
198 if (!ex_shot) ex_shot = _snapshot_shot_get(event->object);
199 if (!ex_shot) return;
155 200
156 ee_orig = ecore_evas_ecore_evas_get(e); 201 efl_key_data_set(event->object, "_last_shot", NULL);
157 202
158 ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h); 203 if (_dest_type == FTYPE_DIR)
159 if ((w < 1) || (h < 1)) return; 204 {
205 char *filename = e_data;
206 Eo *o = evas_object_image_add(event->object);
207 evas_object_image_size_set(o, ex_shot->w, ex_shot->h);
208 evas_object_image_data_set(o, ex_shot->pixels);
209 _printf(1, "Shot taken (%s).\n", filename);
210 if (!evas_object_image_save(o, filename, NULL, NULL))
211 {
212 printf("Cannot save widget to <%s>\n", filename);
213 }
214 free(filename);
215 }
216 else if (_dest_type == FTYPE_EXU)
217 {
218 Exactness_Image *ex_img = e_data;
219 memcpy(ex_img, ex_shot, sizeof(Exactness_Image));
220 ex_shot->pixels = NULL;
221 _printf(1, "Shot taken (in %s).\n", _dest);
222 }
223 exactness_image_free(ex_shot);
224 efl_key_data_set(event->object, "_shot", NULL);
225 evas_object_del(efl_key_data_get(event->object, "_snapshot"));
226 efl_key_data_set(event->object, "_snapshot", NULL);
227 /* This part is needed when the shot is needed at the end of the scenario.
228 * As it is async, we need to wait for the shot termination. */
229 _shot_needed = EINA_FALSE;
230 if (_exit_required) ecore_main_loop_quit();
231 }
232}
233
234static void
235_shot_do(Evas *e)
236{
237 if (!e) return;
160 238
161 if (!_disable_shots) 239 if (!_disable_shots)
162 { 240 {
163 void *e_data = NULL; 241 void *e_data = NULL;
164 Evas_Object *snapshot = evas_object_image_filled_add(e);
165 if (!snapshot) return;
166 evas_object_image_snapshot_set(snapshot, EINA_TRUE);
167
168 evas_object_geometry_set(snapshot, 0, 0, w, h);
169 efl_gfx_entity_visible_set(snapshot, EINA_TRUE);
170 242
171 if (_dest_type == FTYPE_DIR) 243 if (_dest_type == FTYPE_DIR)
172 { 244 {
@@ -184,15 +256,16 @@ _shot_do(Evas *e)
184 else if (_dest_type == FTYPE_EXU) 256 else if (_dest_type == FTYPE_EXU)
185 { 257 {
186 Exactness_Image *ex_img = malloc(sizeof(*ex_img)); 258 Exactness_Image *ex_img = malloc(sizeof(*ex_img));
187 ex_img->w = w;
188 ex_img->h = h;
189 _dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img); 259 _dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img);
190 _dest_unit->nb_shots++; 260 _dest_unit->nb_shots++;
191 e_data = ex_img; 261 e_data = ex_img;
192 } 262 }
193 efl_key_data_set(e, "_shot", e_data); 263 efl_key_data_set(e, "_shot", e_data);
194 efl_key_data_set(e, "_snapshot", snapshot);
195 _shot_needed = EINA_TRUE; 264 _shot_needed = EINA_TRUE;
265 Efl_Event ev;
266 ev.info = NULL;
267 ev.object = e;
268 _evas_render_post_cb(NULL, &ev);
196 } 269 }
197 270
198 if (_scan_objects && _dest_type == FTYPE_EXU) 271 if (_scan_objects && _dest_type == FTYPE_EXU)
@@ -234,34 +307,6 @@ _shot_do(Evas *e)
234 } 307 }
235} 308}
236 309
237static Exactness_Image *
238_sync_shot_get(Evas *e)
239{
240 Exactness_Image *ex_img;
241 Ecore_Evas *ee_orig;
242 unsigned int *pixels;
243 int w, h, nb_bytes;
244
245 if (!e) return NULL;
246
247 ee_orig = ecore_evas_ecore_evas_get(e);
248
249 ecore_evas_manual_render(ee_orig);
250 pixels = (void *)ecore_evas_buffer_pixels_get(ee_orig);
251 if (!pixels) return NULL;
252
253 ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h);
254 if ((w < 1) || (h < 1)) return NULL;
255
256 ex_img = malloc(sizeof(*ex_img));
257 nb_bytes = w * h * 4;
258 ex_img->w = w;
259 ex_img->h = h;
260 ex_img->pixels = malloc(nb_bytes);
261 memcpy(ex_img->pixels, pixels, nb_bytes);
262 return ex_img;
263}
264
265static void 310static void
266_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data) 311_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data)
267{ 312{
@@ -490,12 +535,15 @@ _stabilization_timer_cb(void *data EINA_UNUSED)
490{ 535{
491 Eina_List *itr; 536 Eina_List *itr;
492 Evas *e; 537 Evas *e;
493 Eina_Bool need_more = EINA_FALSE; 538#define STAB_MAX 5
539 static int need_more = STAB_MAX;
494 EINA_LIST_FOREACH(_evas_list, itr, e) 540 EINA_LIST_FOREACH(_evas_list, itr, e)
495 { 541 {
496 Exactness_Image *last_img = efl_key_data_get(e, "_last_shot"); 542 Exactness_Image *last_img = efl_key_data_get(e, "_last_shot");
497 Exactness_Image *cur_img = _sync_shot_get(e); 543 Exactness_Image *cur_img = _snapshot_shot_get(e);
498 if (!last_img || exactness_image_compare(last_img, cur_img, NULL)) need_more = EINA_TRUE; 544 if (!last_img || exactness_image_compare(last_img, cur_img, NULL)) need_more = STAB_MAX;
545 if (need_more != STAB_MAX) printf("cur == last\n");
546 else printf("cur != last\n");
499 exactness_image_free(last_img); 547 exactness_image_free(last_img);
500 efl_key_data_set(e, "_last_shot", cur_img); 548 efl_key_data_set(e, "_last_shot", cur_img);
501 } 549 }
@@ -503,9 +551,8 @@ _stabilization_timer_cb(void *data EINA_UNUSED)
503 { 551 {
504 if (!need_more) 552 if (!need_more)
505 { 553 {
506 Exactness_Image *last_img = efl_key_data_get(e, "_last_shot"); 554 evas_object_del(efl_key_data_get(e, "_snapshot"));
507 exactness_image_free(last_img); 555 efl_key_data_set(e, "_snapshot", NULL);
508 efl_key_data_set(e, "_last_shot", NULL);
509 } 556 }
510 } 557 }
511 if (!need_more) 558 if (!need_more)
@@ -516,56 +563,12 @@ _stabilization_timer_cb(void *data EINA_UNUSED)
516 _printf(2, " %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0); 563 _printf(2, " %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0);
517 ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL); 564 ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
518 } 565 }
566 need_more = STAB_MAX;
567 printf("end stab\n");
519 return ECORE_CALLBACK_CANCEL; 568 return ECORE_CALLBACK_CANCEL;
520 } 569 }
521 else return ECORE_CALLBACK_RENEW; 570 need_more--;
522} 571 return ECORE_CALLBACK_RENEW;
523
524static void
525_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event)
526{
527 if (_shot_needed)
528 {
529 Evas_Event_Render_Post *post = event->info;
530 void *e_data = efl_key_data_get(event->object, "_shot");
531 Evas_Object *snapshot = efl_key_data_get(event->object, "_snapshot");
532 void *pixels;
533 int w, h;
534
535 // Nothing was updated, so let's not bother sending nothingness
536 if (!post->updated_area) return;
537 pixels = evas_object_image_data_get(snapshot, EINA_FALSE);
538 if (!pixels) return;
539 evas_object_geometry_get(snapshot, NULL, NULL, &w, &h);
540
541 if (_dest_type == FTYPE_DIR)
542 {
543 char *filename = e_data;
544 Eo *o = evas_object_image_add(event->object);
545 evas_object_image_size_set(o, w, h);
546 evas_object_image_data_set(o, pixels);
547 _printf(1, "Shot taken (%s).\n", filename);
548 if (!evas_object_image_save(o, filename, NULL, NULL))
549 {
550 printf("Cannot save widget to <%s>\n", filename);
551 }
552 free(filename);
553 }
554 else if (_dest_type == FTYPE_EXU)
555 {
556 int nb_bytes = w * h * 4;
557 Exactness_Image *ex_img = e_data;
558 ex_img->pixels = malloc(nb_bytes);
559 memcpy(ex_img->pixels, pixels, nb_bytes);
560 _printf(1, "Shot taken (in %s).\n", _dest);
561 }
562 efl_key_data_set(event->object, "_shot", NULL);
563 evas_object_del(snapshot);
564 /* This part is needed when the shot is needed at the end of the scenario.
565 * As it is async, we need to wait for the shot termination. */
566 _shot_needed = EINA_FALSE;
567 if (_exit_required) ecore_main_loop_quit();
568 }
569} 572}
570 573
571static void 574static void