hwc: redesign the hwc policy 70/169270/4
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 5 Feb 2018 06:54:14 +0000 (15:54 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 7 Feb 2018 23:46:02 +0000 (23:46 +0000)
Change-Id: Ib7afc8bbd169e391e2fb59466e9fbab13b067221

src/tdm_exynos.c
src/tdm_exynos.h
src/tdm_exynos_display.c
src/tdm_exynos_types.h
src/tdm_exynos_window.c

index 8bcde6240000505d23fe6e146bc0b2edcefeda08..9e53b7cbc5e5aa1f43c9e7e40b6d4b33bccde738 100644 (file)
@@ -296,7 +296,7 @@ failed_l:
 tdm_backend_module tdm_backend_module_data = {
        "exynos",
        "Samsung",
-       TDM_BACKEND_ABI_VERSION,
+       TDM_BACKEND_SET_ABI_VERSION(1, 5),
        tdm_exynos_init,
        tdm_exynos_deinit
 };
index 180b7c3af35b5e4c6de4425371fd4bdb34d1a3aa..133785cc5487c82ef6b43acb27e4c214f9b7e8e2 100644 (file)
@@ -70,8 +70,8 @@ tdm_error    exynos_layer_get_property(tdm_layer *layer, unsigned int id, tdm_va
 tdm_error    exynos_layer_set_info(tdm_layer *layer, tdm_info_layer *info);
 tdm_error    exynos_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
 tdm_error    exynos_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
-tdm_error    exynos_layer_unset_buffer(tdm_layer *layer);
 tbm_surface_queue_h exynos_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error);
+tdm_error    exynos_layer_unset_buffer(tdm_layer *layer);
 tdm_error    exynos_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
                                                                                                        tdm_hwc_window_composition composition_type);
 tdm_error    exynos_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage);
@@ -101,5 +101,4 @@ void         tdm_exynos_pp_handler(struct tdm_pp_event *hw_ipp_p);
 tdm_error      tdm_exynos_pp_task_done_handler(int fd, tdm_event_loop_mask mask, void *user_data);
 tdm_error   tdm_exynos_display_init_event_handling(tdm_exynos_data *exynos_data);
 void        tdm_exynos_display_deinit_event_handling(tdm_exynos_data *exynos_data);
-tdm_exynos_layer_data *tdm_exynos_output_get_layer(tdm_exynos_output_data *output_data, int index);
 #endif /* _TDM_EXYNOS_H_ */
index 5a14d0aa322bb858945fb8fc0665d1bd04b55255..4dbd5fd2b80f17ce8b45af080d82a22006d6a2e3 100644 (file)
@@ -117,6 +117,24 @@ check_hw_restriction(unsigned int output_w, unsigned int buf_w,
 }
 #endif
 
+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_exynos_display_buffer *
 _tdm_exynos_display_find_buffer(tdm_exynos_data *exynos_data, tbm_surface_h buffer)
@@ -349,6 +367,12 @@ _tdm_exynos_display_do_commit(tdm_exynos_output_data *output_data)
                                memcpy(&layer_data->win_cfg, &win_data.config[layer_index], sizeof(struct decon_win_config));
                        }
                        layer_data->enabled_flag = 1;
+
+                       /* free pending display buffer */
+                       if (layer_data->pending_free_display_buffer) {
+                               layer_data->pending_free_display_buffer = NULL;
+                               free(layer_data->pending_free_display_buffer);
+                       }
                } else {
                        _tdm_exynos_display_layer_disable(layer_data);
                }
@@ -572,17 +596,30 @@ _tdm_exynos_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data)
                TDM_ERR("no display_buffer");
                return;
        }
-       TDM_DBG("destroy buffer fd:%d", display_buffer->fds[0]);
+       LIST_DEL(&display_buffer->link);
 
-       LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
-               LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-                       if (display_buffer == layer_data->display_buffer) {
-                               _tdm_exynos_display_layer_disable(layer_data);
-                               layer_data->display_buffer = NULL;
+       if (exynos_data->hwc_mode) {
+               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+                       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+                               if (display_buffer == layer_data->display_buffer) {
+                                       TDM_DBG("display buffer is pending to free!!! buffer:%p", buffer);
+                                       layer_data->pending_free_display_buffer = display_buffer;
+                                       return;
+                               }
+                       }
+               }
+       } else {
+               LIST_FOR_EACH_ENTRY(output_data, &exynos_data->output_list, link) {
+                       LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+                               if (display_buffer == layer_data->display_buffer) {
+                                       _tdm_exynos_display_layer_disable(layer_data);
+                                       layer_data->display_buffer = NULL;
+                               }
                        }
                }
        }
-       LIST_DEL(&display_buffer->link);
+
+       TDM_DBG("destroy buffer fd:%d", display_buffer->fds[0]);
 
        free(display_buffer);
 }
@@ -1252,7 +1289,7 @@ exynos_output_set_vblank_handler(tdm_output *output,
 }
 
 tdm_exynos_layer_data *
-tdm_exynos_output_get_layer(tdm_exynos_output_data *output_data, int zpos)
+_exynos_output_get_layer(tdm_exynos_output_data *output_data, int zpos)
 {
        tdm_exynos_layer_data *l = NULL;
        LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
@@ -1297,13 +1334,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->is_device_to_client_transition))
-                       return hwc_window_data;
+                       (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 : 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;
@@ -1314,116 +1356,37 @@ _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)
+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;
 
-       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 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 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
-_get_number_of_visible_windows(struct list_head *hwc_window_list)
-{
-       int number = 0;
-       tdm_exynos_hwc_window_data *window = NULL;
-
-       LIST_FOR_EACH_ENTRY(window, hwc_window_list, link) {
-               if (window->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-               number++;
+               if (hwc_window_data->assigned_layer_zpos == layer_zpos) {
+                       return hwc_window_data;
+               }
        }
 
-       return number;
-}
-
-static void
-_reset_buffers_for_unvis_hwc_windows(tdm_exynos_output_data *output_data)
-{
-       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;
-
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       hwc_window_data->surface = NULL;
-       }
+       return NULL;
 }
 
 static tdm_error
@@ -1431,80 +1394,29 @@ _tdm_exynos_display_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 = tdm_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 = tdm_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 = tdm_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)
+               if (output_data->need_target_window && layer == output_data->primary_layer)
                        continue;
 
-               if (output_data->video_hwc_window && layer->zpos == output_data->video_hwc_window->assigned_layer_zpos)
-                       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;
 }
 
@@ -2090,8 +2002,6 @@ _exynos_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info,
 
        hwc_window_data->output_data = output;
        hwc_window_data->client_type = TDM_COMPOSITION_NONE;
-       hwc_window_data->prev_validated_type = TDM_COMPOSITION_NONE;
-
 
        LIST_INITHEAD(&hwc_window_data->link);
 
@@ -2170,56 +2080,6 @@ exynos_output_hwc_destroy_window(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 "NONE";
-
-       return "unknown";
-}
-
-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)
 {
@@ -2248,169 +2108,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 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 3 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window 2 zpos(DEVICE -> CLIENT) (it is composited on primary layer)
- * hwc_window 1 zpos(DEVICE -> CLIENT) (it is composited on primary layer)
- * hwc_window 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 2 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window 1 zpos(DEVICE -> DEVICE) (it is mapped to primary layer)
- * hwc_window 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 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 1 zpos(DEVICE -> DEVICE) (it is mapped to layer with 2 zpos)
- * hwc_window 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 1 zpos(CLIENT -> CLIENT) (it is composited on primary layer)
- * hwc_window 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, tdm_hwc_window **composited_wnds, uint32_t num_wnds)
 {
-       int layer_zpos;
        tdm_exynos_hwc_window_data *hwc_window_data = NULL;
-       int max_hw_layer_zpos;
-       int need_target_window = 0;
+       tdm_exynos_hwc_window_data **composited_list = NULL;
+       int num_visible_windows = num_wnds;
+       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;
+       int i;
 
-       _reset_composition_types(&output_data->hwc_window_list);
+       composited_list = (tdm_exynos_hwc_window_data**)composited_wnds;
+
+       /* reset the validated_type and hw layer policy */
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO)
+                       continue;
+               composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
+               composited_list[i]->candidate_layer_zpos = -1;
+       }
 
-       if (!num_unmarked_layers && !output_data->video_hwc_window) {
+       /* initialize the zpos of the target_window */
+       output_data->target_window_zpos = primary_layer_zpos;
+       output_data->need_target_window = 0;
+
+       /* 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 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 is not TDM_COMPOSITION_DEVICE or hwc_window cannot
-                        * be set on hwc_window_data layer*/
-                       if (hwc_window_data->client_type == TDM_COMPOSITION_DEVICE &&
-                               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 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
-        */
-       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 to layer with the video hwc_window */
-       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(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 */
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO)
+                       continue;
+               if (composited_list[i] == output_data->video_hwc_window)
                        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 (available_layers == 0)
+                       break;
+
+               /* meet the client type, set need_target_window and break */
+               if (composited_list[i]->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 is not TDM_COMPOSITION_DEVICE or hwc_window 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 cannot be mapped on layer target_window is needed */
-               need_target_window = 1;
-               break;
+               if (composited_list[i]->client_type == TDM_COMPOSITION_DEVICE ||
+                   composited_list[i]->client_type == TDM_COMPOSITION_CURSOR) {
+                       if (_can_set_hwc_window_on_hw_layer(composited_list[i])) {
+                               composited_list[i]->validated_type = composited_list[i]->client_type;
+                               composited_list[i]->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;
 
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+set_all_client_types:
+       for (i = 0; i < num_wnds; i++) {
+               if (composited_list[i]->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;
+               composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
+               composited_list[i]->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
@@ -2435,59 +2244,26 @@ _print_validate_result(tdm_exynos_output_data *output_data)
 }
 
 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;
-
-               hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
-       }
-}
-
-/* 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;
+               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);
 
-               if (hwc_window_data->grabbed_layer_zpos >= 0 &&
-                               hwc_window_data->validated_type == TDM_COMPOSITION_CLIENT)
-                       return 1;
+               hwc_window_data->assigned_layer_zpos = hwc_window_data->candidate_layer_zpos;
        }
-
-       return 0;
 }
 
 tdm_error
@@ -2496,42 +2272,27 @@ exynos_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
 {
        tdm_exynos_output_data *output_data = output;
        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);
 
-       prev_need_target_window = output_data->need_target_window;
-
-       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);
-
-       _update_layers_info(output_data);
-
-       _print_validate_result(output_data);
+       _exynos_output_hwc_adapt_policy(output_data, composited_wnds, num_wnds);
 
+       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;
 }
@@ -2578,17 +2339,13 @@ 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;
        output_data->need_validate = 0;
 
        return TDM_ERROR_NONE;
@@ -2662,7 +2419,7 @@ exynos_output_hwc_get_video_supported_formats(tdm_output *output,
        RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        /* now the video window supported only on the layer with index 0 */
-       layer = tdm_exynos_output_get_layer(output_data, 0);
+       layer = _exynos_output_get_layer(output_data, 0);
        RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_OPERATION_FAILED);
 
        *formats = layer->formats;
index 8946139d243e8f237e717cfeb426fd69f30c54b1..4920b964a593d4dacbf36aaa9c25025fd2d3b066 100644 (file)
@@ -210,6 +210,7 @@ struct _tdm_exynos_output_data {
        int need_validate;
        int need_target_window;
 
+       int target_window_zpos;
        struct list_head hwc_window_list;
 };
 
@@ -222,19 +223,24 @@ struct _tdm_exynos_layer_data {
        tdm_layer_capability capabilities;
        int zpos;
 
-       //list of exynos formats
-       int format_count;
-       tbm_format *formats;
-
        /* not fixed data below */
        tdm_info_layer info;
        int info_changed;
 
        tdm_exynos_display_buffer *display_buffer;
        int display_buffer_changed;
+       tdm_exynos_display_buffer *pending_free_display_buffer;
+       int pending_free_ready;
+
        /* current hw overlay setting */
        struct decon_win_config win_cfg;
        int enabled_flag;
+
+       tbm_format *formats;
+       int format_count;
+
+       tdm_prop *props;
+       int prop_count;
 };
 
 struct _tdm_exynos_hwc_window_data {
@@ -252,20 +258,16 @@ struct _tdm_exynos_hwc_window_data {
        int display_buffer_changed;
        int enabled_flag;
 
-       /* client_type stores the initial type given to us by client(compositor) */
+       /* client_type stores the initial type given to us by client(compositor),
+        *  validated_type stores the type after running Validate
+        */
        tdm_hwc_window_composition client_type;
-       /* validated_type stores the type after running Validate */
        tdm_hwc_window_composition validated_type;
-       /* prev_validated_type is used to achieve requirements tied with the client_candidate 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;
 };
 
 #endif /* _TDM_EXYNOS_TYPES_H_ */
index c389110b156c800348d39faa24e4f46f755adc80..1c06f7d47ce3cc5375bb749b974f6277a3bbd6f2 100644 (file)
@@ -4,18 +4,40 @@
 
 #include "tdm_exynos.h"
 
+tdm_exynos_layer_data *
+_exynos_output_get_layer(tdm_exynos_output_data *output_data, int index);
+
 tbm_surface_queue_h
 exynos_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
 {
+       tdm_exynos_hwc_window_data *hwc_window_data = NULL;
+       tdm_exynos_output_data *output_data = NULL;
+       tbm_surface_queue_h tqueue = NULL;
+       tbm_format format;
+
        if (error)
                *error = TDM_ERROR_INVALID_PARAMETER;
 
        RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
+       hwc_window_data = hwc_window;
+       output_data = hwc_window_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
+       RETURN_VAL_IF_FAIL(output_data->video_hwc_window != hwc_window_data, NULL);
+
+       int wight = hwc_window_data->info.src_config.size.h;
+       int hight = hwc_window_data->info.src_config.size.v;
 
+       format = hwc_window_data->info.src_config.format;
+
+       tqueue = tbm_surface_queue_create(3, wight, hight, format, TBM_BO_SCANOUT);
        if (error)
                *error = TDM_ERROR_OPERATION_FAILED;
+       RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
 
-       return NULL;
+       return tqueue;
 
 }
 
@@ -28,16 +50,24 @@ 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;
+       }
+
        output_data->need_validate = 1;
 
        return TDM_ERROR_NONE;
-
 }
 
 tdm_error
@@ -64,13 +94,6 @@ exynos_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info
        output_data = hwc_window_data->output_data;
        RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       if (output_data->video_hwc_window == hwc_window_data) {
-               tdm_exynos_layer_data *layer;
-               layer = tdm_exynos_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
-
-               return exynos_layer_set_info(layer, (tdm_info_layer *)info);
-       }
-
        if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)))
                return TDM_ERROR_NONE;
 
@@ -135,7 +158,7 @@ exynos_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
        tdm_exynos_hwc_window_data *hwc_window_data = hwc_window;
        tdm_exynos_output_data *output_data;
 
-       RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        output_data = hwc_window_data->output_data;
        RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);