From: Boram Park Date: Thu, 15 Jun 2017 04:46:51 +0000 (+0900) Subject: e_comp_wl: adding window rotation information to surface's buffer transform X-Git-Tag: submit/tizen/20170705.010527~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F85%2F136085%2F3;p=platform%2Fupstream%2Fenlightenment.git e_comp_wl: adding window rotation information to surface's buffer transform 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 --- diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index f3ec52905f..86f99e894f 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -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; diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 8c37564224..29f77be507 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -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)) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index ad13bbe9a4..a6616894f3 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -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 */ diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 50f3b1511d..3e0f3265ee 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -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);