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
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
}
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;
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>",
unsigned int fps;
int offset;
unsigned int enable_fake;
+ unsigned int ignore_global_fps;
double vblank_gap;
unsigned int quotient;
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);
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)
{
}
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;
{
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);
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
* 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;
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);
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);