From ef44f45e3a3e6870518529c540fe7862647145ba Mon Sep 17 00:00:00 2001 From: Nobuhiko Tanibata Date: Fri, 30 May 2014 17:29:12 +0900 Subject: Transition animation support when attribute change of surface happens by ivi-layout api. interpolate frames during transition. Signed-off-by: Nobuhiko Tanibata --- Makefile.am | 4 +- clients/ivi-shell-user-interface.c | 1 + ivi-shell/hmi-controller.c | 470 ++++-------------- ivi-shell/ivi-layout-export.h | 54 --- ivi-shell/ivi-layout-private.h | 120 +++++ ivi-shell/ivi-layout-transition.c | 948 +++++++++++++++++++++++++++++++++++++ ivi-shell/ivi-layout-transition.h | 77 +++ ivi-shell/ivi-layout.c | 111 +---- ivi-shell/ivi-layout.h | 53 +++ ivi-shell/weston.ini.in | 2 + 10 files changed, 1313 insertions(+), 527 deletions(-) create mode 100644 ivi-shell/ivi-layout-private.h create mode 100644 ivi-shell/ivi-layout-transition.c create mode 100644 ivi-shell/ivi-layout-transition.h diff --git a/Makefile.am b/Makefile.am index e9b6621d..224a9576 100644 --- a/Makefile.am +++ b/Makefile.am @@ -750,7 +750,9 @@ ivi_layout_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) ivi_layout_la_SOURCES = \ ivi-shell/ivi-layout.h \ ivi-shell/ivi-layout-export.h \ - ivi-shell/ivi-layout.c + ivi-shell/ivi-layout.c \ + ivi-shell/ivi-layout-transition.h \ + ivi-shell/ivi-layout-transition.c nodist_ivi_layout_la_SOURCES = \ protocol/ivi-application-protocol.c \ protocol/ivi-application-server-protocol.h diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c index 70b854b9..a8089f14 100644 --- a/clients/ivi-shell-user-interface.c +++ b/clients/ivi-shell-user-interface.c @@ -153,6 +153,7 @@ hmi_homescreen_setting { char *cursor_theme; int32_t cursor_size; + uint32_t transition_duration; }; volatile int gRun = 0; diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c index ab37ae93..68c3336c 100644 --- a/ivi-shell/hmi-controller.c +++ b/ivi-shell/hmi-controller.c @@ -55,6 +55,7 @@ #include "ivi-layout-export.h" #include "ivi-hmi-controller-server-protocol.h" +#include "ivi-layout-transition.h" /***************************************************************************** * structure, globals @@ -73,60 +74,11 @@ struct link_layer { struct wl_list link; }; -struct link_animation { - struct hmi_controller_animation *animation; - struct wl_list link; -}; - -struct hmi_controller_animation; -typedef void (*hmi_controller_animation_frame_func)(void *animation, uint32_t timestamp); -typedef void (*hmi_controller_animation_frame_user_func)(void *animation); -typedef void (*hmi_controller_animation_destroy_func)(struct hmi_controller_animation *animation); - -struct move_animation_user_data { - struct ivi_layout_layer* layer; - struct animation_set *anima_set; - struct hmi_controller *hmi_ctrl; -}; - -struct hmi_controller_animation { - void *user_data; - uint32_t time_start; - uint32_t is_done; - hmi_controller_animation_frame_func frame_func; - hmi_controller_animation_frame_user_func frame_user_func; - hmi_controller_animation_destroy_func destroy_func; -}; - -struct hmi_controller_animation_fade { - struct hmi_controller_animation base; - double start; - double end; - struct weston_spring spring; -}; - -struct hmi_controller_animation_move { - struct hmi_controller_animation base; - double pos; - double pos_start; - double pos_end; - double v0; - double a; - double time_end; -}; - struct hmi_controller_fade { uint32_t isFadeIn; - struct hmi_controller_animation_fade *animation; - struct animation_set *anima_set; struct wl_list layer_list; }; -struct animation_set { - struct wl_event_source *event_source; - struct wl_list animation_list; -}; - struct hmi_server_setting { uint32_t base_layer_id; @@ -134,6 +86,7 @@ hmi_server_setting { uint32_t workspace_background_layer_id; uint32_t workspace_layer_id; uint32_t panel_height; + uint32_t transition_duration; char *ivi_homescreen; }; @@ -146,9 +99,8 @@ struct hmi_controller struct hmi_controller_layer workspace_layer; enum ivi_hmi_controller_layout_mode layout_mode; - struct animation_set *anima_set; struct hmi_controller_fade workspace_fade; - struct hmi_controller_animation_move *workspace_swipe_animation; + int32_t workspace_count; struct wl_array ui_widgets; int32_t is_initialized; @@ -243,10 +195,14 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, int32_t surface_x = 0; int32_t surface_y = 0; struct ivi_layout_surface *ivisurf = NULL; - int32_t ret = 0; + + struct ivi_layout_surface *surfaces[1024] = {}; //FIXME + struct ivi_layout_surface *new_order[1024] = {}; //FIXME + + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; uint32_t i = 0; - uint32_t num = 1; + uint32_t surf_num = 0; for (i = 0; i < surface_length; i++) { ivisurf = ppSurface[i]; @@ -255,6 +211,16 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, continue; } + surfaces[surf_num++] = ivisurf; + } + + static uint32_t si = 0; + uint32_t num = 1; + for(i=0; i < surf_num; i++){ + + ivisurf = surfaces[(i + si) % surf_num]; + new_order[i] = ivisurf; + if (num <= 8) { if (num < 5) { surface_x = (int32_t)((num - 1) * (surface_width)); @@ -264,20 +230,28 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, surface_x = (int32_t)((num - 5) * (surface_width)); surface_y = (int32_t)surface_height; } - ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, - surface_width, surface_height); - assert(!ret); - ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); - assert(!ret); + ivi_layout_transition_move_resize_view(ivisurf, surface_x, surface_y, + surface_width, surface_height, + duration); + + ivi_layout_transition_visibility_on(ivisurf, duration); num++; continue; } - ret = ivi_layout_surfaceSetVisibility(ivisurf, 0); - assert(!ret); + ivi_layout_transition_visibility_off(ivisurf, duration); + } + + if(surf_num > 0){ + ivi_layout_transition_layer_render_order(layer->ivilayer, + new_order, + surf_num, + duration); } + + si++; } static void @@ -291,6 +265,7 @@ mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, struct ivi_layout_surface *ivisurf = NULL; int32_t ret = 0; + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; uint32_t i = 0; uint32_t num = 1; for (i = 0; i < surface_length; i++) { @@ -302,29 +277,29 @@ mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, } if (num == 1) { - ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, - surface_width, surface_height); - assert(!ret); + ivi_layout_transition_move_resize_view(ivisurf, 0, 0, + surface_width, surface_height, + duration); + - ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); - assert(!ret); + ivi_layout_transition_visibility_on(ivisurf, duration); num++; continue; } else if (num == 2) { - ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_width, 0, - surface_width, surface_height); - assert(!ret); - ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); - assert(!ret); + ivi_layout_transition_move_resize_view(ivisurf, surface_width, 0, + surface_width, surface_height, + duration); + ivi_layout_transition_visibility_on(ivisurf, duration); num++; continue; } - ivi_layout_surfaceSetVisibility(ivisurf, 0); + ivi_layout_transition_visibility_off(ivisurf, duration); + assert(!ret); } } @@ -338,8 +313,8 @@ mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, const uint32_t surface_width = layer->width; const uint32_t surface_height = layer->height; struct ivi_layout_surface *ivisurf = NULL; - int32_t ret = 0; + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; uint32_t i = 0; for (i = 0; i < surface_length; i++) { ivisurf = ppSurface[i]; @@ -349,13 +324,13 @@ mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, continue; } - ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, - surface_width, surface_height); - assert(!ret); + ivi_layout_transition_move_resize_view(ivisurf, 0, 0, + surface_width, surface_height, + duration); - ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); - assert(!ret); + ivi_layout_transition_visibility_on(ivisurf, duration); } + } static void @@ -369,7 +344,8 @@ mode_random_replace(struct hmi_controller *hmi_ctrl, uint32_t surface_x = 0; uint32_t surface_y = 0; struct ivi_layout_surface *ivisurf = NULL; - int32_t ret = 0; + + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; uint32_t i = 0; for (i = 0; i < surface_length; i++) { @@ -383,13 +359,13 @@ mode_random_replace(struct hmi_controller *hmi_ctrl, surface_x = rand() % (layer->width - surface_width); surface_y = rand() % (layer->height - surface_height); - ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, - surface_width, surface_height); - assert(!ret); + ivi_layout_transition_move_resize_view(ivisurf, surface_x, surface_y, + surface_width, surface_height, + duration); - ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); - assert(!ret); + ivi_layout_transition_visibility_on(ivisurf, duration); } + } static int32_t @@ -466,280 +442,27 @@ switch_mode(struct hmi_controller *hmi_ctrl, } /** - * Internal method for animation + * Internal method for transition */ -static void -hmi_controller_animation_frame( - struct hmi_controller_animation *animation, uint32_t timestamp) -{ - if (0 == animation->time_start) { - animation->time_start = timestamp; - } - - animation->frame_func(animation, timestamp); - animation->frame_user_func(animation); -} - -static int -animation_set_do_anima(void* data) -{ - struct animation_set *anima_set = data; - uint32_t fps = 30; - - if (wl_list_empty(&anima_set->animation_list)) { - wl_event_source_timer_update(anima_set->event_source, 0); - return 1; - } - - wl_event_source_timer_update(anima_set->event_source, 1000 / fps); - - struct timespec timestamp = {0}; - clock_gettime(CLOCK_MONOTONIC, ×tamp); - uint32_t msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); - - struct link_animation *link_animation = NULL; - struct link_animation *next = NULL; - - wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { - hmi_controller_animation_frame(link_animation->animation, msec); - } - - ivi_layout_commitChanges(); - return 1; -} - -static struct animation_set * -animation_set_create(struct weston_compositor* ec) -{ - struct animation_set *anima_set = MEM_ALLOC(sizeof(*anima_set)); - - wl_list_init(&anima_set->animation_list); - - struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); - anima_set->event_source = wl_event_loop_add_timer(loop, animation_set_do_anima, anima_set); - wl_event_source_timer_update(anima_set->event_source, 0); - - return anima_set; -} - -static void -animation_set_add_animation(struct animation_set *anima_set, - struct hmi_controller_animation *anima) -{ - struct link_animation *link_anima = NULL; - - link_anima = MEM_ALLOC(sizeof(*link_anima)); - if (NULL == link_anima) { - return; - } - - link_anima->animation = anima; - wl_list_insert(&anima_set->animation_list, &link_anima->link); - wl_event_source_timer_update(anima_set->event_source, 1); -} - -static void -animation_set_remove_animation(struct animation_set *anima_set, - struct hmi_controller_animation *anima) -{ - struct link_animation *link_animation = NULL; - struct link_animation *next = NULL; - - wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { - if (link_animation->animation == anima) { - wl_list_remove(&link_animation->link); - free(link_animation); - break; - } - } -} static void -hmi_controller_animation_spring_frame( - struct hmi_controller_animation_fade *animation, uint32_t timestamp) +hmi_controller_fade_run(struct hmi_controller* hmi_ctrl, uint32_t isFadeIn, struct hmi_controller_fade *fade) { - if (0 == animation->spring.timestamp) { - animation->spring.timestamp = timestamp; - } - - weston_spring_update(&animation->spring, timestamp); - animation->base.is_done = weston_spring_done(&animation->spring); -} - -static void -hmi_controller_animation_move_frame( - struct hmi_controller_animation_move *animation, uint32_t timestamp) -{ - double s = animation->pos_start; - double t = timestamp - animation->base.time_start; - double v0 = animation->v0; - double a = animation->a; - double time_end = animation->time_end; - - if (time_end <= t) { - animation->pos = animation->pos_end; - animation->base.is_done = 1; - } else { - animation->pos = v0 * t + 0.5 * a * t * t + s; - } -} - -static void -hmi_controller_animation_destroy(struct hmi_controller_animation *animation) -{ - if (animation->destroy_func) { - animation->destroy_func(animation); - } - - free(animation); -} - -static void -hmi_controller_fade_animation_destroy(struct hmi_controller_animation *animation) -{ - struct hmi_controller_fade *fade = animation->user_data; - animation_set_remove_animation(fade->anima_set, animation); - fade->animation = NULL; - animation->user_data = NULL; -} - -static struct hmi_controller_animation_fade * -hmi_controller_animation_fade_create(double start, double end, double k, - hmi_controller_animation_frame_user_func frame_user_func, void* user_data, - hmi_controller_animation_destroy_func destroy_func) -{ - struct hmi_controller_animation_fade* animation = MEM_ALLOC(sizeof(*animation)); - - animation->base.frame_user_func = frame_user_func; - animation->base.user_data = user_data; - animation->base.frame_func = - (hmi_controller_animation_frame_func)hmi_controller_animation_spring_frame; - animation->base.destroy_func = destroy_func; - - animation->start = start; - animation->end = end; - weston_spring_init(&animation->spring, k, start, end); - animation->spring.friction = 1400; - animation->spring.previous = -(end - start) * 0.03; - - return animation; -} - -static struct hmi_controller_animation_move * -hmi_controller_animation_move_create( - double pos_start, double pos_end, double v_start, double v_end, - hmi_controller_animation_frame_user_func frame_user_func, void* user_data, - hmi_controller_animation_destroy_func destroy_func) -{ - struct hmi_controller_animation_move* animation = MEM_ALLOC(sizeof(*animation)); - - animation->base.frame_user_func = frame_user_func; - animation->base.user_data = user_data; - animation->base.frame_func = - (hmi_controller_animation_frame_func)hmi_controller_animation_move_frame; - animation->base.destroy_func = destroy_func; - - animation->pos_start = pos_start; - animation->pos_end = pos_end; - animation->v0 = v_start; - animation->pos = pos_start; - - double dx = (pos_end - pos_start); - - if (1e-3 < fabs(dx)) { - animation->a = 0.5 * (v_end * v_end - v_start * v_start) / dx; - if (1e-6 < fabs(animation->a)) { - animation->time_end = (v_end - v_start) / animation->a; - - } else { - animation->a = 0; - animation->time_end = fabs(dx / animation->v0); - } - - } else { - animation->time_end = 0; - } - - return animation; -} - -static double -hmi_controller_animation_fade_alpha_get(struct hmi_controller_animation_fade* animation) -{ - if (animation->spring.current > 0.999) { - return 1.0; - } else if (animation->spring.current < 0.001 ) { - return 0.0; - } else { - return animation->spring.current; - } -} - -static uint32_t -hmi_controller_animation_is_done(struct hmi_controller_animation *animation) -{ - return animation->is_done; -} - -static void -hmi_controller_fade_update(struct hmi_controller_animation_fade *animation, double end) -{ - animation->spring.target = end; -} - -static void -hmi_controller_anima_fade_user_frame(struct hmi_controller_animation_fade *animation) -{ - double alpha = hmi_controller_animation_fade_alpha_get(animation); - alpha = wl_fixed_from_double(alpha); - struct hmi_controller_fade *fade = animation->base.user_data; - struct link_layer *linklayer = NULL; - int32_t is_done = hmi_controller_animation_is_done(&animation->base); - int32_t is_visible = !is_done || fade->isFadeIn; - - wl_list_for_each(linklayer, &fade->layer_list, link) { - ivi_layout_layerSetOpacity(linklayer->layout_layer, alpha); - ivi_layout_layerSetVisibility(linklayer->layout_layer, is_visible); - } + double tint = isFadeIn ? 1.0 : 0.0; + fade->isFadeIn = isFadeIn; - if (is_done) { - hmi_controller_animation_destroy(&animation->base); - } -} + struct link_layer* linklayer = NULL; -static void -hmi_controller_anima_move_user_frame(struct hmi_controller_animation_move *animation) -{ - struct move_animation_user_data* user_data = animation->base.user_data; - struct ivi_layout_layer *layer = user_data->layer; - int32_t is_done = hmi_controller_animation_is_done(&animation->base); + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - int32_t pos[2] = {0}; - ivi_layout_layerGetPosition(layer, pos); + wl_list_for_each(linklayer, &fade->layer_list, link){ + ivi_layout_transition_fade_layer(linklayer->layout_layer, + isFadeIn, + 1.0 - tint, tint, + NULL, NULL, + duration); - pos[0] = (int32_t)animation->pos; - ivi_layout_layerSetPosition(layer, pos); - if (is_done) { - hmi_controller_animation_destroy(&animation->base); - } -} - -static void -hmi_controller_fade_run(uint32_t isFadeIn, struct hmi_controller_fade *fade) -{ - double tint = isFadeIn ? 1.0 : 0.0; - fade->isFadeIn = isFadeIn; - - if (fade->animation) { - hmi_controller_fade_update(fade->animation, tint); - } else { - fade->animation = hmi_controller_animation_fade_create( - 1.0 - tint, tint, 300.0, - (hmi_controller_animation_frame_user_func)hmi_controller_anima_fade_user_frame, - fade, hmi_controller_fade_animation_destroy); - - animation_set_add_animation(fade->anima_set, &fade->animation->base); } } @@ -833,6 +556,10 @@ hmi_server_setting_create(void) weston_config_section_get_uint( shellSection, "application-layer-id", &setting->application_layer_id, 4000); + weston_config_section_get_uint( + shellSection, "transition-duration", + &setting->transition_duration, 300); + setting->panel_height = 70; weston_config_section_get_string( @@ -925,9 +652,6 @@ hmi_controller_create(struct weston_compositor *ec) ivi_layout_layerSetOpacity(hmi_ctrl->workspace_layer.ivilayer, 0); ivi_layout_layerSetVisibility(hmi_ctrl->workspace_layer.ivilayer, 0); - /* set up animation to workspace background and workspace */ - hmi_ctrl->anima_set = animation_set_create(ec); - wl_list_init(&hmi_ctrl->workspace_fade.layer_list); tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer; @@ -935,7 +659,6 @@ hmi_controller_create(struct weston_compositor *ec) tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); tmp_link_layer->layout_layer = hmi_ctrl->workspace_background_layer.ivilayer; wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, &tmp_link_layer->link); - hmi_ctrl->workspace_fade.anima_set = hmi_ctrl->anima_set; ivi_layout_addNotificationCreateSurface(set_notification_create_surface, hmi_ctrl); ivi_layout_addNotificationRemoveSurface(set_notification_remove_surface, hmi_ctrl); @@ -1446,19 +1169,6 @@ range_val(int32_t val, int32_t min, int32_t max) return val; } -static void -hmi_controller_move_animation_destroy(struct hmi_controller_animation *animation) -{ - struct move_animation_user_data *user_data = animation->user_data; - if (animation == &user_data->hmi_ctrl->workspace_swipe_animation->base) { - user_data->hmi_ctrl->workspace_swipe_animation = NULL; - } - - animation_set_remove_animation(user_data->anima_set, animation); - free(animation->user_data); - animation->user_data = NULL; -} - static void move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, wl_fixed_t grab_x, struct ivi_layout_layer *layer) @@ -1505,6 +1215,7 @@ move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, page_no = range_val(page_no, 0, hmi_ctrl->workspace_count - 1); double end_pos = -page_no * width; +/* double dst = fabs(end_pos - pos[0]); double max_time = 0.5 * 1e+3; double v = dst / max_time; @@ -1520,23 +1231,12 @@ move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, } else { v0 = -v; } +*/ - struct move_animation_user_data *animation_user_data = NULL; - animation_user_data = MEM_ALLOC(sizeof(*animation_user_data)); - animation_user_data->layer = layer; - animation_user_data->anima_set = hmi_ctrl->anima_set; - animation_user_data->hmi_ctrl = hmi_ctrl; - - struct hmi_controller_animation_move* animation = NULL; - animation = hmi_controller_animation_move_create( - pos[0], end_pos, v0, v0, - (hmi_controller_animation_frame_user_func)hmi_controller_anima_move_user_frame, - animation_user_data, hmi_controller_move_animation_destroy); - - hmi_ctrl->workspace_swipe_animation = animation; - animation_set_add_animation(hmi_ctrl->anima_set, &animation->base); - + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved); + ivi_layout_transition_move_layer(layer, end_pos, pos[1], duration); + ivi_layout_commitChanges(); } static void @@ -1814,14 +1514,12 @@ ivi_hmi_controller_workspace_control(struct wl_client *client, return; } - if (hmi_ctrl->workspace_swipe_animation) { - hmi_controller_animation_destroy(&hmi_ctrl->workspace_swipe_animation->base); - } - struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; struct pointer_move_grab *pnt_move_grab = NULL; struct touch_move_grab *tch_move_grab = NULL; + ivi_layout_transition_move_layer_cancel(layer); + switch (device) { case HMI_GRAB_DEVICE_POINTER: pnt_move_grab = create_workspace_pointer_move(seat->pointer, resource); @@ -1870,8 +1568,10 @@ ivi_hmi_controller_home(struct wl_client *client, (IVI_HMI_CONTROLLER_HOME_OFF == home && hmi_ctrl->workspace_fade.isFadeIn)) { uint32_t isFadeIn = !hmi_ctrl->workspace_fade.isFadeIn; - hmi_controller_fade_run(isFadeIn, &hmi_ctrl->workspace_fade); + hmi_controller_fade_run(hmi_ctrl, isFadeIn, &hmi_ctrl->workspace_fade); } + + ivi_layout_commitChanges(); } /** diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h index 016c4396..41e1dee1 100644 --- a/ivi-shell/ivi-layout-export.h +++ b/ivi-shell/ivi-layout-export.h @@ -52,60 +52,6 @@ extern "C" { #include "compositor.h" #include "ivi-layout.h" -struct ivi_layout_SurfaceProperties -{ - float opacity; - uint32_t sourceX; - uint32_t sourceY; - uint32_t sourceWidth; - uint32_t sourceHeight; - uint32_t origSourceWidth; - uint32_t origSourceHeight; - int32_t destX; - int32_t destY; - uint32_t destWidth; - uint32_t destHeight; - uint32_t orientation; - uint32_t visibility; - uint32_t frameCounter; - uint32_t drawCounter; - uint32_t updateCounter; - uint32_t pixelformat; - uint32_t nativeSurface; - uint32_t inputDevicesAcceptance; - uint32_t chromaKeyEnabled; - uint32_t chromaKeyRed; - uint32_t chromaKeyGreen; - uint32_t chromaKeyBlue; - int32_t creatorPid; -}; - -struct ivi_layout_LayerProperties -{ - float opacity; - uint32_t sourceX; - uint32_t sourceY; - uint32_t sourceWidth; - uint32_t sourceHeight; - uint32_t origSourceWidth; - uint32_t origSourceHeight; - int32_t destX; - int32_t destY; - uint32_t destWidth; - uint32_t destHeight; - uint32_t orientation; - uint32_t visibility; - uint32_t type; - uint32_t chromaKeyEnabled; - uint32_t chromaKeyRed; - uint32_t chromaKeyGreen; - uint32_t chromaKeyBlue; - int32_t creatorPid; -}; - -struct ivi_layout_layer; -struct ivi_layout_screen; - enum ivi_layout_notification_mask { IVI_NOTIFICATION_NONE = 0, IVI_NOTIFICATION_OPACITY = (1 << 1), diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h new file mode 100644 index 00000000..5d5c240a --- /dev/null +++ b/ivi-shell/ivi-layout-private.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2014 DENSO CORPORATION + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _ivi_layout_PRIVATE_H_ +#define _ivi_layout_PRIVATE_H_ + +#include "compositor.h" +#include "ivi-layout.h" +#include "ivi-layout-transition.h" + +struct ivi_layout_surface { + struct wl_list link; + struct wl_list list_notification; + struct wl_list list_layer; + uint32_t update_count; + uint32_t id_surface; + + struct ivi_layout *layout; + struct weston_surface *surface; + struct weston_view *view; + + uint32_t buffer_width; + uint32_t buffer_height; + + struct wl_listener surface_destroy_listener; + struct weston_transform surface_rotation; + struct weston_transform layer_rotation; + struct weston_transform surface_pos; + struct weston_transform layer_pos; + struct weston_transform scaling; + struct ivi_layout_SurfaceProperties prop; + int32_t pixelformat; + uint32_t event_mask; + + struct { + struct ivi_layout_SurfaceProperties prop; + struct wl_list link; + } pending; + + struct { + struct wl_list link; + struct wl_list list_layer; + } order; + + struct { + ivi_controller_surface_content_callback callback; + void* userdata; + } content_observer; +}; + +struct ivi_layout_layer { + struct wl_list link; + struct wl_list list_notification; + struct wl_list list_screen; + struct wl_list link_to_surface; + uint32_t id_layer; + + struct ivi_layout *layout; + + struct ivi_layout_LayerProperties prop; + uint32_t event_mask; + + struct { + struct ivi_layout_LayerProperties prop; + struct wl_list list_surface; + struct wl_list link; + } pending; + + struct { + struct wl_list list_surface; + struct wl_list link; + } order; +}; + +struct ivi_layout { + struct weston_compositor *compositor; + + struct wl_list list_surface; + struct wl_list list_layer; + struct wl_list list_screen; + + struct { + struct wl_list list_create; + struct wl_list list_remove; + } layer_notification; + + struct { + struct wl_list list_create; + struct wl_list list_remove; + struct wl_list list_configure; + } surface_notification; + + struct weston_layer layout_layer; + + struct ivi_layout_transition_set* transitions; + struct wl_list pending_transition_list; +}; + +struct ivi_layout *get_instance(void); + +#endif diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c new file mode 100644 index 00000000..da05230c --- /dev/null +++ b/ivi-shell/ivi-layout-transition.c @@ -0,0 +1,948 @@ +/* + * Copyright (C) 2014 DENSO CORPORATION + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "ivi-layout.h" +#include "ivi-layout-export.h" +#include "ivi-layout-transition.h" +#include "ivi-layout-private.h" + +struct ivi_layout_transition; +typedef void (*ivi_layout_transition_frame_func)(struct ivi_layout_transition *transition); +typedef void (*ivi_layout_transition_destroy_func)(struct ivi_layout_transition* transition); +typedef int32_t (*ivi_layout_transition_identifire_func)(void* private_data, void* id); + +enum layout_transition_type{ + LAYOUT_TRANSITION_VIEW_MOVE_RESIZE, + LAYOUT_TRANSITION_VIEW_FADE, + LAYOUT_TRANSITION_LAYER_FADE, + LAYOUT_TRANSITION_LAYER_MOVE, + LAYOUT_TRANSITION_LAYER_VIEW_ORDER, + LAYOUT_TRANSITION_MAX, +}; + +struct ivi_layout_transition { + enum layout_transition_type type; + void *private_data; + void *user_data; + + uint32_t time_start; + uint32_t time_duration; + uint32_t time_elapsed; + uint32_t is_done; + ivi_layout_transition_identifire_func id_func; + ivi_layout_transition_frame_func frame_func; + ivi_layout_transition_destroy_func destroy_func; +}; + +struct transition_node { + struct ivi_layout_transition *transition; + struct wl_list link; +}; + +static void layout_transition_destroy(struct ivi_layout_transition* transition); + +static struct ivi_layout_transition* +get_transition_from_type_and_id(enum layout_transition_type type, void* id_data) +{ + struct ivi_layout* layout = get_instance(); + struct transition_node *node=NULL; + wl_list_for_each(node, &layout->transitions->transition_list, link){ + if(node->transition->type == type) + if(node->transition->id_func(node->transition->private_data, id_data)) + return node->transition; + } + return NULL; +} + +static void +tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp) +{ + const double t = timestamp - transition->time_start; + + if (transition->time_duration <= t) { + transition->time_elapsed = transition->time_duration; + transition->is_done = 1; + } else { + transition->time_elapsed = t; + } +} + +static float time_to_nowpos(struct ivi_layout_transition* transition) +{ + return sin((float)transition->time_elapsed / (float)transition->time_duration * M_PI_2); +} + +static void +do_transition_frame( + struct ivi_layout_transition *transition, uint32_t timestamp) +{ + if (0 == transition->time_start) { + transition->time_start = timestamp; + } + + tick_transition(transition, timestamp); + transition->frame_func(transition); + + if(transition->is_done){ + layout_transition_destroy(transition); + } +} + +static int32_t +layout_transition_frame(void* data) +{ + struct ivi_layout_transition_set *transitions = data; + uint32_t fps = 30; + + if (wl_list_empty(&transitions->transition_list)) { + wl_event_source_timer_update(transitions->event_source, 0); + return 1; + } + + wl_event_source_timer_update(transitions->event_source, 1000 / fps); + + struct timespec timestamp = {0}; + clock_gettime(CLOCK_MONOTONIC, ×tamp); + uint32_t msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); + + struct transition_node *node = NULL; + struct transition_node *next = NULL; + + wl_list_for_each_safe(node, next, &transitions->transition_list, link) { + do_transition_frame(node->transition, msec); + } + + ivi_layout_commitChanges(); + return 1; +} + +WL_EXPORT struct ivi_layout_transition_set * +ivi_layout_transition_set_create(struct weston_compositor* ec) +{ + struct ivi_layout_transition_set *transitions = malloc(sizeof(*transitions)); + assert(transitions); + + wl_list_init(&transitions->transition_list); + + struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); + transitions->event_source = wl_event_loop_add_timer(loop, layout_transition_frame, transitions); + wl_event_source_timer_update(transitions->event_source, 0); + + return transitions; +} + +static void +layout_transition_register(struct ivi_layout_transition *trans) +{ + struct ivi_layout* layout = get_instance(); + struct transition_node *node = NULL; + + node = malloc(sizeof(*node)); + assert(node); + + node->transition = trans; + wl_list_insert(&layout->pending_transition_list, &node->link); +} + +static void +remove_transition(struct ivi_layout* layout, + struct ivi_layout_transition *trans) +{ + struct transition_node *node = NULL; + struct transition_node *next = NULL; + + wl_list_for_each_safe(node, next, &layout->transitions->transition_list, link) { + if (node->transition == trans) { + wl_list_remove(&node->link); + free(node); + return; + } + } + + wl_list_for_each_safe(node, next, &layout->pending_transition_list, link) { + if (node->transition == trans) { + wl_list_remove(&node->link); + free(node); + return; + } + } + + return; +} + +static void +layout_transition_destroy(struct ivi_layout_transition *transition) +{ + struct ivi_layout* layout = get_instance(); + + remove_transition(layout, transition); + if(transition->destroy_func) + transition->destroy_func(transition); + free(transition); +} + +static struct ivi_layout_transition* +create_layout_transition(void) +{ + struct ivi_layout_transition* transition = malloc(sizeof(*transition)); + assert(transition); + + transition->type = LAYOUT_TRANSITION_MAX; + transition->time_start = 0; + transition->time_duration = 300; // 300ms + transition->time_elapsed = 0; + + transition->is_done = 0; + + transition->private_data = NULL; + transition->user_data = NULL; + + transition->frame_func = NULL; + transition->destroy_func = NULL; + + return transition; +} + +/* move and resize view transition */ + +struct move_resize_view_data { + struct ivi_layout_surface* surface; + int32_t start_x; + int32_t start_y; + int32_t end_x; + int32_t end_y; + uint32_t start_width; + uint32_t start_height; + uint32_t end_width; + uint32_t end_height; +}; + +static void +transition_move_resize_view_destroy(struct ivi_layout_transition* transition) +{ + if(transition->private_data){ + free(transition->private_data); + transition->private_data = NULL; + } +} + +static void +transition_move_resize_view_user_frame(struct ivi_layout_transition *transition) +{ + struct move_resize_view_data* private_data = transition->private_data; + struct ivi_layout_surface *surface = private_data->surface; + + const double current = time_to_nowpos(transition); + const int32_t destx = private_data->start_x + (private_data->end_x - private_data->start_x)*current; + const int32_t desty = private_data->start_y + (private_data->end_y - private_data->start_y)*current; + + const uint32_t dest_width = (int32_t)private_data->start_width + + ((int32_t)private_data->end_width - (int32_t)private_data->start_width) *current; + + const uint32_t dest_height = (int32_t)private_data->start_height + + ((int32_t)private_data->end_height - (int32_t)private_data->start_height)*current; + + ivi_layout_surfaceSetDestinationRectangle(surface, + destx, desty, dest_width, dest_height); + +} + +static int32_t +transition_move_resize_view_identifire(struct move_resize_view_data* data, + struct ivi_layout_surface* view) +{ + return data->surface == view; +} + +static struct ivi_layout_transition * +create_move_resize_view_transition( + struct ivi_layout_surface* surface, + int32_t start_x, int32_t start_y, + int32_t end_x, int32_t end_y, + uint32_t start_width, uint32_t start_height, + uint32_t end_width, uint32_t end_height, + ivi_layout_transition_frame_func frame_func, + ivi_layout_transition_destroy_func destroy_func, + uint32_t duration) +{ + struct ivi_layout_transition* transition = create_layout_transition(); + struct move_resize_view_data* data = malloc(sizeof(*data)); + + transition->type = LAYOUT_TRANSITION_VIEW_MOVE_RESIZE; + transition->id_func = (ivi_layout_transition_identifire_func)transition_move_resize_view_identifire; + + transition->frame_func = frame_func; + transition->destroy_func = destroy_func; + transition->private_data = data; + + if(duration != 0){ + transition->time_duration = duration; + } + + data->surface = surface; + data->start_x = start_x; + data->start_y = start_y; + data->end_x = end_x; + data->end_y = end_y; + + data->start_width = start_width; + data->start_height = start_height; + data->end_width = end_width; + data->end_height = end_height; + + return transition; +} + +WL_EXPORT void +ivi_layout_transition_move_resize_view(struct ivi_layout_surface* surface, + int32_t dest_x, int32_t dest_y, + uint32_t dest_width, uint32_t dest_height, + uint32_t duration) +{ + int32_t start_pos[2] = {}; + ivi_layout_surfaceGetPosition(surface, start_pos); + + uint32_t start_size[2] = {}; + ivi_layout_surfaceGetDimension(surface, start_size); + + struct ivi_layout_transition* transition = NULL; + + transition = get_transition_from_type_and_id(LAYOUT_TRANSITION_VIEW_MOVE_RESIZE, surface); + if(transition){ + + transition->time_start = 0; + transition->time_duration = duration; + + struct move_resize_view_data* data = transition->private_data; + data->start_x = start_pos[0]; + data->start_y = start_pos[1]; + data->end_x = dest_x; + data->end_y = dest_y; + + data->start_width = start_size[0]; + data->start_height = start_size[1]; + data->end_width = dest_width; + data->end_height = dest_height; + return; + } + + transition = create_move_resize_view_transition( + surface, + start_pos[0], start_pos[1], + dest_x, dest_y, + start_size[0], start_size[1], + dest_width, dest_height, + transition_move_resize_view_user_frame, + transition_move_resize_view_destroy, + duration); + + layout_transition_register(transition); + +} + +/* fade transition */ +struct fade_view_data { + struct ivi_layout_surface* surface; + float start_alpha; + float end_alpha; +}; + +struct store_alpha{ + float alpha; +}; + +static void +fade_view_user_frame(struct ivi_layout_transition *transition) +{ + struct fade_view_data* private_data = transition->private_data; + struct ivi_layout_surface *surface = private_data->surface; + + const double current = time_to_nowpos(transition); + const float alpha = private_data->start_alpha + (private_data->end_alpha - private_data->start_alpha)*current; + + ivi_layout_surfaceSetOpacity(surface, wl_fixed_from_double(alpha)); + ivi_layout_surfaceSetVisibility(surface, 1); + +} + +static int32_t +transition_fade_view_identifire(struct fade_view_data* data, + struct ivi_layout_surface* view) +{ + return data->surface == view; +} + +static struct ivi_layout_transition* +create_fade_view_transition( + struct ivi_layout_surface* surface, + float start_alpha, float end_alpha, + ivi_layout_transition_frame_func frame_func, + void* user_data, + ivi_layout_transition_destroy_func destroy_func, + uint32_t duration) +{ + struct ivi_layout_transition* transition = create_layout_transition(); + struct fade_view_data* data = malloc(sizeof(*data)); + assert(data); + + transition->type = LAYOUT_TRANSITION_VIEW_FADE; + transition->id_func = (ivi_layout_transition_identifire_func)transition_fade_view_identifire; + + transition->user_data = user_data; + transition->private_data = data; + transition->frame_func = frame_func; + transition->destroy_func = destroy_func; + + if(duration != 0){ + transition->time_duration = duration; + } + + data->surface = surface; + data->start_alpha = start_alpha; + data->end_alpha = end_alpha; + + return transition; +} + +static void +create_visibility_transition(struct ivi_layout_surface* surface, + float start_alpha, + float dest_alpha, + void* user_data, + ivi_layout_transition_destroy_func destroy_func, + uint32_t duration) +{ + struct ivi_layout_transition* transition = NULL; + + transition = create_fade_view_transition( + surface, + start_alpha, dest_alpha, + fade_view_user_frame, + user_data, + destroy_func, + duration); + + layout_transition_register(transition); + +} + +static void +visibility_on_transition_destroy(struct ivi_layout_transition* transition) +{ + struct fade_view_data *data = transition->private_data; + ivi_layout_surfaceSetVisibility(data->surface, 1); + + free(data); + transition->private_data = NULL; + + struct store_alpha *user_data = transition->user_data; + + free(user_data); + transition->user_data = NULL; + +} + +WL_EXPORT void +ivi_layout_transition_visibility_on(struct ivi_layout_surface* surface, + uint32_t duration) +{ + + struct ivi_layout_transition* transition = NULL; + + transition = get_transition_from_type_and_id(LAYOUT_TRANSITION_VIEW_FADE, surface); + if(transition){ + transition->time_start = 0; + transition->time_duration = duration; + transition->destroy_func = visibility_on_transition_destroy; + + float start_alpha=0.0; + ivi_layout_surfaceGetOpacity(surface, &start_alpha); + + const struct store_alpha* user_data = transition->user_data; + struct fade_view_data* data = transition->private_data; + data->start_alpha = wl_fixed_to_double(start_alpha); + data->end_alpha = user_data->alpha; + return; + } + + uint32_t is_visible = 0; + ivi_layout_surfaceGetVisibility(surface, &is_visible); + if(is_visible){ + return; + } + + float dest_alpha = 0; + ivi_layout_surfaceGetOpacity(surface, &dest_alpha); + + struct store_alpha* user_data = malloc(sizeof(*user_data)); + user_data->alpha = wl_fixed_to_double(dest_alpha); + + create_visibility_transition(surface, + 0.0, // start_alpha + wl_fixed_to_double(dest_alpha), + user_data, + visibility_on_transition_destroy, + duration); +} + +static void +visibility_off_transition_destroy(struct ivi_layout_transition* transition) +{ + struct fade_view_data *data = transition->private_data; + + ivi_layout_surfaceSetVisibility(data->surface, 0); + + struct store_alpha* user_data = transition->user_data; + ivi_layout_surfaceSetOpacity(data->surface, wl_fixed_from_double(user_data->alpha)); + + free(data); + transition->private_data = NULL; + + free(user_data); + transition->user_data= NULL; + +} + +WL_EXPORT void +ivi_layout_transition_visibility_off(struct ivi_layout_surface* surface, + uint32_t duration) +{ + + struct ivi_layout_transition* transition = NULL; + + transition = get_transition_from_type_and_id(LAYOUT_TRANSITION_VIEW_FADE, surface); + if(transition){ + transition->time_start = 0; + transition->time_duration = duration; + transition->destroy_func = visibility_off_transition_destroy; + + float start_alpha=0.0; + ivi_layout_surfaceGetOpacity(surface, &start_alpha); + + struct fade_view_data* data = transition->private_data; + data->start_alpha = wl_fixed_to_double(start_alpha); + data->end_alpha = 0; + return; + } + + float start_alpha=0; + ivi_layout_surfaceGetOpacity(surface, &start_alpha); + + struct store_alpha* user_data = malloc(sizeof(*user_data)); + user_data->alpha = wl_fixed_to_double(start_alpha); + + create_visibility_transition(surface, + wl_fixed_to_double(start_alpha), + 0.0f, // dest_alpha + user_data, + visibility_off_transition_destroy, + duration); +} + +/* move layer transition */ + +struct move_layer_data { + struct ivi_layout_layer* layer; + int32_t start_x; + int32_t start_y; + int32_t end_x; + int32_t end_y; + ivi_layout_transition_destroy_user_func destroy_func; +}; + +static void +transition_move_layer_user_frame(struct ivi_layout_transition* transition) +{ + struct move_layer_data* data = transition->private_data; + struct ivi_layout_layer* layer = data->layer; + + const float current = time_to_nowpos(transition); + + const int32_t dest_x = data->start_x + (data->end_x - data->start_x) * current; + const int32_t dest_y = data->start_y + (data->end_y - data->start_y) * current; + + + int32_t pos[2] = {dest_x, dest_y}; + + ivi_layout_layerSetPosition(layer, pos); + +} + +static void +transition_move_layer_destroy(struct ivi_layout_transition* transition) +{ + + struct move_layer_data* data = transition->private_data; + + if(data->destroy_func) + data->destroy_func(transition->user_data); + + free(data); + transition->private_data = NULL; + +} + +static int32_t +transition_move_layer_identifire(struct move_layer_data* data, struct ivi_layout_layer* layer) +{ + return data->layer == layer; +} + + +static struct ivi_layout_transition* +create_move_layer_transition( + struct ivi_layout_layer* layer, + int32_t start_x, int32_t start_y, + int32_t end_x, int32_t end_y, + void* user_data, + ivi_layout_transition_destroy_user_func destroy_user_func, + uint32_t duration) +{ + struct ivi_layout_transition* transition = create_layout_transition(); + struct move_layer_data* data = malloc(sizeof(*data)); + + transition->type = LAYOUT_TRANSITION_LAYER_MOVE; + transition->id_func = (ivi_layout_transition_identifire_func)transition_move_layer_identifire; + + transition->frame_func = transition_move_layer_user_frame; + transition->destroy_func = transition_move_layer_destroy; + transition->private_data = data; + transition->user_data = user_data; + + if(duration != 0) + transition->time_duration = duration; + + data->layer = layer; + data->start_x = start_x; + data->start_y = start_y; + data->end_x = end_x; + data->end_y = end_y; + data->destroy_func = destroy_user_func; + + return transition; +} + +WL_EXPORT void +ivi_layout_transition_move_layer(struct ivi_layout_layer* layer, + int32_t dest_x, int32_t dest_y, + uint32_t duration) +{ + int32_t start_pos[2] = {}; + ivi_layout_layerGetPosition(layer, start_pos); + + struct ivi_layout_transition* transition = NULL; + transition = create_move_layer_transition( + layer, + start_pos[0], start_pos[1], + dest_x, dest_y, + NULL, NULL, + duration); + + layout_transition_register(transition); + + return; +} + +WL_EXPORT void +ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer) +{ + struct ivi_layout_transition* transition = + get_transition_from_type_and_id(LAYOUT_TRANSITION_LAYER_MOVE, layer); + if(transition){ + layout_transition_destroy(transition); + } +} + +/* fade layer transition */ +struct fade_layer_data { + struct ivi_layout_layer* layer; + int32_t is_fade_in; + double start_alpha; + double end_alpha; + ivi_layout_transition_destroy_user_func destroy_func; +}; + +static void +transition_fade_layer_destroy(struct ivi_layout_transition* transition) +{ + struct fade_layer_data* data = transition->private_data; + transition->private_data = NULL; + + free(data); +} + +static void +transition_fade_layer_user_frame(struct ivi_layout_transition *transition) +{ + double current = time_to_nowpos(transition); + struct fade_layer_data* data = transition->private_data; + double alpha = data->start_alpha + (data->end_alpha - data->start_alpha) * current; + int32_t fixed_alpha = wl_fixed_from_double(alpha); + + int32_t is_done = transition->is_done; + int32_t is_visible = !is_done || data->is_fade_in; + + ivi_layout_layerSetOpacity(data->layer, fixed_alpha); + ivi_layout_layerSetVisibility(data->layer, is_visible); +} + +static int32_t +transition_fade_layer_identifire(struct fade_layer_data* data, struct ivi_layout_layer* layer) +{ + return data->layer == layer; +} + +WL_EXPORT void +ivi_layout_transition_fade_layer(struct ivi_layout_layer* layer, + int32_t is_fade_in, + double start_alpha, double end_alpha, + void* user_data, + ivi_layout_transition_destroy_user_func destroy_func, + uint32_t duration) +{ + struct ivi_layout_transition* transition = NULL; + + transition = get_transition_from_type_and_id(LAYOUT_TRANSITION_LAYER_FADE, layer); + + if(transition){ + /* transition update */ + struct fade_layer_data* data = transition->private_data; + + float fixed_opacity=0.0; //FIXME + ivi_layout_layerGetOpacity(layer, &fixed_opacity); + const double now_opacity = wl_fixed_to_double(fixed_opacity); + + data->is_fade_in = is_fade_in; + data->start_alpha = now_opacity; + data->end_alpha = end_alpha; + + float remain = is_fade_in? 1.0 - now_opacity : now_opacity; + transition->time_start = 0; + transition->time_elapsed = 0; + transition->time_duration = duration * remain; + + return; + } + + transition = create_layout_transition(); + struct fade_layer_data* data = malloc(sizeof(*data)); + assert(data); + + transition->type = LAYOUT_TRANSITION_LAYER_FADE; + transition->id_func = (ivi_layout_transition_identifire_func)transition_fade_layer_identifire; + + transition->private_data = data; + transition->user_data = user_data; + + transition->frame_func = transition_fade_layer_user_frame; + transition->destroy_func = transition_fade_layer_destroy; + + if(duration != 0){ + transition->time_duration = duration; + } + + data->layer = layer; + data->is_fade_in = is_fade_in; + data->start_alpha = start_alpha; + data->end_alpha = end_alpha; + data->destroy_func = destroy_func; + + layout_transition_register(transition); + + return; +} + +/* render order transition */ +struct surface_reorder{ + uint32_t id_surface; + uint32_t new_index; +}; + +struct change_order_data{ + struct ivi_layout_layer* layer; + uint32_t surface_num; + struct surface_reorder* reorder; +}; + +struct surf_with_index{ + uint32_t id_surface; + float surface_index; +}; + +static int cmp_order_asc(const void* lhs, const void* rhs) +{ + return ((struct surf_with_index*)lhs)->surface_index > ((struct surf_with_index*)rhs)->surface_index; +} + +/* +render oerder transition + +index 0 1 2 +old surfA, surfB, surfC +new surfB, surfC, surfA + (-1) (-1) (+2) + +after 10% of time elapsed + 0.2 0.9 1.9 + surfA, surfB, surfC + +after 50% of time elapsed + 0.5 1.0 1.5 + surfB, surfA, surfC +*/ + +static void +transition_change_order_user_frame(struct ivi_layout_transition *transition) +{ + uint32_t i, old_index; + double current = time_to_nowpos(transition); + struct change_order_data* data = transition->private_data; + + struct surf_with_index* swi = malloc(sizeof(*swi)*data->surface_num); + + for(old_index=0; old_indexsurface_num; old_index++){ + swi[old_index].id_surface = data->reorder[old_index].id_surface; + swi[old_index].surface_index = (float)old_index + + ((float)data->reorder[old_index].new_index - (float)old_index) * current; + } + + qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc); + +/* + fprintf(stderr, "=========\n"); + for(i=0; isurface_num;i++){ + fprintf(stderr, "surface %d: %f\n", swi[i].id_surface, swi[i].surface_index); + } +*/ + + struct ivi_layout_surface** new_surface_order = + malloc(sizeof(*new_surface_order) * data->surface_num); + + uint32_t surface_num = 0; + for(i=0; isurface_num; i++){ + struct ivi_layout_surface* surf = ivi_layout_getSurfaceFromId(swi[i].id_surface); + if(surf) + new_surface_order[surface_num++] = surf; + } + + ivi_layout_layerSetRenderOrder(data->layer, new_surface_order, surface_num); + + free(new_surface_order); + free(swi); +} + +static void +transition_change_order_destroy(struct ivi_layout_transition* transition) +{ + struct change_order_data* data = transition->private_data; + + free(data->reorder); + free(data); +} + +static int32_t find_surface(struct ivi_layout_surface** surfaces, + uint32_t surface_num, + struct ivi_layout_surface* target) +{ + uint32_t i=0; + for(i=0; ilayer == layer; +} + +WL_EXPORT void +ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, + struct ivi_layout_surface** new_order, + uint32_t surface_num, + uint32_t duration) +{ + struct surface_reorder* reorder = malloc(sizeof(*reorder)*surface_num); + struct ivi_layout_surface* surf=NULL; + uint32_t old_index = 0; + + wl_list_for_each(surf, &layer->order.list_surface, order.link){ + int32_t new_index = find_surface(new_order, surface_num, surf); + if(new_index < 0){ + fprintf(stderr, "invalid render order!!!\n"); + return; + } + + const uint32_t id = ivi_layout_getIdOfSurface(surf); + + reorder[old_index].id_surface = id; + reorder[old_index].new_index = new_index; + old_index++; + } + + struct ivi_layout_transition* transition = NULL; + + transition = get_transition_from_type_and_id(LAYOUT_TRANSITION_LAYER_VIEW_ORDER, layer); + if(transition){ + /* update transition */ + transition->time_start = 0; /* timer reset */ + + if(duration != 0){ + transition->time_duration = duration; + } + + struct change_order_data* data = transition->private_data; + free(data->reorder); + data->reorder = reorder; + return; + } + + transition = create_layout_transition(); + struct change_order_data* data = malloc(sizeof(*data)); + assert(data); + + transition->type = LAYOUT_TRANSITION_LAYER_VIEW_ORDER; + transition->id_func = (ivi_layout_transition_identifire_func)transition_change_order_identifire; + + transition->private_data = data; + transition->frame_func = transition_change_order_user_frame; + transition->destroy_func = transition_change_order_destroy; + + if(duration != 0){ + transition->time_duration = duration; + } + + data->layer = layer; + data->reorder = reorder; + data->surface_num = old_index; + + layout_transition_register(transition); + +} diff --git a/ivi-shell/ivi-layout-transition.h b/ivi-shell/ivi-layout-transition.h new file mode 100644 index 00000000..e8e55090 --- /dev/null +++ b/ivi-shell/ivi-layout-transition.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 DENSO CORPORATION + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WESTON_LAYOUT_TRANSITION_H_ +#define _WESTON_LAYOUT_TRANSITION_H_ + +#include "ivi-layout.h" + +struct ivi_layout_transition; + +struct ivi_layout_transition_set { + struct wl_event_source *event_source; + struct wl_list transition_list; +}; + +typedef void (*ivi_layout_transition_destroy_user_func)(void* user_data); + +struct ivi_layout_transition_set * +ivi_layout_transition_set_create(struct weston_compositor* ec); + +void +ivi_layout_transition_move_resize_view(struct ivi_layout_surface* surface, + int32_t dest_x, int32_t dest_y, + uint32_t dest_width, uint32_t dest_height, + uint32_t duration); + +void +ivi_layout_transition_visibility_on(struct ivi_layout_surface* surface, + uint32_t duration); + +void +ivi_layout_transition_visibility_off(struct ivi_layout_surface* surface, + uint32_t duration); + + +void +ivi_layout_transition_move_layer(struct ivi_layout_layer* layer, + int32_t dest_x, int32_t dest_y, + uint32_t duration); + +void +ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer); + +void +ivi_layout_transition_fade_layer(struct ivi_layout_layer* layer, + int32_t is_fade_in, + double start_alpha, double end_alpha, + void* user_data, + ivi_layout_transition_destroy_user_func destroy_func, + uint32_t duration); + +void +ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, + struct ivi_layout_surface** new_order, + uint32_t surface_num, + uint32_t duration); + +#endif diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c index 32a87a85..3152a911 100644 --- a/ivi-shell/ivi-layout.c +++ b/ivi-shell/ivi-layout.c @@ -55,6 +55,7 @@ #include "compositor.h" #include "ivi-layout.h" #include "ivi-layout-export.h" +#include "ivi-layout-private.h" enum ivi_layout_surface_orientation { IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES = 0, @@ -130,70 +131,6 @@ struct link_surfaceConfigureNotification { struct ivi_layout; -struct ivi_layout_surface { - struct wl_list link; - struct wl_list list_notification; - struct wl_list list_layer; - uint32_t update_count; - uint32_t id_surface; - - struct ivi_layout *layout; - struct weston_surface *surface; - struct weston_view *view; - - uint32_t buffer_width; - uint32_t buffer_height; - - struct wl_listener surface_destroy_listener; - struct weston_transform surface_rotation; - struct weston_transform layer_rotation; - struct weston_transform surface_pos; - struct weston_transform layer_pos; - struct weston_transform scaling; - struct ivi_layout_SurfaceProperties prop; - int32_t pixelformat; - uint32_t event_mask; - - struct { - struct ivi_layout_SurfaceProperties prop; - struct wl_list link; - } pending; - - struct { - struct wl_list link; - struct wl_list list_layer; - } order; - - struct { - ivi_controller_surface_content_callback callback; - void* userdata; - } content_observer; -}; - -struct ivi_layout_layer { - struct wl_list link; - struct wl_list list_notification; - struct wl_list list_screen; - struct wl_list link_to_surface; - uint32_t id_layer; - - struct ivi_layout *layout; - - struct ivi_layout_LayerProperties prop; - uint32_t event_mask; - - struct { - struct ivi_layout_LayerProperties prop; - struct wl_list list_surface; - struct wl_list link; - } pending; - - struct { - struct wl_list list_surface; - struct wl_list link; - } order; -}; - struct ivi_layout_screen { struct wl_list link; struct wl_list link_to_layer; @@ -215,30 +152,9 @@ struct ivi_layout_screen { } order; }; -struct ivi_layout { - struct weston_compositor *compositor; - - struct wl_list list_surface; - struct wl_list list_layer; - struct wl_list list_screen; - - struct { - struct wl_list list_create; - struct wl_list list_remove; - } layer_notification; - - struct { - struct wl_list list_create; - struct wl_list list_remove; - struct wl_list list_configure; - } surface_notification; - - struct weston_layer layout_layer; -}; - static struct ivi_layout ivilayout = {0}; -static struct ivi_layout * +struct ivi_layout * get_instance(void) { return &ivilayout; @@ -708,7 +624,7 @@ update_surface_position(struct ivi_layout_surface *ivisurf) weston_view_update_transform(view); #if 0 - /* disable zoom animation */ + /* disable zoom transition */ weston_zoom_run(es, 0.0, 1.0, NULL, NULL); #endif @@ -967,6 +883,21 @@ commit_list_screen(struct ivi_layout *layout) } } +static void +commit_transition(struct ivi_layout* layout) +{ + if(wl_list_empty(&layout->pending_transition_list)){ + return; + } + + wl_list_insert_list(&layout->transitions->transition_list, + &layout->pending_transition_list); + + wl_list_init(&layout->pending_transition_list); + + wl_event_source_timer_update(layout->transitions->event_source, 1); +} + static void send_surface_prop(struct ivi_layout_surface *ivisurf) { @@ -2700,6 +2631,8 @@ ivi_layout_commitChanges(void) commit_list_layer(layout); commit_list_screen(layout); + commit_transition(layout); + commit_changes(layout); send_prop(layout); weston_compositor_schedule_repaint(layout->compositor); @@ -2955,6 +2888,10 @@ ivi_layout_initWithCompositor(struct weston_compositor *ec) else wl_list_remove(&ec->cursor_layer.link); weston_config_destroy(config); + + layout->transitions = ivi_layout_transition_set_create(ec); + wl_list_init(&layout->pending_transition_list); + } diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h index a949b4c5..21762ad0 100644 --- a/ivi-shell/ivi-layout.h +++ b/ivi-shell/ivi-layout.h @@ -52,6 +52,59 @@ extern "C" { #include "compositor.h" struct ivi_layout_surface; +struct ivi_layout_layer; +struct ivi_layout_screen; + +struct ivi_layout_SurfaceProperties +{ + float opacity; + uint32_t sourceX; + uint32_t sourceY; + uint32_t sourceWidth; + uint32_t sourceHeight; + uint32_t origSourceWidth; + uint32_t origSourceHeight; + int32_t destX; + int32_t destY; + uint32_t destWidth; + uint32_t destHeight; + uint32_t orientation; + uint32_t visibility; + uint32_t frameCounter; + uint32_t drawCounter; + uint32_t updateCounter; + uint32_t pixelformat; + uint32_t nativeSurface; + uint32_t inputDevicesAcceptance; + uint32_t chromaKeyEnabled; + uint32_t chromaKeyRed; + uint32_t chromaKeyGreen; + uint32_t chromaKeyBlue; + int32_t creatorPid; +}; + +struct ivi_layout_LayerProperties +{ + float opacity; + uint32_t sourceX; + uint32_t sourceY; + uint32_t sourceWidth; + uint32_t sourceHeight; + uint32_t origSourceWidth; + uint32_t origSourceHeight; + int32_t destX; + int32_t destY; + uint32_t destWidth; + uint32_t destHeight; + uint32_t orientation; + uint32_t visibility; + uint32_t type; + uint32_t chromaKeyEnabled; + uint32_t chromaKeyRed; + uint32_t chromaKeyGreen; + uint32_t chromaKeyBlue; + int32_t creatorPid; +}; struct ivi_layout_interface { struct weston_view* (*get_weston_view)(struct ivi_layout_surface *surface); diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in index c192d68e..050b806d 100644 --- a/ivi-shell/weston.ini.in +++ b/ivi-shell/weston.ini.in @@ -13,6 +13,8 @@ workspace-background-layer-id=2000 workspace-layer-id=3000 application-layer-id=4000 +transition-duration=300 + background-image=@abs_top_builddir@/data/background.png background-id=1001 panel-image=@abs_top_builddir@/data/panel.png -- cgit v1.2.1