tpl_wayland_egl_thread: Cleaned up the codes for creating/deleting/dipatching tdm_source. 73/135173/5
authorjoonbum.ko <joonbum.ko@samsung.com>
Mon, 12 Jun 2017 08:35:18 +0000 (17:35 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 22 Jun 2017 08:56:11 +0000 (08:56 +0000)
 - It has been modified to control tdm resources only within threads
  to prevent wl_display errors due to thread differences.

 tdm_source (gsource)
 - tdm_source will be created when before loop running start.

 tdm_client_vblank object
 - vblank object of twe_surf_source will be created newly when surface commit.

 If both tdm_source and vblank object failed to create,
 surface commit will fall back to TPL_WAIT_VBLANK disabled mode.

Change-Id: I417b36e7f5e8f5964af267a0ecae83899b5a3c2d
Signed-off-by: joonbum.ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index d9f0884..fb6f859 100644 (file)
@@ -24,6 +24,7 @@ static int buffer_info_key;
 typedef struct _twe_wl_disp_source     twe_wl_disp_source;
 typedef struct _twe_wl_surf_source     twe_wl_surf_source;
 typedef struct _twe_wl_buffer_info     twe_wl_buffer_info;
+typedef struct _twe_tdm_source         twe_tdm_source;
 
 struct _twe_thread_context {
        int ref_cnt;
@@ -31,10 +32,7 @@ struct _twe_thread_context {
        GThread *twe_thread;
        GMainLoop *twe_loop;
 
-       /*TDM*/
-       tdm_client      *tdm_client;
-       int                     tdm_fd;
-       GSource         *tdm_gsource;
+       twe_tdm_source *tdm_source;
 };
 
 struct _twe_thread {
@@ -42,6 +40,13 @@ struct _twe_thread {
        /* TODO : display list */
 };
 
+struct _twe_tdm_source {
+       GSource gsource;
+       gpointer tag;
+       tdm_client *tdm_client;
+       int     tdm_fd;
+};
+
 struct _twe_wl_disp_source {
        GSource gsource;
        GPollFD gfd;
@@ -62,11 +67,11 @@ struct _twe_wl_surf_source {
        struct wl_egl_window *wl_egl_window;
        int rotation;
        tpl_bool_t rotation_capability;
-       tpl_bool_t vblank_done;
        tpl_object_t obj; /* for mutex lock */
        tpl_list_t *committed_buffers;
        tpl_list_t *in_use_buffers;
        tdm_client_vblank *vblank;
+       tpl_bool_t vblank_done;
        struct tizen_surface_shm_flusher *tss_flusher;
        tbm_surface_queue_h tbm_queue;
        twe_wl_disp_source *disp_source;
@@ -85,11 +90,30 @@ struct _twe_wl_buffer_info {
 };
 
 static twe_thread_context *_twe_ctx;
+static twe_tdm_source *
+_twe_thread_tdm_source_create(void);
 
 static gpointer
 _twe_thread_loop(gpointer data)
 {
        twe_thread_context *ctx = data;
+       char *env = getenv("TPL_WAIT_VBLANK");
+
+       if (env == NULL || atoi(env)) {
+               twe_tdm_source *tdm_source = _twe_thread_tdm_source_create();
+
+               if (tdm_source) {
+                       g_source_attach(&tdm_source->gsource,
+                                                       g_main_loop_get_context(ctx->twe_loop));
+                       g_source_unref(&tdm_source->gsource);
+               }
+
+               _twe_ctx->tdm_source = tdm_source;
+
+               if (!ctx->tdm_source) {
+                       TPL_WARN("Failed to create tdm_source. TPL_WAIT_VLANK:DISABLED");
+               }
+       }
 
        g_main_loop_run(ctx->twe_loop);
 
@@ -97,45 +121,115 @@ _twe_thread_loop(gpointer data)
 }
 
 static gboolean
-_twe_thread_tdm_source_dispatch(gpointer user_data)
+_twe_thread_tdm_source_dispatch(GSource *source, GSourceFunc cb, gpointer data)
 {
-       twe_thread_context* context = user_data;
+       twe_tdm_source *tdm_source = (twe_tdm_source *)source;
        tdm_error tdm_err;
+       GIOCondition cond;
 
-       TPL_LOG_T("WL_EGL", "tdm_dispatch| tdm_client(%p)", context->tdm_client);
-       tdm_err = tdm_client_handle_events(context->tdm_client);
-       if (tdm_err) {
-               TPL_ERR("TDM_ERROR:%d context:%p, tdm_cleint:%p\n", tdm_err, context, context->tdm_client);
+       if (!source || g_source_is_destroyed(source)) {
+               TPL_ERR("TDM source(%p) already destroyed.", source);
                return G_SOURCE_REMOVE;
        }
 
+       cond = g_source_query_unix_fd(source, tdm_source->tag);
+
+       if (cond & G_IO_IN) {
+               tdm_err = tdm_client_handle_events(tdm_source->tdm_client);
+               if (tdm_err != TDM_ERROR_NONE) {
+                       TPL_ERR("TDM_ERROR:%d tdm_client:%p\n",
+                                       tdm_err, tdm_source->tdm_client);
+                       return G_SOURCE_REMOVE;
+               }
+       }
+
        return G_SOURCE_CONTINUE;
 }
 
 static void
-_twe_thread_tdm_source_destroy(gpointer user_data)
+_twe_thread_tdm_source_finalize(GSource *source)
 {
-       twe_thread_context* context = user_data;
+       twe_tdm_source *tdm_source = (twe_tdm_source *)source;
+
+       TPL_LOG_T("WL_EGL", "tdm_destroy| tdm_source(%p) tdm_client(%p)",
+                         tdm_source, tdm_source->tdm_client);
 
-       TPL_LOG_T("WL_EGL", "tdm_destroy| tdm_gsource(%p) tdm_client(%p)",
-                         context->tdm_gsource, context->tdm_client);
-       g_source_destroy(context->tdm_gsource);
-       g_source_unref(context->tdm_gsource);
-       context->tdm_gsource = NULL;
+       if (tdm_source->tdm_client) {
+               tdm_client_destroy(tdm_source->tdm_client);
+               tdm_source->tdm_client = NULL;
+       }
 
-       tdm_client_destroy(context->tdm_client);
-       context->tdm_client = NULL;
+       tdm_source->tdm_fd = -1;
+}
+
+static GSourceFuncs _twe_tdm_funcs = {
+       .prepare = NULL,
+       .check = NULL,
+       .dispatch = _twe_thread_tdm_source_dispatch,
+       .finalize = _twe_thread_tdm_source_finalize,
+};
+
+static twe_tdm_source *
+_twe_thread_tdm_source_create(void)
+{
+       twe_tdm_source *tdm_source = NULL;
+       tdm_client *client = NULL;
+       int tdm_fd = -1;
+       tdm_error tdm_err = TDM_ERROR_NONE;
+
+       client = tdm_client_create(&tdm_err);
+       if (!client || tdm_err != TDM_ERROR_NONE) {
+               TPL_ERR("TDM_ERROR:%d Failed to create tdm_client\n", tdm_err);
+               return NULL;
+       }
+
+       tdm_err = tdm_client_get_fd(client, &tdm_fd);
+       if (tdm_fd < 0 || tdm_err != TDM_ERROR_NONE) {
+               TPL_ERR("TDM_ERROR:%d Failed to get tdm_client fd\n", tdm_err);
+               tdm_client_destroy(client);
+               return NULL;
+       }
+
+       tdm_source = (twe_tdm_source *)g_source_new(&_twe_tdm_funcs,
+                                                                                               sizeof(twe_tdm_source));
+       if (!tdm_source) {
+               TPL_ERR("Failed to create tdm_gsource\n");
+               tdm_client_destroy(client);
+               return NULL;
+       }
+
+       tdm_source->tdm_client = client;
+       tdm_source->tdm_fd = tdm_fd;
+       tdm_source->tag = g_source_add_unix_fd(&tdm_source->gsource,
+                                                                                  tdm_fd,
+                                                                                  G_IO_IN);
+
+       TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DEFAULT_ENABLED");
+       TPL_LOG_T("WL_EGL", "tdm_source(%p) tdm_client(%p) tdm_fd(%d)",
+                         tdm_source, client, tdm_fd);
+
+       return tdm_source;
+}
+
+static void
+_twe_thread_tdm_source_destroy(twe_tdm_source *tdm_source)
+{
+       if (!tdm_source || g_source_is_destroyed(&tdm_source->gsource)) {
+               TPL_ERR("TDM source(%p) already destroyed.", tdm_source);
+               return;
+       }
+
+       g_source_destroy(&tdm_source->gsource);
+       g_source_unref(&tdm_source->gsource);
 }
 
 twe_thread*
 twe_thread_create(void)
 {
        twe_thread *thread;
-       char *env = getenv("TPL_WAIT_VBLANK");
 
        if (!_twe_ctx) {
                GMainContext *context;
-               tdm_error tdm_err = TDM_ERROR_NONE;
                _twe_ctx = calloc(1, sizeof(twe_thread_context));
 
                context = g_main_context_new();
@@ -144,42 +238,6 @@ twe_thread_create(void)
 
                _twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop,
                                                                                        _twe_ctx);
-
-               if (env == NULL || atoi(env)) {
-                       /*Connect to tdm server*/
-                       _twe_ctx->tdm_client = tdm_client_create(&tdm_err);
-                       if (!_twe_ctx->tdm_client) {
-                               TPL_ERR("Failed to create tdm_client\n");
-                       }
-
-                       TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DEFAULT_ENABLED");
-
-                       _twe_ctx->tdm_fd = tdm_client_get_fd(_twe_ctx->tdm_client,
-                                                                                                &_twe_ctx->tdm_fd);
-                       if (_twe_ctx->tdm_fd < 0) {
-                               TPL_ERR("Failed to get tdm_client fd\n");
-                               tdm_client_destroy(_twe_ctx->tdm_client);
-                       } else {
-                               _twe_ctx->tdm_gsource = g_unix_fd_source_new(_twe_ctx->tdm_fd,
-                                                                                                                        G_IO_IN);
-                               if (!_twe_ctx->tdm_gsource) {
-                                       TPL_ERR("Failed to create tdm_gsource\n");
-                                       tdm_client_destroy(_twe_ctx->tdm_client);
-                               }
-
-                               g_source_set_callback(_twe_ctx->tdm_gsource,
-                                                                         _twe_thread_tdm_source_dispatch,
-                                                                         NULL,
-                                                                         NULL);
-                               g_source_attach(_twe_ctx->tdm_gsource,
-                                                               g_main_loop_get_context(_twe_ctx->twe_loop));
-                               TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)",
-                                               _twe_ctx->tdm_gsource, _twe_ctx->twe_loop);
-                       }
-               } else {
-                       TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DISABLED");
-               }
-
        }
 
        thread = calloc(1, sizeof(twe_thread));
@@ -196,8 +254,9 @@ twe_thread_destroy(twe_thread* thread)
        thread->ctx->ref_cnt--;
 
        if (thread->ctx->ref_cnt == 0) {
-               if (thread->ctx->tdm_gsource) {
-                       _twe_thread_tdm_source_destroy(thread->ctx);
+               if (thread->ctx->tdm_source) {
+                       _twe_thread_tdm_source_destroy(thread->ctx->tdm_source);
+                       thread->ctx->tdm_source = NULL;
                }
 
                g_main_loop_quit(thread->ctx->twe_loop);
@@ -278,7 +337,7 @@ _twe_thread_wl_disp_check(GSource *source)
 }
 
 static gboolean
-_twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer date)
+_twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data)
 {
        twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source;
 
@@ -857,6 +916,9 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error,
        surf_source->vblank_done = TPL_TRUE;
 }
 
+static tdm_client_vblank*
+_twe_surface_create_vblank(tdm_client *tdm_client);
+
 static void
 _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source,
                                                          tbm_surface_h tbm_surface)
@@ -905,7 +967,16 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source,
                          buf_info->wl_buffer, tbm_surface,
                          tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
 
-       if (_twe_ctx->tdm_client && surf_source->vblank) {
+       if (_twe_ctx->tdm_source && !surf_source->vblank) {
+               surf_source->vblank =
+                       _twe_surface_create_vblank(_twe_ctx->tdm_source->tdm_client);
+               if (!surf_source->vblank) {
+                       TPL_WARN("Failed to create vblank. surf_source(%p)",
+                                        surf_source);
+               }
+       }
+
+       if (_twe_ctx->tdm_source && surf_source->vblank) {
                tdm_error tdm_err = TDM_ERROR_NONE;
                tdm_err = tdm_client_vblank_wait(surf_source->vblank,
                                                                                 1, /* TODO: interval */
@@ -954,7 +1025,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
                while (!surf_source->vblank_done) {
                        tdm_error tdm_err = TDM_ERROR_NONE;
 
-                       tdm_err = tdm_client_handle_events(_twe_ctx->tdm_client);
+                       tdm_err = tdm_client_handle_events(_twe_ctx->tdm_source->tdm_client);
                        if (tdm_err != TDM_ERROR_NONE) {
                                TPL_ERR("Failed to tdm_client_handle_events.");
                                break;
@@ -966,7 +1037,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
 }
 
 static gboolean
-_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date)
+_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer data)
 {
        twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source;
        GIOCondition cond;
@@ -1209,7 +1280,7 @@ twe_surface_add(twe_thread* thread,
        source->disp_source = (twe_wl_disp_source *)twe_display;
        source->rotation = 0;
        source->rotation_capability = TPL_FALSE;
-       source->vblank = _twe_surface_create_vblank(_twe_ctx->tdm_client);
+       source->vblank = NULL;
        source->vblank_done = TPL_TRUE;
        source->committed_buffers = __tpl_list_alloc();
        source->in_use_buffers = __tpl_list_alloc();