From e50628d570b10fe9455a2c6e7f49abac53f159bf Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 15 Nov 2017 08:44:13 +0900 Subject: [PATCH] ecore_evas: support output transform Change-Id: I66f1577e67a087a77b473da3c3f76f9daf91fc45 --- src/lib/ecore_wl2/Ecore_Wl2.h | 4 + src/lib/ecore_wl2/ecore_wl2_display.c | 36 ++++ src/lib/ecore_wl2/ecore_wl2_private.h | 10 + src/lib/ecore_wl2/ecore_wl2_window.c | 25 +++ .../engines/wayland/ecore_evas_wayland_common.c | 225 +++++++++++++++++++++ .../engines/wayland/ecore_evas_wayland_private.h | 6 + .../engines/wayland_common/Evas_Engine_Wayland.h | 4 + .../evas/engines/wayland_egl/evas_wl_main.c | 11 + 8 files changed, 321 insertions(+) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index bbec62e..8107c00 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -2300,6 +2300,10 @@ EAPI Eina_Bool ecore_wl2_window_pointer_warp(Ecore_Wl2_Window *win, int x, int y EAPI void ecore_wl2_sync(void); // +//TIZEN_ONLY(20171115): support output transform +EAPI Eina_Bool ecore_wl2_window_ignore_output_transform_get(Ecore_Wl2_Window *win); +// + # endif # undef EAPI diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index 047b328..8a7a240 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -600,6 +600,32 @@ static const struct tizen_clipboard_listener _tizen_clipboard_listener = }; // +//TIZEN_ONLY(20171115): support output transform +static void +_tizen_screen_rotation_cb_ignore_output_transform(void *data EINA_UNUSED, struct tizen_screen_rotation *tizen_screen_rotation EINA_UNUSED, struct wl_surface *surface, uint32_t ignore) +{ + Ecore_Wl2_Window *win = NULL; + Ecore_Wl2_Event_Ignore_Output_Transform *ev; + + if (!surface) return; + win = ecore_wl2_window_surface_find(surface); + if (!win) return; + + _ecore_wl2_window_ignore_output_transform_set(win, ignore); + + if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Ignore_Output_Transform)))) return; + + ev->win = win; + ev->ignore = (ignore) ? EINA_TRUE : EINA_FALSE; + ecore_event_add(ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM, ev, NULL, NULL); +} + +static const struct tizen_screen_rotation_listener _tizen_screen_rotation_listener = +{ + _tizen_screen_rotation_cb_ignore_output_transform, +}; +// + static void _cb_global_event_free(void *data EINA_UNUSED, void *event) { @@ -802,6 +828,15 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const _ecore_wl2_input_device_manager_setup(ewd, id, version); } // +//TIZEN_ONLY(20171115): support output transform + else if (!strcmp(interface, "tizen_screen_rotation")) + { + ewd->wl.tz_screen_rotation = + wl_registry_bind(registry, id, &tizen_screen_rotation_interface, 1); + if (ewd->wl.tz_screen_rotation) + tizen_screen_rotation_add_listener(ewd->wl.tz_screen_rotation, &_tizen_screen_rotation_listener, ewd->wl.display); + } +// // @@ -913,6 +948,7 @@ _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd) if (ewd->wl.tz_effect) tizen_effect_destroy(ewd->wl.tz_effect); if (ewd->wl.tz_indicator) tizen_indicator_destroy(ewd->wl.tz_indicator); if (ewd->wl.tz_clipboard) tizen_clipboard_destroy(ewd->wl.tz_clipboard); + if (ewd->wl.tz_screen_rotation) tizen_screen_rotation_destroy(ewd->wl.tz_screen_rotation); // if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry); diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index a4b12ca..940a486 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -108,6 +108,9 @@ struct _Ecore_Wl2_Display struct tizen_keyrouter *tz_keyrouter; struct tizen_input_device_manager *tz_input_device_manager; // + //TIZEN_ONLY(20171115): support output transform + struct tizen_screen_rotation *tz_screen_rotation; + // int compositor_version; } wl; @@ -261,6 +264,9 @@ struct _Ecore_Wl2_Window Ecore_Wl2_Window_Configure_State req_config; Ecore_Wl2_Window_Configure_State def_config; + //TIZEN_ONLY(20171115): support output transform + Eina_Bool ignore_output_transform : 1; + // Eina_Bool moving : 1; //TODO: move the iconified into the Ecore_Wl2_Window_Configure_State structure. // TIZEN_ONLY(20150822) @@ -768,6 +774,10 @@ void _ecore_wl2_keyrouter_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigne void _ecore_wl2_input_device_manager_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version); // +//TIZEN_ONLY(20171115): support output transform +void _ecore_wl2_window_ignore_output_transform_set(Ecore_Wl2_Window *window, Eina_Bool ignore); +// + EAPI extern int _ecore_wl2_event_window_www; EAPI extern int _ecore_wl2_event_window_www_drag; diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index 834bc77..9901a82 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -822,6 +822,11 @@ _ecore_wl2_window_surface_create(Ecore_Wl2_Window *window) } wl_surface_set_user_data(window->surface, window); + //TIZEN_ONLY(20171115): support output transform + if (window->display->wl.tz_screen_rotation) + tizen_screen_rotation_get_ignore_output_transform(window->display->wl.tz_screen_rotation, window->surface); + // + window->surface_id = wl_proxy_get_id((struct wl_proxy *)window->surface); if (window->display->wl.efl_aux_hints) @@ -899,6 +904,10 @@ ecore_wl2_window_new(Ecore_Wl2_Display *display, Ecore_Wl2_Window *parent, int x win->configured.edges = 0; // + //TIZEN_ONLY(20171115): support output transform + win->ignore_output_transform = EINA_TRUE; + // + win->pending.configure = EINA_TRUE; display->windows = eina_inlist_append(display->windows, EINA_INLIST_GET(win)); @@ -2869,3 +2878,19 @@ ecore_wl2_window_video_has_set(Ecore_Wl2_Window *window, Eina_Bool has) tizen_policy_has_video(display->wl.tz_policy, window->surface, has); } // + +//TIZEN_ONLY(20171115): support output transform +void +_ecore_wl2_window_ignore_output_transform_set(Ecore_Wl2_Window *window, Eina_Bool ignore) +{ + if (!window) return; + + window->ignore_output_transform = ignore; +} + +EAPI Eina_Bool +ecore_wl2_window_ignore_output_transform_get(Ecore_Wl2_Window *window) +{ + return window->ignore_output_transform; +} +// \ No newline at end of file diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c index 5d22c54..d2a4a88 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c @@ -41,6 +41,71 @@ static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location); static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize); static void _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on); +//TIZEN_ONLY(20171115): support output transform +static void _rotation_do(Ecore_Evas *ee, int rotation, int output_rotation, int resize); + +static int +_ecore_evas_wl_common_engine_rotation_get(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland *einfo; + einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas); + if (!einfo) return 0; + return einfo->info.rotation; +} + +void +_ecore_evas_wl_common_engine_info_rotation_set(Ecore_Evas *ee, Evas_Engine_Info *info) +{ + Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data; + + if (!strncmp(ee->driver, "wayland_shm", 11)) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + Evas_Engine_Info_Wayland *einfo = (Evas_Engine_Info_Wayland *)info; + einfo->info.rotation = (ee->rotation + wdata->output_rotation) % 360; + ecore_wl2_window_buffer_transform_set(wdata->win, wdata->output_rotation / 90); + WRN("evas engine rotate: %d", einfo->info.rotation); +#endif + } + else if (!strncmp(ee->driver, "wayland_egl", 11)) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL + Evas_Engine_Info_Wayland *einfo = (Evas_Engine_Info_Wayland *)info; + einfo->info.rotation = (ee->rotation + wdata->output_rotation) % 360; + /* the buffer transform information will be set in side of gl when rendering finish */ + einfo->window_rotation = ee->rotation; + WRN("evas engine rotate: %d", einfo->info.rotation); +#endif + } +} + +static Eina_Bool +_ecore_evas_wl_common_rotate_update(Ecore_Evas *ee) +{ + Ecore_Evas_Engine_Wl_Data *wdata; + int rotation; + + wdata = ee->engine.data; + + if (ecore_wl2_window_ignore_output_transform_get(wdata->win)) + rotation = 0; + else + { + Ecore_Wl2_Output *output = ecore_wl2_window_output_find(wdata->win); + rotation = ecore_wl2_output_transform_get(output) * 90; + } + + WRN("ignore_output_transform(%d) rotation(%d)", ecore_wl2_window_ignore_output_transform_get(wdata->win), rotation); + + if (_ecore_evas_wl_common_engine_rotation_get(ee) == ((rotation + ee->rotation) % 360)) + return EINA_FALSE; + + _rotation_do(ee, ee->rotation, rotation, 0); + + return EINA_TRUE; +} +// + /* local functions */ static void _anim_cb_tick(Ecore_Wl2_Window *win EINA_UNUSED, uint32_t timestamp EINA_UNUSED, void *data) @@ -408,6 +473,10 @@ _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h) } } + //TIZEN_ONLY(20171115): support output transform + _ecore_evas_wl_common_rotate_update(ee); + // + evas_output_size_get(ee->evas, &ow, &oh); if (ECORE_EVAS_PORTRAIT(ee) && ((ow != w) || (oh != h))) @@ -634,6 +703,10 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_ } } + //TIZEN_ONLY(20171115): support output transform + _ecore_evas_wl_common_rotate_update(ee); + // + return ECORE_CALLBACK_PASS_ON; } @@ -831,8 +904,17 @@ _mouse_move_dispatch(Ecore_Evas *ee) eina_iterator_free(itr); } +//TIZEN_ONLY(20171115): support output transform +/* ee->rotation shouldn't include the output rotation value. Therefore, we + * SHOULD handle the window rotation and output transform seperately. + * rotation: window rotation + * output_rotation: screen rotation static void _rotation_do(Ecore_Evas *ee, int rotation, int resize) + */ +static void +_rotation_do(Ecore_Evas *ee, int rotation, int output_rotation, int resize) +// { Evas_Engine_Info_Wayland *einfo; Ecore_Evas_Engine_Wl_Data *wdata; @@ -856,7 +938,12 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) ecore_wl2_window_rotation_set(wdata->win, rotation); /* check if rotation is just a flip */ + //TIZEN_ONLY(20171115): support output transform + /* if (rot_dif != 180) + */ + if (rot_dif % 180) + // { int minw, minh, maxw, maxh; int basew, baseh, stepw, steph; @@ -871,7 +958,12 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); /* check for fullscreen */ + //TIZEN_ONLY(20171115): support output transform + /* if (ee->prop.fullscreen) + */ + if (ee->prop.fullscreen && !ee->prop.maximized) + // { /* resize the canvas based on rotation */ if ((rotation == 0) || (rotation == 180)) @@ -934,6 +1026,9 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) /* record the current rotation of the ecore_evas */ ee->rotation = rotation; + //TIZEN_ONLY(20171115): support output transform + wdata->output_rotation = output_rotation; + // /* reset min, max, base, & step sizes */ ecore_evas_size_min_set(ee, minh, minw); @@ -953,6 +1048,9 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) { /* record the current rotation of the ecore_evas */ ee->rotation = rotation; + //TIZEN_ONLY(20171115): support output transform + wdata->output_rotation = output_rotation; + // /* send a mouse_move process * @@ -969,6 +1067,37 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize) else evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); } + + //TIZEN_ONLY(20171115): support output transform + if (!strcmp(ee->driver, "wayland_shm")) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + Evas_Engine_Info_Wayland *einfo; + einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas); + if (!einfo) return; + + _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo); + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); +#endif + } + else if (!strcmp(ee->driver, "wayland_egl")) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL + Evas_Engine_Info_Wayland *einfo; + einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas); + if (!einfo) return; + + _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo); + + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); +#endif + } + + _ecore_evas_wl_common_state_update(ee); + // } static Eina_Bool @@ -1630,6 +1759,13 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee) wdata = ee->engine.data; ee_list = eina_list_remove(ee_list, ee); + //TIZEN_ONLY(20171115): support output transform + if (wdata->output_transform_hdl) + ecore_event_handler_del(wdata->output_transform_hdl); + if (wdata->ignore_output_transform_hdl) + ecore_event_handler_del(wdata->ignore_output_transform_hdl); + // + eina_list_free(wdata->regen_objs); if (wdata->frame) ecore_wl2_window_frame_callback_del(wdata->frame); wdata->frame = NULL; @@ -1948,7 +2084,12 @@ _ecore_evas_wl_common_wm_rot_cb_angle_changed(Ecore_Wl2_Window *win, int rot, Ei einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas); if (!einfo) return; + //TIZEN_ONLY(20171115): support output transform + /* einfo->info.rotation = rot; + */ + _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo); + // if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); @@ -1961,7 +2102,12 @@ _ecore_evas_wl_common_wm_rot_cb_angle_changed(Ecore_Wl2_Window *win, int rot, Ei einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas); if (!einfo) return; + //TIZEN_ONLY(20171115): support output transform + /* einfo->info.rotation = rot; + */ + _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo); + // /* TIZEN_ONLY(20160728): wayland spec is not define whether wl_egl_window_create() can use null surface or not. @@ -2396,7 +2542,12 @@ _ecore_evas_wl_common_render_updates(void *data, Evas *evas EINA_UNUSED, void *e } if (ee->delayed.rotation_changed) { + //TIZEN_ONLY(20171115): support output transform + /* _rotation_do(ee, ee->delayed.rotation, ee->delayed.rotation_resize); + */ + Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data; + _rotation_do(ee, ee->delayed.rotation, wdata->output_rotation, ee->delayed.rotation_resize); ee->delayed.rotation_changed = EINA_FALSE; } } @@ -2821,9 +2972,79 @@ _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize) ee->delayed.rotation_changed = EINA_TRUE; } else + //TIZEN_ONLY(20171115): support output transform + /* _rotation_do(ee, rotation, resize); + */ + { + Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data; + _rotation_do(ee, rotation, wdata->output_rotation, resize); + } +} + +//TIZEN_ONLY(20171115): support output transform +static Eina_Bool +_ecore_evas_wl_common_cb_output_transform(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee = data; + Ecore_Wl2_Event_Output_Transform *ev = event; + Ecore_Evas_Engine_Wl_Data *wdata; + Ecore_Wl2_Output *output; + Eina_Bool changed; + + if (!ee) return ECORE_CALLBACK_PASS_ON; + if (!(wdata = ee->engine.data)) return ECORE_CALLBACK_PASS_ON; + if (ecore_wl2_window_iconified_get(wdata->win)) return ECORE_CALLBACK_PASS_ON; + + output = ecore_wl2_window_output_find(wdata->win); + if (output != ev->output) return ECORE_CALLBACK_PASS_ON; + + changed = _ecore_evas_wl_common_rotate_update(ee); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + if (!ee->manual_render && changed) + _ecore_evas_wl_common_render(ee); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Eina_Bool changed; + + if (!ee) return ECORE_CALLBACK_PASS_ON; + + changed = _ecore_evas_wl_common_rotate_update(ee); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + if (!ee->manual_render && changed) + _ecore_evas_wl_common_render(ee); + + return ECORE_CALLBACK_PASS_ON; } +static void +_ecore_evas_wl_common_output_transform_register(Ecore_Evas *ee) +{ + Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data; + Ecore_Wl2_Output *output; + + if (wdata->output_transform_hdl) return; + + output = ecore_wl2_window_output_find(wdata->win); + wdata->output_rotation = ecore_wl2_output_transform_get(output) * 90; + + wdata->output_transform_hdl = + ecore_event_handler_add(ECORE_WL2_EVENT_OUTPUT_TRANSFORM, + _ecore_evas_wl_common_cb_output_transform, ee); + wdata->ignore_output_transform_hdl = + ecore_event_handler_add(ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM, + _ecore_evas_wl_common_cb_ignore_output_transform, ee); +} +// + static Eina_Bool _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) { @@ -3124,6 +3345,10 @@ _ecore_evas_wl_common_new_internal(const char *disp_name, unsigned int parent, i ee->prop.aux_hint.supported_list = ecore_wl2_window_aux_hints_supported_get(wdata->win); ecore_evas_aux_hint_add(ee, "wm.policy.win.msg.use", "1"); + //TIZEN_ONLY(20171115): support output transform + _ecore_evas_wl_common_output_transform_register(ee); + // + ee->evas = evas_new(); evas_data_attach_set(ee->evas, ee); evas_output_method_set(ee->evas, method); diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h index d264df2..fcc1d8b 100644 --- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h +++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h @@ -51,6 +51,12 @@ struct _Ecore_Evas_Engine_Wl_Data Eina_List *tz_devices_list; // + //TIZEN_ONLY(20171115): support output transform + Ecore_Event_Handler *output_transform_hdl; + short output_rotation; + Ecore_Event_Handler *ignore_output_transform_hdl; + // + struct { Eina_Bool supported : 1; diff --git a/src/modules/evas/engines/wayland_common/Evas_Engine_Wayland.h b/src/modules/evas/engines/wayland_common/Evas_Engine_Wayland.h index e733825..0d16ea4 100644 --- a/src/modules/evas/engines/wayland_common/Evas_Engine_Wayland.h +++ b/src/modules/evas/engines/wayland_common/Evas_Engine_Wayland.h @@ -35,6 +35,10 @@ struct _Evas_Engine_Info_Wayland Eina_Bool drag_start : 1; Eina_Bool drag_stop : 1; Eina_Bool drag_ack : 1; + + //TIZEN_ONLY(20171115): support output transform + int window_rotation; + // }; #endif diff --git a/src/modules/evas/engines/wayland_egl/evas_wl_main.c b/src/modules/evas/engines/wayland_egl/evas_wl_main.c index 7b916cc..dfb26e1 100644 --- a/src/modules/evas/engines/wayland_egl/evas_wl_main.c +++ b/src/modules/evas/engines/wayland_egl/evas_wl_main.c @@ -349,6 +349,17 @@ eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EIN dy = ah - h; } + //TIZEN_ONLY(20171115): support output transform + /* buffer_transform: screen rotation + window rotation + * window_transform: window rotation only + * We have to let the display server know the window rotation value + * because the display server needs to calcuate the screen rotation value + * from buffer_transform value. + */ + wl_egl_window_set_buffer_transform(ob->win, ob->rot / 90); + wl_egl_window_set_window_transform(ob->win, ob->info->window_rotation / 90); + // + if ((ob->rot == 90) || (ob->rot == 270)) wl_egl_window_resize(ob->win, h, w, dx, dy); else -- 2.7.4