write comments on the hwc_windows mapping algorithm 88/163488/2 accepted/tizen/unified/20171213.040839 submit/tizen/20171212.223103
authorKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Mon, 11 Dec 2017 11:56:01 +0000 (13:56 +0200)
committerKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Tue, 12 Dec 2017 11:53:25 +0000 (13:53 +0200)
Change-Id: I0ff7561dbf61164d1433d663095be0760f97f0d1
Signed-off-by: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
src/tdm_exynos_output.c

index 561e203ef934d333a86c289dbc06ab1e3dd38e6e..39b2a7b04af250e47697db1682405264bcb257c2 100644 (file)
@@ -1302,6 +1302,9 @@ _get_number_of_visible_windows(struct list_head *hwc_window_list)
        return number;
 }
 
+/* If there is only 1 visible hwc_window 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)
 {
@@ -1370,12 +1373,42 @@ _can_set_hwc_window_on_hw_layer(tdm_exynos_hwc_window_data *hw)
 
        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)
+ */
 static void
 _map_hwc_windows_to_layers(tdm_exynos_output_data *exynos_output)
 {
        int layer_zpos;
        tdm_exynos_hwc_window_data *hw = NULL;
-       int max_hw_layer_zpos = LIST_LENGTH(&exynos_output->layer_list);
+       int max_hw_layer_zpos;
        int need_target_window = 0;
        int primary_layer_zpos = _get_primary_layer_zpos(exynos_output);
        int num_skip_layers = 0;
@@ -1384,15 +1417,20 @@ _map_hwc_windows_to_layers(tdm_exynos_output_data *exynos_output)
 
        _reset_composition_types(&exynos_output->hwc_window_list);
 
-       /* mark the top window */
+       /* 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(&exynos_output->hwc_window_list)) {
-               layer_zpos = max_hw_layer_zpos;
+               layer_zpos = LIST_LENGTH(&exynos_output->layer_list);
                LIST_FOR_EACH_ENTRY_REV(hw, &exynos_output->hwc_window_list, link) {
                        if (hw->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 hw layer*/
                        if (hw->client_type == TDM_COMPOSITION_DEVICE && layer_zpos != primary_layer_zpos) {
-                               /* check format */
                                if (_can_set_hwc_window_on_hw_layer(hw)) {
                                        hw->validated_type = TDM_COMPOSITION_DEVICE;
                                        num_unmarked_layers--;
@@ -1404,34 +1442,47 @@ _map_hwc_windows_to_layers(tdm_exynos_output_data *exynos_output)
                }
        }
 
+       /* if there is the video hwc_window the bottom layer is used for it */
        if (exynos_output->video_hwc_window)
                num_bottom_layer_with_primary--;
 
        if (num_unmarked_layers > num_bottom_layer_with_primary)
                need_target_window = 1;
 
-       max_hw_layer_zpos = primary_layer_zpos + 1;
+       /* max zpos of layer which can be used for mapping. If the target_window is
+        * not needed primary layer can be used for mapping
+        */
+       max_hw_layer_zpos = primary_layer_zpos;
        if (need_target_window)
                max_hw_layer_zpos--;
 
+       /* 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;
 
        /* 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 (exynos_output->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(hw, &exynos_output->hwc_window_list, link) {
                if (hw->client_type == TDM_COMPOSITION_NONE)
                        continue;
                layer_zpos++;
-               /* break if the remaining windows are already marked */
+               /* break if the remaining windows are already marked in the
+                * previous iteration */
                if (hw->validated_type == TDM_COMPOSITION_DEVICE)
                        break;
+               /* break if we have reached max hw layer or the composition type of
+                * current hwc_window is not TDM_COMPOSITION_DEVICE or hwc_window cannot
+                * be set on hw layer */
                if ((hw->client_type == TDM_COMPOSITION_DEVICE)
-                       && layer_zpos < max_hw_layer_zpos) {
-                       /* check format */
+                       && layer_zpos <= max_hw_layer_zpos) {
                        if (_can_set_hwc_window_on_hw_layer(hw)) {
                                hw->validated_type = TDM_COMPOSITION_DEVICE;
                                hw->assigned_layer_zpos = layer_zpos;
@@ -1439,6 +1490,7 @@ _map_hwc_windows_to_layers(tdm_exynos_output_data *exynos_output)
                        }
                }
 
+               /* if hwc_window cannot be mapped on layer target_window is needed */
                need_target_window = 1;
                break;
        }
@@ -1554,6 +1606,8 @@ exynos_output_hwc_validate(tdm_output *output, uint32_t *num_types)
 
                _reset_composition_types(&exynos_output->hwc_window_list);
        } else {
+               /* 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(exynos_output);
 
                if (need_map_hwc_windows_to_layers)