timeline: convert vblank timestamp to MONOTONIC

All timeline event timestamps are in CLOCK_MONOTONIC already. DRM KMS
timestamps are practically guaranteed to be CLOCK_MONOTONIC too, even though
presentation clock could theoretically be something else. For other backends,
the presentation clock is likely CLOCK_MONOTONIC_RAW due to
weston_compositor_set_presentation_clock_software().

This patch ensures that the recorded vblank timestamp is in CLOCK_MONOTONIC.
Otherwise interpreting the timeline traces might be difficult to do accurately,
since it would be hard to recover the relationship between the presentation
clock and timeline event timestamps.

The time conversion routine is the simplest possible, I don't think we need any
more accurate conversion for timeline purposes. Besides, DRM-backend is the
only backend where the timings actually matter, the other backends are
software-timed anyway.

Since the clock domain of the "vblank" attribute potentially changes, the
attribute is renamed. Wesgr never used this attribute.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
dev
Pekka Paalanen 5 years ago
parent 40c519a3e6
commit 50aa3a76c0
  1. 40
      libweston/compositor.c
  2. 2
      libweston/timeline.c

@ -2938,6 +2938,39 @@ output_repaint_timer_handler(void *data)
return 0;
}
/** Convert a presentation timestamp to another clock domain
*
* \param compositor The compositor defines the presentation clock domain.
* \param presentation_stamp The timestamp in presentation clock domain.
* \param presentation_now Current time in presentation clock domain.
* \param target_clock Defines the target clock domain.
*
* This approximation relies on presentation_stamp to be close to current time.
* The further it is from current time and the bigger the speed difference
* between the two clock domains, the bigger the conversion error.
*
* Conversion error due to system load is biased and unbounded.
*/
static struct timespec
convert_presentation_time_now(struct weston_compositor *compositor,
const struct timespec *presentation_stamp,
const struct timespec *presentation_now,
clockid_t target_clock)
{
struct timespec target_now = {};
struct timespec target_stamp;
int64_t delta_ns;
if (compositor->presentation_clock == target_clock)
return *presentation_stamp;
clock_gettime(target_clock, &target_now);
delta_ns = timespec_sub_to_nsec(presentation_stamp, presentation_now);
timespec_add_nsec(&target_stamp, &target_now, delta_ns);
return target_stamp;
}
/**
* \ingroup output
*/
@ -2949,9 +2982,9 @@ weston_output_finish_frame(struct weston_output *output,
struct weston_compositor *compositor = output->compositor;
int32_t refresh_nsec;
struct timespec now;
struct timespec vblank_monotonic;
int64_t msec_rel;
assert(output->repaint_status == REPAINT_AWAITING_COMPLETION);
assert(stamp || (presented_flags & WP_PRESENTATION_FEEDBACK_INVALID));
@ -2965,8 +2998,11 @@ weston_output_finish_frame(struct weston_output *output,
goto out;
}
vblank_monotonic = convert_presentation_time_now(compositor,
stamp, &now,
CLOCK_MONOTONIC);
TL_POINT(compositor, "core_repaint_finished", TLP_OUTPUT(output),
TLP_VBLANK(stamp), TLP_END);
TLP_VBLANK(&vblank_monotonic), TLP_END);
refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
weston_presentation_feedback_present_list(&output->feedback_list,

@ -324,7 +324,7 @@ emit_vblank_timestamp(struct timeline_emit_context *ctx, void *obj)
{
struct timespec *ts = obj;
fprintf(ctx->cur, "\"vblank\":[%" PRId64 ", %ld]",
fprintf(ctx->cur, "\"vblank_monotonic\":[%" PRId64 ", %ld]",
(int64_t)ts->tv_sec, ts->tv_nsec);
return 1;

Loading…
Cancel
Save