e_hwc_window_display_or_commit_buffer_check(E_Hwc_Window *hwc_window, tbm_surface_h tsurface)
{
E_Hwc *hwc;
+ E_Hwc_Window_Commit_Data *commit_data;
+ Eina_List *l;
hwc = hwc_window->hwc;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
if (hwc_window->display.buffer.tsurface == tsurface) return EINA_TRUE;
- if (!hwc_window->commit_data) return EINA_FALSE;
- if (hwc_window->commit_data->buffer.tsurface == tsurface) return EINA_TRUE;
+ EINA_LIST_FOREACH(hwc_window->commit_data_list, l, commit_data)
+ {
+ if (commit_data->buffer.tsurface == tsurface)
+ return EINA_TRUE;
+ }
if (hwc->pp_buffer.tsurface == tsurface)
return EINA_TRUE;
return ret;
}
-EINTERN Eina_Bool
+EINTERN E_Hwc_Window_Commit_Data *
e_hwc_window_commit_data_acquire(E_Hwc_Window *hwc_window)
{
E_Hwc_Window_Commit_Data *commit_data = NULL;
if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CURSOR)
{
- if (!hwc_window->cursor.buffer) return EINA_FALSE;
- if ((hwc_window->cursor.buffer == hwc_window->display.buffer_ref.buffer) &&
- (!memcmp(&hwc_window->info, &hwc_window->display.info, sizeof(tdm_hwc_window_info))))
- return EINA_FALSE;
+ if (!hwc_window->cursor.buffer) return NULL;
+ if ((hwc_window->cursor.buffer == hwc_window->commit.buffer_ref.buffer) &&
+ (!memcmp(&hwc_window->info, &hwc_window->commit.info, sizeof(tdm_hwc_window_info))))
+ return NULL;
commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, EINA_FALSE);
(hwc_window->accepted_state == E_HWC_WINDOW_STATE_VIDEO))
{
if (!hwc_window->buffer.tsurface) return EINA_FALSE;
- if ((hwc_window->buffer.tsurface == hwc_window->display.buffer.tsurface) &&
- (!memcmp(&hwc_window->info, &hwc_window->display.info, sizeof(tdm_hwc_window_info))))
- return EINA_FALSE;
+ if ((hwc_window->buffer.tsurface == hwc_window->commit.buffer.tsurface) &&
+ (!memcmp(&hwc_window->info, &hwc_window->commit.info, sizeof(tdm_hwc_window_info))))
+ return NULL;
commit_data = _e_hwc_window_commit_data_acquire_device(hwc_window);
- EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, NULL);
}
else
{
if (e_hwc_window_is_cursor(hwc_window))
{
- if (!hwc_window->display.buffer_ref.buffer)
- return EINA_FALSE;
+ if (!hwc_window->commit.buffer_ref.buffer)
+ return NULL;
}
else
{
- if (!hwc_window->display.buffer.tsurface)
- return EINA_FALSE;
+ if (!hwc_window->commit.buffer.tsurface)
+ return NULL;
}
commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, NULL);
e_hwc_window_buffer_set(&commit_data->buffer, NULL, NULL);
}
e_hwc_window_state_string_get(hwc_window->state),
hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no"));
+ commit_data->hwc_window = hwc_window;
e_object_ref(E_OBJECT(hwc_window));
- hwc_window->commit_data = commit_data;
+ /* set latest commit_data */
+ memcpy(&hwc_window->commit.info, &commit_data->info, sizeof(tdm_hwc_window_info));
+ e_comp_wl_buffer_reference(&hwc_window->commit.buffer_ref, commit_data->buffer_ref.buffer);
+ e_hwc_window_buffer_set(&hwc_window->commit.buffer, commit_data->buffer.tsurface, commit_data->buffer.queue);
- return EINA_TRUE;
+ hwc_window->commit_data_list = eina_list_append(hwc_window->commit_data_list, commit_data);
+
+ return commit_data;
}
EINTERN void
}
EINTERN Eina_Bool
-e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window)
+e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window, E_Hwc_Window_Commit_Data *commit_data)
{
tbm_surface_h tsurface = NULL;
E_Hwc_Window_Queue *queue = NULL;
E_Hwc_Window_Queue_Buffer *queue_buffer = NULL;
/* we don't have data to release */
- if (!hwc_window->commit_data) return EINA_FALSE;
+ if (!commit_data) return EINA_FALSE;
+
+ if (!eina_list_data_find(hwc_window->commit_data_list, commit_data))
+ {
+ EHWERR("failed to find commit_data:%p in commit_data_list",
+ hwc_window->ec, hwc_window->hwc, hwc_window, commit_data);
+ return EINA_FALSE;
+ }
- tsurface = hwc_window->commit_data->buffer.tsurface;
- queue = hwc_window->commit_data->buffer.queue;
+ tsurface = commit_data->buffer.tsurface;
+ queue = commit_data->buffer.queue;
EHWTRACE("DON ts:%10p ------- {%25s}, state:%s, zpos:%d, deleted:%s (Window)",
hwc_window->ec, hwc_window->hwc, hwc_window,
if (e_hwc_window_is_cursor(hwc_window))
{
- if (hwc_window->commit_data->buffer_ref.buffer)
+ if (commit_data->buffer_ref.buffer)
{
e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref,
- hwc_window->commit_data->buffer_ref.buffer);
- memcpy(&hwc_window->display.info, &hwc_window->commit_data->info, sizeof(tdm_hwc_window_info));
+ commit_data->buffer_ref.buffer);
+ memcpy(&hwc_window->display.info, &commit_data->info, sizeof(tdm_hwc_window_info));
}
else
{
CLEAR(hwc_window->display.info);
}
- e_comp_wl_buffer_reference(&hwc_window->commit_data->buffer_ref, NULL);
- free(hwc_window->commit_data);
- hwc_window->commit_data = NULL;
+ e_comp_wl_buffer_reference(&commit_data->buffer_ref, NULL);
+ hwc_window->commit_data_list = eina_list_remove(hwc_window->commit_data_list, commit_data);
+ free(commit_data);
e_object_unref(E_OBJECT(hwc_window));
return EINA_TRUE;
e_object_unref(E_OBJECT(hwc_window));
}
- if (hwc_window->commit_data->buffer_ref.buffer)
+ if (commit_data->buffer_ref.buffer)
e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref,
- hwc_window->commit_data->buffer_ref.buffer);
+ commit_data->buffer_ref.buffer);
/* update hwc_window display info */
e_hwc_window_buffer_set(&hwc_window->display.buffer, tsurface, queue);
- memcpy(&hwc_window->display.info, &hwc_window->commit_data->info, sizeof(tdm_hwc_window_info));
+ memcpy(&hwc_window->display.info, &commit_data->info, sizeof(tdm_hwc_window_info));
e_object_ref(E_OBJECT(hwc_window));
}
- e_comp_wl_buffer_reference(&hwc_window->commit_data->buffer_ref, NULL);
- e_hwc_window_buffer_set(&hwc_window->commit_data->buffer, NULL, NULL);
+ e_comp_wl_buffer_reference(&commit_data->buffer_ref, NULL);
+ e_hwc_window_buffer_set(&commit_data->buffer, NULL, NULL);
- free(hwc_window->commit_data);
- hwc_window->commit_data = NULL;
+ hwc_window->commit_data_list = eina_list_remove(hwc_window->commit_data_list, commit_data);
+ free(commit_data);
e_object_unref(E_OBJECT(hwc_window));
return EINA_TRUE;
}
EINTERN void
-e_hwc_window_commit_data_buffer_dump(E_Hwc_Window *hwc_window)
+e_hwc_window_commit_data_buffer_dump(E_Hwc_Window *hwc_window, E_Hwc_Window_Commit_Data *commit_data)
{
char fname[64];
EINA_SAFETY_ON_FALSE_RETURN(hwc_window);
-
- if (!hwc_window->commit_data) return;
- if (!hwc_window->commit_data->buffer.tsurface) return;
+ EINA_SAFETY_ON_FALSE_RETURN(commit_data);
if (hwc_window->is_target)
snprintf(fname, sizeof(fname), "hwc_commit_composite_%p",
snprintf(fname, sizeof(fname), "hwc_commit_0x%08zx_%p",
e_client_util_win_get(hwc_window->ec), hwc_window);
- tbm_surface_internal_dump_buffer(hwc_window->commit_data->buffer.tsurface,
+ tbm_surface_internal_dump_buffer(commit_data->buffer.tsurface,
fname);
}
#define EHWS_BUFFER_COMP_INFO_KEY (unsigned long)(&ehws_comp_buffer_info_key)
static Eina_Bool _e_hwc_windows_target_window_queue_set(E_Hwc_Window_Target *target_hwc_window);
-static void _e_hwc_windows_wait_commit_set(E_Hwc *hwc, Eina_Bool set);
+static void _e_hwc_windows_wait_commit_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set);
static E_Comp_Wl_Buffer *
_e_hwc_windows_comp_wl_buffer_get(E_Hwc_Window *hwc_window)
}
static void
-_e_hwc_windows_commit_data_release(E_Hwc *hwc, int sequence,
- unsigned int tv_sec, unsigned int tv_usec)
+_e_hwc_windows_commit_data_release(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data,
+ int sequence, unsigned int tv_sec, unsigned int tv_usec)
{
const Eina_List *l, *ll;
E_Hwc_Window *hwc_window;
- E_Hwc_Window *hwc_window_target;
+ E_Hwc_Window_Commit_Data *commit_data;
- hwc_window_target = (E_Hwc_Window *)hwc->target_hwc_window;
- if (hwc_window_target)
+ if (!eina_list_data_find(hwc->wins_commit_data_list, wins_commit_data))
+ {
+ EHWSERR("failed to find wins_commit_data:%p in wins_commit_data_list",
+ hwc, wins_commit_data);
+ return;
+ }
+
+ if (wins_commit_data->target_commit_data)
{
- e_hwc_window_presentation_time_feedback_present(hwc_window_target,
+ hwc_window = wins_commit_data->target_commit_data->hwc_window;
+ e_hwc_window_presentation_time_feedback_present(hwc_window,
sequence,
tv_sec,
tv_usec);
* _e_hwc_windows_rendered_windows_free.
* we must don't call commit_data_release of target_window in list.
*/
- if (hwc_window_target->commit_data)
- e_hwc_window_commit_data_release(hwc_window_target);
+ e_hwc_window_commit_data_release(hwc_window, wins_commit_data->target_commit_data);
}
- EINA_LIST_FOREACH_SAFE(hwc->hwc_windows, l, ll, hwc_window)
+ /* window_commit_data is freed in e_hwc_window_commit_data_release */
+ EINA_LIST_FOREACH_SAFE(wins_commit_data->commit_data_list, l, ll, commit_data)
{
- if (hwc_window->is_target) continue;
- if (!hwc_window->commit_data) continue;
+ hwc_window = commit_data->hwc_window;
+ if (hwc_window->is_target) continue;
- e_hwc_window_presentation_time_feedback_present(hwc_window, sequence, tv_sec, tv_usec);
+ e_hwc_window_presentation_time_feedback_present(hwc_window, sequence, tv_sec, tv_usec);
- if (e_hwc_window_is_video(hwc_window) && hwc_window->ec)
- e_client_video_commit_data_release(hwc_window->ec, sequence, tv_sec, tv_usec);
+ if (e_hwc_window_is_video(hwc_window) && hwc_window->ec)
+ e_client_video_commit_data_release(hwc_window->ec, sequence, tv_sec, tv_usec);
- if (!e_hwc_window_commit_data_release(hwc_window)) continue;
+ if (!e_hwc_window_commit_data_release(hwc_window, commit_data)) continue;
}
+
+ hwc->wins_commit_data_list = eina_list_remove(hwc->wins_commit_data_list, wins_commit_data);
+ free(wins_commit_data);
}
-static Eina_Bool
+static E_Hwc_Windows_Commit_Data *
_e_hwc_windows_commit_data_acquire(E_Hwc *hwc)
{
const Eina_List *l;
E_Hwc_Window *hwc_window;
- Eina_Bool ret = EINA_FALSE;
+ E_Hwc_Window_Commit_Data *commit_data = NULL;
+ E_Hwc_Windows_Commit_Data *wins_commit_data = NULL;
+
+ wins_commit_data = E_NEW(E_Hwc_Windows_Commit_Data, 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(wins_commit_data, NULL);
+
+ wins_commit_data->hwc = hwc;
/* return TRUE when the number of the commit data is more than one */
EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
{
- if (!e_hwc_window_commit_data_acquire(hwc_window)) continue;
+ commit_data = e_hwc_window_commit_data_acquire(hwc_window);
+ if (!commit_data) continue;
_e_hwc_windows_presentation_feedback_take(hwc_window);
if (ehws_dump_enable)
- e_hwc_window_commit_data_buffer_dump(hwc_window);
+ e_hwc_window_commit_data_buffer_dump(hwc_window, commit_data);
/* send frame event enlightenment doesn't send frame event in nocomp */
if (hwc_window->ec)
e_pixmap_image_clear(hwc_window->ec->pixmap, 1);
- if (!ret) ret = EINA_TRUE;
+ if (hwc_window->is_target)
+ wins_commit_data->target_commit_data = commit_data;
+ else
+ wins_commit_data->commit_data_list = eina_list_append(wins_commit_data->commit_data_list,
+ commit_data);
+ }
+
+ if ((!wins_commit_data->commit_data_list) && (!wins_commit_data->target_commit_data))
+ {
+ free(wins_commit_data);
+ return NULL;
}
- return ret;
+ return wins_commit_data;
}
static void
unsigned int tv_sec, unsigned int tv_usec,
void *user_data)
{
- E_Hwc *hwc = (E_Hwc *)user_data;
+ E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)user_data;
+ E_Hwc *hwc;
+
+ EINA_SAFETY_ON_NULL_RETURN(wins_commit_data);
+
+ hwc = wins_commit_data->hwc;
EINA_SAFETY_ON_NULL_RETURN(hwc);
EHWSTRACE("!!!!!!!! HWC Commit Handler !!!!!!!!", NULL, hwc);
- _e_hwc_windows_commit_data_release(hwc, sequence, tv_sec, tv_usec);
-
/* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame;
* a 'page flip' happened so it's time to allow to make 'fetch and commit' for the e_output */
- _e_hwc_windows_wait_commit_set(hwc, EINA_FALSE);
+ _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_FALSE);
+
+ _e_hwc_windows_commit_data_release(hwc, wins_commit_data, sequence, tv_sec, tv_usec);
}
static void
E_Hwc_Window *hwc_window = NULL;
E_Hwc_Window *hwc_window_target;
Eina_List *l, *ll;
- Eina_Bool ret = EINA_FALSE;
+ E_Hwc_Window_Commit_Data *commit_data = NULL;
hwc_window_target = (E_Hwc_Window *)hwc->target_hwc_window;
if (hwc_window_target)
{
e_hwc_window_presentation_time_feedback_discard(hwc_window_target);
- ret = e_hwc_window_commit_data_acquire(hwc_window_target);
- if (ret)
+ commit_data = e_hwc_window_commit_data_acquire(hwc_window_target);
+ if (commit_data)
{
/* it is possible that other hwc_window is freed in
* _e_hwc_windows_rendered_windows_free.
* we must don't call commit_data_release of target_window in list.
*/
EHWSTRACE("!!!!!!!! HWC OffScreen Commit !!!!!!!!", NULL, hwc);
- e_hwc_window_commit_data_release(hwc_window_target);
+ e_hwc_window_commit_data_release(hwc_window_target, commit_data);
}
}
EINA_LIST_FOREACH_SAFE(hwc->hwc_windows, l, ll, hwc_window)
{
+ commit_data = NULL;
+
if (hwc_window->is_target) continue;
- ret = e_hwc_window_commit_data_acquire(hwc_window);
- if (!ret) continue;
+ commit_data = e_hwc_window_commit_data_acquire(hwc_window);
+ if (!commit_data) continue;
EHWSTRACE("!!!!!!!! HWC OffScreen Commit !!!!!!!!", NULL, hwc);
e_hwc_window_presentation_time_feedback_discard(hwc_window);
- e_hwc_window_commit_data_release(hwc_window);
+ e_hwc_window_commit_data_release(hwc_window, commit_data);
}
}
static Eina_Bool
_e_hwc_windows_commit_handler_timeout(void *data)
{
- E_Hwc *hwc = (E_Hwc *)data;
+ E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)data;
- if (!hwc) return ECORE_CALLBACK_CANCEL;
+ if (!wins_commit_data) return ECORE_CALLBACK_CANCEL;
- EHWSERR("Timeout wait commit", hwc);
+ EHWSERR("Timeout wait commit", wins_commit_data->hwc);
- _e_hwc_windows_commit_handler(hwc->thwc, 0, 0, 0, hwc);
+ wins_commit_data->hwc->wait_commit = EINA_FALSE;
+ wins_commit_data->hwc->commit_handler_timer = NULL;
- hwc->wait_commit = EINA_FALSE;
- hwc->commit_handler_timer = NULL;
+ _e_hwc_windows_commit_handler(wins_commit_data->hwc->thwc, 0, 0, 0, wins_commit_data);
return ECORE_CALLBACK_CANCEL;
}
static void
-_e_hwc_windows_wait_commit_set(E_Hwc *hwc, Eina_Bool set)
+_e_hwc_windows_wait_commit_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set)
{
if (hwc->wait_commit == set) return;
if (set)
hwc->commit_handler_timer = ecore_timer_add(e_comp->commit_handler_timer.interval,
_e_hwc_windows_commit_handler_timeout,
- hwc);
+ wins_commit_data);
}
hwc->wait_commit = set;
E_Output *output = NULL;
tdm_error error = TDM_ERROR_NONE;
int commit_fence_fd = -1;
+ E_Hwc_Windows_Commit_Data *wins_commit_data = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
return EINA_TRUE;
}
- if (!_e_hwc_windows_commit_data_acquire(hwc))
+ if (!(wins_commit_data = _e_hwc_windows_commit_data_acquire(hwc)))
return EINA_TRUE;
EHWSTRACE("!!!!!!!! HWC Commit !!!!!!!!", NULL, hwc);
_e_hwc_windows_update_fps(hwc);
- _e_hwc_windows_wait_commit_set(hwc, EINA_TRUE);
+ _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_TRUE);
+
+ hwc->wins_commit_data_list = eina_list_append(hwc->wins_commit_data_list, wins_commit_data);
- error = tdm_hwc_commit(hwc->thwc, 0, _e_hwc_windows_commit_handler, hwc);
+ error = tdm_hwc_commit(hwc->thwc, 0, _e_hwc_windows_commit_handler, wins_commit_data);
if (error != TDM_ERROR_NONE)
{
- EHWSERR("tdm_hwc_commit failed.", hwc);
- _e_hwc_windows_commit_handler(hwc->thwc, 0, 0, 0, hwc);
- goto fail;
+ EHWSERR("tdm_hwc_commit failed.", hwc);
+ _e_hwc_windows_commit_handler(hwc->thwc, 0, 0, 0, wins_commit_data);
+ goto fail;
}
if (e_hwc_windows_fence_enabled_get(hwc))
fail:
/* send tizen_hwc_commit feedback discarded */
e_comp_wl_tizen_hwc_discarded();
- _e_hwc_windows_wait_commit_set(hwc, EINA_FALSE);
+ _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_FALSE);
return EINA_FALSE;
}