vblank: support global fps 40/128640/2
authorBoram Park <boram1288.park@samsung.com>
Thu, 27 Apr 2017 04:39:10 +0000 (13:39 +0900)
committerBoram Park <boram1288.park@samsung.com>
Wed, 10 May 2017 23:12:25 +0000 (08:12 +0900)
Change-Id: Iec9c621fc270336a0d95c4a2f90b583704f9cc46

include/tdm.h
src/tdm_monitor_server.c
src/tdm_vblank.c

index 63700a7..29c8193 100644 (file)
@@ -924,6 +924,20 @@ tdm_error
 tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps);
 
 /**
+ * @brief Set the vblank global fps for the entire system.
+ * @param[in] enable 1:enable, 0:disable
+ * @param[in] fps The vblank global fps
+ * @details
+ * This global fps will be applied to all client's vblanks for all outputs.
+ * If the client's vblank fps is less than this, the global fps will be ignored
+ * for that client. And if a client calls #tdm_vblank_ignore_global_fps to ignore
+ * the global fps, it will be ignored also.
+ * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ */
+tdm_error
+tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps);
+
+/**
  * @brief Create a vblank object
  * @param[in] dpy A display object
  * @param[in] output A output object
@@ -982,6 +996,20 @@ tdm_error
 tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps);
 
 /**
+ * @brief Ignore the vblank global fps
+ * @details
+ * The global fps will be applied to all client's vblanks for all outputs.
+ * If the client's vblank fps is less than this, the global fps will be ignored
+ * for that client. And if a client calls #tdm_vblank_ignore_global_fps to ignore
+ * the global fps, it will be ignored also.
+ * @param[in] vblank A vblank object
+ * @param[in] ignore 1: ignore 0:not ignore(default)
+ * @return #TDM_ERROR_NONE if success. Otherwise, error value.
+ */
+tdm_error
+tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore);
+
+/**
  * @brief Set the offset(milli-second) to a vblank object
  * @details Default is @b 0.
  * @param[in] vblank A vblank object
index 2df4dd3..c46d457 100644 (file)
@@ -308,6 +308,36 @@ _tdm_monitor_server_vblank_fps(unsigned int pid, char *cwd, int argc, char *argv
 }
 
 static void
+_tdm_monitor_server_global_fps(unsigned int pid, char *cwd, int argc, char *argv[],
+                                                          char *reply, int *len, tdm_display *dpy)
+{
+       unsigned int fps;
+       char *arg;
+       char *end;
+       tdm_error ret;
+
+       if (argc < 3) {
+               _tdm_monitor_server_usage(argv[0], reply, len);
+               return;
+       }
+
+       arg = argv[2];
+       fps = strtol(arg, &end, 10);
+
+       if (fps > 0)
+               ret = tdm_vblank_enable_global_fps(1, fps);
+       else
+               ret = tdm_vblank_enable_global_fps(0, 0);
+
+       if (ret != TDM_ERROR_NONE) {
+               TDM_SNPRINTF(reply, len, "can't set '%u' fps to global fps\n", fps);
+               return;
+       }
+
+       TDM_SNPRINTF(reply, len, "success: '%u' global fps\n", fps);
+}
+
+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;
@@ -531,6 +561,12 @@ static struct {
                NULL
        },
        {
+               "global_fps", _tdm_monitor_server_global_fps,
+               "set the global vblank fps for the entire system",
+               "<fps>",
+               NULL
+       },
+       {
                "prop", _tdm_monitor_server_prop,
                "set the property of a output or a layer",
                "<output_idx>[,<layer_idx>]:<prop_name>,<value>",
index ee8d352..cb21a0c 100644 (file)
@@ -97,6 +97,7 @@ typedef struct _tdm_private_vblank {
        unsigned int fps;
        int offset;
        unsigned int enable_fake;
+       unsigned int ignore_global_fps;
 
        double vblank_gap;
        unsigned int quotient;
@@ -142,6 +143,7 @@ static pthread_mutex_t valid_list_lock;
 static struct list_head valid_vblank_list;
 static struct list_head valid_wait_list;
 static unsigned int vblank_list_inited;
+static unsigned int vblank_global_fps;
 static double stamp = 0;
 
 static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data);
@@ -371,6 +373,32 @@ tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned in
        return TDM_ERROR_NONE;
 }
 
+EXTERN tdm_error
+tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps)
+{
+       tdm_private_vblank *v = NULL;
+
+       if (enable)
+               TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
+
+       TDM_INFO("global fps: %s fps(%d)", (enable) ? "enabled" : "disabled", fps);
+
+       pthread_mutex_lock(&valid_list_lock);
+
+       vblank_global_fps = (enable) ? fps : 0;
+
+       LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) {
+               /* skip if vblank is created in server side */
+               if (!v->resource)
+                       continue;
+
+               v->check_HW_or_SW = 1;
+       }
+       pthread_mutex_unlock(&valid_list_lock);
+
+       return TDM_ERROR_NONE;
+}
+
 EXTERN tdm_vblank *
 tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error)
 {
@@ -543,6 +571,25 @@ tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps)
 }
 
 EXTERN tdm_error
+tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore)
+{
+       tdm_private_vblank *private_vblank = vblank;
+
+       TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if (private_vblank->ignore_global_fps == ignore)
+               return TDM_ERROR_NONE;
+
+       private_vblank->ignore_global_fps = ignore;
+       private_vblank->check_HW_or_SW = 1;
+
+       if (tdm_debug_module & TDM_DEBUG_VBLANK)
+               VIN("ignore_global_fps(%d)", private_vblank->ignore_global_fps);
+
+       return TDM_ERROR_NONE;
+}
+
+EXTERN tdm_error
 tdm_vblank_set_offset(tdm_vblank *vblank, int offset)
 {
        tdm_private_vblank *private_vblank = vblank;
@@ -949,6 +996,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
 {
        tdm_private_vblank *private_vblank = vblank;
        tdm_vblank_wait_info *wait_info;
+       unsigned int fps;
        tdm_error ret;
 
        TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
@@ -988,10 +1036,17 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
        wait_info->user_data = user_data;
        wait_info->private_vblank = private_vblank;
 
+       if (private_vblank->ignore_global_fps ||
+               vblank_global_fps == 0 ||
+               private_vblank->fps < vblank_global_fps)
+               fps = private_vblank->fps;
+       else
+               fps = vblank_global_fps;
+
        if (private_vblank->check_HW_or_SW) {
                private_vblank->check_HW_or_SW = 0;
-               private_vblank->vblank_gap = 1.0 / private_vblank->fps;
-               private_vblank->quotient = private_vblank->vrefresh / private_vblank->fps;
+               private_vblank->vblank_gap = 1.0 / fps;
+               private_vblank->quotient = private_vblank->vrefresh / fps;
        }
 
        /* 1) if fps != factor of vrefresh, SW timer
@@ -1000,7 +1055,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec,
         * 3) if fps == factor of vrefresh && dpms == on && offset != 0, HW vblank + SW timer
         * In case of 1), we really don't need to align with HW vblank.
         */
-       if (private_vblank->vrefresh % private_vblank->fps)
+       if (private_vblank->vrefresh % fps)
                wait_info->type = VBLANK_TYPE_SW;
        else if (private_vblank->dpms == TDM_OUTPUT_DPMS_OFF)
                wait_info->type = VBLANK_TYPE_SW_FAKE;
@@ -1115,8 +1170,9 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len)
        tdm_private_vblank *v = NULL;
 
        TDM_SNPRINTF(reply, len, "[Client Vblank List]\n");
+       TDM_SNPRINTF(reply, len, "* global fps: %u\n", vblank_global_fps);
        TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n");
-       TDM_SNPRINTF(reply, len, "name         fps offset fake process\n");
+       TDM_SNPRINTF(reply, len, "name         fps ignore offset fake process\n");
        TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n");
 
        pthread_mutex_lock(&valid_list_lock);
@@ -1130,8 +1186,8 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len)
                        proc_name = tdm_server_get_client_name(pid);
                }
 
-               TDM_SNPRINTF(reply, len, "%-12s %u  %d      %u    %s (pid: %u)\n",
-                                        v->name, v->fps, v->offset, v->enable_fake,
+               TDM_SNPRINTF(reply, len, "%-12s %u  %u     %d      %u    %s (pid: %u)\n",
+                                        v->name, v->fps, v->ignore_global_fps, v->offset, v->enable_fake,
                                         (proc_name) ? proc_name : "Unknown", pid);
        }
        pthread_mutex_unlock(&valid_list_lock);