support the commit-per-vblank
authorBoram Park <boram1288.park@samsung.com>
Tue, 29 Nov 2016 03:23:07 +0000 (12:23 +0900)
committerBoram Park <boram1288.park@samsung.com>
Thu, 12 Jan 2017 03:30:49 +0000 (12:30 +0900)
If TDM_COMMIT_PER_VBLANK enviroment is set to 1, tdm frontend will
call the backend's output_commit function once per a vblank.

Change-Id: I9df27288fd9318a64305491e4dc96d686a223baf

doc/tdm_doc.h
include/tdm.h
include/tdm_types.h
src/tdm.c
src/tdm_display.c
src/tdm_macro.h
src/tdm_monitor_server.c
src/tdm_private.h
src/tdm_vblank.c
tools/tdm_test_server.c

index 2bcfce7..02e3024 100644 (file)
@@ -56,7 +56,7 @@
  * and #tdm_layer_create_capture if available.\n
  * \n
  * All changes of output/layer/pp/capture objects are applied when committed.
- * See #tdm_output_commit, #tdm_pp_commit and #tdm_capture_commit.
+ * See #tdm_output_commit, #tdm_layer_commit, #tdm_pp_commit and #tdm_capture_commit.
  * \n
  * @par Buffer management
  * TDM has its own buffer release mechanism to let an user know when a TDM buffer
index 15b1f56..3a066c1 100644 (file)
@@ -479,6 +479,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
  * @param[in] func A user commit handler
  * @param[in] user_data The user data
  * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ * @see #tdm_layer_commit
  */
 tdm_error
 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
@@ -613,7 +614,7 @@ tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value);
  * @param[in] layer A layer object
  * @param[in] info The geometry information
  * @return #TDM_ERROR_NONE if success. Otherwise, error value.
- * @see tdm_output_commit
+ * @see tdm_layer_commit
  */
 tdm_error
 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info);
@@ -634,7 +635,7 @@ tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
  * @param[in] layer A layer object
  * @param[in] buffer A TDM buffer
  * @return #TDM_ERROR_NONE if success. Otherwise, error value.
- * @see tdm_output_commit
+ * @see tdm_layer_commit
  */
 tdm_error
 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
@@ -650,6 +651,21 @@ tdm_error
 tdm_layer_unset_buffer(tdm_layer *layer);
 
 /**
+ * @brief Commit changes for a layer object
+ * @details After all change of a layer object are applied, a user commit handler
+ * will be called.
+ * @param[in] layer A layer object
+ * @param[in] func A user commit handler
+ * @param[in] user_data The user data
+ * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ */
+tdm_error
+tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data);
+
+tdm_error
+tdm_layer_is_committing(tdm_layer *layer, unsigned int *committing);
+
+/**
  * @brief Get a displaying TDM buffer from a layer object
  * @details A displaying TDM buffer is a current showing buffer on screen
  * that is set to layer object and applied output object of a layer object.
@@ -666,7 +682,7 @@ tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error);
  * @param[in] layer A layer object
  * @param[in] buffer_queue A TBM surface_queue
  * @return #TDM_ERROR_NONE if success. Otherwise, error value.
- * @see tdm_output_commit
+ * @see tdm_layer_commit
  */
 tdm_error
 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue);
index 3cd8560..3b62ff5 100644 (file)
@@ -166,12 +166,20 @@ typedef void (*tdm_output_vblank_handler)(tdm_output *output, unsigned int seque
                                                                                  void *user_data);
 
 /**
- * @brief The commit handler
+ * @brief The output commit handler
  * @see output_set_commit_handler() function of #tdm_func_display
  */
 typedef void (*tdm_output_commit_handler)(tdm_output *output, unsigned int sequence,
                                                                                  unsigned int tv_sec, unsigned int tv_usec,
                                                                                  void *user_data);
+
+/**
+ * @brief The layer commit handler
+ */
+typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence,
+                                                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                                                void *user_data);
+
 /**
  * @brief The done handler of a pp object
  */
index c6023a2..ef6e1af 100644 (file)
--- a/src/tdm.c
+++ b/src/tdm.c
@@ -146,10 +146,12 @@ _tdm_display_destroy_private_layer(tdm_private_layer *private_layer)
 static void
 _tdm_display_destroy_private_output(tdm_private_output *private_output)
 {
+       tdm_private_display *private_display = private_output->private_display;
        tdm_private_layer *l = NULL, *ll = NULL;
        tdm_private_capture *c = NULL, *cc = NULL;
        tdm_private_vblank_handler *v = NULL, *vv = NULL;
-       tdm_private_commit_handler *m = NULL, *mm = NULL;
+       tdm_private_output_commit_handler *om = NULL, *omm = NULL;
+       tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
        tdm_private_change_handler *h = NULL, *hh = NULL;
 
        LIST_DEL(&private_output->link);
@@ -161,9 +163,19 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output)
                free(v);
        }
 
-       LIST_FOR_EACH_ENTRY_SAFE(m, mm, &private_output->commit_handler_list, link) {
-               LIST_DEL(&m->link);
-               free(m);
+       LIST_FOR_EACH_ENTRY_SAFE(om, omm, &private_output->output_commit_handler_list, link) {
+               LIST_DEL(&om->link);
+               free(om);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
+               LIST_DEL(&lm->link);
+               free(lm);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
+               LIST_DEL(&lm->link);
+               free(lm);
        }
 
        LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
@@ -176,6 +188,13 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output)
                free(h);
        }
 
+       if (private_output->vblank) {
+               /* tdm_vblank APIs is for server. it should be called in unlock status*/
+               _pthread_mutex_unlock(&private_display->lock);
+               tdm_vblank_destroy(private_output->vblank);
+               _pthread_mutex_lock(&private_display->lock);
+       }
+
        LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_output->capture_list, link)
        tdm_capture_destroy_internal(c);
 
@@ -381,7 +400,9 @@ tdm_display_update_output(tdm_private_display *private_display,
                LIST_INITHEAD(&private_output->layer_list);
                LIST_INITHEAD(&private_output->capture_list);
                LIST_INITHEAD(&private_output->vblank_handler_list);
-               LIST_INITHEAD(&private_output->commit_handler_list);
+               LIST_INITHEAD(&private_output->output_commit_handler_list);
+               LIST_INITHEAD(&private_output->layer_commit_handler_list);
+               LIST_INITHEAD(&private_output->pending_commit_handler_list);
                LIST_INITHEAD(&private_output->change_handler_list_main);
                LIST_INITHEAD(&private_output->change_handler_list_sub);
 
@@ -862,7 +883,7 @@ EXTERN tdm_display *
 tdm_display_init(tdm_error *error)
 {
        tdm_private_display *private_display = NULL;
-       const char *debug;
+       const char *str;
        tdm_error ret;
        double stamp1, stamp2, start;
 
@@ -885,17 +906,21 @@ tdm_display_init(tdm_error *error)
                goto failed_alloc;
        }
 
-       debug = getenv("TDM_DEBUG_MODULE");
-       if (debug)
-               tdm_display_enable_debug_module(debug);
+       str = getenv("TDM_DEBUG_MODULE");
+       if (str)
+               tdm_display_enable_debug_module(str);
+
+       str = getenv("TDM_DEBUG_DUMP");
+       if (str)
+               tdm_display_enable_dump(private_display, str, NULL, NULL);
 
-       debug = getenv("TDM_DEBUG_DUMP");
-       if (debug)
-               tdm_display_enable_dump(private_display, debug, NULL, NULL);
+       str = getenv("TDM_DEBUG_PATH");
+       if (str)
+               tdm_display_enable_path(str);
 
-       debug = getenv("TDM_DEBUG_PATH");
-       if (debug)
-               tdm_display_enable_path(debug);
+       str = getenv("TDM_COMMIT_PER_VBLANK");
+       if (str && (strstr(str, "1")))
+               tdm_display_enable_commit_per_vblank(private_display, 1);
 
        if (pthread_mutex_init(&private_display->lock, NULL)) {
                ret = TDM_ERROR_OPERATION_FAILED;
@@ -956,6 +981,7 @@ tdm_display_init(tdm_error *error)
        tdm_event_loop_create_backend_source(private_display);
 
        private_display->init_count = 1;
+       private_display->commit_type = TDM_COMMIT_TYPE_NONE;
 
        g_private_display = private_display;
 
@@ -1076,6 +1102,8 @@ tdm_display_enable_debug_module(const char*modules)
                        tdm_debug_module |= TDM_DEBUG_MUTEX;
                else if (!strncmp(arg, "vblank", 6))
                        tdm_debug_module |= TDM_DEBUG_VBLANK;
+               else if (!strncmp(arg, "commit", 6))
+                       tdm_debug_module |= TDM_DEBUG_COMMIT;
                else
                        return TDM_ERROR_BAD_REQUEST;
 
@@ -1263,3 +1291,29 @@ enable_fail:
        return ret;
 }
 
+INTERN tdm_error
+tdm_display_enable_commit_per_vblank(tdm_private_display *private_display, int enable)
+{
+       private_display->commit_per_vblank = enable;
+
+       if (private_display->commit_per_vblank == 1)
+               TDM_INFO("commit per vblank: enable (1 layer)");
+       else if (private_display->commit_per_vblank == 2)
+               TDM_INFO("commit per vblank: enable (previous commit)");
+       else if (private_display->commit_per_vblank > 0)
+               TDM_INFO("commit per vblank: enable (unknown)");
+       else
+               TDM_INFO("commit per vblank: disable");
+
+       return TDM_ERROR_NONE;
+}
+
+INTERN tdm_error
+tdm_display_enable_fps(tdm_private_display *private_display, int enable)
+{
+       private_display->print_fps = enable;
+
+       TDM_INFO("print fps: %s", (enable) ? "enable" : "disable");
+
+       return TDM_ERROR_NONE;
+}
index 9cfd290..9cd7c4a 100644 (file)
        private_output = private_layer->private_output; \
        private_display = private_output->private_display
 
+static void _tdm_layer_committed(tdm_private_layer *private_layer);
+static void _tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence,
+                                                                               unsigned int tv_sec, unsigned int tv_usec, void *user_data);
+static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
+                                                                         unsigned int tv_sec, unsigned int tv_usec, void *user_data);
+
 EXTERN tdm_error
 tdm_display_get_capabilities(tdm_display *dpy,
                                                         tdm_display_capability *capabilities)
@@ -492,6 +498,20 @@ tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
        return ret;
 }
 
+static unsigned int
+_tdm_output_used_layer_count(tdm_private_output *private_output)
+{
+       tdm_private_layer *private_layer = NULL;
+       unsigned int count = 0;
+
+       LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
+               if (!private_layer->usable)
+                       count++;
+       }
+
+       return count;
+}
+
 static void
 _tdm_output_update(tdm_output *output_backend, void *user_data)
 {
@@ -926,14 +946,20 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
                                         unsigned int tv_sec, unsigned int tv_usec, void *user_data)
 {
        tdm_private_vblank_handler *vblank_handler = user_data;
+       tdm_private_vblank_handler *v = NULL, *vv = NULL;
+       tdm_private_output *private_output;
        tdm_private_display *private_display;
+       struct list_head clone_list;
+       int interval, sync;
+       pid_t tid = syscall(SYS_gettid);
 
        TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
        TDM_RETURN_IF_FAIL(vblank_handler);
 
-       private_display = vblank_handler->private_output->private_display;
+       private_output = vblank_handler->private_output;
+       private_display = private_output->private_display;
 
-       if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
+       if (vblank_handler->owner_tid != tid) {
                tdm_thread_cb_output_vblank output_vblank;
                tdm_error ret;
 
@@ -951,36 +977,48 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
                return;
        }
 
-       if (vblank_handler->owner_tid != syscall(SYS_gettid))
+       if (vblank_handler->owner_tid != tid)
                TDM_NEVER_GET_HERE();
 
-       if (vblank_handler->func) {
-               _pthread_mutex_unlock(&private_display->lock);
-               vblank_handler->func(vblank_handler->private_output, sequence,
-                                                        tv_sec, tv_usec, vblank_handler->user_data);
-               _pthread_mutex_lock(&private_display->lock);
+       interval = vblank_handler->interval;
+       sync = vblank_handler->sync;
+
+       LIST_INITHEAD(&clone_list);
+
+       LIST_FOR_EACH_ENTRY_SAFE(v, vv, &private_output->vblank_handler_list, link) {
+               if (v->interval != interval || v->sync != sync || v->owner_tid != tid)
+                       continue;
+
+               LIST_DEL(&v->link);
+               LIST_ADD(&v->link, &clone_list);
        }
 
-       LIST_DEL(&vblank_handler->link);
-       free(vblank_handler);
+       _pthread_mutex_unlock(&private_display->lock);
+       LIST_FOR_EACH_ENTRY_SAFE(v, vv, &clone_list, link) {
+               if (v->func)
+                       v->func(v->private_output, sequence, tv_sec, tv_usec, v->user_data);
+               LIST_DEL(&v->link);
+               free(v);
+       }
+       _pthread_mutex_lock(&private_display->lock);
 }
 
 INTERN void
 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
                                         unsigned int tv_sec, unsigned int tv_usec, void *user_data)
 {
-       tdm_private_commit_handler *commit_handler = user_data;
+       tdm_private_output_commit_handler *output_commit_handler = user_data;
        tdm_private_display *private_display;
        tdm_private_output *private_output;
        tdm_private_layer *private_layer = NULL;
 
        TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
-       TDM_RETURN_IF_FAIL(commit_handler);
+       TDM_RETURN_IF_FAIL(output_commit_handler);
 
-       private_output = commit_handler->private_output;
+       private_output = output_commit_handler->private_output;
        private_display = private_output->private_display;
 
-       if (commit_handler->owner_tid != syscall(SYS_gettid)) {
+       if (output_commit_handler->owner_tid != syscall(SYS_gettid)) {
                tdm_thread_cb_output_commit output_commit;
                tdm_error ret;
 
@@ -998,94 +1036,103 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
                return;
        }
 
-       LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
-               if (!private_layer->waiting_buffer)
-                       continue;
-
-               if (private_layer->showing_buffer) {
-                       _pthread_mutex_unlock(&private_display->lock);
-                       tdm_buffer_unref_backend(private_layer->showing_buffer);
-                       _pthread_mutex_lock(&private_display->lock);
-
-                       if (private_layer->buffer_queue) {
-                               _pthread_mutex_unlock(&private_display->lock);
-                               tbm_surface_queue_release(private_layer->buffer_queue,
-                                                                                 private_layer->showing_buffer);
-                               _pthread_mutex_lock(&private_display->lock);
-                       }
+       if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
+               /* In case of layer commit, the below will be handled in the layer commit callback */
+               LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
+                       _tdm_layer_committed(private_layer);
                }
-
-               private_layer->showing_buffer = private_layer->waiting_buffer;
-               private_layer->waiting_buffer = NULL;
-
-               if (tdm_debug_module & TDM_DEBUG_BUFFER)
-                       TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
-                                        private_layer, private_layer->waiting_buffer,
-                                        private_layer->showing_buffer);
        }
 
-       if (commit_handler->func) {
+       if (output_commit_handler->func) {
                _pthread_mutex_unlock(&private_display->lock);
-               commit_handler->func(private_output, sequence,
-                                                        tv_sec, tv_usec, commit_handler->user_data);
+               output_commit_handler->func(private_output, sequence,
+                                                                       tv_sec, tv_usec, output_commit_handler->user_data);
                _pthread_mutex_lock(&private_display->lock);
        }
 
-       LIST_DEL(&commit_handler->link);
-       free(commit_handler);
+       LIST_DEL(&output_commit_handler->link);
+       free(output_commit_handler);
 }
 
-EXTERN tdm_error
-tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
-                                          tdm_output_vblank_handler func, void *user_data)
+static tdm_error
+_tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
+                                               tdm_output_vblank_handler func, void *user_data)
 {
        tdm_func_output *func_output;
-       tdm_private_vblank_handler *vblank_handler;
-       OUTPUT_FUNC_ENTRY();
-
-       _pthread_mutex_lock(&private_display->lock);
+       tdm_private_vblank_handler *vblank_handler = NULL, *v = NULL;
+       unsigned int skip_request = 0;
+       pid_t tid = syscall(SYS_gettid);
 
-       if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
-               TDM_WRN("output(%d) dpms: %s", private_output->pipe,
-                               tdm_dpms_str(private_output->current_dpms_value));
-               _pthread_mutex_unlock(&private_display->lock);
-               return TDM_ERROR_DPMS_OFF;
-       }
+       OUTPUT_FUNC_ENTRY();
 
        func_output = &private_display->func_output;
 
        if (!func_output->output_wait_vblank) {
-               _pthread_mutex_unlock(&private_display->lock);
                TDM_ERR("not implemented!!");
                return TDM_ERROR_NOT_IMPLEMENTED;
        }
 
+       if (!private_output->regist_vblank_cb) {
+               private_output->regist_vblank_cb = 1;
+               ret = func_output->output_set_vblank_handler(private_output->output_backend,
+                               tdm_output_cb_vblank);
+       }
+
        vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
        if (!vblank_handler) {
                TDM_ERR("failed: alloc memory");
-               _pthread_mutex_unlock(&private_display->lock);
                return TDM_ERROR_OUT_OF_MEMORY;
        }
 
+       LIST_FOR_EACH_ENTRY(v, &private_output->vblank_handler_list, link) {
+               if (v->interval == interval && v->sync == sync && v->owner_tid == tid) {
+                       skip_request = 1;
+                       break;
+               }
+       }
+
        LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
        vblank_handler->private_output = private_output;
+       vblank_handler->interval = interval;
+       vblank_handler->sync = sync;
        vblank_handler->func = func;
        vblank_handler->user_data = user_data;
-       vblank_handler->owner_tid = syscall(SYS_gettid);
+       vblank_handler->owner_tid = tid;
 
-       ret = func_output->output_wait_vblank(private_output->output_backend, interval,
-                                                                                 sync, vblank_handler);
-       if (ret != TDM_ERROR_NONE) {
-               _pthread_mutex_unlock(&private_display->lock);
-               return ret;
+       /* If there is the previous request, we can skip to call output_wait_vblank() */
+       if (!skip_request) {
+               ret = func_output->output_wait_vblank(private_output->output_backend, interval,
+                                                                                         sync, vblank_handler);
+               TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
        }
 
-       if (!private_output->regist_vblank_cb) {
-               private_output->regist_vblank_cb = 1;
-               ret = func_output->output_set_vblank_handler(private_output->output_backend,
-                               tdm_output_cb_vblank);
+       return ret;
+
+wait_failed:
+       if (vblank_handler) {
+               LIST_DEL(&vblank_handler->link);
+               free(vblank_handler);
+       }
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
+                                          tdm_output_vblank_handler func, void *user_data)
+{
+       OUTPUT_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
+               TDM_WRN("output(%d) dpms: %s", private_output->pipe,
+                               tdm_dpms_str(private_output->current_dpms_value));
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_DPMS_OFF;
        }
 
+       ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data);
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
@@ -1096,7 +1143,7 @@ _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
                                   void *user_data)
 {
        tdm_func_output *func_output;
-       tdm_private_commit_handler *commit_handler;
+       tdm_private_output_commit_handler *output_commit_handler = NULL;
        OUTPUT_FUNC_ENTRY();
 
        func_output = &private_display->func_output;
@@ -1106,29 +1153,39 @@ _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
                return TDM_ERROR_NOT_IMPLEMENTED;
        }
 
-       commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
-       if (!commit_handler) {
-               TDM_ERR("failed: alloc memory");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
-       commit_handler->private_output = private_output;
-       commit_handler->func = func;
-       commit_handler->user_data = user_data;
-       commit_handler->owner_tid = syscall(SYS_gettid);
-
        if (!private_output->regist_commit_cb) {
                private_output->regist_commit_cb = 1;
                ret = func_output->output_set_commit_handler(private_output->output_backend,
                                tdm_output_cb_commit);
        }
 
+       output_commit_handler = calloc(1, sizeof(tdm_private_output_commit_handler));
+       if (!output_commit_handler) {
+               TDM_ERR("failed: alloc memory");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       LIST_ADD(&output_commit_handler->link, &private_output->output_commit_handler_list);
+       output_commit_handler->private_output = private_output;
+       output_commit_handler->func = func;
+       output_commit_handler->user_data = user_data;
+       output_commit_handler->owner_tid = syscall(SYS_gettid);
+
        ret = func_output->output_commit(private_output->output_backend, sync,
-                                                                        commit_handler);
-       TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+                                                                        output_commit_handler);
+       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("output(%d) backend commit", private_output->pipe);
 
        return ret;
+
+commit_failed:
+       if (output_commit_handler) {
+               LIST_DEL(&output_commit_handler->link);
+               free(output_commit_handler);
+       }
+       return ret;
 }
 
 EXTERN tdm_error
@@ -1139,6 +1196,20 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
 
        _pthread_mutex_lock(&private_display->lock);
 
+       if (private_display->commit_type == TDM_COMMIT_TYPE_NONE)
+               private_display->commit_type = TDM_COMMIT_TYPE_OUTPUT;
+       else if (private_display->commit_type == TDM_COMMIT_TYPE_LAYER) {
+               TDM_ERR("Can't supported. Use tdm_layer_commit");
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       if (private_display->commit_per_vblank) {
+               TDM_ERR("Use tdm_layer_commit");
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
        if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
                TDM_ERR("output(%d) dpms: %s", private_output->pipe,
                                tdm_dpms_str(private_output->current_dpms_value));
@@ -1146,6 +1217,9 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
                return TDM_ERROR_DPMS_OFF;
        }
 
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("output(%d) commit", private_output->pipe);
+
        ret = _tdm_output_commit(output, sync, func, user_data);
 
        _pthread_mutex_unlock(&private_display->lock);
@@ -1488,7 +1562,7 @@ tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
        func_layer = &private_display->func_layer;
 
        if (private_layer->usable)
-               TDM_INFO("layer(%p) not usable", private_layer);
+               TDM_INFO("layer(%d) not usable", private_layer->index);
 
        private_layer->usable = 0;
 
@@ -1686,6 +1760,7 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
 EXTERN tdm_error
 tdm_layer_unset_buffer(tdm_layer *layer)
 {
+       tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
        tdm_func_layer *func_layer;
        LAYER_FUNC_ENTRY();
 
@@ -1715,6 +1790,20 @@ tdm_layer_unset_buffer(tdm_layer *layer)
                                         private_layer, private_layer->showing_buffer);
        }
 
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
+               if (lm->private_layer != private_layer)
+                       continue;
+               LIST_DEL(&lm->link);
+               free(lm);
+       }
+
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
+               if (lm->private_layer != private_layer)
+                       continue;
+               LIST_DEL(&lm->link);
+               free(lm);
+       }
+
        private_layer->usable = 1;
 
        if (private_layer->usable)
@@ -1734,6 +1823,343 @@ tdm_layer_unset_buffer(tdm_layer *layer)
        return ret;
 }
 
+static void
+_tdm_layer_committed(tdm_private_layer *private_layer)
+{
+       tdm_private_output *private_output = private_layer->private_output;
+       tdm_private_display *private_display = private_output->private_display;
+
+       private_layer->committing = 0;
+
+       if (private_display->print_fps) {
+               double curr = tdm_helper_get_time();
+               private_layer->fps_count++;
+               if (private_layer->fps_stamp == 0) {
+                       private_layer->fps_stamp = curr;
+               } else if ((curr - private_layer->fps_stamp) > 1.0) {
+                       TDM_INFO("output(%d) layer(%d) fps: %d", private_output->index, private_layer->index, private_layer->fps_count - 1);
+                       private_layer->fps_count = 1;
+                       private_layer->fps_stamp = curr;
+               }
+       } else if (private_layer->fps_stamp != 0) {
+               private_layer->fps_stamp = 0;
+               private_layer->fps_count = 0;
+       }
+
+       if (!private_layer->waiting_buffer)
+               return;
+
+       if (private_layer->showing_buffer) {
+               _pthread_mutex_unlock(&private_display->lock);
+               tdm_buffer_unref_backend(private_layer->showing_buffer);
+               _pthread_mutex_lock(&private_display->lock);
+
+               if (private_layer->buffer_queue) {
+                       _pthread_mutex_unlock(&private_display->lock);
+                       tbm_surface_queue_release(private_layer->buffer_queue,
+                                                                         private_layer->showing_buffer);
+                       _pthread_mutex_lock(&private_display->lock);
+               }
+       }
+
+       private_layer->showing_buffer = private_layer->waiting_buffer;
+       private_layer->waiting_buffer = NULL;
+
+       if (tdm_debug_module & TDM_DEBUG_BUFFER)
+               TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
+                                private_layer, private_layer->waiting_buffer,
+                                private_layer->showing_buffer);
+}
+
+static void
+_tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int sequence,
+                                                        unsigned int tv_sec, unsigned int tv_usec)
+{
+       tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
+       tdm_private_display *private_display;
+       tdm_error ret;
+
+       private_display = private_output->private_display;
+
+       private_output->waiting_vblank = 0;
+
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
+               _tdm_layer_committed(lm->private_layer);
+
+               if (lm->func) {
+                       _pthread_mutex_unlock(&private_display->lock);
+                       lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data);
+                       _pthread_mutex_lock(&private_display->lock);
+               }
+
+               LIST_DEL(&lm->link);
+               free(lm);
+       }
+
+       if (LIST_IS_EMPTY(&private_output->pending_commit_handler_list))
+               return;
+
+#if 1
+       ret = _tdm_output_commit(private_output, 0, _tdm_layer_cb_output_commit, NULL);
+       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("layer commit: output(%d) commit", private_output->pipe);
+
+       private_output->waiting_vblank = 1;
+#else
+       ret = _tdm_output_commit(private_output, 0, NULL, NULL);
+       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("layer commit: output(%d) commit", private_output->pipe);
+
+       TDM_RETURN_IF_FAIL(private_output->vblank != NULL);
+
+       /* tdm_vblank APIs is for server. it should be called in unlock status*/
+       _pthread_mutex_unlock(&private_display->lock);
+       ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
+       _pthread_mutex_lock(&private_display->lock);
+       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
+       private_output->waiting_vblank = 1;
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("layer commit: output(%d) wait vblank", private_output->pipe);
+#endif
+
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
+               LIST_DEL(&lm->link);
+               LIST_ADD(&lm->link, &private_output->layer_commit_handler_list);
+       }
+
+       return;
+wait_failed:
+       LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
+               LIST_DEL(&lm->link);
+               free(lm);
+       }
+       return;
+}
+
+static void
+_tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence,
+                                                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       tdm_private_layer_commit_handler *layer_commit_handler = user_data;
+       tdm_private_display *private_display;
+       tdm_private_output *private_output = output;
+       tdm_private_layer *private_layer;
+
+       private_display = private_output->private_display;
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (layer_commit_handler) {
+               tdm_private_layer_commit_handler *lm = NULL;
+               int found = 0;
+
+               LIST_FOR_EACH_ENTRY(lm, &private_output->layer_commit_handler_list, link) {
+                       if (layer_commit_handler == lm) {
+                               found = 1;
+                               break;
+                       }
+               }
+
+               if (found) {
+                       private_layer = layer_commit_handler->private_layer;
+
+                       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                               TDM_INFO("layer(%p) commit: output(%d) committed", private_layer, private_output->pipe);
+
+                       _tdm_layer_committed(private_layer);
+
+                       if (layer_commit_handler->func) {
+                               _pthread_mutex_unlock(&private_display->lock);
+                               layer_commit_handler->func(private_output, sequence,
+                                                                                  tv_sec, tv_usec, layer_commit_handler->user_data);
+                               _pthread_mutex_lock(&private_display->lock);
+                       }
+
+                       LIST_DEL(&layer_commit_handler->link);
+                       free(layer_commit_handler);
+               }
+       } else {
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer commit: output(%d) committed", private_output->pipe);
+
+               _tdm_layer_got_output_vblank(private_output, sequence, tv_sec, tv_usec);
+       }
+
+       _pthread_mutex_unlock(&private_display->lock);
+}
+
+static void
+_tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
+                                                 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       tdm_private_output *private_output = user_data;
+       tdm_private_display *private_display;
+
+       TDM_RETURN_IF_FAIL(private_output != NULL);
+
+       private_display = private_output->private_display;
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("layer commit: output(%d) got vblank", private_output->pipe);
+
+       _tdm_layer_got_output_vblank(private_output, sequence, tv_sec, tv_usec);
+
+       _pthread_mutex_unlock(&private_display->lock);
+}
+
+static int
+_tdm_layer_commit_possible(tdm_private_layer *private_layer)
+{
+       tdm_private_output *private_output = private_layer->private_output;
+       tdm_private_display *private_display = private_output->private_display;
+
+       if (!private_display->commit_per_vblank) {
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer(%p) commit: commit_per_vblank false", private_layer);
+               return 1;
+       }
+
+       if (private_display->commit_per_vblank == 1 && _tdm_output_used_layer_count(private_output) == 1) {
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer(%p) commit: 1 layer", private_layer);
+               return 1;
+       }
+
+       if (private_display->commit_per_vblank == 2 && LIST_IS_EMPTY(&private_output->layer_commit_handler_list)) {
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer(%p) commit: non previous commit", private_layer);
+               return 1;
+       }
+
+       return 0;
+}
+
+static tdm_error
+_tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
+{
+       tdm_private_layer_commit_handler *layer_commit_handler;
+       LAYER_FUNC_ENTRY();
+
+       layer_commit_handler = calloc(1, sizeof(tdm_private_layer_commit_handler));
+       if (!layer_commit_handler) {
+               TDM_ERR("failed: alloc memory");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       LIST_INITHEAD(&layer_commit_handler->link);
+       layer_commit_handler->private_layer = private_layer;
+       layer_commit_handler->func = func;
+       layer_commit_handler->user_data = user_data;
+
+       if (_tdm_layer_commit_possible(private_layer)) {
+               if (private_layer->committing)
+                       TDM_WRN("layer(%d) too many commit", private_layer->index);
+               else
+                       private_layer->committing = 1;
+
+               LIST_ADD(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
+               ret = _tdm_output_commit(private_layer->private_output, 0, _tdm_layer_cb_output_commit, layer_commit_handler);
+               TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer(%p) commit: output", private_layer);
+       } else {
+               if (private_layer->committing)
+                       TDM_WRN("layer(%d) too many commit", private_layer->index);
+               else
+                       private_layer->committing = 1;
+
+               LIST_ADD(&layer_commit_handler->link, &private_output->pending_commit_handler_list);
+
+               if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                       TDM_INFO("layer(%p) commit: pending", private_layer);
+
+               if (!private_output->vblank) {
+                       /* tdm_vblank APIs is for server. it should be called in unlock status*/
+                       _pthread_mutex_unlock(&private_display->lock);
+                       private_output->vblank = tdm_vblank_create(private_display, private_output, NULL);
+                       _pthread_mutex_lock(&private_display->lock);
+                       TDM_GOTO_IF_FAIL(private_output->vblank != NULL, commit_failed);
+               }
+
+               if (!private_output->waiting_vblank) {
+                       /* tdm_vblank APIs is for server. it should be called in unlock status*/
+                       _pthread_mutex_unlock(&private_display->lock);
+                       ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
+                       _pthread_mutex_lock(&private_display->lock);
+                       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+                       private_output->waiting_vblank = 1;
+
+                       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+                               TDM_INFO("layer(%p) commit: wait vblank", private_layer);
+               }
+       }
+
+       return ret;
+
+commit_failed:
+       if (layer_commit_handler) {
+               LIST_DEL(&layer_commit_handler->link);
+               free(layer_commit_handler);
+       }
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
+{
+       LAYER_FUNC_ENTRY();
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       if (private_display->commit_type == TDM_COMMIT_TYPE_NONE)
+               private_display->commit_type = TDM_COMMIT_TYPE_LAYER;
+       else if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
+               TDM_ERR("Can't supported. Use tdm_output_commit");
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
+               TDM_ERR("layer(%p)'s output(%d) dpms: %s", layer, private_output->pipe,
+                               tdm_dpms_str(private_output->current_dpms_value));
+               _pthread_mutex_unlock(&private_display->lock);
+               return TDM_ERROR_DPMS_OFF;
+       }
+
+       if (tdm_debug_module & TDM_DEBUG_COMMIT)
+               TDM_INFO("layer(%p) commit", private_layer);
+
+       ret = _tdm_layer_commit(private_layer, func, user_data);
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
+EXTERN tdm_error
+tdm_layer_is_committing(tdm_layer *layer, unsigned int *committing)
+{
+       LAYER_FUNC_ENTRY();
+
+       TDM_RETURN_VAL_IF_FAIL(committing != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       _pthread_mutex_lock(&private_display->lock);
+
+       *committing = private_layer->committing;
+
+       _pthread_mutex_unlock(&private_display->lock);
+
+       return ret;
+}
+
 EXTERN tbm_surface_h
 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
 {
@@ -1803,9 +2229,17 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
                        TDM_INFO("layer(%p) waiting_buffer(%p)",
                                         private_layer, private_layer->waiting_buffer);
 
-               ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
-               if (ret != TDM_ERROR_NONE)
-                       TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
+               if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
+                       ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
+                       if (ret != TDM_ERROR_NONE)
+                               TDM_ERR("_tdm_output_commit() is fail");
+               } else if (private_display->commit_type == TDM_COMMIT_TYPE_LAYER) {
+                       ret = _tdm_layer_commit(private_layer, NULL, NULL);
+                       if (ret != TDM_ERROR_NONE)
+                               TDM_ERR("layer(%p) _tdm_layer_commit() is fail", private_layer);
+               } else {
+                       TDM_NEVER_GET_HERE();
+               }
        }
 
        _pthread_mutex_unlock(&private_display->lock);
index 61d8658..f377fae 100644 (file)
@@ -96,7 +96,7 @@ extern "C" {
 
 #define TDM_WARNING_IF_FAIL(cond)  { \
        if (!(cond)) \
-               TDM_ERR("'%s' failed", #cond); \
+               TDM_WRN("'%s' failed", #cond); \
 }
 #define TDM_GOTO_IF_FAIL(cond, dst) { \
        if (!(cond)) { \
index 55ef89b..0d18743 100644 (file)
@@ -201,6 +201,46 @@ done:
 }
 
 static void
+_tdm_monitor_server_commit_per_vblank(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy)
+{
+       int enable;
+       char *arg;
+       char *end;
+
+       if (argc < 3) {
+               _tdm_monitor_server_usage(argv[0], reply, len);
+               return;
+       }
+
+       arg = argv[2];
+       enable = strtol(arg, &end, 10);
+
+       tdm_display_enable_commit_per_vblank(dpy, enable);
+
+       TDM_SNPRINTF(reply, len, "%s the commit-per-vblank\n", (enable) ? "enable" : "disable");
+}
+
+static void
+_tdm_monitor_server_fps(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy)
+{
+       int enable;
+       char *arg;
+       char *end;
+
+       if (argc < 3) {
+               _tdm_monitor_server_usage(argv[0], reply, len);
+               return;
+       }
+
+       arg = argv[2];
+       enable = strtol(arg, &end, 10);
+
+       tdm_display_enable_fps(dpy, enable);
+
+       TDM_SNPRINTF(reply, len, "%s to print fps\n", (enable) ? "enable" : "disable");
+}
+
+static void
 _tdm_monitor_server_prop(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy)
 {
        tdm_output *output;
@@ -394,6 +434,18 @@ static struct {
                "console"
        },
        {
+               "commit_per_vblank", _tdm_monitor_server_commit_per_vblank,
+               "enable/disable the commit per vblank",
+               "<enable>",
+               "0 or 1"
+       },
+       {
+               "fps", _tdm_monitor_server_fps,
+               "enable/disable to print fps",
+               "<enable>",
+               "0 or 1"
+       },
+       {
                "prop", _tdm_monitor_server_prop,
                "set the property of a output or a layer",
                "<output_idx>[,<layer_idx>]:<prop_name>,<value>",
index 5749782..0e52605 100644 (file)
@@ -80,6 +80,7 @@ enum {
        TDM_DEBUG_THREAD    = (1 << 2),
        TDM_DEBUG_SERVER    = (1 << 3),
        TDM_DEBUG_VBLANK    = (1 << 4),
+       TDM_DEBUG_COMMIT    = (1 << 5),
 };
 
 extern int tdm_debug_module;
@@ -111,6 +112,12 @@ enum {
 
 #define TDM_DUMP_DIR    "/tmp"
 
+typedef enum {
+       TDM_COMMIT_TYPE_NONE,
+       TDM_COMMIT_TYPE_OUTPUT,
+       TDM_COMMIT_TYPE_LAYER,
+} tdm_commit_type;
+
 typedef struct _tdm_private_display tdm_private_display;
 typedef struct _tdm_private_output tdm_private_output;
 typedef struct _tdm_private_layer tdm_private_layer;
@@ -120,7 +127,8 @@ typedef struct _tdm_private_loop tdm_private_loop;
 typedef struct _tdm_private_server tdm_private_server;
 typedef struct _tdm_private_thread tdm_private_thread;
 typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler;
-typedef struct _tdm_private_commit_handler tdm_private_commit_handler;
+typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler;
+typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler;
 typedef struct _tdm_private_change_handler tdm_private_change_handler;
 
 struct _tdm_private_display {
@@ -161,6 +169,12 @@ struct _tdm_private_display {
 
        /* output order */
        tdm_output **outputs;
+
+       /* calling a output commit per a vblank */
+       int commit_per_vblank;
+       tdm_commit_type commit_type;
+
+       int print_fps;
 };
 
 struct _tdm_private_output {
@@ -186,7 +200,13 @@ struct _tdm_private_output {
        struct list_head layer_list;
        struct list_head capture_list;
        struct list_head vblank_handler_list;
-       struct list_head commit_handler_list;
+       struct list_head output_commit_handler_list;
+
+       /* for layer commit */
+       struct list_head layer_commit_handler_list;
+       struct list_head pending_commit_handler_list;
+       tdm_vblank *vblank;
+       int waiting_vblank;
 
        /* seperate list for multi-thread*/
        struct list_head change_handler_list_main;
@@ -217,6 +237,10 @@ struct _tdm_private_layer {
        struct list_head capture_list;
 
        unsigned int usable;
+       unsigned int committing;
+
+       double fps_stamp;
+       unsigned int fps_count;
 };
 
 struct _tdm_private_pp {
@@ -298,13 +322,15 @@ struct _tdm_private_vblank_handler {
        struct list_head link;
 
        tdm_private_output *private_output;
+       int interval;
+       int sync;
        tdm_output_vblank_handler func;
        void *user_data;
 
        pid_t owner_tid;
 };
 
-struct _tdm_private_commit_handler {
+struct _tdm_private_output_commit_handler {
        struct list_head link;
 
        tdm_private_output *private_output;
@@ -314,6 +340,14 @@ struct _tdm_private_commit_handler {
        pid_t owner_tid;
 };
 
+struct _tdm_private_layer_commit_handler {
+       struct list_head link;
+
+       tdm_private_layer *private_layer;
+       tdm_layer_commit_handler func;
+       void *user_data;
+};
+
 struct _tdm_private_change_handler {
        struct list_head link;
 
@@ -593,6 +627,10 @@ tdm_error
 tdm_display_enable_path(const char *path);
 tdm_error
 tdm_display_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable);
+tdm_error
+tdm_display_enable_commit_per_vblank(tdm_private_display *private_display, int enable);
+tdm_error
+tdm_display_enable_fps(tdm_private_display *private_display, int enable);
 
 void
 tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len);
index 947fcf6..114e743 100644 (file)
@@ -575,9 +575,6 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence,
                VWR("couldn't update sw timer");
        }
 
-       if (private_vblank->last_seq >= wait_info->target_seq)
-               TDM_ERR("last_seq(%u) target_seq(%u)", private_vblank->last_seq, wait_info->target_seq);
-
        /* tv_sec & tv_usec shouldn't be zero. But sometimes they are zero in some hardware.
         * We need to prohibit that last_time becomes zero because "last_time == 0" means
         * that a tdm_vblank object is just created and doesn't have the first vblank event.
@@ -819,7 +816,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
        TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        if (private_vblank->owner_tid != syscall(SYS_gettid)) {
-               TDM_ERR("SHOULD be called in the owner thread");
+               TDM_ERR("SHOULD be called in the owner thread(%d)", (int)private_vblank->owner_tid);
                return TDM_ERROR_BAD_REQUEST;
        }
 
index 1b3854e..cfd6a02 100644 (file)
@@ -819,7 +819,7 @@ exit_test(int sig)
                LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
                        tdm_layer_unset_buffer(l->layer);
                }
-               tdm_output_commit(o->output, 0, NULL, NULL);
+               tdm_layer_commit(l->layer, NULL, NULL);
        }
 
        LIST_FOR_EACH_ENTRY_SAFE(p, pp, &data->pp_list, link) {
@@ -994,7 +994,7 @@ layer_get_buffer(tdm_test_server_layer *l)
 }
 
 static void
-layer_cb_commit(tdm_output *output, unsigned int sequence,
+layer_cb_commit(tdm_layer *layer, unsigned int sequence,
                                unsigned int tv_sec, unsigned int tv_usec,
                                void *user_data)
 {
@@ -1038,9 +1038,9 @@ layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b)
        tdm_buffer_add_release_handler(b, layer_cb_buffer_release, NULL);
 
        if (data->do_vblank)
-               ret = tdm_output_commit(l->o->output, 0, layer_cb_commit, l);
+               ret = tdm_layer_commit(l->layer, layer_cb_commit, l);
        else
-               ret = tdm_output_commit(l->o->output, 0, NULL, NULL);
+               ret = tdm_layer_commit(l->layer, NULL, NULL);
        TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
 
        printf("show:\tl(%p) b(%p)\n", l, b);