* Taeheon Kim <th908.kim@samsung.com>,
* YoungJun Cho <yj44.cho@samsung.com>,
* SooChan Lim <sc1.lim@samsung.com>,
- * Boram Park <sc1.lim@samsung.com>
+ * Boram Park <boram1288.park@samsung.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
tdm_output *output = private_vblank->output;
tdm_output_conn_status connection = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
unsigned int vrefresh = TDM_VBLANK_DEFAULT_VREFRESH;
+ const tdm_output_mode *mode = NULL;
tdm_error ret;
ret = tdm_output_get_conn_status(output, &connection);
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
- if (connection == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
- const tdm_output_mode *mode = NULL;
- tdm_output_get_mode(output, &mode);
- if (mode)
- vrefresh = mode->vrefresh;
- else
- VWR("mode not setted!!!");
- }
+ ret = tdm_output_get_mode(output, &mode);
+ if (ret == TDM_ERROR_NONE && mode)
+ vrefresh = mode->vrefresh;
+ else
+ VWR("mode not setted!!!");
private_vblank->connection = connection;
private_vblank->vrefresh = vrefresh;
}
/* LCOV_EXCL_STOP */
+static tdm_error
+_tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ if (private_vblank->fps_fixed) {
+ VIN("fps(%u) can't be changed", private_vblank->fps);
+ return TDM_ERROR_NONE;
+ }
+
+ private_vblank->fps_changeable = 0;
+
+ if (private_vblank->fps == fps)
+ return TDM_ERROR_NONE;
+
+ private_vblank->fps = fps;
+ private_vblank->check_HW_or_SW = 1;
+
+ VIN("fps(%u) changed", fps);
+
+ return TDM_ERROR_NONE;
+}
+
+static tdm_error
+_tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ if (private_vblank->ignore_global_fps == ignore)
+ return TDM_ERROR_NONE;
+
+ private_vblank->ignore_global_fps = ignore;
+ private_vblank->check_HW_or_SW = 1;
+
+ VIN("ignore_global_fps(%u)", private_vblank->ignore_global_fps);
+
+ return TDM_ERROR_NONE;
+}
+
EXTERN tdm_error
tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps)
{
tdm_private_vblank *v = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
continue;
}
- tdm_vblank_set_fps(v, fps);
-
- TDM_INFO("(pid:%u) '%s' fps changed: %d", pid, v->name, fps);
+ ret = _tdm_vblank_set_fps(v, fps);
+ if (ret == TDM_ERROR_NONE)
+ TDM_INFO("(pid:%u) '%s' fps changed: %d", pid, v->name, fps);
+ else
+ TDM_ERR("(pid:%u) '%s' fps changing failed: %d", pid, v->name, fps);
}
pthread_mutex_unlock(&valid_list_lock);
tdm_vblank_set_client_ignore_global_fps(unsigned int pid, const char *name, unsigned int ignore)
{
tdm_private_vblank *v = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER);
continue;
}
- tdm_vblank_ignore_global_fps(v, ignore);
-
- TDM_INFO("(pid:%u) '%s' ignore changed: %u", pid, v->name, ignore);
+ ret = _tdm_vblank_ignore_global_fps(v, ignore);
+ if (ret == TDM_ERROR_NONE)
+ TDM_INFO("(pid:%u) '%s' ignore changed: %u", pid, v->name, ignore);
+ else
+ TDM_ERR("(pid:%u) '%s' ignore changing failed: %u", pid, v->name, ignore);
}
pthread_mutex_unlock(&valid_list_lock);
vblank_create.base.sync = 0;
vblank_create.vblank_stamp = private_vblank->stamp;
- ret = tdm_thread_cb_call(private_vblank->dpy, &vblank_create.base);
+ ret = tdm_thread_cb_call(private_vblank->dpy, &vblank_create.base, 1);
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
return TDM_ERROR_NONE;
tdm_private_vblank *private_vblank;
tdm_error ret;
- TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER, NULL);
- TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(tdm_output_is_valid(output), TDM_ERROR_INVALID_PARAMETER, NULL);
+ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL);
+ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL);
if (error)
*error = TDM_ERROR_NONE;
/* LCOV_EXCL_STOP */
}
- tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank);
+ ret = tdm_output_add_change_handler(output, _tdm_vblank_cb_output_change, private_vblank);
+ if (ret != TDM_ERROR_NONE) {
+ free(private_vblank);
+ if (error)
+ *error = TDM_ERROR_OPERATION_FAILED;
+ TDM_ERR("tdm_output_add_change_handler failed");
+ return NULL;
+ }
private_vblank->stamp = ++stamp;
private_vblank->owner_tid = syscall(SYS_gettid);
EXTERN tdm_error
tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps)
{
- tdm_private_vblank *private_vblank = vblank;
-
TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
- if (private_vblank->fps_fixed) {
- VIN("fps(%u) can't be changed", private_vblank->fps);
- return TDM_ERROR_NONE;
- }
-
- private_vblank->fps_changeable = 0;
-
- if (private_vblank->fps == fps)
- return TDM_ERROR_NONE;
-
- private_vblank->fps = fps;
- private_vblank->check_HW_or_SW = 1;
-
- VIN("fps(%u) changed", fps);
-
- return TDM_ERROR_NONE;
+ return _tdm_vblank_set_fps(vblank, fps);
}
EXTERN tdm_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(tdm_vblank_is_valid(vblank), 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;
-
- VIN("ignore_global_fps(%u)", private_vblank->ignore_global_fps);
-
- return TDM_ERROR_NONE;
+ return _tdm_vblank_ignore_global_fps(vblank, ignore);
}
EXTERN tdm_error
tdm_private_vblank *private_vblank = vblank;
TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(offset >= 0, TDM_ERROR_INVALID_PARAMETER);
if (private_vblank->offset == offset)
return TDM_ERROR_NONE;
vblank_sw.base.data = NULL;
vblank_sw.base.sync = 0;
- ret = tdm_thread_cb_call(private_vblank, &vblank_sw.base);
+ ret = tdm_thread_cb_call(private_vblank, &vblank_sw.base, 1);
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
return TDM_ERROR_NONE;
{
tdm_private_vblank *private_vblank = wait_info->private_vblank;
tdm_error ret;
+ double last, prev, req, curr, target;
+ unsigned int skip;
if (private_vblank->last_type != VBLANK_EVENT_TYPE_SW) {
- VIN("Use SW vblank");
+ tdm_output_dpms dpms;
+
+ tdm_output_get_dpms(private_vblank->output, &dpms);
+
+ VIN("Use SW vblank. connection(%s), dpms(%s), vrefresh(%d), fps(%d), offset(%d)",
+ tdm_status_str(private_vblank->connection), tdm_dpms_str(dpms),
+ private_vblank->vrefresh, private_vblank->fps, private_vblank->offset);
private_vblank->last_type = VBLANK_EVENT_TYPE_SW;
}
if (private_vblank->last_time == 0) {
/* SW vblank starts from now. SW vblank doesn't need to be aligned with HW vblank. */
private_vblank->last_seq = 0;
- private_vblank->last_time = tdm_helper_get_time();
+ private_vblank->last_time = tdm_helper_get_time() - private_vblank->vblank_gap;
/* +1 ms to call the handler ASAP at the first. no matter for SW timer. */
wait_info->target_seq = 1;
- wait_info->target_time = private_vblank->last_time + 0.001;
+ }
- VDB("wait(%p) last(%.6f) target(%.6f) target sequence(%u)",
- wait_info, private_vblank->last_time, wait_info->target_time, wait_info->target_seq);
- } else {
- double last, prev, req, curr, target;
- unsigned int skip;
+ last = private_vblank->last_time;
+ req = wait_info->req_time;
- last = private_vblank->last_time;
- req = wait_info->req_time;
+ /* make sure that req time is bigger than last. */
+ if (req < last)
+ req = last;
- /* make sure that req time is bigger than last. */
- if (req < last)
- req = last;
-
- skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
- prev = last + private_vblank->vblank_gap * skip;
+ skip = (unsigned int)((req - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
+ prev = last + private_vblank->vblank_gap * skip;
- curr = tdm_helper_get_time();
- target = prev + private_vblank->vblank_gap * wait_info->interval;
+ curr = tdm_helper_get_time();
+ target = prev + private_vblank->vblank_gap * wait_info->interval;
- while (target < curr)
- target += private_vblank->vblank_gap;
+ while (target < curr)
+ target += private_vblank->vblank_gap;
- wait_info->target_seq = private_vblank->last_seq;
- wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
+ wait_info->target_seq = private_vblank->last_seq;
+ wait_info->target_seq += (unsigned int)((target - last) / private_vblank->vblank_gap + TDM_TIME_MARGIN);
- wait_info->target_time = target;
+ wait_info->target_time = target + (double)(private_vblank->offset) / 1000;
- VDB("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) targ_seq(%u)",
- wait_info, last, req - last, prev - last, curr - last,
- target, target - last, skip, wait_info->target_seq);
- }
+ VDB("wait(%p) last(%.6f) req(%.6f) prev(%.6f) curr(%.6f) targ(%.6f,%.6f) skip(%u) targ_seq(%u)",
+ wait_info, last, req - last, prev - last, curr - last,
+ target, target - last, skip, wait_info->target_seq);
_tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list);
wait_info->user_data = user_data;
wait_info->private_vblank = private_vblank;
- if (private_vblank->ignore_global_fps ||
+ if (!private_vblank->resource ||
+ private_vblank->ignore_global_fps ||
vblank_global_fps == 0 ||
private_vblank->fps < vblank_global_fps)
fps = private_vblank->fps;