From: SooChan Lim Date: Fri, 10 Sep 2021 08:08:54 +0000 (+0900) Subject: tdm: implement the tdm_hwc display X-Git-Tag: accepted/tizen/6.5/unified/20211028.121928~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80dab22d13b521d323646dbabe7346394340691b;p=platform%2Fcore%2Fuifw%2Fpepper.git tdm: implement the tdm_hwc display output uses tdm_hwc. Change-Id: I99bfc15c95c80d52a53aefcd60813ead77e1e1a0 --- diff --git a/src/lib/tdm/tdm-output.c b/src/lib/tdm/tdm-output.c index 30dbd82..8183a83 100644 --- a/src/lib/tdm/tdm-output.c +++ b/src/lib/tdm/tdm-output.c @@ -88,21 +88,56 @@ __tdm_renderer_pixman_get_target(tbm_surface_h surface) return target; } +static const pepper_list_t * +__tdm_output_get_render_list(pepper_tdm_output_t *output) +{ + const pepper_list_t *render_list; + + if (output->hwc) + render_list = pepper_hwc_get_render_list(output->hwc->base); + else + render_list = pepper_plane_get_render_list(output->primary_plane->base); + + return render_list; +} + +static pepper_region_t * +__tdm_output_get_damage_region(pepper_tdm_output_t *output) +{ + pepper_region_t *damage; + + if (output->hwc) + damage = pepper_hwc_get_damage_region(output->hwc->base); + else + damage = pepper_plane_get_damage_region(output->primary_plane->base); + + return damage; +} + +static void +__tdm_output_clear_damage_region(pepper_tdm_output_t *output) +{ + if (output->hwc) + pepper_hwc_clear_damage_region(output->hwc->base); + else + pepper_plane_clear_damage_region(output->primary_plane->base); +} + static void __tdm_renderer_pixman_render(pepper_tdm_output_t *output) { PEPPER_INFO("\n"); - const pepper_list_t *render_list = pepper_plane_get_render_list( - output->primary_plane->base); - pepper_region_t *damage = pepper_plane_get_damage_region( - output->primary_plane->base); - pepper_region_t total_damage; - tbm_surface_h back; + const pepper_list_t *render_list; + pepper_region_t *damage; + pepper_region_t total_damage; + tbm_surface_h back; pepper_render_target_t *target; - int ret; + render_list = __tdm_output_get_render_list(output); + damage = __tdm_output_get_damage_region(output); + /*Set render target*/ ret = tbm_surface_queue_dequeue(output->tbm_surface_queue, &back); PEPPER_CHECK(ret == TBM_SURFACE_QUEUE_ERROR_NONE, return, @@ -122,7 +157,15 @@ __tdm_renderer_pixman_render(pepper_tdm_output_t *output) &total_damage); pepper_region_fini(&total_damage); - pepper_plane_clear_damage_region(output->primary_plane->base); + + __tdm_output_clear_damage_region(output); + +#if 0 // for debugging + static int dump_cnt = 0; + char filename[256]; + snprintf(filename, sizeof filename, "/tmp/pixman_render_%d.png", dump_cnt++); + tdm_helper_dump_buffer(back, (const char*)filename); +#endif output->back = back; } @@ -137,8 +180,13 @@ __tdm_renderer_pixman_fini(pepper_tdm_output_t *output) if (output->render_target) pepper_render_target_destroy(output->render_target); - if (output->tbm_surface_queue) - tbm_surface_queue_destroy(output->tbm_surface_queue); + if (output->tbm_surface_queue) { + // DO NOT destroy tbm_surface_queue_h + if (output->hwc) + output->tbm_surface_queue = NULL; + else + tbm_surface_queue_destroy(output->tbm_surface_queue); + } output->renderer = NULL; output->render_target = NULL; @@ -148,7 +196,9 @@ __tdm_renderer_pixman_fini(pepper_tdm_output_t *output) static void __tdm_renderer_pixman_init(pepper_tdm_output_t *output) { - pepper_tdm_t *tdm = output->tdm; + pepper_tdm_t *tdm = output->tdm; + pepper_tdm_hwc_t *hwc = output->hwc; + const tdm_output_mode *mode; tdm_error err = TDM_ERROR_NONE; @@ -164,12 +214,19 @@ __tdm_renderer_pixman_init(pepper_tdm_output_t *output) err = tdm_output_get_mode(output->toutput, &mode); PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, - "tdm_output_get_mode() failed.\n"); - output->tbm_surface_queue = tbm_surface_queue_create(3, - mode->hdisplay, mode->vdisplay, - TBM_FORMAT_XBGR8888, TBM_BO_SCANOUT); - PEPPER_CHECK(output->tbm_surface_queue, goto error, - "tbm_surface_queue_create() failed.\n"); + "tdm_output_get_mode() failed.\n"); + + if (output->hwc) { + output->tbm_surface_queue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &err); + PEPPER_CHECK(output->tbm_surface_queue, goto error, + "tdm_hwc_get_client_target_buffer_queue() failed.\n"); + } else { + output->tbm_surface_queue = tbm_surface_queue_create(3, + mode->hdisplay, mode->vdisplay, + TBM_FORMAT_XBGR8888, TBM_BO_SCANOUT); + PEPPER_CHECK(output->tbm_surface_queue, goto error, + "tbm_surface_queue_create() failed.\n"); + } pepper_region_init(&output->previous_damage); output->render_type = TDM_RENDER_TYPE_PIXMAN; @@ -186,14 +243,14 @@ __tdm_renderer_gl_render(pepper_tdm_output_t *output) PEPPER_INFO("\n"); int ret; + const pepper_list_t *render_list; + pepper_region_t *damage; - const pepper_list_t *render_list = pepper_plane_get_render_list( - output->primary_plane->base); - pepper_region_t *damage = pepper_plane_get_damage_region( - output->primary_plane->base); + render_list = __tdm_output_get_render_list(output); + damage = __tdm_output_get_damage_region(output); pepper_renderer_repaint_output(output->renderer, output->base, render_list, - damage); + damage); ret = tbm_surface_queue_can_acquire(output->tbm_surface_queue, 1); PEPPER_CHECK(ret > 0, return, "tbm_surface_queue_can_acquire() failed.\n"); @@ -202,7 +259,7 @@ __tdm_renderer_gl_render(pepper_tdm_output_t *output) PEPPER_CHECK(ret == TBM_SURFACE_QUEUE_ERROR_NONE, return, "tbm_surface_queue_acquire() failed.\n"); - pepper_plane_clear_damage_region(output->primary_plane->base); + __tdm_output_clear_damage_region(output); } static void @@ -213,8 +270,13 @@ __tdm_renderer_gl_fini(pepper_tdm_output_t *output) if (output->render_target) pepper_render_target_destroy(output->render_target); - if (output->tbm_surface_queue) - tbm_surface_queue_destroy(output->tbm_surface_queue); + if (output->tbm_surface_queue) { + // DO NOT destroy tbm_surface_queue_h + if (output->hwc) + output->tbm_surface_queue = NULL; + else + tbm_surface_queue_destroy(output->tbm_surface_queue); + } output->renderer = NULL; output->render_target = NULL; @@ -226,10 +288,11 @@ __tdm_renderer_gl_init(pepper_tdm_output_t *output) { PEPPER_INFO("\n"); - pepper_tdm_t *tdm = output->tdm; + pepper_tdm_t *tdm = output->tdm; + pepper_tdm_hwc_t *hwc = output->hwc; const tdm_output_mode *mode; - uint32_t native_visual_id = TBM_FORMAT_XRGB8888; - tdm_error err = TDM_ERROR_NONE; + uint32_t native_visual_id = TBM_FORMAT_XRGB8888; + tdm_error err = TDM_ERROR_NONE; if (!tdm->gl_renderer) { tdm->gl_renderer = pepper_gl_renderer_create(tdm->compositor, tdm->bufmgr, @@ -243,18 +306,29 @@ __tdm_renderer_gl_init(pepper_tdm_output_t *output) PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, "tdm_output_get_mode() failed.\n"); - output->tbm_surface_queue = tbm_surface_queue_create(3, - mode->hdisplay, mode->vdisplay, - TBM_FORMAT_XRGB8888, - TBM_BO_SCANOUT); - PEPPER_CHECK(output->tbm_surface_queue, goto error, - "tbm_surface_queue_create() failed.\n"); - - output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer, - output->tbm_surface_queue, - PEPPER_FORMAT_XRGB8888, - &native_visual_id, - mode->hdisplay, mode->vdisplay); + if (output->hwc) { + output->tbm_surface_queue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &err); + PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, + "tdm_hwc_get_client_target_buffer_queue() failed.\n"); + output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer, + output->tbm_surface_queue, + PEPPER_FORMAT_XRGB8888, + &native_visual_id, + mode->hdisplay, mode->vdisplay); + } else { + output->tbm_surface_queue = tbm_surface_queue_create(3, + mode->hdisplay, mode->vdisplay, + TBM_FORMAT_XRGB8888, + TBM_BO_SCANOUT); + PEPPER_CHECK(output->tbm_surface_queue, goto error, + "tbm_surface_queue_create() failed.\n"); + + output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer, + output->tbm_surface_queue, + PEPPER_FORMAT_XRGB8888, + &native_visual_id, + mode->hdisplay, mode->vdisplay); + } PEPPER_CHECK(output->render_target, goto error, "pepper_gl_renderer_create_target() failed.\n"); output->render_type = TDM_RENDER_TYPE_GL; @@ -268,6 +342,78 @@ error: } static void +__tdm_hwc_destroy(pepper_event_listener_t *listener, pepper_object_t *object, + uint32_t id, void *info, void *data) +{ + PEPPER_INFO("\n"); + + free(data); +} + +static int +__tdm_output_hwc_init(pepper_tdm_output_t *output) +{ + pepper_tdm_hwc_t *hwc; + tdm_hwc *thwc; + tdm_error err; + + PEPPER_INFO("\n"); + + hwc = (pepper_tdm_hwc_t *)calloc(1, sizeof(pepper_tdm_hwc_t)); + PEPPER_CHECK(hwc, return PEPPER_FALSE, "calloc failed\n"); + hwc->output = output; + + thwc = tdm_output_get_hwc(output->toutput, &err); + PEPPER_CHECK(thwc, goto error, "Failed to get tdm_hwc\n"); + hwc->thwc = thwc; + + err = tdm_hwc_get_capabilities(hwc->thwc, &hwc->caps); + PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, + "tdm_hwc_get_capabilities failed err:%d\n", err); + + // TODO: check and save the video capabiliites. initialize the video capabilities. + /* for examples below. + // hwc video capabilities + if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_STREAM) + hwc->tdm_hwc_video_stream = EINA_TRUE; + if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCALE) + hwc->tdm_hwc_video_scale = EINA_TRUE; + if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_TRANSFORM) + hwc->tdm_hwc_video_transform = EINA_TRUE; + if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCANOUT) + hwc->tdm_hwc_video_scanout = EINA_TRUE; + if (hwc_caps & TDM_HWC_CAPABILITY_FENCE) + hwc->tdm_hwc_fence = EINA_TRUE; + */ + + // initialize a hwc_window list. + pepper_list_init(&hwc->window_list); + + // Add pepper_hwc of pepper_output and set it to hwc->base + hwc->base = pepper_output_initialize_hwc(output->base); + PEPPER_CHECK(hwc->base, goto error, "pepper_output_initialize_hwc() failed\n"); + + // add destory handler for pepper_hwc object + pepper_object_add_event_listener((pepper_object_t *)hwc->base, + PEPPER_EVENT_OBJECT_DESTROY, + 0, + __tdm_hwc_destroy, hwc); + + output->hwc = hwc; + + return PEPPER_TRUE; + +error: + if (hwc->base) + pepper_hwc_destroy(hwc->base); + + if (hwc) + free(hwc); + + return PEPPER_FALSE; +} + +static void __tdm_plane_destroy(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data) { @@ -389,6 +535,9 @@ pepper_tdm_output_destroy(void *o) /* TODO: */ + if (output->hwc) + pepper_hwc_destroy(output->hwc->base); + free(output); } @@ -503,13 +652,22 @@ pepper_tdm_output_assign_planes(void *o, const pepper_list_t *view_list) PEPPER_INFO("\n"); - pepper_list_for_each_list(l, view_list) { - pepper_view_t *view = l->item; - pepper_plane_t *plane = NULL; + if (output->hwc) { + // update info, buffer, compostiion type of hwc_windows + if (!pepper_tdm_hwc_update_changes(output->hwc, view_list)) + return; - plane = output->primary_plane->base; + if (!pepper_tdm_hwc_evaluate(output->hwc, view_list)) + return; + } else { + pepper_list_for_each_list(l, view_list) { + pepper_view_t *view = l->item; + pepper_plane_t *plane = NULL; - pepper_view_assign_plane(view, output->base, plane); + plane = output->primary_plane->base; + + pepper_view_assign_plane(view, output->base, plane); + } } } @@ -519,7 +677,7 @@ pepper_tdm_output_start_repaint_loop(void *o) PEPPER_INFO("\n"); pepper_tdm_output_t *output = (pepper_tdm_output_t *)o; - struct timespec ts; + struct timespec ts; pepper_compositor_get_time(output->tdm->compositor, &ts); pepper_output_finish_frame(output->base, &ts); @@ -531,8 +689,9 @@ pepper_tdm_output_repaint(void *o, const pepper_list_t *plane_list) PEPPER_INFO("\n"); pepper_tdm_output_t *output = (pepper_tdm_output_t *)o; - tdm_error err; + tdm_error terror; + // render if (!output->back) { if (output->render_type == TDM_RENDER_TYPE_GL) __tdm_renderer_gl_render(output); @@ -544,13 +703,25 @@ pepper_tdm_output_repaint(void *o, const pepper_list_t *plane_list) } } - if (output->back) { - err = tdm_layer_set_buffer((tdm_layer *)output->primary_plane->layer, - output->back); - PEPPER_CHECK(err == TDM_ERROR_NONE, return, "tdm_layer_set_buffer() failed"); + // TODO: fix this... + if (!output->back) + return; + + if (output->hwc) { + // set back buffer as a client_target_buffer + pepper_tdm_hwc_set_client_target_buffer(output->hwc, output->back); + + if (!pepper_tdm_hwc_commit(output->hwc)) + return; + + output->page_flip_pending = PEPPER_TRUE; + } else { + terror = tdm_layer_set_buffer((tdm_layer *)output->primary_plane->layer, + output->back); + PEPPER_CHECK(terror == TDM_ERROR_NONE, return, "tdm_layer_set_buffer() failed"); - err = tdm_output_commit(output->toutput, 0, __tdm_output_commit_cb, output); - PEPPER_CHECK(err == TDM_ERROR_NONE, return, "tdm_output_commit() failed"); + terror = tdm_output_commit(output->toutput, 0, __tdm_output_commit_cb, output); + PEPPER_CHECK(terror == TDM_ERROR_NONE, return, "tdm_output_commit() failed"); output->page_flip_pending = PEPPER_TRUE; } @@ -563,12 +734,16 @@ pepper_tdm_output_attach_surface(void *o, pepper_surface_t *surface, int *w, PEPPER_INFO("\n"); pepper_tdm_output_t *output = (pepper_tdm_output_t *)o; + + if (output->hwc) + pepper_tdm_hwc_attach_surface(output->hwc, surface); + pepper_renderer_attach_surface(output->renderer, surface, w, h); } static void pepper_tdm_output_flush_surface_damage(void *o, pepper_surface_t *surface, - pepper_bool_t *keep_buffer) + pepper_bool_t *keep_buffer) { PEPPER_INFO("\n"); @@ -583,6 +758,8 @@ pepper_tdm_output_flush_surface_damage(void *o, pepper_surface_t *surface, } else { *keep_buffer = PEPPER_TRUE; } + + // HWC : } struct pepper_output_backend tdm_output_backend = { @@ -607,6 +784,7 @@ int pepper_tdm_output_init(pepper_tdm_t *tdm) { pepper_tdm_output_t *output; + tdm_hwc *thwc; tdm_error err; int i; @@ -668,6 +846,24 @@ pepper_tdm_output_init(pepper_tdm_t *tdm) "tdm_output_set_mode() failed err:%d\n", err); } + /*Add pepper_output to compositor*/ + output->base = pepper_compositor_add_output(tdm->compositor, + &tdm_output_backend, + "tdm_output", + output, + WL_OUTPUT_TRANSFORM_NORMAL, 1); + PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, + "pepper_compositor_add_output() failed err:%d\n", err); + + // check if tdm_output has tdm_hwc. + thwc = tdm_output_get_hwc(output->toutput, &err); + if (thwc && err == TDM_ERROR_NONE) + PEPPER_CHECK(PEPPER_TRUE == __tdm_output_hwc_init(output), goto error, + "pepper_tdm_hwc_init() failed\n"); + else + PEPPER_CHECK(PEPPER_TRUE == __tdm_output_plane_init(output), goto error, + "pepper_tdm_plane_init() failed\n"); + /*Setup renderer*/ if (render_env && !strcmp(render_env, "gl")) { __tdm_renderer_gl_init(output); @@ -680,18 +876,6 @@ pepper_tdm_output_init(pepper_tdm_t *tdm) PEPPER_CHECK(output->renderer, goto error, "Failed to initialize pixman_renderer.\n"); } - - /*Add pepper_output to compositor*/ - output->base = pepper_compositor_add_output(tdm->compositor, - &tdm_output_backend, - "tdm_output", - output, - WL_OUTPUT_TRANSFORM_NORMAL, 1); - PEPPER_CHECK(err == TDM_ERROR_NONE, goto error, - "pepper_compositor_add_output() failed err:%d\n", err); - - PEPPER_CHECK(PEPPER_TRUE == __tdm_output_plane_init(output), goto error, - "pepper_tdm_plane_init() failed\n"); } return PEPPER_TRUE;