virtual: fix voutput commit buffer send fail
[platform/core/uifw/libtdm.git] / src / tdm_output.c
index e043569..dfc96ee 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;
 
@@ -1401,6 +1401,119 @@ _voutput_commit_func(tdm_voutput *voutput, tbm_surface_h buffer)
 }
 
 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)
 {
        tdm_private_display *private_display;
@@ -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 */
 }