e_comp_wl: adding window rotation information to surface's buffer transform 85/136085/3
authorBoram Park <boram1288.park@samsung.com>
Thu, 15 Jun 2017 04:46:51 +0000 (13:46 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Fri, 30 Jun 2017 04:45:06 +0000 (04:45 +0000)
To show a client buffer via a HW overlay, the client buffer status is exactly
same with WR 90(Window Rotation 90) and SR 90(Screen Rotation). So it's
reasonable that the surface's buffer transform contains the information how
a client draws objects on an attached buffer regarding window rotation.

Then, we have to distinguish the window rotation and screen rotation information
from the surface's buffer transform in server side.

Change-Id: I34128a6c192fcb4fb8527f9f1fb1984a5950bc4d

src/bin/e_comp.c
src/bin/e_comp_object.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h

index f3ec52905f8bfad71881049701bd58642584ebde..86f99e894f5212dab1027f69691a9816179cb8db 100644 (file)
@@ -320,7 +320,7 @@ _hwc_available_get(E_Client *ec)
    if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
      return EINA_FALSE;
 
-   transform = cdata->scaler.buffer_viewport.buffer.transform;
+   transform = e_comp_wl_output_buffer_transform_get(ec);
    if ((eout->config.rotation / 90) != transform)
      return EINA_FALSE;
 
index 8c37564224a7d1518d51875442f60daf1a70e57f..29f77be5076f9746f785b5defb7d44bb14ddc91b 100644 (file)
@@ -556,7 +556,7 @@ _e_comp_object_map_transform_pos(E_Client *ec, int sx, int sy, int *dx, int *dy)
      }
 
    vp = &ec->comp_data->scaler.buffer_viewport;
-   transform = vp->buffer.transform;
+   transform = e_comp_wl_output_buffer_transform_get(ec);
 
    e_pixmap_size_get(ec->pixmap, &bw, &bh);
 
@@ -5466,7 +5466,7 @@ e_comp_object_map_update(Evas_Object *obj)
 
    if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return;
 
-   if (!ec->comp_data->scaler.buffer_viewport.buffer.transform &&
+   if (!e_comp_wl_output_buffer_transform_get(ec) &&
        ec->comp_data->scaler.buffer_viewport.buffer.scale == 1)
      {
         if (evas_object_map_enable_get(cw->effect_obj))
index ad13bbe9a4b282fa94663352d3213e26617987ec..a6616894f3813d8a789724ee9d29a24cd0dfb25f 100644 (file)
@@ -159,6 +159,42 @@ _e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED
    wl_display_flush_clients(e_comp_wl->wl.disp);
 }
 
+E_API enum wl_output_transform
+e_comp_wl_output_buffer_transform_get(E_Client *ec)
+{
+   E_Comp_Wl_Buffer_Viewport *vp;
+   E_Comp_Wl_Buffer *buffer;
+   enum wl_output_transform transform, rotation;
+
+   if (!ec) return WL_OUTPUT_TRANSFORM_NORMAL;
+   if (e_object_is_del(E_OBJECT(ec))) return WL_OUTPUT_TRANSFORM_NORMAL;
+   if (!ec->comp_data) return WL_OUTPUT_TRANSFORM_NORMAL;
+
+   vp = &ec->comp_data->scaler.buffer_viewport;
+   if (ec->comp_data->sub.data)
+     return vp->buffer.transform;
+
+   buffer = ec->comp_data->buffer_ref.buffer;
+
+   if (!buffer ||
+       (buffer->type != E_COMP_WL_BUFFER_TYPE_NATIVE && buffer->type != E_COMP_WL_BUFFER_TYPE_TBM))
+     return vp->buffer.transform;
+
+   rotation = wayland_tbm_server_buffer_get_buffer_transform(NULL, buffer->resource);
+   if (rotation == 0)
+     return vp->buffer.transform;
+
+   /* ignore the flip value when calculating transform because the screen rotation
+    * functionality doesn't consider the flip output transform currently
+    */
+   transform = (4 + (vp->buffer.transform & 0x3) - rotation) & 0x3;
+
+   DBG("ec(%p) window rotation(%d) buffer_transform(%d) : transform(%d)",
+       ec, rotation, vp->buffer.transform, transform);
+
+   return transform;
+}
+
 E_API void
 e_comp_wl_map_size_cal_from_buffer(E_Client *ec)
 {
@@ -174,7 +210,7 @@ e_comp_wl_map_size_cal_from_buffer(E_Client *ec)
         return;
      }
 
-   switch (vp->buffer.transform)
+   switch (e_comp_wl_output_buffer_transform_get(ec))
      {
       case WL_OUTPUT_TRANSFORM_90:
       case WL_OUTPUT_TRANSFORM_270:
@@ -1999,6 +2035,45 @@ _e_comp_wl_cb_zone_display_state_change(void *d EINA_UNUSED, int t EINA_UNUSED,
     return ECORE_CALLBACK_PASS_ON;
  }
 
+static Eina_Bool
+_e_comp_wl_cb_client_rot_change_begin(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_Begin *ev)
+{
+   E_Client *ec = ev->ec;
+   E_Comp_Wl_Buffer_Viewport *vp;
+
+   if (!ec) return ECORE_CALLBACK_PASS_ON;
+   if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
+   if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
+   if (ec->comp_data->sub.data) return ECORE_CALLBACK_PASS_ON;
+   if (ec->e.state.rot.ang.next < 0) return ECORE_CALLBACK_PASS_ON;
+
+   vp = &ec->comp_data->scaler.buffer_viewport;
+   vp->wait_for_transform_change = ((360 + ec->e.state.rot.ang.next - ec->e.state.rot.ang.curr) % 360) / 90;
+
+   DBG("ec(%p) wait_for_transform_change(%d)", ec, vp->wait_for_transform_change);
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_comp_wl_cb_client_rot_change_cancel(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_Cancel *ev)
+{
+   E_Client *ec = ev->ec;
+   E_Comp_Wl_Buffer_Viewport *vp;
+
+   if (!ec) return ECORE_CALLBACK_PASS_ON;
+   if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
+   if (!ec->comp_data) return ECORE_CALLBACK_PASS_ON;
+   if (ec->comp_data->sub.data) return ECORE_CALLBACK_PASS_ON;
+
+   vp = &ec->comp_data->scaler.buffer_viewport;
+   vp->wait_for_transform_change = 0;
+
+   DBG("ec(%p) wait_for_transform_change(%d) reset", ec, vp->wait_for_transform_change);
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 static Eina_Bool
 _e_comp_wl_cb_client_rot_change_end(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Client_Rotation_Change_End *ev EINA_UNUSED)
 {
@@ -2328,6 +2403,7 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
    E_Comp_Wl_Buffer *buffer;
    struct wl_resource *cb;
    Eina_List *l, *ll;
+   E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
 
    if ((ec->ignored) &&
        (ec->comp_data->shell.surface || ec->internal))
@@ -2338,6 +2414,18 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
         e_client_unignore(ec);
      }
 
+   if (vp->wait_for_transform_change && (vp->buffer.transform != state->buffer_viewport.buffer.transform))
+     {
+        int transform_change = (4 + state->buffer_viewport.buffer.transform - vp->buffer.transform) & 0x3;
+
+        DBG("ec(%p) wait_for_transform_change(%d) change(%d) : new(%d) old(%d)",
+            ec, vp->wait_for_transform_change, transform_change,
+            state->buffer_viewport.buffer.transform, vp->buffer.transform);
+
+        if (transform_change == vp->wait_for_transform_change)
+          vp->wait_for_transform_change = 0;
+     }
+
    ec->comp_data->scaler.buffer_viewport = state->buffer_viewport;
 
    if (state->new_attach)
@@ -2531,13 +2619,12 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
 
              if (eina_list_count(state->buffer_damages))
                {
-                  E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
-
                   EINA_LIST_FREE(state->buffer_damages, dmg)
                     {
                        if (buffer)
                          e_comp_wl_rect_convert_inverse(buffer->w, buffer->h,
-                                                        vp->buffer.transform, vp->buffer.scale,
+                                                        e_comp_wl_output_buffer_transform_get(ec),
+                                                        vp->buffer.scale,
                                                         dmg->x, dmg->y, dmg->w, dmg->h,
                                                         &dmg->x, &dmg->y, &dmg->w, &dmg->h);
                        damages = eina_list_append(damages, dmg);
@@ -4785,6 +4872,8 @@ e_comp_wl_init(void)
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE,          _e_comp_wl_cb_mouse_move,          NULL);
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_CANCEL, _e_comp_wl_cb_mouse_button_cancel, NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_comp_wl_cb_zone_display_state_change, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN, _e_comp_wl_cb_client_rot_change_begin, NULL);
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL, _e_comp_wl_cb_client_rot_change_cancel, NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_ROTATION_CHANGE_END, _e_comp_wl_cb_client_rot_change_end, NULL);
 
    /* add hooks to catch e_client events */
index 50f3b1511d7c0d05e679360f95e56571bd006a0f..3e0f3265eed1372d58b91f665c6daef2043bd056 100644 (file)
@@ -120,6 +120,12 @@ struct _E_Comp_Wl_Buffer_Viewport {
      } surface;
 
    int changed;
+
+   /* When screen or window is rotated, a transformed buffer could be
+    * attached after attaching a few buffers. So to detect when the transformed
+    * buffer exactly, we need to know the status of waiting the transformed buffer.
+    */
+   uint32_t wait_for_transform_change;
 };
 
 struct _E_Comp_Wl_Surface_State
@@ -547,6 +553,7 @@ E_API void e_comp_wl_shell_surface_ready(E_Client *ec);
 EINTERN Eina_Bool e_comp_wl_video_subsurface_has(E_Client *ec);
 EINTERN Eina_Bool e_comp_wl_normal_subsurface_has(E_Client *ec);
 
+E_API enum wl_output_transform e_comp_wl_output_buffer_transform_get(E_Client *ec);
 E_API void e_comp_wl_map_size_cal_from_buffer(E_Client *ec);
 E_API void e_comp_wl_map_size_cal_from_viewport(E_Client *ec);
 E_API void e_comp_wl_map_apply(E_Client *ec);