e_mod_rotation_wl: fix bug for rotation pending show 97/274797/1
authorDoyoun Kang <doyoun.kang@samsung.com>
Mon, 9 May 2022 13:31:09 +0000 (22:31 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Mon, 9 May 2022 13:32:23 +0000 (22:32 +0900)
There was a bug that the window didn't show because the ec's e.state.rot.pending_show
was set.

Normal case:
1. receive a tizen_rotation_ack_angle_change request
2. receive a buffer change event
   ==> unset pending_show
3. show window

Abnormal case:
1. timeout occurs (couldn't receive a tizen_rotation_ack_angle_change request)
   ==> unset pending_show
2. show window forcely by timeout
   ==> set pending_show again
3. receive a tizen_rotation_ack_angle_change request
4. receive a buffer change event
   ==> can not unset pending_show
5. can not show window

So, we add code that call _e_tizen_rotation_angle_change function to clear internal
variables when a timeout occurs.

Change-Id: Id9f4f3bfcfae353a933e0d4652340245788c98c5

src/rotation/e_mod_rotation_wl.c

index 4b57ad9..bf2a0ac 100644 (file)
@@ -559,6 +559,69 @@ _create_rotation_wait_update_done_timer(Policy_Ext_Rotation *rot)
 }
 
 static void
+_e_tizen_rotation_angle_change(Policy_Ext_Rotation *rot)
+{
+   E_Client *ec;
+
+   if (!rot) return;
+   if (!rot->ec) return;
+   if (!rot->angle_change_done) return;
+
+   ec = rot->ec;
+
+   ec->e.state.rot.ang.prev = ec->e.state.rot.ang.curr;
+   ec->e.state.rot.ang.curr = TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle);
+
+   if (TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle) == ec->e.state.rot.ang.next)
+     {
+        ec->e.state.rot.ang.next = -1;
+
+        if (ec->e.state.rot.ang.reserve != -1)
+          {
+             _e_client_rotation_list_remove(ec);
+
+             e_client_rotation_set(ec, ec->e.state.rot.ang.reserve);
+             ec->e.state.rot.ang.reserve = -1;
+          }
+        else
+          {
+             /* it means that we need the next buffer commit after rotation ack event.
+              * once we get next buffer commit, policy module attempts to remove
+              * this ec from rotation_list_remove. and then, rotation process is finished.
+              */
+             rot->wait_update = EINA_TRUE;
+
+             /* WORKAROUND
+              *
+              * Until now, we have assumed that the buffer commit event after the rotation
+              * ack event informs us of completion of rotation. However this assumption could
+              * be wrong because the rotation ack event is dispatched by main thread of client,
+              * whereas the buffer commit event could be dispatched by other thread.
+              *
+              * The ideal solution for resolving this issue is introduction of same protocol
+              * serial number between the rotation ack event and buffer commit event. But this
+              * approach needs much of changes for EFL, E20 and DDK. Thus I have added workaround
+              * code for quick resolving this.
+              *
+              * We have to extend EFL, E20 and DDK to support this later.
+              */
+             if (_browser_check(ec))
+               {
+                  if (rot->wait_update_pending.timer)
+                    ecore_timer_del(rot->wait_update_pending.timer);
+
+                  rot->wait_update_pending.timer = NULL;
+                  rot->wait_update_pending.use = EINA_TRUE;
+                  rot->wait_update_pending.count = 2;
+               }
+          }
+     }
+
+   // check angle change serial
+   rot->angle_change_done = EINA_TRUE;
+}
+
+static void
 _e_tizen_rotation_ack_angle_change_cb(struct wl_client *client,
                                       struct wl_resource *resource,
                                       uint32_t serial)
@@ -586,53 +649,7 @@ _e_tizen_rotation_ack_angle_change_cb(struct wl_client *client,
              return;
           }
 
-        ec->e.state.rot.ang.prev = ec->e.state.rot.ang.curr;
-        ec->e.state.rot.ang.curr = TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle);
-
-        if (TIZEN_ROTATION_ANGLE_TO_INT(rot->cur_angle) == ec->e.state.rot.ang.next)
-          {
-             ec->e.state.rot.ang.next = -1;
-
-             if (ec->e.state.rot.ang.reserve != -1)
-               {
-                  _e_client_rotation_list_remove(ec);
-
-                  e_client_rotation_set(ec, ec->e.state.rot.ang.reserve);
-                  ec->e.state.rot.ang.reserve = -1;
-               }
-             else
-               {
-                  /* it means that we need the next buffer commit after rotation ack event.
-                   * once we get next buffer commit, policy module attempts to remove
-                   * this ec from rotation_list_remove. and then, rotation process is finished.
-                   */
-                  rot->wait_update = EINA_TRUE;
-
-                  /* WORKAROUND
-                   *
-                   * Until now, we have assumed that the buffer commit event after the rotation
-                   * ack event informs us of completion of rotation. However this assumption could
-                   * be wrong because the rotation ack event is dispatched by main thread of client,
-                   * whereas the buffer commit event could be dispatched by other thread.
-                   *
-                   * The ideal solution for resolving this issue is introduction of same protocol
-                   * serial number between the rotation ack event and buffer commit event. But this
-                   * approach needs much of changes for EFL, E20 and DDK. Thus I have added workaround
-                   * code for quick resolving this.
-                   *
-                   * We have to extend EFL, E20 and DDK to support this later.
-                   */
-                  if (_browser_check(ec))
-                    {
-                       if (rot->wait_update_pending.timer)
-                         ecore_timer_del(rot->wait_update_pending.timer);
-
-                       rot->wait_update_pending.timer = NULL;
-                       rot->wait_update_pending.use = EINA_TRUE;
-                       rot->wait_update_pending.count = 2;
-                    }
-               }
-          }
+        _e_tizen_rotation_angle_change(rot);
      }
    else // rotation fail
      {
@@ -2357,6 +2374,12 @@ _e_client_rotation_wait_update_clear(E_Client *ec)
    rot->wait_update_pending.timer = NULL;
    _remove_rotation_wait_update_done_timer(rot);
 
+   if (!rot->angle_change_done)
+     {
+        ELOGF("ROTATION", "TIMEOUT... waiting for rotation_ack_done... angle change by force", ec);
+        _e_tizen_rotation_angle_change(rot);
+     }
+
    _e_client_rotation_list_remove(ec);
    if (ec->e.state.rot.pending_show)
      {