uint64_t value = 1;
int ret;
- if (!surf_source->disp_source->is_vulkan_dpy
- || !surf_source->use_sync_fence) {
+ if (!surf_source->use_sync_fence) {
ret = write(surf_source->event_fd, &value, sizeof(uint64_t));
if (ret == -1) {
TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)",
g_mutex_unlock(&surf_source->surf_mutex);
}
+static gboolean
+_twe_thread_fence_wait_source_dispatch(GSource *source, GSourceFunc cb, gpointer data)
+{
+ twe_fence_wait_source *wait_source = (twe_fence_wait_source *)source;
+ twe_wl_surf_source *surf_source = wait_source->surf_source;
+ tbm_surface_h tbm_surface = wait_source->tbm_surface;
+ GIOCondition cond = g_source_query_unix_fd(source, wait_source->tag);
+
+ if (cond & G_IO_IN) {
+ TPL_LOG_T(BACKEND, "[RENDER DONE] wait_source(%p) tbm_surface(%p) fence_fd(%d)",
+ wait_source, tbm_surface, wait_source->fence_fd);
+ } else {
+ /* When some io errors occur, it is not considered as a critical error.
+ * There may be problems with the screen, but it does not affect the operation. */
+ TPL_WARN("Invalid GIOCondition occured. fd(%d) cond(%d)",
+ wait_source->fence_fd, cond);
+ }
+
+ /* Since this source is going to be removed, acquire_and_commit must be
+ * executed even in a situation other than G_IO_IN.
+ * Nevertheless, there may be room for improvement. */
+ _twe_thread_wl_surface_acquire_and_commit(surf_source);
+ tbm_surface_internal_unref(tbm_surface);
+
+ /* This source is used only once and does not allow reuse.
+ * So finalize will be executed immediately. */
+ g_source_remove_unix_fd(&wait_source->gsource, wait_source->tag);
+ g_source_destroy(&wait_source->gsource);
+ g_source_unref(&wait_source->gsource);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+_twe_thread_fence_wait_source_finalize(GSource *source)
+{
+ twe_fence_wait_source *wait_source = (twe_fence_wait_source *)source;
+
+ TPL_DEBUG("[FINALIZE] wait_source(%p) fence_fd(%d)",
+ wait_source, wait_source->fence_fd);
+
+ close(wait_source->fence_fd);
+
+ wait_source->fence_fd = -1;
+ wait_source->surf_source = NULL;
+ wait_source->tbm_surface = NULL;
+ wait_source->tag = NULL;
+}
+
+static GSourceFuncs _twe_fence_wait_source_funcs = {
+ .prepare = NULL,
+ .check = NULL,
+ .dispatch = _twe_thread_fence_wait_source_dispatch,
+ .finalize = _twe_thread_fence_wait_source_finalize,
+};
+
+tpl_result_t
+_twe_thread_fence_wait_source_attach(twe_wl_surf_source *surf_source,
+ tbm_surface_h tbm_surface, tbm_fd sync_fd)
+{
+ twe_fence_wait_source *wait_source = NULL;
+
+ wait_source = (twe_fence_wait_source *)g_source_new(&_twe_fence_wait_source_funcs,
+ sizeof(twe_fence_wait_source));
+ if (!wait_source) {
+ TPL_ERR("[WAIT_SOURCE] Failed to create GSource");
+ return TPL_ERROR_OUT_OF_MEMORY;
+ }
+
+ tbm_surface_internal_ref(tbm_surface);
+
+ wait_source->fence_fd = sync_fd;
+ wait_source->surf_source = surf_source;
+ wait_source->tbm_surface = tbm_surface;
+
+ wait_source->tag = g_source_add_unix_fd(&wait_source->gsource,
+ wait_source->fence_fd,
+ G_IO_IN);
+ g_source_attach(&wait_source->gsource, g_main_loop_get_context(_twe_ctx->twe_loop));
+
+ return TPL_ERROR_NONE;
+}
+
tpl_result_t
twe_surface_set_sync_fd(twe_surface_h twe_surface,
tbm_surface_h tbm_surface, tbm_fd sync_fd)
{
- TPL_IGNORE(twe_surface);
- TPL_IGNORE(tbm_surface);
- TPL_IGNORE(sync_fd);
+ twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface;
+ tpl_result_t ret = TPL_ERROR_NONE;
- return TPL_ERROR_NONE;
+ if (!surf_source) {
+ TPL_ERR("Invalid parameter. twe_surface(%p)", twe_surface);
+ return TPL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!tbm_surface || !tbm_surface_internal_is_valid(tbm_surface)) {
+ TPL_ERR("Invalid parameter. tbm_surface(%p)", tbm_surface);
+ return TPL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = _twe_thread_fence_wait_source_attach(surf_source, tbm_surface, sync_fd);
+ if (ret != TPL_ERROR_NONE) {
+ TPL_ERR("Failed to attach source with fence_fd(%d) ret(%d)",
+ sync_fd, ret);
+ surf_source->use_sync_fence = TPL_FALSE;
+ return ret;
+ }
+
+ surf_source->use_sync_fence = TPL_TRUE;
+
+ return ret;
}
tbm_fd