From: Changyeon Lee Date: Thu, 13 Aug 2020 11:58:22 +0000 (+0900) Subject: e_hwc_windows: refactoring external output mirror/presentation mode X-Git-Tag: submit/tizen/20200825.082113~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb955bff640b82ab39310aa8977a8c7354949699;p=platform%2Fupstream%2Fenlightenment.git e_hwc_windows: refactoring external output mirror/presentation mode 1. use pp_queue of target_hwc_window 2. unified tdm_pp of zoom and external output mode 3. set hwc_window to pp_hwc_window if need to use tdm_pp Change-Id: I3077206a235cceca294abc8f7207f0e3a844fff0 --- diff --git a/src/bin/e_hwc.h b/src/bin/e_hwc.h index 974a85ebe2..093324690b 100644 --- a/src/bin/e_hwc.h +++ b/src/bin/e_hwc.h @@ -110,12 +110,9 @@ struct _E_Hwc tdm_pp *tpp; tbm_surface_queue_h pp_tqueue; E_Hwc_Window_Queue *pp_queue; - tbm_surface_h pp_tsurface; - Eina_Bool pp_set_info; Eina_Bool pp_set; Eina_Bool pp_commit; - E_Hwc_Window_Commit_Data *pp_output_commit_data; - Eina_Rectangle pp_src_rect_prev; + Eina_Bool pp_dst_buffer_clear; Eina_Rectangle pp_src_rect, pp_dst_rect; Eina_Rectangle pp_set_src_rect, pp_set_dst_rect; E_Hwc_Window *pp_hwc_window; diff --git a/src/bin/e_hwc_windows.c b/src/bin/e_hwc_windows.c index e7e5822520..d1e58533c2 100644 --- a/src/bin/e_hwc_windows.c +++ b/src/bin/e_hwc_windows.c @@ -56,17 +56,8 @@ #define ROUNDUP(s,c) (((s) + (c-1)) & ~(c-1)) -typedef struct _E_Hwc_Windows_Pp_Data E_Hwc_Windows_Pp_Data; typedef struct _E_Hwc_Windows_Buffer_Comp_Info E_Hwc_Windows_Buffer_Comp_Info; -struct _E_Hwc_Windows_Pp_Data -{ - E_Hwc *hwc; - E_Hwc_Window_Queue_Buffer *queue_buffer; - e_hwc_pp_done_handler func; - E_Output_Display_Mode mode; -}; - struct _E_Hwc_Windows_Buffer_Comp_Info { E_Presentation_Time_Container presentation_container; @@ -344,12 +335,6 @@ _e_hwc_windows_commit_handler(tdm_hwc *thwc, unsigned int sequence, EHWSTRACE("!!!!!!!! HWC Commit Handler !!!!!!!!", NULL, hwc); - if (hwc->pp_tsurface && !hwc->pp_set) - { - tbm_surface_internal_unref(hwc->pp_tsurface); - hwc->pp_tsurface = NULL; - } - _e_hwc_windows_commit_data_release(hwc, sequence, tv_sec, tv_usec); /* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame; @@ -549,7 +534,6 @@ _e_hwc_windows_target_buffer_fetch(E_Hwc *hwc) CLEAR(fb_damage); tdm_hwc_set_client_target_buffer(thwc, hwc_window->buffer.tsurface, fb_damage); - if ((target_hwc_window->end_render_sync) && (e_hwc_windows_fence_enabled_get(hwc))) { int fence = e_egl_sync_fence_fd_dup(target_hwc_window->end_render_sync); @@ -2257,129 +2241,6 @@ _e_hwc_windows_target_state_set(E_Hwc_Window_Target *target_hwc_window, E_Hwc_Wi e_hwc_window_accepted_state_set(target_window, state); } -/* evaluate the hwc_windows */ -static Eina_Bool -_e_hwc_windows_evaluate(E_Hwc *hwc) -{ - E_Hwc_Mode hwc_mode = E_HWC_MODE_NONE; - E_Hwc_Window *hwc_window = NULL; - const Eina_List *l; - uint32_t num_changes; - int num_client = 0, num_device = 0, num_video = 0, num_cursor = 0; - - /* validate the visible hwc_windows' states*/ - if (!_e_hwc_windows_validate(hwc, &num_changes)) - { - EHWSERR("_e_hwc_windows_validate failed.", hwc); - goto re_evaluate; - } - - /* update the valiated_changes if there are the composition changes after validation */ - if (num_changes) - { - if (!_e_hwc_windows_validated_changes_update(hwc, num_changes)) - { - EHWSERR("_e_hwc_windows_validated_changes_update failed.", hwc); - goto re_evaluate; - } - } - - /* constraints update and update the windows to be composited to the target_buffer */ - EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window) - { - if (e_hwc_window_is_target(hwc_window)) continue; - - e_hwc_window_constraints_update(hwc_window); - e_hwc_window_rendered_window_update(hwc_window); - - if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT) num_client++; - if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE) num_device++; - if (hwc_window->state == E_HWC_WINDOW_STATE_CURSOR) num_cursor++; - if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) num_video++; - } - - /* update the E_HWC_MODE */ - hwc_mode = _e_hwc_windows_hwc_mode_update(hwc, num_client, num_device, num_cursor ,num_video); - - /* set the state of the target_window */ - if (hwc_mode == E_HWC_MODE_NONE) - { - EHWSTRACE(" HWC_MODE is NONE composition.", NULL, hwc); - _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_DEVICE); - } - else if (hwc_mode == E_HWC_MODE_HYBRID) - { - EHWSTRACE(" HWC_MODE is HYBRID composition.", NULL, hwc); - _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_DEVICE); - } - else - { - EHWSTRACE(" HWC_MODE is FULL HW composition.", NULL, hwc); - _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_NONE); - } - - /* skip the target_buffer when the window is on trainsition of the composition */ - if ((hwc_mode != E_HWC_MODE_FULL) && (_e_hwc_windows_transition_check(hwc)) && (!hwc->pp_set)) - { - _e_hwc_windows_target_window_buffer_skip(hwc); - - if (!hwc->transition) - { - _e_hwc_windows_target_window_force_render(hwc->target_hwc_window); - hwc->transition = EINA_TRUE; - } - - goto re_evaluate; - } - - if (_e_hwc_windows_present_sync_check(hwc)) - { - EHWSTRACE(" Not accpet display sync.", NULL, hwc); - goto re_evaluate; - } - - if (e_hwc_norender_get(hwc) > 0) - { - EHWSTRACE(" Not accpet validation NoRender get.", NULL, hwc); - goto re_evaluate; - } - - if (hwc_mode == E_HWC_MODE_FULL) - { - if (((E_Hwc_Window *)hwc->target_hwc_window)->buffer.tsurface) - _e_hwc_windows_target_buffer_fetch(hwc); - } - - /* accept the result of the validation */ - if (!_e_hwc_windows_accept(hwc)) - { - EHWSERR("_e_hwc_windows_validated_changes_update failed.", hwc); - goto re_evaluate; - } - - hwc->transition = EINA_FALSE; - - return EINA_TRUE; - -re_evaluate: - EHWSTRACE("======= HWC NOT Accept Validation Yet !! =======", NULL, hwc); - - return EINA_FALSE; -} - -static Eina_Bool -_e_hwc_windows_target_buffer_prepared(E_Hwc *hwc) -{ - E_Hwc_Window *hwc_window = NULL; - - hwc_window = (E_Hwc_Window *)hwc->target_hwc_window; - EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->target_hwc_window, EINA_FALSE); - - if (!hwc_window->buffer.tsurface) return EINA_FALSE; - - return EINA_TRUE; -} - static void _e_hwc_windows_center_rect_get(int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *fit) { @@ -2596,111 +2457,6 @@ _e_hwc_windows_sw_copy(E_Hwc *hwc, tbm_surface_h src_tsurface, tbm_surface_h dst dst_pos.x, dst_pos.y, dst_pos.w, dst_pos.h); } -static void -_e_hwc_windows_pp_rect_set(E_Hwc *hwc, Eina_Rectangle *src_rect, Eina_Rectangle *dst_rect) -{ - memcpy(&hwc->pp_src_rect, src_rect, sizeof(Eina_Rectangle)); - memcpy(&hwc->pp_dst_rect, dst_rect, sizeof(Eina_Rectangle)); -} - -static Eina_Bool -_e_hwc_windows_pp_buffer_update(E_Hwc *hwc) -{ - E_Hwc_Window_Queue_Buffer *queue_buffer; - E_Hwc_Window *hwc_window; - - EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE); - - if (hwc->pp_hwc_window) - { - hwc_window = hwc->pp_hwc_window; - - e_hwc_window_queue_clear(((E_Hwc_Window *)hwc->target_hwc_window)->queue); - } - else - hwc_window = (E_Hwc_Window *)hwc->target_hwc_window; - - if ((hwc_window->is_target) && ((E_Hwc_Window *)hwc->target_hwc_window == hwc_window)) - { - queue_buffer = e_hwc_window_queue_buffer_acquire(hwc_window->queue); - if (!queue_buffer) return EINA_FALSE; - - e_hwc_window_buffer_set(&hwc->pp_buffer, queue_buffer->tsurface, hwc_window->queue); - } - else - { - if (hwc_window->buffer.tsurface == hwc->pp_buffer.tsurface) - return EINA_FALSE; - - e_hwc_window_buffer_set(&hwc->pp_buffer, - hwc_window->buffer.tsurface, hwc_window->buffer.queue); - - if (!e_hwc_window_is_target(hwc_window)) - e_comp_wl_buffer_reference(&hwc->pp_buffer_ref, _e_hwc_windows_comp_wl_buffer_get(hwc_window)); - } - - return EINA_TRUE; -} - -static Eina_Bool -_e_hwc_windows_mirror_changes_update(E_Hwc *hwc) -{ - E_Hwc *mirror_src_hwc; - E_Hwc_Window_Target *target_hwc_window, *src_target_hwc_window; - tbm_surface_h target_tsurface, src_target_tsurface; - E_Hwc_Window_Queue *queue; - E_Hwc_Window_Queue_Buffer *queue_buffer = NULL; - - mirror_src_hwc = hwc->mirror_src_hwc; - EINA_SAFETY_ON_NULL_RETURN_VAL(mirror_src_hwc, EINA_FALSE); - - target_hwc_window = hwc->target_hwc_window; - EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE); - - src_target_hwc_window = mirror_src_hwc->target_hwc_window; - EINA_SAFETY_ON_NULL_RETURN_VAL(src_target_hwc_window, EINA_FALSE); - - target_tsurface = target_hwc_window->hwc_window.buffer.tsurface; - src_target_tsurface = src_target_hwc_window->hwc_window.buffer.tsurface; - - if (hwc->mirror_src_tsurface == src_target_tsurface) return EINA_FALSE; - - queue = ((E_Hwc_Window *)target_hwc_window)->queue; - EINA_SAFETY_ON_NULL_RETURN_VAL(queue, EINA_FALSE); - - /* dequeue buffer */ - queue_buffer = e_hwc_window_queue_buffer_dequeue(queue); - EINA_SAFETY_ON_NULL_RETURN_VAL(queue_buffer, EINA_FALSE); - - /* copy */ - target_tsurface = queue_buffer->tsurface; - _e_hwc_windows_sw_copy(hwc, src_target_tsurface, target_tsurface, E_OUTPUT_DISPLAY_MODE_MIRROR); - - /* enqueue buffer */ - e_hwc_window_queue_buffer_enqueue(queue, queue_buffer); - - /* fetch the buffer */ - _e_hwc_windows_target_buffer_fetch(hwc); - - hwc->mirror_src_tsurface = src_target_tsurface; - - return EINA_TRUE; -} - -static Eina_Bool -_e_hwc_windows_presentation_changes_update(E_Hwc *hwc) -{ - /* set buffer */ - if (!e_hwc_window_buffer_fetch(hwc->presentation_hwc_window)) - return EINA_FALSE; - - e_hwc_window_zpos_set(hwc->presentation_hwc_window, 0); - e_hwc_window_state_set(hwc->presentation_hwc_window, E_HWC_WINDOW_STATE_DEVICE, EINA_TRUE); - e_hwc_window_info_update(hwc->presentation_hwc_window); - - return EINA_TRUE; -} - static Eina_Bool _e_hwc_windows_presentation_evaluation_check(E_Hwc *hwc) { @@ -2721,12 +2477,14 @@ _e_hwc_windows_presentation_evaluation_check(E_Hwc *hwc) queue = ((E_Hwc_Window *)target_hwc_window)->queue; EINA_SAFETY_ON_NULL_RETURN_VAL(queue, EINA_FALSE); + src_tsurface = hwc->presentation_hwc_window->buffer.tsurface; + if (!src_tsurface) return EINA_TRUE; + /* dequeue buffer */ queue_buffer = e_hwc_window_queue_buffer_dequeue(queue); EINA_SAFETY_ON_NULL_RETURN_VAL(queue_buffer, EINA_FALSE); /* copy */ - src_tsurface = hwc->presentation_hwc_window->buffer.tsurface; target_tsurface = queue_buffer->tsurface; _e_hwc_windows_sw_copy(hwc, src_tsurface, target_tsurface, E_OUTPUT_DISPLAY_MODE_PRESENTATION); @@ -2739,296 +2497,296 @@ _e_hwc_windows_presentation_evaluation_check(E_Hwc *hwc) return EINA_TRUE; } +/* evaluate the hwc_windows */ static Eina_Bool -_e_hwc_windows_external_evaluate(E_Hwc *hwc, E_Output_Display_Mode display_mode) +_e_hwc_windows_evaluate(E_Hwc *hwc, E_Output_Display_Mode display_mode) { - if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR) - { - if (!_e_hwc_windows_mirror_changes_update(hwc)) - return EINA_TRUE; + E_Hwc_Mode hwc_mode = E_HWC_MODE_NONE; + E_Hwc_Window *hwc_window = NULL; + const Eina_List *l; + uint32_t num_changes; + int num_client = 0, num_device = 0, num_video = 0, num_cursor = 0; - if (!_e_hwc_windows_evaluate(hwc)) - return EINA_TRUE; - } - else if (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION) + /* validate the visible hwc_windows' states*/ + if (!_e_hwc_windows_validate(hwc, &num_changes)) { - if (!_e_hwc_windows_presentation_changes_update(hwc)) - return EINA_TRUE; + EHWSERR("_e_hwc_windows_validate failed.", hwc); + goto re_evaluate; + } - if (!_e_hwc_windows_evaluate(hwc)) - return EINA_TRUE; - - /* if the presentation window is client type. copy it on the target window. */ - if (!_e_hwc_windows_presentation_evaluation_check(hwc)) - return EINA_TRUE; - } - else + /* update the valiated_changes if there are the composition changes after validation */ + if (num_changes) { - EHWSERR("Unknown display_mode : %d", hwc, display_mode); - return EINA_FALSE; + if (!_e_hwc_windows_validated_changes_update(hwc, num_changes)) + { + EHWSERR("_e_hwc_windows_validated_changes_update failed.", hwc); + goto re_evaluate; + } } - return EINA_TRUE; -} - -static Eina_Bool -_e_hwc_windows_ext_pp_output_commit(E_Hwc *hwc, tbm_surface_h tsurface, E_Output_Display_Mode mode) -{ - tdm_error error = TDM_ERROR_NONE; - tdm_region fb_damage; - - /* the damage isn't supported by hwc extension yet */ - memset(&fb_damage, 0, sizeof(fb_damage)); - - tbm_surface_internal_ref(tsurface); - hwc->pp_tsurface = tsurface; + /* constraints update and update the windows to be composited to the target_buffer */ + EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window) + { + if (e_hwc_window_is_target(hwc_window)) continue; - EHWSTRACE("!!!!!!!! HWC Ext PP Output Commit !!!!!!!!", NULL, hwc); + e_hwc_window_constraints_update(hwc_window); + e_hwc_window_rendered_window_update(hwc_window); - if (!_e_hwc_windows_target_buffer_fetch(hwc)) - return EINA_FALSE; + if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT) num_client++; + if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE) num_device++; + if (hwc_window->state == E_HWC_WINDOW_STATE_CURSOR) num_cursor++; + if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) num_video++; + } - if (!_e_hwc_windows_evaluate(hwc)) - return EINA_FALSE; + /* update the E_HWC_MODE */ + hwc_mode = _e_hwc_windows_hwc_mode_update(hwc, num_client, num_device, num_cursor ,num_video); - if (mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION) + /* set the state of the target_window */ + if (hwc_mode == E_HWC_MODE_NONE) { - e_hwc_window_commit_data_acquire(hwc->presentation_hwc_window); - if (hwc->presentation_hwc_window->ec) - e_pixmap_image_clear(hwc->presentation_hwc_window->ec->pixmap, 1); + EHWSTRACE(" HWC_MODE is NONE composition.", NULL, hwc); + _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_DEVICE); } - - tdm_hwc_set_client_target_buffer(hwc->thwc, tsurface, fb_damage); - tdm_hwc_accept_validation(hwc->thwc); - - error = tdm_hwc_commit(hwc->thwc, 0, _e_hwc_windows_commit_handler, hwc); - if (error != TDM_ERROR_NONE) + else if (hwc_mode == E_HWC_MODE_HYBRID) { - EHWSERR("tdm_hwc_commit failed.", hwc); - /* send tizen_hwc_commit feedback discarded */ - e_comp_wl_tizen_hwc_discarded(); - _e_hwc_windows_commit_handler(hwc->thwc, 0, 0, 0, hwc); - return EINA_FALSE; + EHWSTRACE(" HWC_MODE is HYBRID composition.", NULL, hwc); + _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_DEVICE); + } + else + { + EHWSTRACE(" HWC_MODE is FULL HW composition.", NULL, hwc); + _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_NONE); } - /* send tizen_hwc_commit feedback committed */ - e_comp_wl_tizen_hwc_committed(); - - return EINA_TRUE; -} + if ((!hwc->primary_output) && (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION)) + _e_hwc_windows_presentation_evaluation_check(hwc); -static void -_e_hwc_windows_external_pp_handler(E_Hwc *hwc, tbm_surface_h src, tbm_surface_h dst, void *user_data) -{ - E_Hwc_Window_Target *target_hwc_window; - E_Hwc_Window_Queue *queue; - E_Hwc_Window_Queue_Buffer *queue_buffer = NULL; - E_Hwc_Windows_Pp_Data *pp_data = NULL; - E_Output_Display_Mode mode; + /* skip the target_buffer when the window is on trainsition of the composition */ + if ((hwc_mode != E_HWC_MODE_FULL) && (_e_hwc_windows_transition_check(hwc)) && (!hwc->pp_set)) + { + _e_hwc_windows_target_window_buffer_skip(hwc); - pp_data = (E_Hwc_Windows_Pp_Data *)user_data; - EINA_SAFETY_ON_NULL_RETURN(pp_data); + if (!hwc->transition) + { + _e_hwc_windows_target_window_force_render(hwc->target_hwc_window); + hwc->transition = EINA_TRUE; + } - target_hwc_window = hwc->target_hwc_window; - EINA_SAFETY_ON_NULL_RETURN(target_hwc_window); + goto re_evaluate; + } - queue = ((E_Hwc_Window *)target_hwc_window)->queue; - queue_buffer = pp_data->queue_buffer; - e_hwc_window_queue_buffer_enqueue(queue, queue_buffer); + if (_e_hwc_windows_present_sync_check(hwc)) + { + EHWSTRACE(" Not accpet display sync.", NULL, hwc); + goto re_evaluate; + } - mode = e_output_display_mode_get(hwc->output); - if (mode != pp_data->mode) + if (e_hwc_norender_get(hwc) > 0) { - e_hwc_window_queue_buffer_release(queue, queue_buffer); - goto done; + EHWSTRACE(" Not accpet validation NoRender get.", NULL, hwc); + goto re_evaluate; } - hwc->pp_commit = EINA_FALSE; - EHWSTRACE("!!!!!!!! HWC Ext PP Commit Handler !!!!!!!!", NULL, hwc); - EHWSTRACE(" tsurface src(%p) dst(%p)", NULL, hwc, src, dst); + if (hwc_mode == E_HWC_MODE_FULL) + { + if (((E_Hwc_Window *)hwc->target_hwc_window)->buffer.tsurface) + _e_hwc_windows_target_buffer_fetch(hwc); + } - /* if pp_set is false, skip the commit */ - if (!hwc->pp_set) + /* accept the result of the validation */ + if (!_e_hwc_windows_accept(hwc)) { - if (hwc->tpp) - { - e_hwc_window_queue_buffer_release(queue, queue_buffer); - tdm_pp_destroy(hwc->tpp); - hwc->tpp = NULL; - } - goto done; + EHWSERR("_e_hwc_windows_validated_changes_update failed.", hwc); + goto re_evaluate; } - if (!_e_hwc_windows_ext_pp_output_commit(hwc, dst, pp_data->mode)) - EHWSERR("fail to _e_hwc_windows_ext_pp_output_commit", hwc); + hwc->transition = EINA_FALSE; + + return EINA_TRUE; -done: - tbm_surface_internal_unref(src); - tbm_surface_internal_unref(dst); +re_evaluate: + EHWSTRACE("======= HWC NOT Accept Validation Yet !! =======", NULL, hwc); - E_FREE(pp_data); + return EINA_FALSE; } -static void -_e_hwc_windows_external_pp_commit_handler(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data) +static Eina_Bool +_e_hwc_windows_target_buffer_prepared(E_Hwc *hwc) { - E_Hwc *hwc = NULL; - E_Hwc_Windows_Pp_Data *pp_data = NULL; + E_Hwc_Window *hwc_window = NULL; - pp_data = (E_Hwc_Windows_Pp_Data *)user_data; - EINA_SAFETY_ON_NULL_RETURN(pp_data); + hwc_window = (E_Hwc_Window *)hwc->target_hwc_window; + EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->target_hwc_window, EINA_FALSE); - hwc = pp_data->hwc; - EINA_SAFETY_ON_NULL_RETURN(hwc); + if (!hwc_window->buffer.tsurface) return EINA_FALSE; - pp_data->func(hwc, src, dst, user_data); + return EINA_TRUE; } -static Eina_Bool -_e_hwc_windows_external_pp_set(E_Hwc *hwc, tbm_surface_h src, tbm_surface_h dst, - Eina_Rectangle *src_rect, Eina_Rectangle *dst_rect, e_hwc_pp_done_handler func, - E_Hwc_Window_Queue_Buffer *queue_buffer, E_Output_Display_Mode display_mode) +static void +_e_hwc_windows_pp_rect_set(E_Hwc *hwc, Eina_Rectangle *src_rect, Eina_Rectangle *dst_rect) { - tdm_error ret = TDM_ERROR_NONE; - E_Hwc_Windows_Pp_Data *pp_data = NULL; + memcpy(&hwc->pp_src_rect, src_rect, sizeof(Eina_Rectangle)); + memcpy(&hwc->pp_dst_rect, dst_rect, sizeof(Eina_Rectangle)); +} - pp_data = E_NEW(E_Hwc_Windows_Pp_Data, 1); - EINA_SAFETY_ON_NULL_RETURN_VAL(pp_data, EINA_FALSE); +static Eina_Bool +_e_hwc_windows_pp_buffer_update(E_Hwc *hwc) +{ + E_Hwc_Window_Queue_Buffer *queue_buffer; + E_Hwc_Window *hwc_window; - tbm_surface_internal_ref(src); - tbm_surface_internal_ref(dst); + EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE); - /* when the pp_set_info is true, change the pp set_info */ - if (hwc->pp_set_info) + if (hwc->pp_hwc_window) { - if (_e_hwc_windows_pp_info_set(hwc, src, dst, src_rect, dst_rect) != EINA_TRUE) - { - EHWSERR("fail pp info set", hwc); - goto pp_fail; - } + hwc_window = hwc->pp_hwc_window; - hwc->pp_set_info = EINA_FALSE; + e_hwc_window_queue_clear(((E_Hwc_Window *)hwc->target_hwc_window)->queue); } + else + hwc_window = (E_Hwc_Window *)hwc->target_hwc_window; - pp_data->hwc = hwc; - pp_data->queue_buffer = queue_buffer; - pp_data->func = func; - pp_data->mode = display_mode; - ret = tdm_pp_set_done_handler(hwc->tpp, _e_hwc_windows_external_pp_commit_handler, pp_data); - EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, pp_fail); + if ((hwc_window->is_target) && ((E_Hwc_Window *)hwc->target_hwc_window == hwc_window)) + { + queue_buffer = e_hwc_window_queue_buffer_acquire(hwc_window->queue); + if (!queue_buffer) return EINA_FALSE; - ret = tdm_pp_attach(hwc->tpp, src, dst); - EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, pp_fail); + e_hwc_window_buffer_set(&hwc->pp_buffer, queue_buffer->tsurface, hwc_window->queue); + } + else + { + if (hwc_window->buffer.tsurface == hwc->pp_buffer.tsurface) + return EINA_FALSE; - ret = tdm_pp_commit(hwc->tpp); - EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, pp_fail); + e_hwc_window_buffer_set(&hwc->pp_buffer, + hwc_window->buffer.tsurface, hwc_window->buffer.queue); - _e_hwc_windows_wait_commit_set(hwc, EINA_TRUE); - hwc->pp_commit = EINA_TRUE; + if (!e_hwc_window_is_target(hwc_window)) + e_comp_wl_buffer_reference(&hwc->pp_buffer_ref, _e_hwc_windows_comp_wl_buffer_get(hwc_window)); + } return EINA_TRUE; - -pp_fail: - tbm_surface_internal_unref(src); - tbm_surface_internal_unref(dst); - - E_FREE(pp_data); - - return EINA_FALSE; } static Eina_Bool -_e_hwc_windows_external_pp_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode) +_e_hwc_windows_mirror_changes_update(E_Hwc *hwc) { + E_Hwc *mirror_src_hwc; E_Hwc_Window_Target *target_hwc_window, *src_target_hwc_window; + tbm_surface_h target_tsurface, src_target_tsurface; E_Hwc_Window_Queue *queue; E_Hwc_Window_Queue_Buffer *queue_buffer = NULL; - tbm_surface_h src; - tbm_surface_h dst; Eina_Rectangle src_rect = {0, }; Eina_Rectangle dst_rect = {0, }; - EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE); + mirror_src_hwc = hwc->mirror_src_hwc; + EINA_SAFETY_ON_NULL_RETURN_VAL(mirror_src_hwc, EINA_FALSE); target_hwc_window = hwc->target_hwc_window; EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE); + src_target_hwc_window = mirror_src_hwc->target_hwc_window; + EINA_SAFETY_ON_NULL_RETURN_VAL(src_target_hwc_window, EINA_FALSE); + + target_tsurface = target_hwc_window->hwc_window.buffer.tsurface; + src_target_tsurface = src_target_hwc_window->hwc_window.buffer.tsurface; + + if (!src_target_hwc_window->hwc_window.buffer.tsurface) return EINA_FALSE; + if (hwc->mirror_src_tsurface == src_target_tsurface) return EINA_FALSE; + queue = ((E_Hwc_Window *)target_hwc_window)->queue; EINA_SAFETY_ON_NULL_RETURN_VAL(queue, EINA_FALSE); - if (!e_hwc_window_queue_buffer_can_dequeue(queue)) + if (hwc->pp_set) { - EHWSERR("cannot dequeue skipped", hwc); - return EINA_FALSE; - } + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = tbm_surface_get_width(src_target_tsurface); + src_rect.h = tbm_surface_get_height(src_target_tsurface); + _e_hwc_windows_capture_position_get(hwc->mirror_src_hwc->output, + queue->width, queue->height, &dst_rect); + _e_hwc_windows_pp_rect_set(hwc, &src_rect, &dst_rect); - if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR) + hwc->pp_hwc_window = (E_Hwc_Window *)src_target_hwc_window; + } + else { - EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->mirror_src_hwc, EINA_FALSE); + queue = ((E_Hwc_Window *)target_hwc_window)->queue; + EINA_SAFETY_ON_NULL_RETURN_VAL(queue, EINA_FALSE); + + /* dequeue buffer */ + queue_buffer = e_hwc_window_queue_buffer_dequeue(queue); + EINA_SAFETY_ON_NULL_RETURN_VAL(queue_buffer, EINA_FALSE); - src_target_hwc_window = hwc->mirror_src_hwc->target_hwc_window; - EINA_SAFETY_ON_NULL_RETURN_VAL(src_target_hwc_window, EINA_FALSE); + /* copy */ + target_tsurface = queue_buffer->tsurface; + _e_hwc_windows_sw_copy(hwc, src_target_tsurface, target_tsurface, E_OUTPUT_DISPLAY_MODE_MIRROR); - src = src_target_hwc_window->hwc_window.buffer.tsurface; - if (hwc->mirror_src_tsurface == src) return EINA_FALSE; + /* enqueue buffer */ + e_hwc_window_queue_buffer_enqueue(queue, queue_buffer); - hwc->mirror_src_tsurface = src; + /* fetch the buffer */ + _e_hwc_windows_target_buffer_fetch(hwc); } - else if (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION) - { - EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->presentation_hwc_window, EINA_FALSE); - if (!_e_hwc_windows_presentation_changes_update(hwc)) - return EINA_TRUE; + hwc->mirror_src_tsurface = src_target_tsurface; - src = hwc->presentation_hwc_window->buffer.tsurface; - } - else - { - EHWSERR("Unknown display_mode : %d", hwc, display_mode); - return EINA_FALSE; - } + return EINA_TRUE; +} - src_rect.w = tbm_surface_get_width(src); - src_rect.h = tbm_surface_get_height(src); +static Eina_Bool +_e_hwc_windows_presentation_changes_update(E_Hwc *hwc) +{ + Eina_Rectangle src_rect = {0, }; + Eina_Rectangle dst_rect = {0, }; + tbm_surface_h tsurface; - /* dequeue buffer */ - queue_buffer = e_hwc_window_queue_buffer_dequeue(queue); - EINA_SAFETY_ON_NULL_RETURN_VAL(queue_buffer, EINA_FALSE); - dst = queue_buffer->tsurface; + EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->presentation_hwc_window, EINA_FALSE); - if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR) - { - _e_hwc_windows_capture_position_get(hwc->mirror_src_hwc->output, - tbm_surface_get_width(dst), tbm_surface_get_height(dst), &dst_rect); - } - else - { - dst_rect.w = tbm_surface_get_width(dst); - dst_rect.h = tbm_surface_get_height(dst); - } + /* set buffer */ + if (!e_hwc_window_buffer_fetch(hwc->presentation_hwc_window)) + return EINA_FALSE; - _e_hwc_windows_buffer_clear(hwc, dst); + e_hwc_window_zpos_set(hwc->presentation_hwc_window, 0); + e_hwc_window_state_set(hwc->presentation_hwc_window, E_HWC_WINDOW_STATE_DEVICE, EINA_TRUE); + e_hwc_window_info_update(hwc->presentation_hwc_window); - if ((hwc->pp_src_rect_prev.x != src_rect.x) || (hwc->pp_src_rect_prev.y != src_rect.y) || - (hwc->pp_src_rect_prev.w != src_rect.w) || (hwc->pp_src_rect_prev.h != src_rect.h)) + if (hwc->pp_set) { - hwc->pp_src_rect_prev.x = src_rect.x; - hwc->pp_src_rect_prev.y = src_rect.y; - hwc->pp_src_rect_prev.w = src_rect.w; - hwc->pp_src_rect_prev.h = src_rect.h; + tsurface = hwc->presentation_hwc_window->buffer.tsurface; - hwc->pp_set_info = EINA_TRUE; + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = tbm_surface_get_width(tsurface); + src_rect.h = tbm_surface_get_height(tsurface); + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.w = hwc->pp_queue->width; + dst_rect.h = hwc->pp_queue->height; + _e_hwc_windows_pp_rect_set(hwc, &src_rect, &dst_rect); } - if (!_e_hwc_windows_external_pp_set(hwc, src, dst, &src_rect, &dst_rect, - _e_hwc_windows_external_pp_handler, queue_buffer, display_mode)) + return EINA_TRUE; +} + +static Eina_Bool +_e_hwc_windows_external_changes_update(E_Hwc *hwc, E_Output_Display_Mode display_mode) +{ + Eina_Bool update_changes = EINA_FALSE; + + if (display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR) { - e_hwc_window_queue_buffer_release(queue, queue_buffer); - return EINA_FALSE; + if (_e_hwc_windows_mirror_changes_update(hwc)) + update_changes = EINA_TRUE; + } + else if (display_mode == E_OUTPUT_DISPLAY_MODE_PRESENTATION) + { + if (_e_hwc_windows_presentation_changes_update(hwc)) + update_changes = EINA_TRUE; } - return EINA_TRUE; + return update_changes; } EINTERN Eina_Bool @@ -3213,6 +2971,9 @@ _e_hwc_windows_pp_commit(E_Hwc *hwc) goto pp_fail; } + if (hwc->pp_dst_buffer_clear) + _e_hwc_windows_buffer_clear(hwc, queue_buffer->tsurface); + tbm_surface_internal_ref(queue_buffer->tsurface); tbm_surface_internal_ref(hwc->pp_buffer.tsurface); terror = tdm_pp_attach(hwc->tpp, hwc->pp_buffer.tsurface, queue_buffer->tsurface); @@ -3269,36 +3030,22 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode) { if (!_e_hwc_windows_changes_update(hwc)) return EINA_TRUE; - - if (output->fake_config) - { - _e_hwc_windows_offscreen_commit(hwc); - return EINA_TRUE; - } - - if (!_e_hwc_windows_evaluate(hwc)) - return EINA_TRUE; } else { - if (output->fake_config) - { - _e_hwc_windows_offscreen_commit(hwc); - return EINA_TRUE; - } + if (!_e_hwc_windows_external_changes_update(hwc, display_mode)) + return EINA_TRUE; + } - if (hwc->pp_set) - { - _e_hwc_windows_external_pp_commit(hwc, display_mode); - return EINA_TRUE; - } - else - { - if (!_e_hwc_windows_external_evaluate(hwc, display_mode)) - return EINA_TRUE; - } + if (output->fake_config) + { + _e_hwc_windows_offscreen_commit(hwc); + return EINA_TRUE; } + if (!_e_hwc_windows_evaluate(hwc, display_mode)) + return EINA_TRUE; + if (hwc->pp_set) { e_output_zoom_rotating_check(output); @@ -3399,7 +3146,7 @@ e_hwc_windows_target_window_del(E_Hwc_Window_Target *target_hwc_window) EINA_SAFETY_ON_NULL_RETURN(hwc); if (!hwc->primary_output) - _e_hwc_windows_tbm_surface_queue_deinit(hwc); + _e_hwc_windows_tbm_surface_queue_deinit(hwc); hwc->hwc_windows = eina_list_remove(hwc->hwc_windows, hwc->target_hwc_window); e_object_del(E_OBJECT(hwc->target_hwc_window)); @@ -3542,10 +3289,12 @@ e_hwc_windows_zoom_unset(E_Hwc *hwc) CLEAR(hwc->pp_set_src_rect); CLEAR(hwc->pp_set_dst_rect); + hwc->pp_dst_buffer_clear = EINA_FALSE; + hwc->pp_hwc_window = NULL; + if (e_comp_screen_pp_support()) { hwc->pp_set = EINA_FALSE; - hwc->pp_hwc_window = NULL; if (hwc->pp_tqueue) { @@ -3851,6 +3600,8 @@ e_hwc_windows_mirror_set(E_Hwc *hwc, E_Hwc *src_hwc, Eina_Rectangle *rect) return EINA_FALSE; } + hwc->pp_dst_buffer_clear = EINA_TRUE; + /* add mirror_src to the hwc*/ hwc->mirror_src_hwc = src_hwc; @@ -3914,16 +3665,19 @@ e_hwc_windows_presentation_update(E_Hwc *hwc, E_Client *ec) // TODO: deal with the video e_output_size_get(hwc->output, &width, &height); + rect.x = 0; rect.y = 0; rect.w = width; rect.h = height; + if (!e_hwc_windows_zoom_set(hwc, &rect)) { EHWSERR("e_hwc_windows_zoom_set failed.", hwc); return EINA_FALSE; } - hwc->pp_set_info = EINA_TRUE; + hwc->pp_dst_buffer_clear = EINA_TRUE; + hwc->pp_hwc_window = hwc->presentation_hwc_window; } /* update the target_buffer */ @@ -3939,6 +3693,8 @@ e_hwc_windows_presentation_update(E_Hwc *hwc, E_Client *ec) if (hwc->presentation_hwc_window) { e_hwc_windows_zoom_unset(hwc); + hwc->pp_hwc_window = NULL; + hwc->pp_dst_buffer_clear = EINA_FALSE; e_hwc_window_free(hwc->presentation_hwc_window); hwc->presentation_hwc_window = NULL; } diff --git a/src/bin/e_hwc_windows.h b/src/bin/e_hwc_windows.h index 39c97ac6e9..25550b9995 100644 --- a/src/bin/e_hwc_windows.h +++ b/src/bin/e_hwc_windows.h @@ -16,8 +16,6 @@ typedef enum E_HWC_WINS_DEBUG_CMD_QUEUE, } E_Hwc_Wins_Debug_Cmd; -typedef void (*e_hwc_pp_done_handler)(E_Hwc *hwc, tbm_surface_h src, tbm_surface_h dst, void *user_data); - EINTERN Eina_Bool e_hwc_windows_init(void); EINTERN void e_hwc_windows_deinit(void); EINTERN Eina_Bool e_hwc_windows_render(E_Hwc *hwc);