hwc: change the hwc policy. 25/169025/2
authorSooChan Lim <sc1.lim@samsung.com>
Fri, 2 Feb 2018 02:27:23 +0000 (11:27 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 2 Feb 2018 02:31:10 +0000 (11:31 +0900)
if there is the changes of the validation,
the backend assigns the candidated zpos at the accept function.

Change-Id: I6ac90da7a3c033b6e1cd78beaa2522de677b5f83

src/tdm_exynos_output.c
src/tdm_exynos_types.h
src/tdm_exynos_window.c

index 12f7801ea625c37b152e2ad9348a263f42936518..9f0556fc4e8f062ebeec2551fdb43522184d29db 100644 (file)
@@ -18,6 +18,25 @@ tdm_hwc_window *
 _exynos_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info,
                                                                 tdm_error *error);
 
+static const char *
+_comp_to_str(tdm_hwc_window_composition composition_type)
+{
+       if (composition_type == TDM_COMPOSITION_CLIENT)
+               return "CLIENT";
+       else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
+               return "DEVICE_CANDIDATE";
+       else if (composition_type == TDM_COMPOSITION_DEVICE)
+               return "DEVICE";
+       else if (composition_type == TDM_COMPOSITION_CURSOR)
+               return "CURSOR";
+       else if (composition_type == TDM_COMPOSITION_VIDEO)
+               return "VIDEO";
+       else if (composition_type == TDM_COMPOSITION_NONE)
+               return "SKIP";
+
+       return "unknown";
+}
+
 static tdm_error
 check_hw_restriction_crtc(unsigned int crtc_w,
                                                          unsigned int buf_w, unsigned int buf_h,
@@ -929,15 +948,18 @@ _find_maped_hwc_window_to_layer(struct list_head *hwc_wnds, int layer_zpos)
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
 
        LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
                        continue;
 
                if (hwc_window_data->assigned_layer_zpos == layer_zpos &&
                        (hwc_window_data->validated_type == TDM_COMPOSITION_DEVICE ||
                         hwc_window_data->validated_type == TDM_COMPOSITION_CURSOR ||
-                        hwc_window_data->is_device_to_client_transition))
-                       return hwc_window_data;
+                        hwc_window_data->validated_type == TDM_COMPOSITION_VIDEO)) {
+                               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
+                                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
+                               return hwc_window_data;
+                }
        }
 
        return NULL;
@@ -948,86 +970,22 @@ _update_layers_info(tdm_exynos_output_data *output_data)
 {
        tdm_exynos_layer_data *layer = NULL;
        tdm_exynos_hwc_window_data *hwc_window_data;
-       int primary_layer_zpos = _get_primary_layer_zpos(output_data);
        tdm_error ret;
 
        LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (output_data->need_target_window && layer->zpos == primary_layer_zpos)
+               if (output_data->need_target_window && layer->zpos == output_data->target_window_zpos)
                        hwc_window_data = output_data->target_hwc_window;
                else
                        hwc_window_data = _find_maped_hwc_window_to_layer(&output_data->hwc_window_list, layer->zpos);
 
                if (hwc_window_data) {
-                       ret = exynos_layer_set_info((tdm_layer *)layer,
-                                                                               (tdm_info_layer *)&(hwc_window_data->info));
+                       ret = exynos_layer_set_info((tdm_layer *)layer, (tdm_info_layer *)&(hwc_window_data->info));
                        if (ret != TDM_ERROR_NONE)
                                TDM_ERR("cannot set info to layer with %d zpos", layer->zpos);
                }
        }
 }
 
-static int
-_is_device_to_client_transition_finished(struct list_head *hwc_wnds)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               /* do not skip hwc_wnds with NONE composition type
-                * 'cause it may lead to dead lock state (we won't be
-                * able to exit from 'device to client transition' state);
-                *
-                * sometimes e20's wm marks ec as an invisible before it's
-                * been composited to the target buffer, so to face with
-                * such situation we don't skip NONE hwcs */
-
-               if (hwc_window_data->is_device_to_client_transition)
-                       goto work;
-       }
-
-       TDM_INFO("no device to client transition.");
-
-       /* if there wasn't the device to client transition there's no
-        * the device to client transition end :) */
-       return 0;
-
-work:
-
-       /* as we reset ALL hwc_wnds to CLIENT when we encountered with a need to
-        * make the smooth transition we have to wait till ALL they being composited
-        * (being presented on the target window) */
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->is_device_to_client_transition && !hwc_window_data->present_on_target_wnd)
-                       return 0;
-       }
-
-       return 1;
-}
-
-static void
-_reset_hwc_windows_grabbed_layer_zpos(struct list_head *hwc_window_list)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_window_list, link) {
-               hwc_window_data->grabbed_layer_zpos = -1;
-       }
-}
-
-static int
-_is_device_to_client_transition(struct list_head *hwc_window_list)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_window_list, link)
-               if (hwc_window_data->is_device_to_client_transition)
-                       return 1;
-
-       return 0;
-}
-
 static int
 _get_number_of_visible_windows(struct list_head *hwc_window_list)
 {
@@ -1043,101 +1001,50 @@ _get_number_of_visible_windows(struct list_head *hwc_window_list)
        return number;
 }
 
-static void
-_reset_buffers_for_unvis_hwc_windows(tdm_exynos_output_data *output_data)
+static tdm_exynos_hwc_window_data *
+_exynos_output_find_assigned_hwc_window(struct list_head *hwc_wnds, int layer_zpos)
 {
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
 
-       if (!output_data->need_target_window)
-               output_data->target_hwc_window->surface = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (!output_data->need_target_window)
-                       hwc_window_data->present_on_target_wnd = 0;
-
+       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       hwc_window_data->surface = NULL;
+                       continue;
+
+               if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
+                       return hwc_window_data;
+               }
        }
+
+       return NULL;
 }
 
 static tdm_error
-_tdm_exynos_display_prepare_commit(tdm_exynos_output_data *output_data) {
-
+_exynos_output_hwc_prepare_commit(tdm_exynos_output_data *output_data) {
        tdm_exynos_layer_data *layer = NULL;
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int primary_layer_zpos = _get_primary_layer_zpos(output_data);
-       int device_to_client_transition_finished;
-
-       RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
 
-       if (!_get_number_of_visible_windows(&output_data->hwc_window_list))
-               output_data->need_target_window = 1;
+       _update_layers_info(output_data);
 
        /* set target hwc window */
        if (output_data->need_target_window) {
-               layer = _exynos_output_get_layer(output_data, primary_layer_zpos);
+               layer = _exynos_output_get_layer(output_data, output_data->target_window_zpos);
                _set_hwc_window_buffer_to_layer(layer, output_data->target_hwc_window);
        }
 
-       if (output_data->video_hwc_window) {
-               layer = _exynos_output_get_layer(output_data, output_data->video_hwc_window->assigned_layer_zpos);
-               _set_hwc_window_buffer_to_layer(layer, output_data->video_hwc_window);
-       }
-
-       device_to_client_transition_finished =
-                       _is_device_to_client_transition_finished(&output_data->hwc_window_list);
-
-       if (device_to_client_transition_finished) {
-               TDM_INFO("the device to client transition has finished, need_target_wnd:%d",
-                               output_data->need_target_window);
-
-               /* if at the moment tdm-backend found a device to client transition
-                * the target_wnd was turned off, we'll skip one frame for target_buffer
-                * without the next lines */
-               if (!output_data->need_target_window) {
-                       output_data->need_target_window = 1;
-
-                       layer = _exynos_output_get_layer(output_data, primary_layer_zpos);
-                       _set_hwc_window_buffer_to_layer(layer, output_data->target_hwc_window);
-
-                       /* preempt the hwc_wnd which was mapped to the primary layer */
-                       hwc_window_data = _find_maped_hwc_window_to_layer(&output_data->hwc_window_list, primary_layer_zpos);
-                       if (hwc_window_data)
-                               hwc_window_data->assigned_layer_zpos = -1;
-
-                       _update_layers_info(output_data);
-               }
-
-               /* tdm-backend resets all hwc_wnds to CLIENTs while there's any hwc_wnd
-                * within 'device to client transition' state, so after such transition
-                * has finished, we trigger a revalidate event to reevaluate the overlay policy */
-               tdm_backend_trigger_need_validate_event(output_data);
-
-               hwc_window_data = NULL;
-
-               LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link)
-                       hwc_window_data->is_device_to_client_transition = 0;
-       }
-
-       if (_is_device_to_client_transition(&output_data->hwc_window_list))
-               return TDM_ERROR_NONE;
-
-       _reset_hwc_windows_grabbed_layer_zpos(&output_data->hwc_window_list);
-
        LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
-               if (output_data->need_target_window && layer->zpos == primary_layer_zpos)
-                       continue;
-               if (output_data->video_hwc_window && layer->zpos == output_data->video_hwc_window->assigned_layer_zpos)
+               if (output_data->need_target_window && layer == output_data->primary_layer)
                        continue;
 
-               hwc_window_data = _find_maped_hwc_window_to_layer(&output_data->hwc_window_list, layer->zpos);
-               if (hwc_window_data)
-                       hwc_window_data->grabbed_layer_zpos = layer->zpos;
-               _set_hwc_window_buffer_to_layer(layer, hwc_window_data);
+               hwc_window_data = _exynos_output_find_assigned_hwc_window(&output_data->hwc_window_list, layer->zpos);
+               if (hwc_window_data) {
+                       _set_hwc_window_buffer_to_layer(layer, hwc_window_data);
+               } else {
+                       /* do not set the null on the primary layer */
+                       if (layer != output_data->primary_layer)
+                               _set_hwc_window_buffer_to_layer(layer, NULL);
+               }
        }
 
-       _reset_buffers_for_unvis_hwc_windows(output_data);
-
        return TDM_ERROR_NONE;
 }
 
@@ -1155,7 +1062,7 @@ exynos_output_commit(tdm_output *output, int sync, void *user_data)
        exynos_data = output_data->exynos_data;
 
        if (output_data->hwc_enable) {
-               ret = _tdm_exynos_display_prepare_commit(output_data);
+               ret = _exynos_output_hwc_prepare_commit(output_data);
                RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
        }
 
@@ -1432,9 +1339,13 @@ _exynos_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info,
                goto fail;
        }
 
+       hwc_window_data->client_type = TDM_COMPOSITION_NONE;
+       hwc_window_data->validated_type = -1;
+       hwc_window_data->assigned_layer_zpos = -1;
+       hwc_window_data->present_on_target_wnd = 0;
+
        hwc_window_data->output_data = output;
        hwc_window_data->zpos = 0;
-       hwc_window_data->prev_validated_type = TDM_COMPOSITION_NONE;
 
        if (info)
                memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
@@ -1472,9 +1383,13 @@ tdm_error
 exynos_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window)
 {
        tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_exynos_output_data *output_data = output;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
+       if (output_data->video_hwc_window == hwc_window)
+               output_data->video_hwc_window = NULL;
+
        LIST_DEL(&hwc_window_data->link);
 
        free(hwc_window_data);
@@ -1482,60 +1397,6 @@ exynos_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window)
        return TDM_ERROR_NONE;
 }
 
-static const char *
-_comp_to_str(tdm_hwc_window_composition composition_type)
-{
-       if (composition_type == TDM_COMPOSITION_CLIENT)
-               return "CLIENT";
-       else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
-               return "DEVICE_CANDIDATE";
-       else if (composition_type == TDM_COMPOSITION_DEVICE)
-               return "DEVICE";
-       else if (composition_type == TDM_COMPOSITION_CURSOR)
-               return "CURSOR";
-       else if (composition_type == TDM_COMPOSITION_NONE)
-                       return "SKIP";
-
-       return "unknown";
-}
-
-/* If there is only 1 visible hwc_window_data it should be placed on the
- * primary layer. The primary layer should always be used.
- */
-static int
-_top_window_should_be_placed_on_fb_layer(struct list_head *hwc_window_list)
-{
-       int num_hwc_windows = _get_number_of_visible_windows(hwc_window_list);
-
-       return num_hwc_windows <= 1;
-}
-
-static void
-_update_windows_previous_type(struct list_head *hwc_wnds)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link)
-               hwc_window_data->prev_validated_type = hwc_window_data->validated_type;
-}
-
-static void
-_reset_composition_types(struct list_head *hwc_window_list)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE) {
-                       hwc_window_data->validated_type = TDM_COMPOSITION_NONE;
-                       hwc_window_data->grabbed_layer_zpos = -1;
-               } else {
-                       hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
-               }
-
-               hwc_window_data->assigned_layer_zpos = -1;
-       }
-}
-
 static int
 _can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window_data *hwc_window_data)
 {
@@ -1564,169 +1425,118 @@ _can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window_data *hwc_window_data)
        return 1;
 }
 
-/* The current algorithm map target_window to primary layer. If primary layer
- * is not needed another hwc_window_data is mapped to primary layer. Algorithm have
- * two iteration:
- * 1) map hwc_windows to layers in order from top layer to primary layer(non-inclusive);
- * 2) map hwc_windows to layers in order from bottom layer to primary layer.
- * hwc_windows that are not mapped to layers are composited to target_window.
- *
- * The result of mapping 4 windows(num_layers = 3, primary_layer_zpos = 1):
- * hwc_window_data 3 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window_data 2 zpos(DEVICE -> CLIENT) (it is composited on primary layer)
- * hwc_window_data 1 zpos(DEVICE -> CLIENT) (it is composited on primary layer)
- * hwc_window_data 0 zpos(DEVICE -> DEVICE) (it is mapped to layer with 0 zpos)
- *
- * The result of mapping 3 windows(num_layers = 3, primary_layer_zpos = 1):
- * hwc_window_data 2 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window_data 1 zpos(DEVICE -> DEVICE) (it is mapped to primary layer)
- * hwc_window_data 0 zpos(DEVICE -> DEVICE) (it is mapped to layer with 0 zpos)
- *
- * The result of mapping 1 windows(num_layers = 3, primary_layer_zpos = 1):
- * hwc_window_data 0 zpos(DEVICE -> DEVICE) (it is mapped to primary layer)
- *
- * The result of mapping 2 windows(num_layers = 3, primary_layer_zpos = 1):
- * hwc_window_data 1 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window_data 0 zpos(CLIENT -> CLIENT) (it is composited on primary layer)
- *
- * The result of mapping 2 windows(num_layers = 3, primary_layer_zpos = 1):
- * hwc_window_data 1 zpos(CLIENT -> CLIENT) (it is composited on primary layer)
- * hwc_window_data 0 zpos(DEVICE -> DEVICE) (it is mapped to layer with 0 zpos)
- */
+/* decide the validated_types and the assigned_layer_zpos of the hwc_windows */
 static void
-_map_hwc_windows_to_layers(tdm_exynos_output_data *output_data)
+_exynos_output_hwc_adapt_policy(tdm_exynos_output_data *output_data)
 {
-       int layer_zpos;
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int max_hw_layer_zpos;
-       int need_target_window = 0;
+       int num_visible_windows = _get_number_of_visible_windows(&output_data->hwc_window_list);
+       int available_layers = LIST_LENGTH(&output_data->layer_list);
        int primary_layer_zpos = _get_primary_layer_zpos(output_data);
-       int num_skip_layers = 0;
-       int num_bottom_layer_with_primary = primary_layer_zpos + 1;
-       int num_unmarked_layers = _get_number_of_visible_windows(&output_data->hwc_window_list);
+       int candidate_ui_top_zpos = 0;
+       int num_video_layers = 0;
+       int is_assigned = 0;
+
+       /* reset the validated_type and hw layer policy */
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE ||
+                       hwc_window_data->client_type == TDM_COMPOSITION_VIDEO)
+                       continue;
+
+               hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
+               hwc_window_data->candidate_layer_zpos = -1;
+       }
 
-       _reset_composition_types(&output_data->hwc_window_list);
+       /* initialize the zpos of the target_window */
+       output_data->target_window_zpos = primary_layer_zpos;
+       output_data->need_target_window = 0;
 
-       if (!num_unmarked_layers && !output_data->video_hwc_window) {
+       /* need_target_window is true and return when there are no visible windows */
+       if (!num_visible_windows) {
                output_data->need_target_window = 1;
                return;
        }
 
-       /* Map hwc_windows to layers in order from top layer to primary layer(non-inclusive).
-        * If top hwc_window_data should be placed on primary layer it is not necessary
-        * this iteration because we cannot use layers above primary layer */
-       if (!_top_window_should_be_placed_on_fb_layer(&output_data->hwc_window_list)) {
-               layer_zpos = LIST_LENGTH(&output_data->layer_list);
-               LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
-                       if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                               continue;
-                       layer_zpos--;
-                       /* break if we have reached primary layer(remaining hwc_windows
-                        * will be mapped in the next iteration) or the composition type of
-                        * current hwc_window_data is not TDM_COMPOSITION_DEVICE or hwc_window_data cannot
-                        * be set on hwc_window_data layer*/
-                       if ((hwc_window_data->client_type == TDM_COMPOSITION_DEVICE || hwc_window_data->client_type == TDM_COMPOSITION_CURSOR) &&
-                               layer_zpos != primary_layer_zpos) {
-                               if (_can_set_hwc_window_on_hw_layer(hwc_window_data)) {
-                                       hwc_window_data->validated_type = hwc_window_data->client_type;
-                                       num_unmarked_layers--;
-                                       hwc_window_data->assigned_layer_zpos = layer_zpos;
-                                       continue;
-                               }
-                       }
-                       break;
-               }
-       }
+       /* At first, assign the hw layers to the video windows from the bottom to the top.
+        * Currenty, exynos supports only one video window.
+        */
+       if (output_data->video_hwc_window &&
+               output_data->video_hwc_window->client_type == TDM_COMPOSITION_VIDEO) {
+               hwc_window_data = output_data->video_hwc_window;
 
-       /* if there is the video hwc_window_data the bottom layer is used for it */
-       if (output_data->video_hwc_window)
-               num_bottom_layer_with_primary--;
+               hwc_window_data->validated_type = hwc_window_data->client_type;
+               hwc_window_data->candidate_layer_zpos = 0;
 
-       if (num_unmarked_layers > num_bottom_layer_with_primary)
-               need_target_window = 1;
+               available_layers--;
+               num_visible_windows--;
+               num_video_layers++;
+       }
 
-       /* max zpos of layer which can be used for mapping. If the target_window is
-        * not needed primary layer can be used for mapping
+       /* need target_window when the number of the visible windows is
+        * more than the number of the available layers.
         */
-       max_hw_layer_zpos = primary_layer_zpos;
-       if (need_target_window)
-               max_hw_layer_zpos--;
+       if (available_layers < num_visible_windows) {
+               output_data->need_target_window = 1;
+               /* the zpos of the primary layer is 1
+                * therefore, exynos backend cannot use the zpos 0 layer
+                * when it uses the target_window.
+                */
+               available_layers = available_layers - 2;
+       } else {
+               output_data->need_target_window = 0;
+       }
 
-       /* The number of layers which need to be skipped because it should always set
-        * on primary layer hwc_window_data
-        */
-       num_skip_layers = num_bottom_layer_with_primary - num_unmarked_layers;
+       /* set the top zpos for ui */
+       candidate_ui_top_zpos = num_visible_windows + num_video_layers - 1;
 
-       /* mark the bottom windows */
-       layer_zpos = -1;
-       if (num_skip_layers > 0)
-               layer_zpos += num_skip_layers;
-       /* don't map hwc_window_data to layer with the video hwc_window_data */
-       if (output_data->video_hwc_window)
-               layer_zpos++;
-       /* map hwc_windows to layers in order from bottom layer to primary layer
-        * (inclusive if primary layer can be used for hwc_window_data(target_window is not used)) */
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+       /* assgin the hw layers to the ui windows from the top to the bottom */
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE ||
+                       hwc_window_data->client_type == TDM_COMPOSITION_VIDEO)
                        continue;
-               layer_zpos++;
-               /* break if the remaining windows are already marked in the
-                * previous iteration */
-               if (hwc_window_data->validated_type == TDM_COMPOSITION_DEVICE || hwc_window_data->validated_type == TDM_COMPOSITION_CURSOR)
+               if (hwc_window_data == output_data->video_hwc_window)
+                       continue;
+               if (available_layers == 0)
+                       break;
+
+               /* meet the client type, set need_target_window and break */
+               if (hwc_window_data->client_type == TDM_COMPOSITION_CLIENT) {
+                       output_data->need_target_window = 1;
                        break;
-               /* break if we have reached max hwc_window_data layer or the composition type of
-                * current hwc_window_data is not TDM_COMPOSITION_DEVICE or hwc_window_data cannot
-                * be set on hwc_window_data layer */
-               if ((hwc_window_data->client_type == TDM_COMPOSITION_DEVICE)
-                       && layer_zpos <= max_hw_layer_zpos) {
-                       if (_can_set_hwc_window_on_hw_layer(hwc_window_data)) {
-                               hwc_window_data->validated_type = TDM_COMPOSITION_DEVICE;
-                               hwc_window_data->assigned_layer_zpos = layer_zpos;
-                               continue;
-                       }
                }
 
-               /* if hwc_window_data cannot be mapped on layer target_window is needed */
-               need_target_window = 1;
-               break;
+               if (hwc_window_data->client_type == TDM_COMPOSITION_DEVICE ||
+                   hwc_window_data->client_type == TDM_COMPOSITION_CURSOR) {
+                       if (_can_set_hwc_window_on_hw_layer(hwc_window_data)) {
+                               hwc_window_data->validated_type = hwc_window_data->client_type;
+                               hwc_window_data->candidate_layer_zpos = candidate_ui_top_zpos;
+                               candidate_ui_top_zpos--;
+                               available_layers--;
+                               if (!is_assigned)
+                                       is_assigned = 1;
+                       } else
+                               goto set_all_client_types;
+               }
        }
 
-       output_data->need_target_window = need_target_window;
-}
+       /* all windows are CLIENT type when is_assigned is 0 */
+       if (!is_assigned)
+               output_data->need_target_window = 1;
 
-static int
-_need_map_hwc_windows_to_layers(tdm_exynos_output_data *output_data)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int primary_layer_zpos = _get_primary_layer_zpos(output_data);
-       int hw_window_is_maped_on_primary_layer = 0;
-       int need_target_window = 0;
+       return;
 
+set_all_client_types:
        LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE ||
+                       hwc_window_data->client_type == TDM_COMPOSITION_VIDEO)
                        continue;
 
-               if (primary_layer_zpos == hwc_window_data->assigned_layer_zpos)
-                       hw_window_is_maped_on_primary_layer = 1;
-
-               if (hwc_window_data->prev_validated_type != hwc_window_data->client_type)
-                       return 1;
-
-               if (hwc_window_data->client_type == TDM_COMPOSITION_CLIENT)
-                       need_target_window = 1;
-
-               if (output_data->video_hwc_window &&
-                       output_data->video_hwc_window->assigned_layer_zpos == hwc_window_data->assigned_layer_zpos)
-                       return 1;
+               hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
+               hwc_window_data->candidate_layer_zpos = -1;
        }
 
-       if (need_target_window != output_data->need_target_window)
-               return 1;
-
-       if (!hw_window_is_maped_on_primary_layer && !output_data->need_target_window)
-               return 1;
-
-       return 0;
+       output_data->need_target_window = 1;
+       output_data->target_window_zpos = primary_layer_zpos;
 }
 
 static void
@@ -1739,73 +1549,42 @@ _print_validate_result(tdm_exynos_output_data *output_data)
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
                        continue;
 
-               if (hwc_window_data->validated_type == TDM_COMPOSITION_DEVICE || hwc_window_data->validated_type == TDM_COMPOSITION_CURSOR)
+               if (hwc_window_data->validated_type == TDM_COMPOSITION_DEVICE ||
+                   hwc_window_data->validated_type == TDM_COMPOSITION_CURSOR ||
+                       hwc_window_data->validated_type == TDM_COMPOSITION_VIDEO)
                        TDM_DBG(" window(%p) type: %s -> %s : is mapped to layer with %d zpos", hwc_window_data,
                                        _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                                       hwc_window_data->assigned_layer_zpos);
+                                       hwc_window_data->candidate_layer_zpos);
                else
-                       TDM_DBG(" window(%p) type: %s -> %s : is composited to layer with %d zpos", hwc_window_data,
+                       TDM_DBG(" window(%p) type: %s -> %s : is composited to layer with %d zpos. need_target_window: %d", hwc_window_data,
                                        _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
-                                       primary_layer_zpos);
+                                       primary_layer_zpos, output_data->need_target_window);
        }
 }
 
 static void
-_restore_windows_assigned_layer_zpos(struct list_head *hwc_wnds)
+_exynos_output_hwc_assigned_layer_zpos_update(tdm_exynos_output_data *output_data)
 {
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
 
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE) {
-                       hwc_window_data->assigned_layer_zpos = -1;
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE ||
+                       hwc_window_data->client_type == TDM_COMPOSITION_VIDEO)
                        continue;
-               }
 
-               hwc_window_data->assigned_layer_zpos = hwc_window_data->grabbed_layer_zpos;
-       }
-}
-
-static void
-_reset_windows_to_client(struct list_head *hwc_wnds)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+               if (hwc_window_data->candidate_layer_zpos == -1) {
+                       hwc_window_data->assigned_layer_zpos = -1;
                        continue;
+               }
 
-               if (hwc_window_data->grabbed_layer_zpos >= 0 &&
-                               hwc_window_data->validated_type == TDM_COMPOSITION_CLIENT)
-                       hwc_window_data->is_device_to_client_transition = 1;
+               TDM_DBG(" window(%p) type: %s -> %s : candidate_zpos:%d assigned_zpos:%d", hwc_window_data,
+                               _comp_to_str(hwc_window_data->client_type), _comp_to_str(hwc_window_data->validated_type),
+                               hwc_window_data->candidate_layer_zpos, hwc_window_data->assigned_layer_zpos);
 
-               hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
+               hwc_window_data->assigned_layer_zpos = hwc_window_data->candidate_layer_zpos;
        }
 }
 
-/* if we got at least one device -> client transition or we have
- * at least one window in 'device to client transitional state' we
- * reset all windows to the client state, as it's a reference
- * implementation of the driver */
-static int
-_is_reset_to_client_needed(struct list_head *hwc_wnds)
-{
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, hwc_wnds, link) {
-               if (hwc_window_data->is_device_to_client_transition)
-                       return 1;
-
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->grabbed_layer_zpos >= 0 &&
-                               hwc_window_data->validated_type == TDM_COMPOSITION_CLIENT)
-                       return 1;
-       }
-
-       return 0;
-}
-
 tdm_error
 exynos_output_hwc_validate(tdm_output *output, uint32_t *num_types)
 {
@@ -1813,49 +1592,28 @@ exynos_output_hwc_validate(tdm_output *output, uint32_t *num_types)
        tdm_exynos_data *exynos_data = NULL;
        RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
-       int need_map_hwc_windows_to_layers;
-       int need_reset_to_client;
-       int prev_need_target_window;
 
        exynos_data = output_data->exynos_data;
        RETURN_VAL_IF_FAIL(exynos_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        if (output_data->need_set_crtc) {
                output_data->need_target_window = 1;
-
-               _reset_composition_types(&output_data->hwc_window_list);
+               output_data->target_window_zpos = _get_primary_layer_zpos(output_data);
        } else {
-       
-               prev_need_target_window = output_data->need_target_window;
-
-               /* if previous mapping can be used it is not needed to remap hwc_windows
-                * to layers */
-               need_map_hwc_windows_to_layers = _need_map_hwc_windows_to_layers(output_data);
-
-               if (need_map_hwc_windows_to_layers)
-                       _map_hwc_windows_to_layers(output_data);
-
-               need_reset_to_client = _is_reset_to_client_needed(&output_data->hwc_window_list);
-               if (need_reset_to_client) {
-                       TDM_INFO("reset all hwc_wnds to CLIENT.");
-
-                       _reset_windows_to_client(&output_data->hwc_window_list);
-                       _restore_windows_assigned_layer_zpos(&output_data->hwc_window_list);
-
-                       output_data->need_target_window = prev_need_target_window;
-               }
-
-               _update_windows_previous_type(&output_data->hwc_window_list);
+               _exynos_output_hwc_adapt_policy(output_data);
        }
 
-       _update_layers_info(output_data);
-
-       _print_validate_result(output_data);
-
+       TDM_DBG(" ==============Validate=================================");
        *num_types = _exynos_output_get_changed_number(output_data);
-
-       if (*num_types == 0)
+       if (*num_types == 0) {
                output_data->need_validate = 0;
+               _exynos_output_hwc_assigned_layer_zpos_update(output_data);
+
+               _print_validate_result(output_data);
+       } else {
+               _print_validate_result(output_data);
+               TDM_DBG(" !!!!!!! BUT NEED TO ACCEPT CHANES.!!!!!!!!");
+       }
 
        return TDM_ERROR_NONE;
 }
@@ -1902,16 +1660,12 @@ tdm_error
 exynos_output_hwc_accept_changes(tdm_output *output)
 {
        tdm_exynos_output_data *output_data = output;
-       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
 
        RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-               hwc_window_data->client_type = hwc_window_data->validated_type;
-       }
+       TDM_DBG(" ==============Accept Changes Done=================================");
 
+       _exynos_output_hwc_assigned_layer_zpos_update(output_data);
        output_data->need_validate = 0;
 
        return TDM_ERROR_NONE;
@@ -1977,8 +1731,10 @@ exynos_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h buf
                composited_list[i]->present_on_target_wnd = 1;
 
        LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link)
-               if (hwc_window_data->present_on_target_wnd)
-                       TDM_INFO("hwc_wnd:%p presents on the target window.", hwc_window_data);
+               if (hwc_window_data->present_on_target_wnd) {
+                       TDM_INFO("hwc_wnd:%p validated_type: %p presents on the target window.",
+                                       hwc_window_data, _comp_to_str(hwc_window_data->validated_type));
+               }
 
        return TDM_ERROR_NONE;
 }
@@ -2004,9 +1760,13 @@ exynos_output_hwc_create_video_window(tdm_output *output, tdm_error *error)
        if (hwc_window_data == NULL)
                return NULL;
 
-       hwc_window_data->assigned_layer_zpos = 0;
+       tdm_exynos_output_insert_hwc_window(output_data, hwc_window_data);
+
        output_data->video_hwc_window = hwc_window_data;
 
+       // Assign the fixed zpos of the layer for video window
+       hwc_window_data->assigned_layer_zpos = 0;
+
        TDM_DBG("hwc_window_data(%p) video create", hwc_window_data);
        if (error)
                *error = TDM_ERROR_NONE;
index ef49bf35a353ddddd42800015ba76464fa4f13e5..9c1516ca14d4c60debf6b2b9e9dae592a608663b 100644 (file)
@@ -150,6 +150,7 @@ struct _tdm_exynos_output_data {
        int need_target_window;
        int need_set_crtc;
 
+       int target_window_zpos;
        struct list_head hwc_window_list;
 };
 
@@ -170,6 +171,7 @@ struct _tdm_exynos_layer_data {
        tdm_exynos_display_buffer *display_buffer;
        int display_buffer_changed;
        tdm_exynos_display_buffer *pending_free_display_buffer;
+       int pending_free_ready;
 
        tbm_format *formats;
        int format_count;
@@ -196,19 +198,17 @@ struct _tdm_exynos_hwc_window_data {
        int enabled_flag;
 
        /* client_type stores the initial type given to us by client(compositor),
-       /  validated_type stores the type after running Validate
-       /  prev_validated_type is used to achieve requirements tied with the client_candidate type */
+        *  validated_type stores the type after running Validate
+        */
        tdm_hwc_window_composition client_type;
        tdm_hwc_window_composition validated_type;
-       tdm_hwc_window_composition prev_validated_type;
 
+    int candidate_layer_zpos;
        int assigned_layer_zpos;
-       int grabbed_layer_zpos;
 
        tdm_hwc_window_flag flags;
 
        int present_on_target_wnd;
-       int is_device_to_client_transition;
 };
 
 struct _tdm_exynos_display_buffer {
index 6ef0a190bf12d09453e3f5b87d2b7f9a5d7c248e..979721e883cca75e33d4900b2c26e8de263ce99f 100644 (file)
@@ -77,12 +77,22 @@ exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data->video_hwc_window != hwc_window_data, TDM_ERROR_INVALID_PARAMETER);
 
+       /* change the client_type when it is different from one which has before */
        if (hwc_window_data->client_type == comp_type)
                return TDM_ERROR_NONE;
 
        hwc_window_data->client_type = comp_type;
+
+       /* if the type is none, reset all status */
+       if (hwc_window_data->client_type == TDM_COMPOSITION_NONE) {
+               hwc_window_data->client_type = TDM_COMPOSITION_NONE;
+               hwc_window_data->validated_type = -1;
+               hwc_window_data->candidate_layer_zpos = -1;
+               hwc_window_data->assigned_layer_zpos = -1;
+               hwc_window_data->present_on_target_wnd = 0;
+       }
+
        output_data->need_validate = 1;
 
        return TDM_ERROR_NONE;
@@ -115,13 +125,6 @@ exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info
        if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)))
                return TDM_ERROR_NONE;
 
-       if (output_data->video_hwc_window == hwc_window_data) {
-               tdm_exynos_layer_data *layer;
-               layer = _exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
-               return exynos_layer_set_info(layer, (tdm_info_layer *)info);
-       }
-
        hwc_window_data->info = *info;
        output_data->need_validate = 1;