virtual: fix voutput commit buffer send fail 98/195198/4
authorJunkyeong Kim <jk0430.kim@samsung.com>
Tue, 11 Dec 2018 12:22:03 +0000 (21:22 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 26 Dec 2018 23:36:42 +0000 (23:36 +0000)
add tdm_output_set_voutput_commit / tdm_output_unset_voutput_commit
execute set_voutput_commit when connect.
execute unset_voutput_commit when disconnect.

cause of tdm thread, the voutput commit request has to be set by client.
before code the voutput commit was set from server(main thread),
client cannot get buffer attach and commit event from server.

Change-Id: I244d9b8b93b3994cba760b9aa8b1ebdfa3102e68
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
backends/virtual/tdm_virtual_display.c
src/tdm_output.c
src/tdm_private.h
src/tdm_private_types.h
src/tdm_server.c

index 875dce409860aeab420b5f130bc9a35cea29a4c4..2d407fe5025b051b7929efa7d445079a02bafdff 100644 (file)
@@ -457,8 +457,9 @@ virtual_output_commit(tdm_output *output, int sync, void *user_data)
                                                                         output_data->status_user_data);
        }
 
+       layer_data = output_data->primary_layer;
+
        if (voutput_data->vcommit_func) {
-               layer_data = output_data->primary_layer;
                if (layer_data->display_buffer_changed) {
                        output_data->commit_user_data = user_data;
                        event_data = calloc(1, sizeof(tdm_virtual_event_data));
@@ -495,6 +496,8 @@ virtual_output_commit(tdm_output *output, int sync, void *user_data)
                }
        }
 
+       layer_data->display_buffer_changed = 0;
+
        return TDM_ERROR_NONE;
 }
 
@@ -940,7 +943,6 @@ virtual_output_set_commit_func(tdm_voutput *voutput,  tdm_voutput_commit_handler
        tdm_virtual_voutput_data *voutput_data = voutput;
 
        RETURN_VAL_IF_FAIL(voutput_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(commit_func, TDM_ERROR_INVALID_PARAMETER);
 
        voutput_data->vcommit_func = commit_func;
 
index e043569e464ad610c349f731e7cfb634fd579d04..dfc96eed02f56446757914dcba6962548dbb3825 100644 (file)
@@ -1101,7 +1101,7 @@ _tdm_voutput_thread_cb_commit(tdm_private_display *private_display, void *object
                TDM_INFO("handler(%p)", voutput_commit_handler);
        }
 
-       if (voutput_commit_handler->func) {
+       if (voutput_commit_handler->func && private_voutput->set_voutput_commit != 0) {
                _pthread_mutex_unlock(&private_display->lock);
                voutput_commit_handler->func(private_voutput, voutput_commit_handler->user_data);
                _pthread_mutex_lock(&private_display->lock);
@@ -1137,9 +1137,9 @@ _tdm_voutput_cb_commit(tdm_voutput *voutput_backend, unsigned int sequence,
                return;
        }
 
-       LIST_FOR_EACH_ENTRY(voutput_commit_handler, &private_voutput->voutput_commit_handler_list, link) {
-               if (voutput_commit_handler) break;
-       }
+       if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) == 0) return;
+
+       voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
 
        private_output = private_voutput->private_output;
 
@@ -1400,6 +1400,119 @@ _voutput_commit_func(tdm_voutput *voutput, tbm_surface_h buffer)
        return;
 }
 
+INTERN tdm_error
+tdm_output_set_voutput_commit(tdm_voutput *voutput)
+{
+       tdm_private_display *private_display;
+       tdm_private_output *private_output;
+       tdm_private_voutput *private_voutput;
+       tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
+       tdm_error ret = TDM_ERROR_NONE;
+
+       TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_voutput = (tdm_private_voutput *)voutput;
+       private_display = private_voutput->private_display;
+       private_output = (tdm_private_output *)private_voutput->private_output;
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+               _pthread_mutex_unlock(&private_display->lock);
+               return ret;
+       }
+
+       if (!private_voutput->regist_commit_cb) {
+               private_voutput->regist_commit_cb = 1;
+               ret = tdm_voutput_set_commit_func(private_voutput, _tdm_voutput_cb_commit);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("failed: tdm_voutput_set_commit_func");
+                       return ret;
+               }
+       }
+
+       voutput_commit_handler = calloc(1, sizeof(tdm_private_voutput_commit_handler));
+       if (!voutput_commit_handler) {
+               /* LCOV_EXCL_START */
+               TDM_ERR("failed: alloc memory");
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_OUT_OF_MEMORY;
+               /* LCOV_EXCL_STOP */
+       }
+
+       ret = tdm_thread_cb_add(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
+       if (ret != TDM_ERROR_NONE) {
+               TDM_ERR("tdm_thread_cb_add failed");
+               free(voutput_commit_handler);
+               _pthread_mutex_unlock(&private_display->lock);
+               return ret;
+       }
+
+       LIST_ADDTAIL(&voutput_commit_handler->link, &private_voutput->voutput_commit_handler_list);
+       voutput_commit_handler->private_voutput = private_voutput;
+       voutput_commit_handler->func = _voutput_commit_func;
+       voutput_commit_handler->owner_tid = syscall(SYS_gettid);
+
+       private_voutput->set_voutput_commit = 1;
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
+INTERN tdm_error
+tdm_output_unset_voutput_commit(tdm_voutput *voutput)
+{
+       tdm_private_display *private_display;
+       tdm_private_output *private_output;
+       tdm_private_voutput *private_voutput;
+       tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
+       tdm_error ret = TDM_ERROR_NONE;
+
+       TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       private_voutput = (tdm_private_voutput *)voutput;
+       private_display = private_voutput->private_display;
+       private_output = (tdm_private_output *)private_voutput->private_output;
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       private_voutput->set_voutput_commit = 0;
+
+       if (private_voutput->regist_commit_cb) {
+               private_voutput->regist_commit_cb = 0;
+               ret = tdm_voutput_set_commit_func(private_voutput, NULL);
+               if (ret != TDM_ERROR_NONE) {
+                       TDM_ERR("failed: tdm_voutput_set_commit_func");
+                       return ret;
+               }
+       }
+
+       if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) == 0) {
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_NONE;
+       }
+
+       if (LIST_LENGTH(&private_output->output_commit_handler_list) != 0) {
+               //commiting. don't remove voutput commit thread here
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_NONE;
+       }
+
+       if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+               voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
+       } else {
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_NONE;
+       }
+
+       tdm_thread_cb_remove(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return TDM_ERROR_NONE;
+}
+
 INTERN tdm_error
 tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
 {
@@ -1452,38 +1565,12 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl
                                free(output_commit_handler);
                                return TDM_ERROR_BAD_MODULE;
                        }
-                       private_voutput = private_output->private_voutput;
-
-                       if (!private_voutput->regist_commit_cb) {
-                               private_voutput->regist_commit_cb = 1;
-                               ret = tdm_voutput_set_commit_func(private_voutput, _tdm_voutput_cb_commit);
-                               TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
-                       }
-
-                       voutput_commit_handler = calloc(1, sizeof(tdm_private_voutput_commit_handler));
-                       if (!voutput_commit_handler) {
-                               /* LCOV_EXCL_START */
-                               TDM_ERR("failed: alloc memory");
-                               free(output_commit_handler);
-                               return TDM_ERROR_OUT_OF_MEMORY;
-                               /* LCOV_EXCL_STOP */
-                       }
-
-                       ret = tdm_thread_cb_add(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
-                       if (ret != TDM_ERROR_NONE) {
-                               TDM_ERR("tdm_thread_cb_add failed");
-                               free(voutput_commit_handler);
-                               free(output_commit_handler);
-                               return ret;
-                       }
                }
 
                ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL);
                if (ret != TDM_ERROR_NONE) {
                        TDM_ERR("tdm_thread_cb_add failed");
                        free(output_commit_handler);
-                       if (voutput_commit_handler)
-                               free(voutput_commit_handler);
                        return ret;
                }
 
@@ -1493,17 +1580,16 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl
                output_commit_handler->user_data = user_data;
                output_commit_handler->owner_tid = syscall(SYS_gettid);
 
-               if (voutput_commit_handler) {
+               if (private_module == private_display->virtual_module) {
+                       private_voutput = private_output->private_voutput;
+
                        /* voutput use only 1 layer */
-                       LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
-                               if (private_layer) break;
-                       }
+                       private_layer = LIST_FIRST_ENTRY(&private_output->layer_list, tdm_private_layer, link);
 
-                       LIST_ADDTAIL(&voutput_commit_handler->link, &private_voutput->voutput_commit_handler_list);
-                       voutput_commit_handler->private_voutput = private_voutput;
-                       voutput_commit_handler->func = _voutput_commit_func;
-                       voutput_commit_handler->user_data = private_layer->commiting_buffer;
-                       voutput_commit_handler->owner_tid = syscall(SYS_gettid);
+                       if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+                               voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
+                               voutput_commit_handler->user_data = private_layer->commiting_buffer;
+                       }
                }
 
                ret = func_output->output_commit(private_output->output_backend, sync,
@@ -1555,11 +1641,7 @@ commit_failed:
                LIST_DEL(&output_commit_handler->link);
                free(output_commit_handler);
        }
-       if (voutput_commit_handler) {
-               tdm_thread_cb_remove(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
-               LIST_DEL(&voutput_commit_handler->link);
-               free(voutput_commit_handler);
-       }
+
        return ret;
        /* LCOV_EXCL_STOP */
 }
index 9e10713f4264ce8296d1a58130de3644c949a45f..b65c01e5246e0b5be4fee1cff49f468d50c2792e 100644 (file)
@@ -279,6 +279,10 @@ tdm_voutput_attach_buffer(tdm_voutput *voutput, tbm_surface_h buffer);
 tdm_error
 tdm_voutput_commit_buffer(tdm_voutput *voutput);
 tdm_error
+tdm_output_set_voutput_commit(tdm_voutput *voutput);
+tdm_error
+tdm_output_unset_voutput_commit(tdm_voutput *voutput);
+tdm_error
 tdm_voutput_commit_done(tdm_voutput *voutput);
 void *
 tdm_display_find_private_voutput(tdm_private_display *private_display, double stamp);
index 993be0e683c96883f51eb9b4c7004c2ebefc958d..80d867f6be41db70e2569b682b68464404b4e4c9 100644 (file)
@@ -267,6 +267,8 @@ struct _tdm_private_voutput {
        unsigned int mmwidth;
        unsigned int mmheight;
        int connect_status;
+
+       int set_voutput_commit;
 };
 
 struct _tdm_private_layer {
index 31ddf14b4fee197f94cdcacb665da5821c045877..dc4f25a0694194844d34f59a058fd7fc4b2e51a2 100644 (file)
@@ -93,6 +93,7 @@ typedef struct _tdm_server_voutput_info {
        struct list_head buffer_list;
        tdm_server_voutput_buffer *attach_buffer;
        int committing;
+       unsigned int request_commit;
 } tdm_server_voutput_info;
 
 typedef struct _tdm_server_vblank_info {
@@ -902,9 +903,12 @@ _tdm_voutput_cb_connect(struct wl_client *client, struct wl_resource *resource)
        voutput_info = wl_resource_get_user_data(resource);
        voutput_info->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
 
+       voutput_info->request_commit = 1;
+
        tdm_voutput_set_physical_size(voutput_info->voutput, voutput_info->mmwidth, voutput_info->mmheight);
        tdm_voutput_set_available_mode(voutput_info->voutput, voutput_info->available_modes.modes, voutput_info->available_modes.count);
        tdm_voutput_connect(voutput_info->voutput);
+       tdm_output_set_voutput_commit(voutput_info->voutput);
 }
 
 static void
@@ -929,6 +933,11 @@ _tdm_voutput_cb_disconnect(struct wl_client *client, struct wl_resource *resourc
                voutput_info->attach_buffer = NULL;
        }
 
+       if (voutput_info->request_commit == 1) {
+               tdm_output_unset_voutput_commit(voutput_info->voutput);
+               voutput_info->request_commit = 0;
+       }
+
        tdm_voutput_disconnect(voutput_info->voutput);
 }
 
@@ -949,6 +958,9 @@ _tdm_voutput_cb_commit_done(struct wl_client *client, struct wl_resource *resour
        voutput_info->committing = 0;
        voutput_info->attach_buffer = NULL;
 
+       if (voutput_info->request_commit == 1)
+               tdm_output_set_voutput_commit(voutput_info->voutput);
+
        tdm_voutput_commit_done(voutput_info->voutput);
 }
 
@@ -1237,10 +1249,14 @@ tdm_voutput_cb_resource_destroy(struct wl_resource *resource)
 
        voutput = voutput_info->voutput;
 
-       if (voutput)
+       if (voutput_info->request_commit)
+               tdm_output_unset_voutput_commit(voutput_info->voutput);
+
+       if (voutput) {
                ret = tdm_voutput_destroy(voutput);
-       if (ret != TDM_ERROR_NONE)
-               TDM_ERR("_tdm_voutput_cb_destroy fail");
+               if (ret != TDM_ERROR_NONE)
+                       TDM_ERR("_tdm_voutput_cb_destroy fail");
+       }
 
        if (voutput_info->attach_buffer) {
                tbm_surface_h buffer = voutput_info->attach_buffer->buffer;