[hwc] adopt COMMIT_PER_VBLANK functionality for each ouptut 13/159513/4 accepted/tizen/unified/20171113.161439 submit/tizen/20171113.023250
authorSergey Sizonov <s.sizonov@samsung.com>
Thu, 9 Nov 2017 09:04:24 +0000 (12:04 +0300)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 13 Nov 2017 02:04:49 +0000 (02:04 +0000)
The new TDM HWC API made us to provide the COMMIT_PER_VBLANK
functionality for each output independently.

An output tdm-backend provides the hwc capability for isn't
intended to be managed by tdm_layer_xxx functions, so there's
no need to have the COMMIT_PER_VBLANK functionality turned on
for such output, in contrast to outputs tdm-backend doesn't
provide the hwc capability for.

So now the COMMIT_PER_VBLANK functionality for the outputs
which don't support hwc behaves depend on a TDM_COMMIT_PER_VBLANK
env variable while outputs which support are always have this
functionality turned off (like they read TDM_COMMIT_PER_VBLANK as '0')

Change-Id: I8454915d635016edfcb2dca3ac4bd455c48f4c44
Signed-off-by: Sergey Sizonov <s.sizonov@samsung.com>
include/tdm_helper.h
src/tdm.c
src/tdm_helper.c
src/tdm_layer.c
src/tdm_monitor_server.c
src/tdm_output.c
src/tdm_private.h

index 3d1d252..8bae8fa 100644 (file)
@@ -221,10 +221,20 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len);
  * @brief Get whether the commit-per-vblank functionality is enabled or not.
  * @param[in] dpy A display object
  * @return 1 if enabled. Otherwise, 0.
+ *
+ * @deprecated use @c tdm_helper_output_commit_per_vblank_enabled instead
  */
 int
 tdm_helper_commit_per_vblank_enabled(tdm_display *dpy);
 
+/**
+ * @brief Get whether the commit-per-vblank functionality is enabled or not for the output.
+ * @param[in] output An output the functionality has to be checked for
+ * @return -1 if error occurred, 1 if enabled, 0 if disabled.
+ */
+int
+tdm_helper_output_commit_per_vblank_enabled(tdm_output *output);
+
 #ifdef __cplusplus
 }
 #endif
index 7c12dfe..2246fc4 100644 (file)
--- a/src/tdm.c
+++ b/src/tdm.c
@@ -943,14 +943,6 @@ tdm_display_init(tdm_error *error)
        if (str)
                tdm_display_enable_path(str);
 
-       str = getenv("TDM_COMMIT_PER_VBLANK");
-       if (str) {
-               char *end;
-               int enable = strtol(str, &end, 10);
-
-               tdm_display_enable_commit_per_vblank(private_display, enable);
-       }
-
        if (pthread_mutex_init(&private_display->lock, NULL)) {
                ret = TDM_ERROR_OPERATION_FAILED;
                TDM_ERR("mutex init failed: %m");
@@ -1010,7 +1002,6 @@ 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;
 
        tdm_private_output *o = NULL;
        LIST_FOR_EACH_ENTRY(o, &private_display->output_list, link) {
@@ -1018,6 +1009,22 @@ tdm_display_init(tdm_error *error)
                        tdm_output_need_validate_event_init(o);
        }
 
+       /* the COMMIT_PER_VBLANK functionality is ability of an output to support
+        * several operational modes (commit_per_vblank modes) related to tdm_commit;
+        * this functionality can be turned off which means a default mode */
+       str = getenv("TDM_COMMIT_PER_VBLANK");
+       if (str) {
+               tdm_private_output *o = NULL;
+               char *end;
+               int mode = strtol(str, &end, 10);
+
+               /* outputs which support hwc capability can work only
+                * if commit_per_vblank mode is '0' (default mode) */
+               LIST_FOR_EACH_ENTRY(o, &private_display->output_list, link)
+                       if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC))
+                               tdm_output_choose_commit_per_vblank_mode(o, mode);
+       }
+
        g_private_display = private_display;
 
        if (error)
@@ -1331,25 +1338,6 @@ enable_fail:
 }
 
 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 == 0)
-               TDM_INFO("commit per vblank: disable");
-       else 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 {
-               private_display->commit_per_vblank = 1;
-               TDM_INFO("commit per vblank: enable (changed to 1 layer)");
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-INTERN tdm_error
 tdm_display_enable_fps(tdm_private_display *private_display, int enable)
 {
        private_display->print_fps = enable;
index a22e0cc..bcd7aec 100644 (file)
@@ -1064,12 +1064,18 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len)
 EXTERN int
 tdm_helper_commit_per_vblank_enabled(tdm_display *dpy)
 {
-       tdm_private_display *private_display;
+       TDM_ERR("the deprecated function, use 'tdm_helper_output_commit_per_vblank_enabled' instead.");
 
-       TDM_RETURN_VAL_IF_FAIL(dpy != NULL, 0);
+       return 0;
+}
 
-       private_display = dpy;
+EXTERN int
+tdm_helper_output_commit_per_vblank_enabled(tdm_output *output)
+{
+       tdm_private_output *private_output = output;
+
+       TDM_RETURN_VAL_IF_FAIL(private_output != NULL, -1);
 
-       return private_display->commit_per_vblank;
+       return !!private_output->commit_per_vblank;
 }
 
index cb4ef55..c1a5d6b 100644 (file)
@@ -713,9 +713,8 @@ 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;
 
-       TDM_RETURN_VAL_IF_FAIL(private_display->commit_per_vblank > 0, 1);
+       TDM_RETURN_VAL_IF_FAIL(private_output->commit_per_vblank > 0, 1);
 
        /* There is a previous commit request which is not done and displayed on screen yet.
         * We can't commit at this time.
@@ -726,7 +725,7 @@ _tdm_layer_commit_possible(tdm_private_layer *private_layer)
                return 0;
        }
 
-       if (private_display->commit_per_vblank == 1 && _tdm_lauer_get_output_used_layer_count(private_output) > 1) {
+       if (private_output->commit_per_vblank == 1 && _tdm_lauer_get_output_used_layer_count(private_output) > 1) {
                if (tdm_debug_module & TDM_DEBUG_COMMIT)
                        TDM_INFO("layer(%p) commit: not possible(more than 2 layers)", private_layer);
                return 0;
@@ -836,8 +835,8 @@ _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_da
                                 private_layer, private_layer->waiting_buffer,
                                 (layer_commit_handler->committed_buffer) ? layer_commit_handler->committed_buffer->buffer : NULL);
 
-       if (!private_display->commit_per_vblank) {
-               TDM_GOTO_IF_FAIL(private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT, commit_failed);
+       if (!private_output->commit_per_vblank) {
+               TDM_GOTO_IF_FAIL(private_output->commit_type == TDM_COMMIT_TYPE_OUTPUT, commit_failed);
 
                LIST_ADDTAIL(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
                ret = tdm_output_commit_internal(private_layer->private_output, 0, _tdm_layer_cb_output_commit, layer_commit_handler);
@@ -846,7 +845,7 @@ _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_da
                if (tdm_debug_module & TDM_DEBUG_COMMIT)
                        TDM_INFO("layer(%p) commit: no commit-per-vblank", private_layer);
        } else {
-               TDM_GOTO_IF_FAIL(private_display->commit_type == TDM_COMMIT_TYPE_LAYER, commit_failed);
+               TDM_GOTO_IF_FAIL(private_output->commit_type == TDM_COMMIT_TYPE_LAYER, commit_failed);
 
                if (private_layer->committing)
                        TDM_WRN("layer(%d) too many commit", private_layer->index);
@@ -908,11 +907,11 @@ tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_dat
 
        _pthread_mutex_lock(&private_display->lock);
 
-       if (private_display->commit_type == TDM_COMMIT_TYPE_NONE) {
-               if (!private_display->commit_per_vblank)
-                       private_display->commit_type = TDM_COMMIT_TYPE_OUTPUT;
+       if (private_output->commit_type == TDM_COMMIT_TYPE_NONE) {
+               if (!private_output->commit_per_vblank)
+                       private_output->commit_type = TDM_COMMIT_TYPE_OUTPUT;
                else
-                       private_display->commit_type = TDM_COMMIT_TYPE_LAYER;
+                       private_output->commit_type = TDM_COMMIT_TYPE_LAYER;
        }
 
        if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
@@ -1077,11 +1076,11 @@ _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->buffer);
 
-               if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
+               if (private_output->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
                        ret = tdm_output_commit_internal(private_layer->private_output, 0, NULL, NULL);
                        if (ret != TDM_ERROR_NONE)
                                TDM_ERR("tdm_output_commit_internal() is fail");
-               } else if (private_display->commit_type == TDM_COMMIT_TYPE_LAYER) {
+               } else if (private_output->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);
index e7844a5..07c2487 100644 (file)
@@ -220,23 +220,34 @@ 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)
+_tdm_monitor_server_choose_commit_per_vblank_mode(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy)
 {
-       int enable;
+       int output_idx;
+       int mode;
        char *arg;
        char *end;
+       tdm_error err;
 
-       if (argc < 3) {
+       /* TODO: do we have to provide an ability to choose commit_per_vblank mode outside? */
+
+       if (argc < 4) {
                _tdm_monitor_server_usage(argv[0], reply, len);
                return;
        }
 
        arg = argv[2];
-       enable = strtol(arg, &end, 10);
+       output_idx = strtol(arg, &end, 10);
 
-       tdm_display_enable_commit_per_vblank(dpy, enable);
+       arg = argv[3];
+       mode = strtol(arg, &end, 10);
 
-       TDM_SNPRINTF(reply, len, "%s the commit-per-vblank\n", (enable) ? "enable" : "disable");
+       err = tdm_output_choose_commit_per_vblank_mode(tdm_display_get_output(dpy, output_idx, NULL), mode);
+       if (err != TDM_ERROR_NONE) {
+               TDM_SNPRINTF(reply, len, "an error: output_idx or mode is wrong\n");
+               return;
+       }
+
+       TDM_SNPRINTF(reply, len, "the mode's been set\n");
 }
 
 static void
@@ -539,10 +550,10 @@ static struct {
                "console"
        },
        {
-               "commit_per_vblank", _tdm_monitor_server_commit_per_vblank,
-               "enable/disable the commit per vblank",
-               "<enable>",
-               "0 or 1"
+               "choose_commit_per_vblank_mode", _tdm_monitor_server_choose_commit_per_vblank_mode,
+               "choose a commit_per_vblank mode for the output",
+               "<output_idx> <mode>",
+               "0 1 or 1 2 or 2 0"
        },
        {
                "fps", _tdm_monitor_server_fps,
index 3dd945c..d445914 100644 (file)
@@ -690,7 +690,7 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
                TDM_INFO("handler(%p)", output_commit_handler);
        }
 
-       if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
+       if (private_output->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) {
                        if (private_layer->committed_buffer)
@@ -922,7 +922,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl
        /* TODO: this is ugly. But before using tdm_output_get_dpms_internal, we have
         * to check if all backends's DPMS operation has no problem.
         */
-       if (private_display->commit_per_vblank)
+       if (private_output->commit_per_vblank)
                tdm_output_get_dpms_internal(output, &dpms_value);
        else
                dpms_value = private_output->current_dpms_value;
@@ -999,15 +999,15 @@ 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) {
+       if (private_output->commit_type == TDM_COMMIT_TYPE_NONE)
+               private_output->commit_type = TDM_COMMIT_TYPE_OUTPUT;
+       else if (private_output->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) {
+       if (private_output->commit_per_vblank) {
                TDM_ERR("Use tdm_layer_commit");
                _pthread_mutex_unlock(&private_display->lock);
                return TDM_ERROR_BAD_REQUEST;
@@ -1298,7 +1298,7 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value)
        }
 
        /* TODO: this is ugly. But we have to check if all backends's DPMS operation has no problem. */
-       if (private_display->commit_per_vblank)
+       if (private_output->commit_per_vblank)
                if (*dpms_value != private_output->current_dpms_value) {
                        private_output->current_dpms_value = *dpms_value;
                        TDM_ERR("output(%d) dpms changed suddenly: %s",
@@ -1727,3 +1727,24 @@ tdm_output_need_validate_event_init(tdm_output *output)
 
        return ret;
 }
+
+INTERN tdm_error
+tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int mode)
+{
+       if (!private_output)
+               return TDM_ERROR_INVALID_PARAMETER;
+
+       if (mode < 0 || mode > 2)
+               return TDM_ERROR_INVALID_PARAMETER;
+
+       private_output->commit_per_vblank = mode;
+
+       if (private_output->commit_per_vblank == 0)
+               TDM_INFO("commit per vblank: disable");
+       else if (private_output->commit_per_vblank == 1)
+               TDM_INFO("commit per vblank: enable (1 layer)");
+       else if (private_output->commit_per_vblank == 2)
+               TDM_INFO("commit per vblank: enable (previous commit)");
+
+       return TDM_ERROR_NONE;
+}
index e6c0801..2a927db 100644 (file)
@@ -177,10 +177,6 @@ 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;
 };
 
@@ -231,6 +227,10 @@ struct _tdm_private_output {
                tdm_output_need_validate_handler hndl;
                int event_fd;
        } need_validate;
+
+       /* calling a output commit per a vblank */
+       int commit_per_vblank;
+       tdm_commit_type commit_type;
 };
 
 struct _tdm_private_layer {
@@ -464,6 +464,8 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value);
 
 tdm_error
 tdm_output_need_validate_event_init(tdm_output *output);
+tdm_error
+tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int mode);
 
 void
 tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data);
@@ -741,8 +743,6 @@ 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