return EINA_TRUE;
}
+#if 0
static Eina_List *
_e_hwc_window_target_window_ee_rendered_hw_list_get(E_Hwc_Window_Target *target_window)
{
return new_list;
}
+#endif
static void
_e_hwc_window_client_cb_new(void *data EINA_UNUSED, E_Client *ec)
tbm_surface_h tsurface = NULL;
E_Client *ec = hwc_window->ec;
- if (!buffer) return NULL;
+ if (!buffer)
+ {
+ ELOGF("HWC-WINS", "[soolim] ehw:%p E_Comp_Wl_Buffer is null.",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec,
+ hwc_window);
+ return NULL;
+ }
tsurface = wayland_tbm_server_get_surface(wl_comp_data->tbm.server, buffer->resource);
if (!tsurface)
E_Pointer *pointer = NULL;
pointer = e_pointer_get(ec);
- if (!pointer) return EINA_FALSE;
+ if (!pointer)
+ {
+ ELOGF("HWC-WINS", "[soolim] ehw:%p Pointer is null.(Cursor)",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec,
+ hwc_window);
+ return NULL;
+ }
buffer = ec->comp_data->buffer_ref.buffer;
- if (!buffer) return NULL;
+ if (!buffer)
+ {
+ ELOGF("HWC-WINS", "[soolim] ehw:%p E_Comp_Wl_Buffer is null.(Cursor)",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec,
+ hwc_window);
+ return NULL;
+ }
if (!e_comp_object_hwc_update_exists(ec->frame) && hwc_window->tsurface) return NULL;
return EINA_TRUE;
}
+#if 0
static Eina_Bool
_e_hwc_window_correct_transformation_check(E_Hwc_Window *hwc_window)
{
return EINA_TRUE;
}
+#endif
+#if 0
/* whether an hwc_window exists on a target_buffer which is currently set at the target_window */
static Eina_Bool
_e_hwc_window_is_on_target_window(E_Hwc_Window *hwc_window)
return EINA_TRUE;
}
+#endif
EINTERN Eina_Bool
e_hwc_window_init(E_Output_Hwc *output_hwc)
EINTERN Eina_Bool
e_hwc_window_zpos_set(E_Hwc_Window *hwc_window, int zpos)
{
- tdm_error error;
- tdm_hwc_window *thwc_window;
-
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
if (hwc_window->zpos != zpos) hwc_window->zpos = zpos;
- thwc_window = hwc_window->thwc_window;
- EINA_SAFETY_ON_NULL_RETURN_VAL(thwc_window, EINA_FALSE);
-
- error = tdm_hwc_window_set_zpos(thwc_window, hwc_window->zpos);
- EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
-
return EINA_TRUE;
}
EINTERN Eina_Bool
e_hwc_window_update(E_Hwc_Window *hwc_window)
{
- Eina_Bool result;
- E_Comp_Wl_Buffer *buffer = NULL;
- E_Comp_Wl_Data *wl_comp_data = (E_Comp_Wl_Data *)e_comp->wl_comp_data;
tbm_surface_h tsurface = NULL;
- E_Hwc_Window_State state = E_HWC_WINDOW_STATE_NONE;
+ tdm_hwc_window *thwc_window;
+ tdm_hwc_window_composition composition_type;
+ tdm_error error;
+ Eina_Bool result;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
- /* hwc_window manager could ask to prevent some e_clients being shown by hw directly;
- * if hwc_window's ec has no correct transformation we can't allow such ec to claim on
- * hw overlay, 'cause currently hw doesn't support transformation; */
- if (hwc_window->hwc_acceptable)
- {
- if (e_hwc_window_is_video(hwc_window))
- {
- tsurface = e_comp_wl_video_hwc_widow_surface_get(hwc_window);
- state = E_HWC_WINDOW_STATE_VIDEO;
+ if (e_hwc_window_is_target(hwc_window))
+ {
+ ERR("HWC-WINS: target window cannot update at e_hwc_window_update.");
+ return EINA_FALSE;
+ }
- if (tsurface)
- {
- result = _e_hwc_window_info_set(hwc_window, tsurface);
- EINA_SAFETY_ON_TRUE_RETURN_VAL(result != EINA_TRUE, EINA_FALSE);
- }
- }
- else
- {
- if (_e_hwc_window_correct_transformation_check(hwc_window))
- {
- if (e_hwc_window_is_cursor(hwc_window))
- {
- tsurface = hwc_window->cursor_tsurface;
- state = E_HWC_WINDOW_STATE_CURSOR;
- }
- else
- {
- buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
- if (buffer) tsurface = wayland_tbm_server_get_surface(wl_comp_data->tbm.server, buffer->resource);
- state = E_HWC_WINDOW_STATE_DEVICE;
- }
-
- if (tsurface)
- {
- result = _e_hwc_window_info_set(hwc_window, tsurface);
- EINA_SAFETY_ON_TRUE_RETURN_VAL(result != EINA_TRUE, EINA_FALSE);
- }
- }
- else
- state = E_HWC_WINDOW_STATE_CLIENT;
- }
- }
- else
- state = E_HWC_WINDOW_STATE_CLIENT;
+ thwc_window = hwc_window->thwc_window;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(thwc_window, EINA_FALSE);
- if (!e_hwc_window_state_set(hwc_window, state))
+ /* set zpos */
+ error = tdm_hwc_window_set_zpos(thwc_window, hwc_window->zpos);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
+
+ /* set composition type */
+ composition_type = _get_composition_type(hwc_window->state);
+ error = tdm_hwc_window_set_composition_type(hwc_window->thwc_window, composition_type);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
+
+ tsurface = hwc_window->tsurface;
+ if (tsurface)
{
- ERR("e_hwc_window_state_set failed.");
- return EINA_FALSE;
+ /* set window info */
+ result = _e_hwc_window_info_set(hwc_window, tsurface);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(result != EINA_TRUE, EINA_FALSE);
}
+ /* set buffer */
+ error = tdm_hwc_window_set_buffer(hwc_window->thwc_window, hwc_window->tsurface);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
+
+ ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d, deleted:%s",
+ hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
+ hwc_window, hwc_window->tsurface, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
+ e_hwc_window_state_string_get(hwc_window->state),
+ hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
+
return EINA_TRUE;
}
static void
_e_hwc_window_client_buffer_reset(E_Hwc_Window *hwc_window)
{
- tdm_hwc_region fb_damage;
-
if (!hwc_window->tsurface) return;
- if (e_hwc_window_is_target(hwc_window))
- {
- if (hwc_window->update_exist && hwc_window->tsurface)
- _e_hwc_window_target_window_surface_release((E_Hwc_Window_Target *)hwc_window, hwc_window->tsurface);
-
- if (!_e_hwc_window_target_window_clear((E_Hwc_Window_Target *)hwc_window))
- ERR("fail to _e_hwc_window_target_window_clear");
-
- /* the damage isn't supported by hwc extension yet */
- memset(&fb_damage, 0, sizeof(fb_damage));
-#if 0
- E_Output_Hwc *output_hwc = NULL;
- E_Output *output = NULL;
+ tdm_hwc_window_set_buffer(hwc_window->thwc_window, NULL);
- output_hwc = hwc_window->output_hwc;
- output = output_hwc->output;
-
- tdm_output_hwc_set_client_target_buffer(output->toutput, NULL, fb_damage, NULL, 0);
-
- ELOGF("HWC-WINS", " ehw:%p sets ts:(NULL) ------- {%25s}, state:%s, zpos:%d",
- NULL, NULL, hwc_window, "@TARGET WINDOW@",
- e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
-#endif
- }
- else
+ if (hwc_window->cursor_tsurface)
{
- tdm_hwc_window_set_buffer(hwc_window->thwc_window, NULL);
-
- if (hwc_window->cursor_tsurface)
- {
- tbm_surface_destroy(hwc_window->cursor_tsurface);
- hwc_window->cursor_tsurface = NULL;
- }
-
- ELOGF("HWC-WINS", " ehw:%p sets ts:(NULL) ------- {%25s}, state:%s, zpos:%d, deleted:%s",
- hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
- e_hwc_window_state_string_get(hwc_window->state),
- hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
+ tbm_surface_destroy(hwc_window->cursor_tsurface);
+ hwc_window->cursor_tsurface = NULL;
}
+ ELOGF("HWC-WINS", " ehw:%p sets ts:(NULL) ------- {%25s}, state:%s, zpos:%d, deleted:%s",
+ hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
+ hwc_window, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
+ e_hwc_window_state_string_get(hwc_window->state),
+ hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
+
hwc_window->tsurface = NULL;
}
EINTERN Eina_Bool
-e_hwc_window_fetch(E_Hwc_Window *hwc_window)
+e_hwc_window_buffer_fetch(E_Hwc_Window *hwc_window)
{
- E_Output_Hwc *output_hwc = NULL;
- E_Hwc_Window *hw;
- E_Hwc_Window_Target *target_hwc_window;
- E_Output *output = NULL;
- Eina_List *ee_rendered_hw_list = NULL;
tbm_surface_h tsurface = NULL;
- tdm_hwc_window **thwc_windows = NULL;
- tdm_hwc_region fb_damage;
- uint32_t n_thw = 0;
- const Eina_List *l;
- int i;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
- if (hwc_window->is_deleted) return EINA_FALSE;
-
- output_hwc = hwc_window->output_hwc;
- output = output_hwc->output;
+ if (hwc_window->is_deleted)
+ {
+ ELOGF("HWC-WINS", "[soolim] ehw:%p is_delete.",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec, hwc_window);
+ return EINA_FALSE;
+ }
/* set the buffer to be null */
if (hwc_window->state == E_HWC_WINDOW_STATE_NONE)
{
_e_hwc_window_client_buffer_reset(hwc_window);
-
- return EINA_FALSE;
+ return EINA_TRUE;
}
- /* return true if the update_exist already set. */
- if (hwc_window->update_exist) return EINA_TRUE;
-
/* for video we set buffer in the video module */
if (e_hwc_window_is_video(hwc_window))
{
return EINA_FALSE;
}
- tdm_hwc_window_set_buffer(hwc_window->thwc_window, tsurface);
hwc_window->tsurface = tsurface;
ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d, deleted:%s",
goto done;
}
+#if 0
/* Do not fetch the buffers of the windows except the video window at the canvas_norender. */
if (e_comp_canvas_norender_get() > 0)
{
hwc_window);
return EINA_FALSE;
}
+#endif
- if (e_hwc_window_is_target(hwc_window))
- {
- /* acquire the surface */
- tsurface = _e_hwc_window_target_window_surface_acquire((E_Hwc_Window_Target *)hwc_window);
- if (!tsurface) return EINA_FALSE;
- }
- else if (e_hwc_window_is_cursor(hwc_window))
+ if (e_hwc_window_is_cursor(hwc_window))
{
tsurface = _e_hwc_window_cursor_surface_acquire(hwc_window);
if (!tsurface) return EINA_FALSE;
{
/* acquire the surface */
tsurface = _e_hwc_window_client_surface_acquire(hwc_window);
- if (hwc_window->tsurface == tsurface) return EINA_FALSE;
+ if (!tsurface) return EINA_FALSE;
}
/* exist tsurface for update hwc_window */
hwc_window->tsurface = tsurface;
- if (e_hwc_window_is_target(hwc_window))
- {
- target_hwc_window = (E_Hwc_Window_Target *)hwc_window;
-
- if (target_hwc_window->skip_surface_set)
- {
- hwc_window->update_exist = EINA_TRUE;
- return EINA_TRUE;
- }
-
- /* the damage isn't supported by hwc extension yet */
- memset(&fb_damage, 0, sizeof(fb_damage));
-
- ee_rendered_hw_list = _e_hwc_window_target_window_ee_rendered_hw_list_get(target_hwc_window);
- n_thw = eina_list_count(ee_rendered_hw_list);
- if (n_thw)
- {
- ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d.",
- NULL, NULL, hwc_window, hwc_window->tsurface, "@TARGET WINDOW@",
- e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
-
- thwc_windows = E_NEW(tdm_hwc_window *, n_thw);
- EINA_SAFETY_ON_NULL_GOTO(thwc_windows, error);
-
- i = 0;
- EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw)
- {
- ELOGF("HWC-WINS", " (%d) with ehw:%p, ts:%p ------- {%25s}, state:%s, zpos:%d, deleted:%s",
- hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- i, hw, hw->tsurface, hw->ec ? hw->ec->icccm.title : "UNKNOWN",
- e_hwc_window_state_string_get(hw->state),
- hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
-
- thwc_windows[i++] = hw->thwc_window;
- }
- }
- else
- ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d no hwc_windows to render.",
- NULL, NULL, hwc_window, hwc_window->tsurface, "@TARGET WINDOW@",
- e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
-
- tdm_output_hwc_set_client_target_buffer(output->toutput, tsurface, fb_damage,
- thwc_windows, n_thw);
-
- E_FREE(thwc_windows);
- eina_list_free(ee_rendered_hw_list);
- }
- else
- {
- tdm_hwc_window_set_buffer(hwc_window->thwc_window, hwc_window->tsurface);
-
- ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d, deleted:%s",
- hwc_window->ec ? hwc_window->ec->pixmap : NULL, hwc_window->ec,
- hwc_window, hwc_window->tsurface, hwc_window->ec ? hwc_window->ec->icccm.title : "UNKNOWN",
- e_hwc_window_state_string_get(hwc_window->state),
- hwc_window->zpos, hwc_window->is_deleted ? "yes" : "no");
- }
-
done:
hwc_window->update_exist = EINA_TRUE;
return EINA_TRUE;
-
-error:
-
- E_FREE(thwc_windows);
- eina_list_free(ee_rendered_hw_list);
-
- return EINA_FALSE;
}
EINTERN Eina_Bool
{
E_Hwc_Window_Commit_Data *commit_data = NULL;
+#if 0
if (!e_hwc_window_is_on_hw_overlay(hwc_window))
{
hwc_window->update_exist = EINA_FALSE;
/* If there are not updates and there is not displaying surface, it means the
* hwc_window's composition type just became TDM_COMPOSITION_DEVICE. Buffer
- * for this hwc_window was set in the previous e_hwc_window_fetch but ref for
+ * for this hwc_window was set in the previous e_hwc_window_buffer_fetch but ref for
* buffer didn't happen because hwc_window had TDM_COMPOSITION_CLIENT type.
* So e20 needs to make ref for the current buffer which is set on the hwc_window.
*/
{
return EINA_FALSE;
}
+#endif
commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, EINA_FALSE);
return EINA_TRUE;
}
+EINTERN Eina_Bool
+e_hwc_window_target_enabled(E_Hwc_Window_Target *target_hwc_window)
+{
+ E_Hwc_Window *hwc_window;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+ hwc_window = (E_Hwc_Window *)target_hwc_window;
+
+ if (hwc_window->state != E_HWC_WINDOW_STATE_DEVICE)
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_hwc_window_target_buffer_fetch(E_Hwc_Window_Target *target_hwc_window)
+{
+ E_Output *output;
+ E_Output_Hwc *output_hwc;
+ E_Hwc_Window *hwc_window;
+ tbm_surface_h tsurface;
+ tdm_hwc_region fb_damage;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+ hwc_window = (E_Hwc_Window *)target_hwc_window;
+
+ if (hwc_window->state == E_HWC_WINDOW_STATE_DEVICE)
+ {
+ /* acquire the surface */
+ tsurface = _e_hwc_window_target_window_surface_acquire((E_Hwc_Window_Target *)hwc_window);
+ if (!tsurface) return EINA_FALSE;
+
+ hwc_window->tsurface = tsurface;
+
+ output_hwc = hwc_window->output_hwc;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(output_hwc, EINA_FALSE);
+
+ output = output_hwc->output;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
+
+ /* the damage isn't supported by hwc extension yet */
+ memset(&fb_damage, 0, sizeof(fb_damage));
+
+ tdm_output_hwc_set_client_target_buffer(output->toutput, hwc_window->tsurface, fb_damage, NULL, 0);
+
+ ELOGF("HWC-WINS", " ehw:%p sets ts:%p ------- {%25s}, state:%s, zpos:%d no hwc_windows to render.",
+ NULL, NULL, hwc_window, hwc_window->tsurface, "@TARGET WINDOW@",
+ e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
+ }
+ else
+ {
+ if (hwc_window->tsurface)
+ _e_hwc_window_target_window_surface_release((E_Hwc_Window_Target *)hwc_window, hwc_window->tsurface);
+
+ if (!_e_hwc_window_target_window_clear((E_Hwc_Window_Target *)hwc_window))
+ ERR("fail to _e_hwc_window_target_window_clear");
+
+ hwc_window->tsurface = NULL;
+
+ //TODO: Do we set the target_buffer to be NULL?
+
+ ELOGF("HWC-WINS", " ehw:%p sets ts:(NULL) ------- {%25s}, state:%s, zpos:%d",
+ NULL, NULL, hwc_window, "@TARGET WINDOW@",
+ e_hwc_window_state_string_get(hwc_window->state), hwc_window->zpos);
+ }
+
+ return EINA_TRUE;
+}
+
EINTERN Eina_Bool
e_hwc_window_activate(E_Hwc_Window *hwc_window)
{
hwc_window->type = composition_type;
hwc_window->state = state;
+
+ e_hwc_window_zpos_set(hwc_window, -999);
}
}
return hwc_window->state;
}
+EINTERN void
+e_hwc_window_prev_state_update(E_Hwc_Window *hwc_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+ hwc_window->prev_state = hwc_window->state;
+}
+
+EINTERN E_Hwc_Window_State
+e_hwc_window_prev_state_get(E_Hwc_Window *hwc_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, E_HWC_WINDOW_STATE_NONE);
+
+ return hwc_window->prev_state;
+}
+
// add hwc_window to the render_list
EINTERN void
e_hwc_window_render_list_add(E_Hwc_Window *hwc_window)
ELOGF("HWC-WINS", " added the render_list -- ehw:%p -- {%25s}.", ec->pixmap, ec, hwc_window, ec->icccm.title);
}
+EINTERN Eina_Bool
+e_hwc_window_is_on_target_window(E_Hwc_Window *hwc_window)
+{
+ Eina_List *ee_rendered_hw_list = NULL;
+ E_Hwc_Window_Target *target_hwc_window;
+ E_Hwc_Window *hw;
+ const Eina_List *l;
+ tbm_surface_h target_tsurface;
+
+ target_hwc_window = _e_hwc_window_target_window_get(hwc_window);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
+
+ target_tsurface = target_hwc_window->hwc_window.tsurface;
+
+ tbm_surface_internal_get_user_data(target_tsurface, ee_rendered_hw_list_key, (void**)&ee_rendered_hw_list);
+
+ EINA_LIST_FOREACH(ee_rendered_hw_list, l, hw)
+ if (hw == hwc_window) return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+
EINTERN const char*
e_hwc_window_state_string_get(E_Hwc_Window_State hwc_window_state)
{
#define DBG_EVALUATE 1
+#define ZPOS_NONE -999
+
static Eina_Bool _e_output_hwc_windows_pp_output_data_commit(E_Output_Hwc *output_hwc, E_Hwc_Window_Commit_Data *data);
static Eina_Bool _e_output_hwc_windows_pp_window_commit(E_Output_Hwc *output_hwc, E_Hwc_Window *hwc_window);
+// if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
static Eina_Bool
_e_output_hwc_windows_ec_check(E_Client *ec)
{
E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
E_Output *eout;
int minw = 0, minh = 0;
+ int transform;
if ((!cdata) || (!cdata->buffer_ref.buffer))
{
return EINA_FALSE;
}
+ transform = e_comp_wl_output_buffer_transform_get(ec);
+
/* If a client doesn't watch the ignore_output_transform events, we can't show
* a client buffer to HW overlay directly when the buffer transform is not same
* with output transform. If a client watch the ignore_output_transform events,
*/
if (!e_comp_screen_rotation_ignore_output_transform_watch(ec))
{
- int transform = e_comp_wl_output_buffer_transform_get(ec);
-
if ((eout->config.rotation / 90) != transform)
{
ELOGF("HWC-WINS", " ehw:%p -- {%25s} is forced to set CL state.(no igrore_transfrom)",
return EINA_TRUE;
}
-static Eina_Bool
-_e_output_hwc_windows_need_target_hwc_window(E_Output_Hwc *output_hwc)
+static E_Output_Hwc_Mode
+_e_output_hwc_windows_hwc_mode_get(E_Output_Hwc *output_hwc)
{
Eina_List *l;
E_Hwc_Window *hwc_window;
- int num_vis_wnd = 0;
+ E_Output_Hwc_Mode hwc_mode = E_OUTPUT_HWC_MODE_NONE;
+ int num_visible = 0;
+ int num_visible_client = 0;
EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
{
+ if (e_hwc_window_is_target(hwc_window)) continue;
+
if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) continue;
+ if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) continue;
- if (!e_hwc_window_is_on_hw_overlay(hwc_window))
- return EINA_TRUE;
+ if (hwc_window->state == E_HWC_WINDOW_STATE_CLIENT)
+ num_visible_client++;
- num_vis_wnd++;
+ num_visible++;
}
- if (!num_vis_wnd)
- return EINA_TRUE;
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_e_output_hwc_windows_all_windows_init(E_Output_Hwc *output_hwc)
-{
- const Eina_List *hwc_windows, *l;
- E_Hwc_Window *hwc_window = NULL;
-
- hwc_windows = e_output_hwc_windows_get(output_hwc);
- EINA_LIST_FOREACH(hwc_windows, l, hwc_window)
- {
-// if (e_hwc_window_is_video(hwc_window)) continue;
-
- if (!e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE))
- {
- ERR("e_hwc_window_state_set failed.");
- return EINA_FALSE;
- }
- }
+ if (!num_visible)
+ hwc_mode = E_OUTPUT_HWC_MODE_NONE;
+ else if (num_visible_client > 0)
+ hwc_mode = E_OUTPUT_HWC_MODE_HYBRID;
+ else
+ hwc_mode = E_OUTPUT_HWC_MODE_FULL;
- return EINA_TRUE;
+ return hwc_mode;
}
static int
output_hwc->wait_commit = EINA_FALSE;
}
+#if 0
/* we can do commit if we set surface at least to one window which displayed on
* the hw layer*/
static Eina_Bool
return can_commit;
}
+#endif
static Eina_Bool
_e_output_hwc_windows_prepare_commit(E_Output *output, E_Hwc_Window *hwc_window)
{
E_Output *output = NULL;
tdm_layer *toutput = NULL;
- tdm_error tdm_err;
+ tdm_error terror;
tdm_hwc_region fb_damage;
/* the damage isn't supported by hwc extension yet */
/* no need to pass composited_wnds list because smooth transition isn't
* used is this case */
- tdm_err = tdm_output_hwc_set_client_target_buffer(toutput, data->tsurface, fb_damage, NULL, 0);
- if (tdm_err != TDM_ERROR_NONE)
+ terror = tdm_output_hwc_set_client_target_buffer(toutput, data->tsurface, fb_damage, NULL, 0);
+ if (terror != TDM_ERROR_NONE)
{
ERR("fail to tdm_output_hwc_set_client_target_buffer");
goto fail;
}
- tdm_err = tdm_output_commit(toutput, 0, _e_output_hwc_windows_pp_output_commit_handler, output_hwc);
+ terror = tdm_output_commit(toutput, 0, _e_output_hwc_windows_pp_output_commit_handler, output_hwc);
- if (tdm_err != TDM_ERROR_NONE)
+ if (terror != TDM_ERROR_NONE)
{
ERR("fail to tdm_output_commit output_hwc:%p", output_hwc);
goto fail;
E_Output *output = NULL;
tbm_surface_h pp_tsurface = NULL;
tbm_error_e tbm_err = TBM_ERROR_NONE;
- tdm_error tdm_err = TDM_ERROR_NONE;
+ tdm_error terror = TDM_ERROR_NONE;
E_Hwc_Window_Commit_Data *commit_data = hwc_window->commit_data;
EINA_SAFETY_ON_FALSE_RETURN_VAL(commit_data, EINA_FALSE);
goto pp_fail;
}
- tdm_err = tdm_pp_set_done_handler(output_hwc->tpp, _e_output_hwc_windows_pp_commit_handler, output_hwc);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+ terror = tdm_pp_set_done_handler(output_hwc->tpp, _e_output_hwc_windows_pp_commit_handler, output_hwc);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, pp_fail);
tbm_surface_internal_ref(pp_tsurface);
tbm_surface_internal_ref(commit_data->tsurface);
- tdm_err = tdm_pp_attach(output_hwc->tpp, commit_data->tsurface, pp_tsurface);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, attach_fail);
+ terror = tdm_pp_attach(output_hwc->tpp, commit_data->tsurface, pp_tsurface);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, attach_fail);
output_hwc->pp_hwc_window_list = eina_list_append(output_hwc->pp_hwc_window_list, hwc_window);
- tdm_err = tdm_pp_commit(output_hwc->tpp);
- EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, commit_fail);
+ terror = tdm_pp_commit(output_hwc->tpp);
+ EINA_SAFETY_ON_FALSE_GOTO(terror == TDM_ERROR_NONE, commit_fail);
output_hwc->wait_commit = EINA_TRUE;
output_hwc->pp_commit = EINA_TRUE;
return NULL;
}
-static void
-_e_output_hwc_windows_update(E_Output_Hwc *output_hwc, Eina_List *cl_list)
+static Eina_Bool
+_e_output_hwc_windows_update(E_Output_Hwc *output_hwc)
{
const Eina_List *l;
E_Hwc_Window *hwc_window;
- E_Client *ec;
- int zpos = 0;
- /* clients are sorted in reverse order */
- EINA_LIST_REVERSE_FOREACH(cl_list, l, ec)
+ EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
{
- hwc_window = ec->hwc_window;
- if (!hwc_window) continue;
+ if (e_hwc_window_is_target(hwc_window)) continue;
- if (!e_hwc_window_zpos_set(hwc_window, zpos))
+ if (!e_hwc_window_buffer_fetch(hwc_window))
{
- ERR("hwc-opt: cannot set zpos for E_Hwc_Window(%p)", hwc_window);
- continue;
+ ELOGF("HWC-WINS", "[soolim] ehw:%p e_hwc_window_buffer_fetch failed.",
+ hwc_window->ec ? ec->pixmap : NULL, hwc_window->ec, hwc_window);
}
- zpos++;
if (!e_hwc_window_update(hwc_window))
{
- ERR("hwc-opt: cannot update E_Hwc_Window(%p)", hwc_window);
- continue;
+ ERR("HWC-WINS: cannot update E_Hwc_Window(%p)", hwc_window);
+ return EINA_FALSE;
}
}
+
#if DBG_EVALUATE
ELOGF("HWC-WINS", " Request HWC Validation to TDM HWC:", NULL, NULL);
_e_output_hwc_windows_status_print(output_hwc);
#endif
+
+ return EINA_TRUE;
}
static E_Hwc_Window_State
break;
default:
state = E_HWC_WINDOW_STATE_NONE;
- ERR("hwc-opt: unknown state of hwc_window.");
+ ERR("HWC-WINS: unknown state of hwc_window.");
}
return state;
}
static Eina_Bool
-_e_output_hwc_windows_validate(E_Output_Hwc *output_hwc)
+_e_output_hwc_windows_accept(E_Output_Hwc *output_hwc, uint32_t num_changes)
{
- tdm_error tdm_err;
- uint32_t num_changes;
- E_Output *eo = output_hwc->output;
- tdm_output *toutput = eo->toutput;
+ E_Output *output = output_hwc->output;
E_Hwc_Window *hwc_window;
E_Hwc_Window_State state;
+ tdm_error terror;
+ tdm_output *toutput = output->toutput;
+ tdm_hwc_window **changed_hwc_window = NULL;
+ tdm_hwc_window_composition *composition_types = NULL;
+ Eina_Bool accept_changes = EINA_TRUE;
+ int i;
- /* make hwc extension choose which clients will own hw overlays */
- tdm_err = tdm_output_hwc_validate(toutput, &num_changes);
- if (tdm_err != TDM_ERROR_NONE)
+ changed_hwc_window = E_NEW(tdm_hwc_window *, num_changes);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(changed_hwc_window, EINA_FALSE);
+
+ composition_types = E_NEW(tdm_hwc_window_composition, num_changes);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(composition_types, EINA_FALSE);
+
+ terror = tdm_output_hwc_get_changed_composition_types(toutput,
+ &num_changes, changed_hwc_window,
+ composition_types);
+ if (terror != TDM_ERROR_NONE)
{
- ERR("hwc-opt: failed to validate the output(%p)", toutput);
- return EINA_FALSE;
+ ERR("HWC-WINS: failed to get changed composition types");
+ goto fail;
}
- if (num_changes)
+ for (i = 0; i < num_changes; ++i)
{
- int i;
- tdm_hwc_window **changed_hwc_window = NULL;
- tdm_hwc_window_composition *composition_types = NULL;
-
- changed_hwc_window = E_NEW(tdm_hwc_window *, num_changes);
- EINA_SAFETY_ON_NULL_RETURN_VAL(changed_hwc_window, EINA_FALSE);
-
- composition_types = E_NEW(tdm_hwc_window_composition, num_changes);
- EINA_SAFETY_ON_NULL_RETURN_VAL(composition_types, EINA_FALSE);
-
- tdm_err = tdm_output_hwc_get_changed_composition_types(toutput,
- &num_changes, changed_hwc_window,
- composition_types);
- if (tdm_err != TDM_ERROR_NONE)
+ hwc_window = _e_output_hwc_windows_window_find_by_twin(output_hwc, changed_hwc_window[i]);
+ if (!hwc_window)
{
- ERR("hwc-opt: failed to get changed composition types");
- free(changed_hwc_window);
- free(composition_types);
- return EINA_FALSE;
+ ERR("HWC-WINS: cannot find the E_Hwc_Window by hwc hwc_window");
+ goto fail;
}
- for (i = 0; i < num_changes; ++i)
+ /* accept_changes failed at DEVICE to CLIENT transition */
+ if (hwc_window->prev_state == E_HWC_WINDOW_STATE_DEVICE &&
+ composition_types[i] == TDM_COMPOSITION_CLIENT)
{
- hwc_window = _e_output_hwc_windows_window_find_by_twin(output_hwc, changed_hwc_window[i]);
- if (!hwc_window)
- {
- ERR("hwc-opt: cannot find the E_Hwc_Window by hwc hwc_window");
- free(changed_hwc_window);
- free(composition_types);
- return EINA_FALSE;
- }
- state = _e_output_hwc_windows_window_state_get(composition_types[i]);
- if (!e_hwc_window_state_set(hwc_window, state))
- {
- ERR("e_hwc_window_state_set failed.");
- return EINA_FALSE;
- }
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
+ accept_changes = EINA_FALSE;
}
- free(changed_hwc_window);
- free(composition_types);
-
- tdm_err = tdm_output_hwc_accept_changes(toutput);
- if (tdm_err != TDM_ERROR_NONE)
+ /* update the state with the changed compsition */
+ state = _e_output_hwc_windows_window_state_get(composition_types[i]);
+ if (!e_hwc_window_state_set(hwc_window, state))
{
- ERR("hwc-opt: failed to accept changes required by the hwc extension");
- return EINA_FALSE;
+ ERR("e_hwc_window_state_set failed.");
+ goto fail;
}
+ }
+
+ /* re-validate when there is a DEVICE_TO_CLIENT transition */
+ if (!accept_changes) goto fail;
+
+ /* accept changes */
+ terror = tdm_output_hwc_accept_changes(toutput);
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("HWC-WINS: failed to accept changes required by the hwc extension");
+ goto fail;
+ }
+
+ free(changed_hwc_window);
+ free(composition_types);
+
#if DBG_EVALUATE
- ELOGF("HWC-WINS", " Modified after HWC Validation:", NULL, NULL);
- _e_output_hwc_windows_status_print(output_hwc);
+ ELOGF("HWC-WINS", " Modified after HWC Validation:", NULL, NULL);
+ _e_output_hwc_windows_status_print(output_hwc);
#endif
+
+ return EINA_TRUE;
+
+fail:
+ if (changed_hwc_window) free(changed_hwc_window);
+ if (composition_types) free(composition_types);
+
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_output_hwc_windows_validate(E_Output_Hwc *output_hwc, uint32_t *num_changes)
+{
+ E_Output *output = output_hwc->output;
+ tdm_error terror;
+ tdm_output *toutput = output->toutput;
+
+ /* make hwc extension choose which clients will own hw overlays */
+ terror = tdm_output_hwc_validate(toutput, num_changes);
+ if (terror != TDM_ERROR_NONE)
+ {
+ ERR("HWC-WINS: failed to validate the output(%p)", toutput);
+ return EINA_FALSE;
}
return EINA_TRUE;
}
static Eina_List *
-_e_output_hwc_windows_vis_ec_list_get(E_Output_Hwc *output_hwc)
+_e_output_hwc_windows_visible_windows_list_get(E_Output_Hwc *output_hwc)
{
- Eina_List *ec_list = NULL;
+ Eina_List *windows_list = NULL;
+ Eina_List *l;
+ E_Hwc_Window *hwc_window;
E_Client *ec;
Evas_Object *o;
int scr_w, scr_h;
+ int zpos = 0;
for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
{
ec = evas_object_data_get(o, "E_Client");
if (!ec) continue;
+ if (!ec->hwc_window) continue;
if (e_object_is_del(E_OBJECT(ec))) continue;
+ hwc_window = ec->hwc_window;
+
// check clients to skip composite
if (e_client_util_ignored_get(ec) || (!evas_object_visible_get(ec->frame)))
- continue;
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
// check geometry if located out of screen such as quick panel
ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &scr_w, &scr_h);
- if (!E_INTERSECTS(0, 0, scr_w, scr_h,
- ec->client.x, ec->client.y, ec->client.w, ec->client.h))
- continue;
+ if (!E_INTERSECTS(0, 0, scr_w, scr_h, ec->client.x, ec->client.y, ec->client.w, ec->client.h))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ e_hwc_window_zpos_set(hwc_window, ZPOS_NONE);
+ continue;
+ }
if (evas_object_data_get(ec->frame, "comp_skip"))
- continue;
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
/* skip all small clients except the video clients */
- if ((ec->w == 1 || ec->h == 1) && !e_hwc_window_is_video(ec->hwc_window))
- continue;
+ if ((ec->w == 1 || ec->h == 1) && !e_hwc_window_is_video(hwc_window))
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ continue;
+ }
- ec_list = eina_list_append(ec_list, ec);
+ windows_list = eina_list_append(windows_list, hwc_window);
}
- output_hwc->num_vis_ec = eina_list_count(ec_list);
+ /* assign zpos */
+ EINA_LIST_REVERSE_FOREACH(windows_list, l, hwc_window)
+ e_hwc_window_zpos_set(hwc_window, zpos++);
+
+ output_hwc->num_visible_windows = eina_list_count(windows_list);
#if DBG_EVALUATE
- ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, eina_list_count(ec_list));
+ ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, output_hwc->num_visible_windows);
#endif
- return ec_list;
+ return windows_list;
}
static Eina_Bool
-_e_output_hwc_windows_full_gl_composite_check(E_Output_Hwc *output_hwc, Eina_List *vis_cl_list)
+_e_output_hwc_windows_full_gl_composite_check(E_Output_Hwc *output_hwc, Eina_List *visible_windows_list)
{
Eina_List *l;
E_Client *ec;
goto full_gl_composite;
}
- EINA_LIST_FOREACH(vis_cl_list, l, ec)
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
{
+ ec = hwc_window->ec;
#if 0 // TODO: check this condition.....
// if there is a ec which is lower than quickpanel and quickpanel is opened.
if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
return EINA_FALSE;
full_gl_composite:
- EINA_LIST_FOREACH(vis_cl_list, l, ec)
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
{
- hwc_window = ec->hwc_window;
-
/* The video window is not composited by gl compositor */
- if (e_hwc_window_is_video(hwc_window))
- {
- hwc_window->hwc_acceptable = EINA_TRUE;
- continue;
- }
+ if (e_hwc_window_is_video(hwc_window)) continue;
+
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
- hwc_window->hwc_acceptable = EINA_FALSE;
ELOGF("HWC-WINS", " ehw:%p -- {%25s} is NOT hwc_acceptable.",
- ec->pixmap, ec, hwc_window, ec->icccm.title);
+ hwc_window->ec->pixmap, hwc_window->ec, hwc_window, hwc_window->ec->icccm.title);
}
return EINA_TRUE;
}
* for optimized hwc the returned list contains ALL clients
*/
static void
-_e_output_hwc_windows_hwc_acceptable_check(Eina_List *vis_cl_list)
+_e_output_hwc_windows_hwc_acceptable_check(Eina_List *visible_windows_list)
{
Eina_List *l;
- E_Client *ec;
E_Hwc_Window *hwc_window = NULL;
- EINA_LIST_FOREACH(vis_cl_list, l, ec)
+ EINA_LIST_FOREACH(visible_windows_list, l, hwc_window)
{
- hwc_window = ec->hwc_window;
- hwc_window->hwc_acceptable = EINA_TRUE;
-
/* The video window is not composited by gl compositor */
if (e_hwc_window_is_video(hwc_window)) continue;
- // check clients not able to use hwc
- // if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
- if (!_e_output_hwc_windows_ec_check(ec))
- {
- hwc_window->hwc_acceptable = EINA_FALSE;
- continue;
- }
- }
-}
-
-static Eina_Bool
-_e_output_hwc_windows_enable_target_window(E_Output_Hwc *output_hwc)
-{
- E_Hwc_Window *hwc_window;
-
- if (!output_hwc->target_hwc_window)
- {
- ERR("we don't have the target hwc_window");
- return EINA_FALSE;
+ // check clients are able to use hwc
+ if (_e_output_hwc_windows_ec_check(hwc_window->ec))
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
+ else
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_DEVICE);
}
-
- hwc_window = (E_Hwc_Window*)output_hwc->target_hwc_window;
- e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_DEVICE);
-
- return EINA_TRUE;
}
EINTERN Eina_Bool
;;;
}
-EINTERN Eina_Bool
-e_output_hwc_windows_evaluate(E_Output_Hwc *output_hwc)
+static Eina_Bool
+_e_output_hwc_windows_uncomplete_transition_check(E_Output_Hwc *output_hwc)
{
- Eina_Bool ret = EINA_FALSE;
- Eina_Bool result;
- Eina_List *vis_clist = NULL;
- E_Output_Hwc_Mode hwc_mode = E_OUTPUT_HWC_MODE_NONE;
+ const Eina_List *l;
+ E_Hwc_Window *hwc_window;
+ E_Hwc_Window_Target *target_hwc_window = output_hwc->target_hwc_window;
+ Eina_Bool ret = EINA_TRUE;
- ELOGF("HWC-WINS", "====================== Output HWC Apply (evaluate) ======================", NULL, NULL);
+ EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
+ {
+ if (e_hwc_window_is_target(hwc_window)) continue;
+ if (e_hwc_window_is_video(hwc_window)) continue;
- /* exclude all hwc_windows from being considered by hwc */
- result = _e_output_hwc_windows_all_windows_init(output_hwc);
- EINA_SAFETY_ON_FALSE_GOTO(result, done);
+ /* deal with the uncompleted_transitions */
+ switch (hwc_window->uncompleted_transition)
+ {
+ case E_HWC_WINDOW_TRANSITION_DEVICE_TO_NONE:
+ if (e_hwc_window_target_enabled(target_hwc_window))
+ {
+ // TODO: to be fixed....
+ if (!e_hwc_window_is_on_target_window(hwc_window))
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ else
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ret = EINA_FALSE;
+ }
+ }
+ else
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ break;
+ case E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT:
+ if (e_hwc_window_target_enabled(target_hwc_window))
+ {
+ if (e_hwc_window_is_on_target_window(hwc_window))
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ else
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT);
+ ret = EINA_FALSE;
+ }
+ }
+ else
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ break;
+ case E_HWC_WINDOW_TRANSITION_CLIENT_TO_DEVICE:
+ if (e_hwc_window_target_enabled(target_hwc_window))
+ {
+ if (!e_hwc_window_is_on_target_window(hwc_window))
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ else
+ {
+ e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE);
+ ret = EINA_FALSE;
+ }
+ }
+ else
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ break;
+ default:
+ break;
+ }
+ }
- /* get the visible ecs */
- vis_clist = _e_output_hwc_windows_vis_ec_list_get(output_hwc);
+ return ret;
+}
- /* in order to turn on target_window and smooth transition is not used the
- * all hwc_windows is excluded
- */
- if (!output_hwc->output->zoom_set)
+static void
+_e_output_hwc_windows_transition_update(E_Output_Hwc *output_hwc)
+{
+ E_Hwc_Window *hwc_window;
+ const Eina_List *l;
+
+ EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
{
- /* check the gles composite with all hwc_windows. */
- if (!_e_output_hwc_windows_full_gl_composite_check(output_hwc, vis_clist))
+ if (e_hwc_window_is_target(hwc_window)) continue;
+ if (e_hwc_window_is_video(hwc_window)) continue;
+
+ switch (hwc_window->prev_state)
{
- /* by demand of hwc_window manager to prevent some e_clients to be shown by hw directly */
- _e_output_hwc_windows_hwc_acceptable_check(vis_clist);
+ case E_HWC_WINDOW_STATE_NONE:
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_NONE)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_NONE;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_CLIENT)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_CLIENT;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_DEVICE)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_DEVICE;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_CURSOR)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_NONE_TO_CURSOR;
+ break;
+ case E_HWC_WINDOW_STATE_CLIENT:
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_NONE)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_NONE;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_CLIENT)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_CLIENT;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_DEVICE)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_DEVICE;
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_CURSOR)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_CLIENT_TO_CURSOR;
+ break;
+ case E_HWC_WINDOW_STATE_DEVICE:
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_NONE)
+ {
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_NONE;
+
+ /* need to complete_transition if target_window is enabled */
+ if (e_hwc_window_target_enabled(output_hwc->target_hwc_window))
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_NONE;
+ }
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_CLIENT)
+ {
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
+
+ /* need to complete_transition if target_window is enabled */
+ if (e_hwc_window_target_enabled(output_hwc->target_hwc_window))
+ hwc_window->uncompleted_transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_CLIENT;
+
+ }
+ if (e_hwc_window_state_get(hwc_window) == E_HWC_WINDOW_STATE_DEVICE)
+ hwc_window->transition = E_HWC_WINDOW_TRANSITION_DEVICE_TO_DEVICE;
+ break;
+ default:
+ ERR("Unknown Prev_State: failed to update the states.");
+ return;
}
+ }
+}
+
+#if 0
+static void
+_e_output_hwc_windows_zpos_assign(E_Output_Hwc *output_hwc)
+{
+ E_Hwc_Window *hwc_window;
+ const Eina_List *l;
+ int zpos = 0;
+
+ EINA_LIST_FOREACH(e_output_hwc_windows_get(output_hwc), l, hwc_window)
+ {
+ if (e_hwc_window_is_target(hwc_window)) continue;
- /* update ehw hwc_windows information with the previous evaluation */
- _e_output_hwc_windows_update(output_hwc, vis_clist);
+ if (hwc_window->state == E_HWC_WINDOW_STATE_NONE)
+ {
+ if (hwc_window->zpos != -999) hwc_window->zpos = -999;
+ continue;
+ }
+
+ hwc_window->zpos = zpos++;
}
- else
- _e_output_hwc_windows_update(output_hwc, NULL);
+}
+#endif
- /* validate the updated hwc_windows by asking tdm_hwc_output */
- result = _e_output_hwc_windows_validate(output_hwc);
- EINA_SAFETY_ON_FALSE_GOTO(result, done);
+static Eina_Bool
+_e_output_hwc_windows_commit_evaulate(E_Output_Hwc *output_hwc)
+{
+ Eina_Bool ret = EINA_FALSE;
+ Eina_Bool can_validate;
+ uint32_t num_changes;
- if (output_hwc->output->zoom_set && eina_list_count(vis_clist) == 1)
+ /* evaluate the transition */
+ can_validate = _e_output_hwc_windows_uncomplete_transition_check(output_hwc);
+ if (can_validate)
{
- E_Client *ec = eina_list_nth(vis_clist, 0);
- /* The vis_hwc_window's buffer will be used as src for pp. In this case
- * vis_hwc_window has to be withdrawn from the gl compositing */
- if (ec && ec->hwc_window)
+ //_e_output_hwc_windows_zpos_assign(output_hwc);
+
+ if (! _e_output_hwc_windows_update(output_hwc))
{
- int w, h;
+ ERR("HWC-WINS: _e_output_hwc_windows_update failed.");
+ ret = EINA_FALSE;
+ goto done;
+ }
- e_output_size_get(output_hwc->output, &w, &h);
- if (ec->comp_data->buffer_ref.buffer &&
- ec->comp_data->buffer_ref.buffer->w == w &&
- ec->comp_data->buffer_ref.buffer->h == h)
- {
- ec->hwc_window->state = E_HWC_WINDOW_STATE_DEVICE;
- ec->hwc_window->type = TDM_COMPOSITION_DEVICE;
- }
+ /* validate the updated hwc_windows by asking tdm_hwc_output */
+ if (!_e_output_hwc_windows_validate(output_hwc, &num_changes))
+ {
+ ERR("HWC-WINS: _e_output_hwc_windows_validate failed.");
+ ret = EINA_FALSE;
+ goto done;
+ }
+
+ if (num_changes > 0)
+ {
+ if (_e_output_hwc_windows_accept(output_hwc, num_changes))
+ ret = EINA_TRUE;
+ else
+ ret = EINA_FALSE;
}
+ else
+ ret = EINA_TRUE;
}
- /* TODO: decide the E_OUTPUT_HWC_MODE */
- hwc_mode = _e_output_hwc_windows_need_target_hwc_window(output_hwc) ?
- E_OUTPUT_HWC_MODE_HYBRID : E_OUTPUT_HWC_MODE_FULL;
+done:
+ return ret;
+}
- if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID || hwc_mode == E_OUTPUT_HWC_MODE_NONE)
+static void
+_e_output_hwc_windows_states_evaluate(E_Output_Hwc *output_hwc)
+{
+ Eina_List *visible_windows_list = NULL;
+
+ /* get the visible ecs */
+ visible_windows_list = _e_output_hwc_windows_visible_windows_list_get(output_hwc);
+
+ /* check the gles composite with all hwc_windows. */
+ if (!_e_output_hwc_windows_full_gl_composite_check(output_hwc, visible_windows_list))
{
-#if DBG_EVALUATE
- ELOGF("HWC-WINS", " HWC_MODE is HYBRID composition.", NULL, NULL);
-#endif
- result = _e_output_hwc_windows_enable_target_window(output_hwc);
- EINA_SAFETY_ON_FALSE_GOTO(result, done);
+ /* by demand of hwc_window manager to prevent some e_clients to be shown by hw directly */
+ _e_output_hwc_windows_hwc_acceptable_check(visible_windows_list);
}
-#if DBG_EVALUATE
+
+ if (visible_windows_list)
+ eina_list_free(visible_windows_list);
+}
+
+/* evaluate the hwc_windows and decide the output_hwc->need_commit */
+EINTERN Eina_Bool
+e_output_hwc_windows_evaluate(E_Output_Hwc *output_hwc)
+{
+ Eina_Bool ret = EINA_FALSE;
+ E_Output_Hwc_Mode hwc_mode = E_OUTPUT_HWC_MODE_NONE;
+ E_Hwc_Window *target_window = (E_Hwc_Window *)output_hwc->target_hwc_window;
+
+ ELOGF("HWC-WINS", "====================== Output HWC Apply (evaluate) ======================", NULL, NULL);
+
+ /* evaulate the current states */
+ _e_output_hwc_windows_states_evaluate(output_hwc);
+
+ /* update transition */
+ _e_output_hwc_windows_transition_update(output_hwc);
+
+ /* evaulate the need_commit */
+ if (_e_output_hwc_windows_commit_evaulate(output_hwc))
+ output_hwc->need_commit = EINA_TRUE;
else
- ELOGF("HWC-WINS", " HWC_MODE is FULL HW composition.", NULL, NULL);
-#endif
+ output_hwc->need_commit = EINA_FALSE;
+
+ /* update the activate/decativate state */
+ _e_output_hwc_windows_activation_states_update(output_hwc);
+
+ /* decide the E_OUTPUT_HWC_MODE */
+ hwc_mode = _e_output_hwc_windows_hwc_mode_get(output_hwc);
+
+ if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID || hwc_mode == E_OUTPUT_HWC_MODE_NONE)
+ e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_DEVICE);
+ else
+ e_hwc_window_state_set(target_window, E_HWC_WINDOW_STATE_NONE);
if (output_hwc->hwc_mode != hwc_mode)
{
- if (hwc_mode == E_OUTPUT_HWC_MODE_FULL)
- ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
- else if(hwc_mode == E_OUTPUT_HWC_MODE_HYBRID)
+ if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID || hwc_mode == E_OUTPUT_HWC_MODE_NONE)
ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
+ else
+ {
+ ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
+ e_hwc_window_target_buffer_fetch(output_hwc->target_hwc_window); // release queue....
+ }
output_hwc->hwc_mode = hwc_mode;
}
- /* update the activate/decativate state */
- _e_output_hwc_windows_activation_states_update(output_hwc);
+#if DBG_EVALUATE
+ if (hwc_mode == E_OUTPUT_HWC_MODE_NONE)
+ ELOGF("HWC-WINS", " HWC_MODE is NONE composition.", NULL, NULL);
+ else if (hwc_mode == E_OUTPUT_HWC_MODE_HYBRID)
+ ELOGF("HWC-WINS", " HWC_MODE is HYBRID composition.", NULL, NULL);
+ else
+ ELOGF("HWC-WINS", " HWC_MODE is FULL HW composition.", NULL, NULL);
+#endif
- ret = EINA_TRUE;
+ if (e_hwc_window_target_enabled(output_hwc->target_hwc_window))
+ {
+ if (!e_hwc_window_target_buffer_fetch(output_hwc->target_hwc_window)) // try aquire
+ {
+ output_hwc->need_commit = EINA_FALSE;
+ }
+ }
-done:
- if (vis_clist)
- eina_list_free(vis_clist);
+ ret = EINA_TRUE;
return ret;
}
return EINA_TRUE;
}
+static void
+_e_output_hwc_windows_prev_states_update(E_Output_Hwc *output_hwc)
+{
+ E_Hwc_Window *hwc_window = NULL;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
+ e_hwc_window_prev_state_update(hwc_window);
+}
+
EINTERN Eina_Bool
e_output_hwc_windows_commit(E_Output_Hwc *output_hwc)
{
E_Hwc_Window *hwc_window = NULL;
Eina_List *l;
- int need_tdm_commit = 0;
E_Output *output = NULL;
tdm_error error = TDM_ERROR_NONE;
return EINA_TRUE;
}
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- {
- /* fetch the surface to the window */
- if (!e_hwc_window_fetch(hwc_window)) continue;
-
- if (output->dpms == E_OUTPUT_DPMS_OFF)
- _e_output_hwc_windows_offscreen_commit(output, hwc_window);
- }
-
if (output->dpms == E_OUTPUT_DPMS_OFF) return EINA_TRUE;
- if (!_e_output_hwc_windows_can_commit(output))
+ if (output_hwc->need_commit)
{
- ELOGF("HWC-WINS", " Prevent by _e_output_hwc_windows_can_commit.", NULL, NULL);
- return EINA_FALSE;
- }
+ EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
+ {
+ _e_output_hwc_windows_prepare_commit(output, hwc_window);
+ }
- EINA_LIST_FOREACH(output_hwc->hwc_windows, l, hwc_window)
- {
- if (_e_output_hwc_windows_prepare_commit(output, hwc_window))
- need_tdm_commit = 1;
- }
+ if (output->zoom_set)
+ {
+ e_output_zoom_rotating_check(output);
+ ELOGF("HWC-WINS", "###### PP Commit", NULL, NULL);
+ if (!_e_output_hwc_windows_pp_commit(output_hwc))
+ {
+ ERR("_e_output_hwc_windows_pp_commit failed.");
+ return EINA_FALSE;
+ }
+ }
+ else
+ {
+ ELOGF("HWC-WINS", "!!!!!!!! Output Commit !!!!!!!!", NULL, NULL);
+ ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, output_hwc->num_visible_windows);
+ _e_output_hwc_windows_status_print(output_hwc);
+
+ error = tdm_output_commit(output->toutput, 0, _e_output_hwc_windows_commit_handler, output_hwc);
+ if (error != TDM_ERROR_NONE)
+ {
+ _e_output_hwc_windows_commit_handler(output->toutput, 0, 0, 0, output_hwc);
+ ERR("tdm_output_commit failed.");
- if (need_tdm_commit)
- {
- if (output->zoom_set)
- {
- e_output_zoom_rotating_check(output);
- ELOGF("HWC-WINS", "###### PP Commit", NULL, NULL);
- if (!_e_output_hwc_windows_pp_commit(output_hwc))
- {
- ERR("_e_output_hwc_windows_pp_commit failed.");
return EINA_FALSE;
- }
- }
- else
- {
- ELOGF("HWC-WINS", "!!!!!!!! Output Commit !!!!!!!!", NULL, NULL);
- ELOGF("HWC-WINS", " The number of visible clients:%d.", NULL, NULL, output_hwc->num_vis_ec);
- _e_output_hwc_windows_status_print(output_hwc);
-
- error = tdm_output_commit(output->toutput, 0, _e_output_hwc_windows_commit_handler, output_hwc);
- if (error != TDM_ERROR_NONE)
- {
- _e_output_hwc_windows_commit_handler(output->toutput, 0, 0, 0, output_hwc);
- ERR("tdm_output_commit failed.");
-
- return EINA_FALSE;
- }
-
- output_hwc->wait_commit = EINA_TRUE;
- }
+ }
+
+ output_hwc->wait_commit = EINA_TRUE;
+ }
+
+ /* update the previous states. */
+ _e_output_hwc_windows_prev_states_update(output_hwc);
}
return EINA_TRUE;