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)
{
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;
_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--;
}
}
+ /* 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;
}
}
+ /* if hwc_window cannot be mapped on layer target_window is needed */
need_target_window = 1;
break;
}
_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)