{
E_Presentation_Time_Container presentation_container;
Eina_Bool skip;
+ E_Egl_Sync *release_fence;
};
static Eina_Bool ehws_trace = EINA_FALSE;
if (tdm_set)
tdm_hwc_set_client_target_buffer(thwc, hwc_window->buffer.tsurface, fb_damage);
+ if ((target_hwc_window->end_render_sync) && (e_hwc_windows_fence_enabled_get(hwc)))
+ {
+ int fence = e_egl_sync_fence_fd_dup(target_hwc_window->end_render_sync);
+ if (fence >= 0)
+ {
+ tdm_hwc_set_client_target_acquire_fence(thwc, fence);
+ close(fence);
+ }
+ }
+
if (ehws_trace)
{
rendered_windows = _e_hwc_windows_target_window_rendered_windows_get(hwc_window->buffer.tsurface);
CLEAR(fb_damage);
tdm_hwc_set_client_target_buffer(thwc, NULL, fb_damage);
+
+ if (e_hwc_windows_fence_enabled_get(hwc))
+ tdm_hwc_set_client_target_acquire_fence(thwc, -1);
}
return EINA_TRUE;
return EINA_TRUE;
}
+static void
+_e_hwc_windows_target_window_render_flush_pre_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ E_Hwc_Window_Target *target_hwc_window = (E_Hwc_Window_Target *)data;
+ E_Hwc_Window *hwc_window;
+ E_Hwc_Windows_Buffer_Comp_Info *buffer_comp_info;
+ E_Hwc *hwc;
+ Eina_List *l;
+
+ hwc = target_hwc_window->hwc;
+ if (!e_hwc_windows_fence_enabled_get(hwc)) return;
+
+ if (target_hwc_window->dequeued_tsurface)
+ {
+ buffer_comp_info = _e_hwc_windows_buffer_comp_info_get(target_hwc_window->dequeued_tsurface);
+ if (buffer_comp_info && buffer_comp_info->release_fence)
+ e_egl_sync_wait(buffer_comp_info->release_fence);
+ }
+
+ if (target_hwc_window->end_render_sync)
+ {
+ e_egl_sync_destroy(target_hwc_window->end_render_sync);
+ target_hwc_window->end_render_sync = NULL;
+ }
+
+ target_hwc_window->end_render_sync = e_egl_sync_fence_create();
+ if (!target_hwc_window->end_render_sync)
+ EHWSERR("Failed to create E_Egl_Sync", hwc);
+
+ EINA_LIST_FOREACH(hwc->visible_windows, l, hwc_window)
+ {
+ if (!hwc_window->is_deleted) continue;
+ if (!hwc_window->ec) continue;
+ if (!hwc_window->ec->explicit_sync_surface) continue;
+ if (e_hwc_window_accepted_state_get(hwc_window) != E_HWC_WINDOW_STATE_CLIENT)
+ continue;
+
+ e_explicit_sync_surface_sync(hwc_window->ec->explicit_sync_surface);
+ }
+}
+
static void
_e_hwc_windows_target_window_render_flush_post_cb(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eina_List *rendered_windows = NULL;
Eina_List *visible_windows = NULL;
Eina_List *l;
+ Eina_Bool fence_enabled;
EHWSTRACE("{%s} gets render_flush_post noti.", NULL, target_hwc_window->hwc, "@TARGET WINDOW@");
if (!buffer_comp_info)
EHWSERR("fail to get buffer_comp_info tsurface:%p", target_hwc_window->hwc, target_hwc_window->dequeued_tsurface);
+ fence_enabled = e_hwc_windows_fence_enabled_get(target_hwc_window->hwc);
+
/* all ecs have been composited so we can attach a list of composited e_hwc_windows to the surface
* which contains their ecs composited */
rendered_windows = eina_list_clone(target_hwc_window->rendered_windows);
*/
if (!buffer->resource) continue;
+ if ((fence_enabled) && (buffer->buffer_release) && (target_hwc_window->end_render_sync))
+ {
+ int fence_fd = -1;
+
+ fence_fd = e_egl_sync_fence_fd_dup(target_hwc_window->end_render_sync);
+ if (fence_fd != -1)
+ {
+ if (!e_explicit_sync_buffer_release_fence_fd_set(buffer->buffer_release, fence_fd))
+ close(fence_fd);
+
+ continue;
+ }
+ else
+ EHWSERR("failed to dup native fence fd", target_hwc_window->hwc);
+ }
+
buffer_ref = E_NEW(E_Comp_Wl_Buffer_Ref, 1);
if (!buffer_ref) continue;
EVAS_CALLBACK_RENDER_FLUSH_POST,
_e_hwc_windows_target_window_render_flush_post_cb);
+ evas_event_callback_del(target_hwc_window->evas,
+ EVAS_CALLBACK_RENDER_FLUSH_PRE,
+ _e_hwc_windows_target_window_render_flush_pre_cb);
+
ecore_main_fd_handler_del(target_hwc_window->event_hdlr);
close(target_hwc_window->event_fd);
_e_hwc_windows_target_window_render_flush_post_cb,
target_hwc_window);
+ evas_event_callback_add(evas,
+ EVAS_CALLBACK_RENDER_FLUSH_PRE,
+ _e_hwc_windows_target_window_render_flush_pre_cb,
+ target_hwc_window);
+
return target_hwc_window;
fail:
return EINA_TRUE;
}
+static void
+_e_hwc_windows_release_fence_fd_update(E_Hwc *hwc)
+{
+ E_Hwc_Window *hwc_window;
+ E_Hwc_Window_Target *target_hwc_window;
+ E_Hwc_Window_Queue_Buffer *queue_buffer;
+ E_Hwc_Windows_Buffer_Comp_Info *comp_info;
+ tdm_hwc_window **thwc_wins = NULL;
+ int *release_fences = NULL;
+ uint32_t num_thwc_wins = 0;
+ tdm_error ret = TDM_ERROR_NONE;
+ int i;
+
+ target_hwc_window = hwc->target_hwc_window;
+ EINA_SAFETY_ON_NULL_RETURN(target_hwc_window);
+
+ hwc_window = (E_Hwc_Window *)target_hwc_window;
+ if ((hwc_window->display.buffer.tsurface) && (hwc_window->display.buffer.queue))
+ {
+ comp_info = _e_hwc_windows_buffer_comp_info_get(hwc_window->display.buffer.tsurface);
+ EINA_SAFETY_ON_NULL_RETURN(comp_info);
+
+ if (comp_info->release_fence)
+ e_egl_sync_destroy(comp_info->release_fence);
+
+ comp_info->release_fence = e_egl_sync_fence_create_with_fd(hwc->commit_fence_fd);
+
+ queue_buffer = e_hwc_window_queue_buffer_find(hwc_window->display.buffer.queue,
+ hwc_window->display.buffer.tsurface);
+ if (queue_buffer)
+ e_hwc_window_queue_buffer_release(hwc_window->display.buffer.queue, queue_buffer);
+
+ /* prevent release buffer to queue in commit handler */
+ hwc_window->display.buffer.queue = NULL;
+ }
+
+ ret = tdm_hwc_get_release_fences(hwc->thwc, &num_thwc_wins, NULL, NULL);
+ EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, clean);
+
+ if (!num_thwc_wins) return;
+
+ thwc_wins = E_NEW(tdm_hwc_window *, num_thwc_wins);
+ EINA_SAFETY_ON_NULL_GOTO(thwc_wins, clean);
+
+ release_fences = E_NEW(int, num_thwc_wins);
+ EINA_SAFETY_ON_NULL_GOTO(release_fences, clean);
+
+ ret = tdm_hwc_get_release_fences(hwc->thwc, &num_thwc_wins, thwc_wins, release_fences);
+ EINA_SAFETY_ON_FALSE_GOTO(ret == TDM_ERROR_NONE, clean);
+
+ for (i = 0; i < num_thwc_wins; i++)
+ {
+ hwc_window = _e_hwc_windows_window_find_by_twin(hwc, thwc_wins[i]);
+
+ if ((!hwc_window) ||
+ (!hwc_window->display.buffer_ref.buffer) ||
+ (!hwc_window->display.buffer_ref.buffer->buffer_release))
+ {
+ close(release_fences[i]);
+ continue;
+ }
+
+ if (!e_explicit_sync_buffer_release_fence_fd_set(hwc_window->display.buffer_ref.buffer->buffer_release,
+ release_fences[i]))
+ {
+ close(release_fences[i]);
+ continue;
+ }
+
+ e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref, NULL);
+ }
+
+clean:
+ if (thwc_wins) free(thwc_wins);
+ if (release_fences) free(release_fences);
+}
+
EINTERN Eina_Bool
e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode)
{
E_Output *output = NULL;
tdm_error error = TDM_ERROR_NONE;
+ int commit_fence_fd = -1;
EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
goto fail;
}
- /* send tizen_hwc_commit feedback committed */
- e_comp_wl_tizen_hwc_committed();
+ if (e_hwc_windows_fence_enabled_get(hwc))
+ {
+ error = tdm_hwc_get_commit_fence(hwc->thwc, &commit_fence_fd);
+ if (error == TDM_ERROR_NONE)
+ {
+ if (hwc->commit_fence_fd >= 0)
+ close(hwc->commit_fence_fd);
+
+ hwc->commit_fence_fd = commit_fence_fd;
+
+ _e_hwc_windows_release_fence_fd_update(hwc);
+ }
+ else
+ EHWSERR("tdm_hwc_get_commit_sync_fence_fd failed.", hwc);
+ }
+
+ /* send tizen_hwc_commit feedback committed */
+ e_comp_wl_tizen_hwc_committed();
}
return EINA_TRUE;
e_hwc_window_client_type_override(hwc_window);
}
}
+
+EINTERN Eina_Bool
+e_hwc_windows_fence_enabled_get(E_Hwc *hwc)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
+
+ if (!hwc->tdm_hwc_fence) return EINA_FALSE;
+ if (!e_egl_sync_enabled_get()) return EINA_FALSE;
+ if (!e_explicit_sync_enabled_get()) return EINA_FALSE;
+
+ return EINA_TRUE;
+}