ecore_evas: Pend the rotation until app set the rotation. 09/123009/2
authorJiyoun Park <jy0703.park@samsung.com>
Sun, 12 Feb 2017 06:54:22 +0000 (15:54 +0900)
committerJiyoun Park <jy0703.park@samsung.com>
Tue, 4 Apr 2017 07:51:47 +0000 (16:51 +0900)
Currently, camera use the elm_win_rotation_with_resize_set.
it rotate the canvas, and chage the win size also.
The reason why they use this api is to use the object rotation effect during the rotation.

If window server send rotation event during the rotation, or efl client deal with the rotation
during the app's rotation effect, it cause flickering.

Before, X backend , landscape rotation
1. set the available rotation set only 0
2. window server didn't send rotation effect
3. apps listen the devicd rotation callback
4. apps set elm_win_rotation_with_resize_set 90 or 270
5. efl client set the X property related with rotation
6. window server deals with the rotation by app side.

But now window server don't want to support this api , becuase client rotation causes the whole of rotation policy.
Opensource side, server need to support this situation, but we need to time to discuss.
to support compatibility, add this code until we find the final solution.

this concept is
1. app set pending rotation using aux_hint (it means app will deal with the rotation)
2. efl client doesn't deal with server's rotation
3. do the rotation job by app just like the server's rotation.

Change-Id: Iabe401a0277acc3a9e873a5745fc45c94f6c2c64

src/lib/ecore_evas/ecore_evas.c
src/lib/ecore_evas/ecore_evas_private.h
src/lib/ecore_wayland/ecore_wl_window.c
src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c

index eb5fa2efe4c26ecb5e0ab27ce39e9295e51e34a8..2acdd410e2f366c656942aeef65cc80d94dae6ab 100644 (file)
@@ -1334,9 +1334,31 @@ ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, in
      }
 }
 
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+
+/* TODO: We need time to set up the role of pending rotation between the server and client.
+ * and also need time to discuss this concept with opensource.
+ * so until that time, we are not open the new ecore_evas_XXX api.
+ */
+
+static void
+_ecore_evas_app_rotation_set(Ecore_Evas *ee, int rot, int resize)
+{
+   DBG("PendingRotation: ecore_evas app rotation_set rot=%d", rot);
+
+   IFC(ee, fn_rotation_set) (ee, rot, resize);
+   /* make sure everything gets redrawn */
+   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
+   evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
+   IFE;
+}
+//
+
 EAPI void
 ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
 {
+   DBG("PendingRotation: ecore_evas rotation_set rot=%d", rot);
+
    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
      {
         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
@@ -1355,6 +1377,8 @@ ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
 EAPI void
 ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot)
 {
+   DBG("PendingRotation: ecore_evas rotation_set rot=%d", rot);
+
    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
      {
         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
@@ -1363,6 +1387,12 @@ ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot)
      }
    rot = rot % 360;
    while (rot < 0) rot += 360;
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+   if (ecore_evas_data_get(ee, "pending_rotation"))
+     {
+        return _ecore_evas_app_rotation_set(ee, rot, 1);
+     }
+//
    IFC(ee, fn_rotation_set) (ee, rot, 1);
    /* make sure everything gets redrawn */
    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
@@ -2269,7 +2299,18 @@ ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val)
                          "ecore_evas_aux_hint_add");
         return -1;
      }
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+/* This is really hotfix.
+ * Until the new api is opened, we use aux_hint as pending rotation set.
+ * X don't need the pending rotation.
+ */
 
+   if(!strncmp(hint, "wm.policy.win.rot.render.nopending", strlen(hint)))
+     {
+        ee->prop.wm_rot.pending_mode.app_set = EINA_TRUE;
+        DBG("PendingRotation: ecore_evas rotation_pending_set sucess");
+     }
+//
    Eina_List *ll;
    char *supported_hint;
    if (ee->prop.aux_hint.supported_list == NULL)
@@ -2312,6 +2353,17 @@ ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val)
                        if (iface->aux_hint_add)
                          iface->aux_hint_add(ee, aux->id, hint, val);
 
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+/* This is really hotfix.
+ * But until the new api is opened, we use aux_hint as pending rotation set
+ * X don't need the pending rotation.
+ */
+                       if(!strncmp(hint, "wm.policy.win.rot.render.nopending", strlen(hint)))
+                         {
+                            ee->prop.wm_rot.pending_mode.app_set = EINA_TRUE;
+                            DBG("PendingRotation: ecore_evas rotation_pending_set sucess");
+                         }
+//
                        return aux->id;
                     }
                   else
index a259f9b59957449036258849df7ab83d696af699..875a526cb6726f336a67810c65ad837741cf57d9 100644 (file)
@@ -253,6 +253,13 @@ struct _Ecore_Evas
             Eina_Bool    wait_for_done;
             Ecore_Timer *timer;
          } manual_mode;
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+         struct {
+            Eina_Bool    app_set;        // indicate that the app rotates the canvas, because it want to rotation effect, so ee pend the rotation until app finish.
+            int          app_angle;      // rotation value which is decided by the app
+            int          wm_angle;       // rotation value which is decided by the WM
+         } pending_mode;
+//
       } wm_rot;
       struct {
          Eina_List      *supported_list;
index d3bb7f31dd41fecbc2b083bb24c6e0afd98b6434..6463273f247901af4a9328c49d8ff66a27ba45da 100644 (file)
@@ -1708,6 +1708,7 @@ _ecore_wl_window_cb_angle_change(void *data, struct tizen_rotation *tizen_rotati
 
    if (!(win = data)) return;
    if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Rotate)))) return;
+   DBG("PendingRotation: wayland rotation callback angle=%d serial=%d", angle, serial);
 
    win->tz_rot.serial = serial;
 
@@ -1742,7 +1743,10 @@ _ecore_wl_window_cb_angle_change(void *data, struct tizen_rotation *tizen_rotati
      }
 
    ecore_event_add(ECORE_WL_EVENT_WINDOW_ROTATE, ev, NULL, NULL);
-   ecore_wl_window_rotation_set(win, ev->angle);
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+   //this code don't need. This code will be added opensource code.
+   //ecore_wl_window_rotation_set(win, ev->angle);
+//
 }
 
 static void
index 2635db8180bbd6afe5375d8d72b4e7e7cc568075..a8702d8406ecf35c13fce60da9d89a03b4136c59 100755 (executable)
@@ -330,6 +330,65 @@ _ecore_evas_wl_common_cb_window_visibility_change(void *data EINA_UNUSED, int ty
 
 }
 
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+static Eina_Bool
+_ecore_evas_wl_common_cb_window_pending_rotate(Ecore_Evas *ee, Ecore_Wl_Event_Window_Rotate *ev)
+{
+   Ecore_Evas_Engine_Wl_Data *wdata;
+   DBG("PendingRotation: ecore_evas_wl pending rotation callback from WM");
+   DBG("PendingRotation: ecore_evas_wl angle app(%d) wm(%d)", ee->prop.wm_rot.pending_mode.app_angle, ee->prop.wm_rot.pending_mode.wm_angle);
+
+   wdata = ee->engine.data;
+   if (!wdata) return ECORE_CALLBACK_PASS_ON;
+
+   if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
+     return ECORE_CALLBACK_PASS_ON;
+
+//TODO: deal with the rotation difference between client and server
+//If app not set proper rotation, client cannot deal with the rotation properly.
+//Need to discuss this issue with server.
+
+//   if (ee->prop.wm_rot.pending_mode.app_angle != (int) ev->angle)
+     {
+        DBG("PendingRotation: ecore_evas_wl pend rotation");
+        ee->prop.wm_rot.pending_mode.wm_angle = ev->angle;
+        return ECORE_CALLBACK_PASS_ON;
+     }
+
+   DBG("PendingRotation: ecore_evas_wl do rotation %d", ev->angle);
+   wdata->wm_rot.request = 1;
+   wdata->wm_rot.done = 0;
+
+   if ((ee->w != ev->w) || (ee->h != ev->h))
+     {
+        _ecore_evas_wl_common_resize(ee, ev->w , ev->h);
+     }
+
+   if (ee->prop.wm_rot.manual_mode.set)
+     {
+        ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
+        _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(ee);
+     }
+
+   if (!strcmp(ee->driver, "wayland_shm"))
+     {
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+        _ecore_evas_wayland_shm_window_rotate(ee, ev->angle, 1);
+#endif
+     }
+   else if (!strcmp(ee->driver, "wayland_egl"))
+     {
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+        _ecore_evas_wayland_egl_window_rotate(ee, ev->angle, 1);
+#endif
+     }
+
+   wdata->wm_rot.done = 1;
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+//
+
 static Eina_Bool
 _ecore_evas_wl_common_cb_window_rotate(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
 {
@@ -344,6 +403,11 @@ _ecore_evas_wl_common_cb_window_rotate(void *data EINA_UNUSED, int type EINA_UNU
    if (!ee) return ECORE_CALLBACK_PASS_ON;
    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
 
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+   if (ee->prop.wm_rot.pending_mode.app_set)
+     return _ecore_evas_wl_common_cb_window_pending_rotate(ee, ev);
+   DBG("PendingRotation: ecore_evas_wl rotation callback from WM");
+//
    wdata = ee->engine.data;
    if (!wdata) return ECORE_CALLBACK_PASS_ON;
 
@@ -566,9 +630,54 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
    _ecore_evas_wl_common_state_update(ee);
 }
 
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+void
+_ecore_evas_wl_common_app_rotation_set(Ecore_Evas *ee, int rotation, int resize)
+{
+   Ecore_Evas_Engine_Wl_Data *wdata;
+
+   DBG("PendingRotation: ecore_evas_wl app rotation_set rot=%d", rotation);
+
+   ecore_evas_data_set(ee, "pending_rotation", NULL);
+
+   if (!resize) return;
+
+   wdata = ee->engine.data;
+   if (!wdata) return;
+
+   if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
+     return;
+
+   DBG("RotationPending: ecore_evas_wl do rotation %d", rotation);
+   wdata->wm_rot.request = 1;
+   wdata->wm_rot.done = 0;
+
+   if (!strcmp(ee->driver, "wayland_shm"))
+     {
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+        _ecore_evas_wayland_shm_window_rotate(ee, rotation, 1);
+#endif
+     }
+   else if (!strcmp(ee->driver, "wayland_egl"))
+     {
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+        _ecore_evas_wayland_egl_window_rotate(ee, rotation, 1);
+#endif
+     }
+
+   wdata->wm_rot.done = 1;
+}
+//
+
 void
 _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize)
 {
+// TIZEN_ONLY(20170212): pend rotation until app set rotation
+   if (ecore_evas_data_get(ee, "pending_rotation"))
+     {
+        return _ecore_evas_wl_common_app_rotation_set(ee, rotation, resize);
+     }
+//
    if (ee->in_async_render)
      {
         ee->delayed.rotation = rotation;
@@ -1852,6 +1961,7 @@ _ecore_evas_wl_common_render_flush_pre(void *data, Evas *evas EINA_UNUSED, void
    if ((wdata->wm_rot.done) &&
        (!ee->prop.wm_rot.manual_mode.set))
      {
+        DBG("PendingRotation: client sends rotation change done to server");
         wdata->wm_rot.request = 0;
         wdata->wm_rot.done = 0;
         ecore_wl_window_rotation_change_done_send(wdata->win);