summaryrefslogtreecommitdiffstats
path: root/video/out/vo.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-09-21 15:42:37 +0200
committerAnton Kindestam <antonki@kth.se>2018-12-06 10:32:27 +0100
commitf4ce3b8bb9ac715e3390f047697d6905eab55ef1 (patch)
tree34c0055f9b513f95691782e04e555c0dba8c6ad8 /video/out/vo.h
parentace16fcfff5ab48f31ad1906532e412584b5e8ea (diff)
downloadmpv-f4ce3b8bb9ac715e3390f047697d6905eab55ef1.tar.bz2
mpv-f4ce3b8bb9ac715e3390f047697d6905eab55ef1.tar.xz
vo, vo_gpu, glx: correct GLX_OML_sync_control usage
I misunderstood how this extension works. If I understand it correctly now, it's worse than I thought. They key thing is that the (ust, msc, sbc) tripple is not for a single swap event. Instead, (ust, msc) run independently from sbc. Assuming a CFR display/compositor, this means you can at best know the vsync phase and frequency, but not the exact time a sbc changed value. There is GLX_INTEL_swap_event, which might work as expected, but it has no EGL equivalent (while GLX_OML_sync_control does, in theory). Redo the context_glx sync code. Now it's either more correct or less correct. I wanted to add proper skip detection (if a vsync gets skipped due to rendering taking too long and other problems), but it turned out to be too complex, so only some unused fields in vo.h are left of it. The "generic" skip detection has to do. The vsync_duration field is also unused by vo.c. Actually this seems to be an improvement. In cases where the flip call timing is off, but the real driver-level timing apparently still works, this will not report vsync skips or higher vsync jitter anymore. I could observe this with screenshots and fullscreen switching. On the other hand, maybe it just introduces an A/V offset or so. Why the fuck can't there be a proper API for retrieving these statistics? I'm not even asking for much.
Diffstat (limited to 'video/out/vo.h')
-rw-r--r--video/out/vo.h38
1 files changed, 27 insertions, 11 deletions
diff --git a/video/out/vo.h b/video/out/vo.h
index f64d94a5ba..3514b6df5c 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -263,19 +263,33 @@ struct vo_frame {
uint64_t frame_id;
};
-// Presentation feedback.
+// Presentation feedback. See get_vsync() for how backends should fill this
+// struct.
struct vo_vsync_info {
- // Last mp_time_us() timestamp at which a frame was queued.
- int64_t last_queue_time;
-
- // The latency at which swap_buffers() is performed. This is in seconds, and
- // valid values are always >= 0. Essentially, it's the predicted time the
- // last shown frame will take until it is actually displayed on the physical
- // screen. (A reasonable implementation is returning the actual measured
- // value for the last frame which was actually displayed. The assumption is
- // that the latency usually doesn't change.)
+ // mp_time_us() timestamp at which the last queued frame will likely be
+ // displayed (this is in the future, unless the frame is instantly output).
// -1 if unset or unsupported.
- double latency;
+ // This implies the latency of the output.
+ int64_t last_queue_display_time;
+
+ // Time between 2 vsync events in microseconds. The difference should be the
+ // from 2 times sampled from the same reference point (it should not be the
+ // difference between e.g. the end of scanout and the start of the next one;
+ // it must be continuous).
+ // -1 if unsupported.
+ // 0 if supported, but no value available yet. It is assumed that the value
+ // becomes available after enough swap_buffers() calls were done.
+ // >0 values are taken for granted. Very bad things will happen if it's
+ // inaccurate.
+ int64_t vsync_duration;
+
+ // Number of skipped physical vsyncs at some point in time. Typically, this
+ // value is some time in the past by an offset that equals to the latency.
+ // This value is reset and newly sampled at every swap_buffers() call.
+ // This can be used to detect delayed frames iff you try to call
+ // swap_buffers() for every physical vsync.
+ // -1 if unset or unsupported.
+ int64_t skipped_vsyncs;
};
struct vo_driver {
@@ -393,6 +407,8 @@ struct vo_driver {
* Return presentation feedback. The implementation should not touch fields
* it doesn't support; the info fields are preinitialized to neutral values.
* Usually called once after flip_page(), but can be called any time.
+ * The values returned by this are always relative to the last flip_page()
+ * call.
*/
void (*get_vsync)(struct vo *vo, struct vo_vsync_info *info);