From: Sung-Jin Park Date: Tue, 14 May 2019 02:55:10 +0000 (+0900) Subject: headless-server::output : Support display X-Git-Tag: submit/tizen/20190530.092249~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7c8ee3ed49aa5e736bc6010e78c3c326f2fcac62;p=platform%2Fcore%2Fuifw%2Fpepper.git headless-server::output : Support display Change-Id: I487d6b7480b196124a12dd801be5458e4542a627 Signed-off-by: Sangjin Lee --- diff --git a/configure.ac b/configure.ac index 537b4a3..e9b5065 100644 --- a/configure.ac +++ b/configure.ac @@ -317,9 +317,9 @@ AC_SUBST(SAMPLES_LIBS) # headless server HEADLESS_SERVER_REQUIRES="wayland-server capi-system-peripheral-io xdg-shell-unstable-v6-server tizen-extension-server" PKG_CHECK_MODULES(HEADLESS_SERVER, $[HEADLESS_SERVER_REQUIRES]) -HEADLESS_SERVER_CFLAGS="$PEPPER_DIR $PEPPER_KEYROUTER_DIR $PEPPER_EVDEV_DIR $HEADLESS_SERVER_CFLAGS" +HEADLESS_SERVER_CFLAGS="$PEPPER_DIR $PEPPER_KEYROUTER_DIR $PEPPER_EVDEV_DIR $HEADLESS_SERVER_CFLAGS $TBM_CFLAGS" HEADLESS_SERVER_CFLAGS="$PEPPER_XKB_DIR $HEADLESS_SERVER_CFLAGS" -HEADLESS_SERVER_LIBS="$PEPPER_LIB $PEPPER_LIBS $PEPPER_EVDEV_LIB $PEPPER_EVDEV_LIBS $HEADLESS_SERVER_LIBS" +HEADLESS_SERVER_LIBS="$PEPPER_LIB $PEPPER_LIBS $PEPPER_EVDEV_LIB $PEPPER_EVDEV_LIBS $HEADLESS_SERVER_LIBS $TBM_LIBS" HEADLESS_SERVER_LIBS="$PEPPER_KEYROUTER_LIB $PEPPER_KEYROUTER_LIBS $HEADLESS_SERVER_LIBS" HEADLESS_SERVER_LIBS="$PEPPER_XKB_LIB $PEPPER_XKB_LIBS $HEADLESS_SERVER_LIBS" diff --git a/src/bin/headless/output/output_led.c b/src/bin/headless/output/output_led.c index fec962f..aebad29 100644 --- a/src/bin/headless/output/output_led.c +++ b/src/bin/headless/output/output_led.c @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include "HL_UI_LED.h" @@ -37,9 +39,16 @@ typedef struct { int num_led; HL_UI_LED *ui_led; + + struct wayland_tbm_server *tbm_server; + struct wl_event_source *frame_done; + + pepper_view_t *top_view; }led_output_t; static const int KEY_OUTPUT; +static void led_output_add_frame_done(led_output_t *output); +static void led_output_update(led_output_t *output); static void led_output_destroy(void *o) @@ -50,34 +59,33 @@ led_output_destroy(void *o) if (output->ui_led) HL_UI_LED_Close(output->ui_led); + if (output->tbm_server) + wayland_tbm_server_deinit(output->tbm_server); + free(output); } static int32_t led_output_get_subpixel_order(void *o) { - PEPPER_TRACE("[OUTPUT]\n"); return 0; } static const char * led_output_get_maker_name(void *o) { - PEPPER_TRACE("[OUTPUT]\n"); return "PePPer LED"; } static const char * led_output_get_model_name(void *o) { - PEPPER_TRACE("[OUTPUT]\n"); return "PePPer LED"; } static int led_output_get_mode_count(void *o) { - PEPPER_TRACE("[OUTPUT]\n"); return 1; } @@ -108,14 +116,22 @@ led_output_assign_planes(void *o, const pepper_list_t *view_list) { led_output_t *output = (led_output_t *)o; pepper_list_t *l; - pepper_view_t *view; + pepper_view_t *view, *top_view = NULL; PEPPER_TRACE("[OUTPUT] Assign plane\n"); pepper_list_for_each_list(l, view_list) { view = (pepper_view_t*)l->item; - pepper_view_assign_plane(view, output->output, output->plane); - PEPPER_TRACE("\t view(%p) assign to output:%p plane:%p\n", view, output->output, output->plane); + + if (pepper_view_is_mapped(view) && pepper_view_is_visible(view)) { + top_view = view; + break; + } } + + if (output->top_view != top_view) + PEPPER_TRACE("\tTop-View is changed(%p -> %p)\n", output->top_view, top_view); + + output->top_view = top_view; } static void @@ -133,20 +149,18 @@ static void led_output_repaint(void *o, const pepper_list_t *plane_list) { pepper_list_t *l; - pepper_list_t *rl; pepper_plane_t *plane; - pepper_render_item_t *ritem; + led_output_t *output = (led_output_t *)o; PEPPER_TRACE("[OUTPUT] Repaint\n"); + pepper_list_for_each_list(l, plane_list) { plane = (pepper_plane_t *)l->item; - PEPPER_TRACE("\t plane:%p\n", plane); - - pepper_list_for_each_list(rl, pepper_plane_get_render_list(plane)) { - ritem = (pepper_render_item_t *)rl->item; - PEPPER_TRACE("\t\t render item: view:%p\n", ritem->view); - } + pepper_plane_clear_damage_region(plane); } + + led_output_update(output); + led_output_add_frame_done(output); } static void @@ -154,14 +168,14 @@ led_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h) { *w = 10; *h = 10; - PEPPER_TRACE("[OUTPUT] surface:%p\n", surface); + PEPPER_TRACE("[OUTPUT] attach surface:%p\n", surface); } static void led_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer) { - *keep_buffer = PEPPER_FALSE; - PEPPER_TRACE("[OUTPUT] surface:%p\n", surface); + *keep_buffer = PEPPER_TRUE; + PEPPER_TRACE("[OUTPUT] flush_surface_damage surface:%p\n", surface); } struct pepper_output_backend led_output_backend = { @@ -182,6 +196,97 @@ struct pepper_output_backend led_output_backend = { led_output_flush_surface_damage, }; +static void +led_output_update_led(led_output_t *output, unsigned char *data) +{ +} + +static void +led_output_update(led_output_t *output) +{ + pepper_buffer_t *buf; + pepper_surface_t *surface; + struct wl_resource *buf_res; + tbm_surface_h tbm_surface; + tbm_surface_info_s info; + int ret; + + if (!output->top_view) { + if (!output->ui_led) + PEPPER_TRACE("[UPDATE LED] Empty Display\n"); + else + led_output_update_led(output, NULL); + + return; + } + + surface = pepper_view_get_surface(output->top_view); + PEPPER_CHECK(surface, return, "fail to get a surafce from a view(%p)\n", output->top_view); + + buf = pepper_surface_get_buffer(surface); + PEPPER_CHECK(buf, return, "fail to get a pepper_buffer from a surface(%p)\n", surface); + + buf_res = pepper_buffer_get_resource(buf); + tbm_surface = wayland_tbm_server_get_surface(NULL, buf_res); + PEPPER_CHECK(tbm_surface, return, "fail to get a tbm_surface from a pepper_buffer(%p)\n", buf); + + ret = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info); + PEPPER_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "fail to map the tbm_surface\n"); + + if (!output->ui_led) + PEPPER_TRACE("[UPDATE LED] %s\n", (char*)info.planes[0].ptr); + else + led_output_update_led(output, info.planes[0].ptr); + + tbm_surface_unmap(tbm_surface); +} + +static void +led_output_cb_frame_done(void *data) +{ + led_output_t *output = (led_output_t *)data; + + PEPPER_TRACE("[OUTPUT] frame_done\n"); + + pepper_output_finish_frame(output->output, NULL); + output->frame_done = NULL; +} + +static void +led_output_add_frame_done(led_output_t *output) +{ + struct wl_event_loop *loop; + + PEPPER_TRACE("[OUTPUT] Add idle for frame(output:%p, frame:%p\n", output, output->frame_done); + + if (!output || output->frame_done) + return; + + loop = wl_display_get_event_loop(pepper_compositor_get_display(output->compositor)); + PEPPER_CHECK(loop, return, "[OUTPUT] fail to get event loop\n"); + + output->frame_done = wl_event_loop_add_idle(loop, led_output_cb_frame_done, output); + PEPPER_CHECK(output->frame_done, return, "fail to add idle\n"); +} + +static void +pepper_output_bind_display(led_output_t *output) +{ + tbm_bufmgr bufmgr = NULL; + + PEPPER_CHECK(getenv("TBM_DISPLAY_SERVER"), return, "[TBM] run the subcompoitor mode\n"); + + bufmgr = wayland_tbm_server_get_bufmgr(output->tbm_server); + PEPPER_CHECK(bufmgr, return, "fail to get tbm_bufmgr\n"); + + if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)pepper_compositor_get_display(output->compositor))) + { + PEPPER_CHECK(0, return, "fail to tbm_bufmgr_bind_native_display\n"); + } + + return; +} + pepper_bool_t pepper_output_led_init(pepper_compositor_t *compositor) { @@ -194,12 +299,17 @@ pepper_output_led_init(pepper_compositor_t *compositor) goto error; } + output->compositor = compositor; + output->tbm_server = wayland_tbm_server_init(pepper_compositor_get_display(compositor), NULL, -1, 0); + PEPPER_CHECK(output->tbm_server, goto error, "failed to wayland_tbm_server_init.\n"); + + pepper_output_bind_display(output); + output->num_led = NUM_LED; output->ui_led = HL_UI_LED_Init(output->num_led); if (!output->ui_led) PEPPER_ERROR("HL_UI_LED_Init() failed.\n"); - output->compositor = compositor; output->output = pepper_compositor_add_output(compositor, &led_output_backend, "led_output", output, WL_OUTPUT_TRANSFORM_NORMAL, 1); @@ -219,6 +329,9 @@ error: if (output->ui_led) HL_UI_LED_Close(output->ui_led); + if (output->tbm_server) + wayland_tbm_server_deinit(output->tbm_server); + if (output->output) pepper_output_destroy(output->output); diff --git a/src/bin/headless/shell/shell.c b/src/bin/headless/shell/shell.c index 8927c91..3962327 100644 --- a/src/bin/headless/shell/shell.c +++ b/src/bin/headless/shell/shell.c @@ -923,6 +923,9 @@ static const struct tizen_policy_interface tizen_policy_iface = static void tizen_policy_cb_unbind(struct wl_resource *resource) { + headless_shell_t *shell = (headless_shell_t *)wl_resource_get_user_data(resource); + + shell->tizen_policy = NULL; } static void @@ -965,7 +968,7 @@ tizen_policy_init(headless_shell_t *shell) void tizen_policy_deinit(headless_shell_t *shell) { - if (shell->zxdg_shell) + if (shell->tizen_policy) wl_global_destroy(shell->tizen_policy); } @@ -1087,7 +1090,7 @@ headless_shell_add_idle(headless_shell_t *shell) { struct wl_event_loop *loop; - if (shell->cb_idle) + if (!shell || shell->cb_idle) return; loop = wl_display_get_event_loop(pepper_compositor_get_display(shell->compositor)); diff --git a/src/lib/pepper/compositor.c b/src/lib/pepper/compositor.c index ad4da74..9d92826 100644 --- a/src/lib/pepper/compositor.c +++ b/src/lib/pepper/compositor.c @@ -185,7 +185,7 @@ pepper_compositor_schedule_repaint(pepper_compositor_t *compositor) pepper_output_t *output; pepper_list_for_each(output, &compositor->output_list, link) - pepper_output_schedule_repaint(output); + pepper_output_schedule_repaint(output); } /** diff --git a/src/lib/pepper/output.c b/src/lib/pepper/output.c index 5630e97..9d68a4c 100644 --- a/src/lib/pepper/output.c +++ b/src/lib/pepper/output.c @@ -125,7 +125,7 @@ output_update_planes(pepper_output_t *output) pepper_region_init(&clip); pepper_list_for_each_reverse(plane, &output->plane_list, link) - pepper_plane_update(plane, &output->view_list, &clip); + pepper_plane_update(plane, &output->view_list, &clip); pepper_region_fini(&clip); } diff --git a/src/lib/pepper/view.c b/src/lib/pepper/view.c index ded296f..bcf6105 100644 --- a/src/lib/pepper/view.c +++ b/src/lib/pepper/view.c @@ -35,8 +35,10 @@ pepper_view_mark_dirty(pepper_view_t *view, uint32_t flag) pepper_view_t *child; int i; - if (view->dirty & flag) + if (view->dirty & flag) { + PEPPER_TRACE("pepper_view_mark_dirty view:%p, dirty:%x, flag:%x\n", view, view->dirty, flag); return; + } view->dirty |= flag; @@ -162,14 +164,18 @@ pepper_view_update(pepper_view_t *view) if (view->active == active) view->dirty &= ~PEPPER_VIEW_ACTIVE_DIRTY; - if (!view->dirty) + if (!view->dirty) { + PEPPER_TRACE("pepper_view_update view:%p not dirty\n", view); return; + } view->active = active; /* Damage for the view unmap will be handled by assigning NULL plane. */ - if (!view->active) + if (!view->active) { + PEPPER_TRACE("pepper_view_update view:%p not active\n", view); return; + } /* We treat the modification as unmapping and remapping the view. So, * damage for the unmap and damage for the remap. diff --git a/src/samples/headless_client.c b/src/samples/headless_client.c index 3ce783e..70f5d72 100644 --- a/src/samples/headless_client.c +++ b/src/samples/headless_client.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define DISPLAY_NAME "headless-0" @@ -33,10 +35,81 @@ struct app_data { Ecore_Wl2_Display *ewd; Ecore_Wl2_Window *win; + + struct wayland_tbm_client *wl_tbm_client; + tbm_surface_queue_h tbm_queue; + int last_serial; }; static Eina_Array *_ecore_event_hdls; +static int KEY_WL_BUFFER = 0; +static int KEY_CLIENT = 0; + +static void +buffer_release(void *data, struct wl_buffer *buffer) +{ + tbm_surface_h surface = (tbm_surface_h)data; + app_data_t *client; + + tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_CLIENT, (void **)&client); + tbm_surface_queue_release(client->tbm_queue, surface); + + //TRACE("[UPDATE] release wl_buffer:%p, surface:%p\n", buffer, surface); +} + +static const struct wl_buffer_listener buffer_listener = { + buffer_release +}; + +static void +_update_window(app_data_t *client) +{ + struct wl_buffer *wl_buffer = NULL; + tbm_surface_h surface; + tbm_surface_error_e ret; + + ERROR_CHECK(tbm_surface_queue_can_dequeue(client->tbm_queue, 0), return, "[UPDATE] Cannot dequeue\n"); + + ret = tbm_surface_queue_dequeue(client->tbm_queue, &surface); + ERROR_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "[UPDATE] dequeue err:%d\n", ret); + + /*TODO : Update something*/ + { + tbm_surface_info_s info; + + tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &info); + snprintf((char *)info.planes[0].ptr,info.planes[0].size, "%s : %d", "DATA print", client->last_serial); + TRACE("[APP] %s\n", info.planes[0].ptr); + tbm_surface_unmap(surface); + client->last_serial++; + } + + ret = tbm_surface_queue_enqueue(client->tbm_queue, surface); + ERROR_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "[UPDATE] enqueue err:%d\n", ret); + + ret = tbm_surface_queue_acquire(client->tbm_queue, &surface); + ERROR_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "[UPDATE] acquire err:%d\n", ret); + + if (!tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_WL_BUFFER, (void **)&wl_buffer)) { + wl_buffer = wayland_tbm_client_create_buffer(client->wl_tbm_client, surface); + ERROR_CHECK(wl_buffer, return, "[UPDATE] failed to create wl_buffer tbm_surface:%p\n", surface); + + wl_buffer_add_listener(wl_buffer, &buffer_listener, surface); + + tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_WL_BUFFER, NULL); + tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_WL_BUFFER, wl_buffer); + tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_CLIENT, NULL); + tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_CLIENT, client); + } + ERROR_CHECK(wl_buffer, return, "[UPDATE] dequeue err:%d\n", ret); + + ecore_wl2_window_buffer_attach(client->win, wl_buffer, 0, 0, 0); + ecore_wl2_window_damage(client->win, NULL, 0); + ecore_wl2_window_commit(client->win, EINA_TRUE); + //TRACE("[UPDATE] commit wl_buffer:%p, surface:%p\n", wl_buffer, surface); +} + static uint32_t _getpid() { static pid_t pid = 0; @@ -194,11 +267,7 @@ _cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) app_data_t *client = (app_data_t *)data; Ecore_Event_Key *ev = event; - TRACE("\n"); - - /* TODO */ - (void) client; - (void) ev; + TRACE("KEY: name:%s, sym:%s, code:%d\n", ev->keyname, ev->key, ev->keycode); do_action(client, ev->keyname); @@ -276,23 +345,44 @@ int main(int argc, char **argv) client->ewd = ecore_wl2_display_connect(DISPLAY_NAME); ERROR_CHECK(client->ewd, goto shutdown, "Failed to connect to wayland display %s", DISPLAY_NAME); + client->wl_tbm_client = wayland_tbm_client_init(ecore_wl2_display_get(client->ewd)); + ERROR_CHECK(client->wl_tbm_client, goto shutdown, "Failed to init wayland_tbm_client"); + _event_handlers_init(client); + /*Create Sample Window*/ x = y = 0; w = h = 1; client->win = ecore_wl2_window_new(client->ewd, NULL, x, y, w, h); + ecore_wl2_window_alpha_set(client->win, EINA_FALSE); ecore_wl2_window_show(client->win); ecore_wl2_window_activate(client->win); ecore_wl2_window_commit(client->win, EINA_TRUE); + client->tbm_queue = wayland_tbm_client_create_surface_queue(client->wl_tbm_client, + ecore_wl2_window_surface_get(client->win), + 2, + 100, 100, + TBM_FORMAT_ABGR8888); + ERROR_CHECK(client->tbm_queue, goto shutdown, "Failed to create tbm_surface_queue"); + usage(); - /* TODO */ + /*Start Loop*/ ecore_main_loop_begin(); - return EXIT_SUCCESS; - shutdown: - return EXIT_FAILURE; + if (client) { + if (client->tbm_queue) + tbm_surface_queue_destroy(client->tbm_queue); + + if (client->wl_tbm_client) + wayland_tbm_client_deinit(client->wl_tbm_client); + + ecore_wl2_shutdown(); + free(client); + } + + return EXIT_SUCCESS; }