summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/oml_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/oml_sync.c')
-rw-r--r--video/out/opengl/oml_sync.c112
1 files changed, 0 insertions, 112 deletions
diff --git a/video/out/opengl/oml_sync.c b/video/out/opengl/oml_sync.c
deleted file mode 100644
index 6efd4265d7..0000000000
--- a/video/out/opengl/oml_sync.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <time.h>
-
-#include "osdep/timer.h"
-#include "oml_sync.h"
-#include "video/out/vo.h"
-
-// General nonsense about the associated extension.
-//
-// This extension returns two unrelated values:
-// (ust, msc): clock time and incrementing counter of last vsync (this is
-// reported continuously, even if we don't swap)
-// sbc: swap counter of frame that was last displayed (every swap
-// increments the user_sbc, and the reported sbc is the sbc
-// of the frame that was just displayed)
-// Invariants:
-// - ust and msc change in lockstep (no value can change without the other)
-// - msc is incremented; if you query it in a loop, and your thread isn't
-// frozen or starved by the scheduler, it will usually either not change, or
-// be incremented by 1 (while the ust will be incremented by vsync
-// duration)
-// - sbc is never higher than the user_sbc
-// - (ust, msc) are equal to or higher by vsync increments than the display
-// time of the frame referenced by the sbc
-// Note that (ust, msc) and sbc are not locked to each other. The following
-// can easily happen if vsync skips occur:
-// - you draw a frame, in the meantime hardware swaps sbc_1
-// - another display vsync happens during drawing
-// - you call swap()
-// - query (ust, msc) and sbc
-// - sbc contains sbc_1, but (ust, msc) contains the vsync after it
-// As a consequence, it's hard to detect the latency or vsync skips.
-
-static void oml_sync_reset(struct oml_sync *oml)
-{
- oml->vsync_duration = -1;
- oml->last_skipped_vsyncs = -1;
- oml->last_queue_display_time = -1;
-}
-
-void oml_sync_swap(struct oml_sync *oml, int64_t ust, int64_t msc, int64_t sbc)
-{
- if (!oml->state_ok)
- oml_sync_reset(oml);
-
- oml->last_skipped_vsyncs = 0;
- oml->user_sbc += 1;
-
- if (sbc < 0)
- return;
-
- oml->state_ok = true;
-
- int64_t ust_passed = oml->last_ust ? ust - oml->last_ust : 0;
- oml->last_ust = ust;
-
- int64_t msc_passed = oml->last_msc ? msc - oml->last_msc : 0;
- oml->last_msc = msc;
-
- int64_t sbc_passed = sbc - oml->last_sbc;
- oml->last_sbc = sbc;
-
- // Display frame duration. This makes assumptions about UST (see below).
- if (msc_passed && ust_passed)
- oml->vsync_duration = ust_passed / msc_passed;
-
- // Only if a new frame was displayed (sbc increased) we have sort-of a
- // chance that the current (ust, msc) is for the sbc. But this is racy,
- // because skipped frames drops could have increased the msc right after the
- // display event and before we queried the values. This code hopes for the
- // best and ignores this.
- if (sbc_passed) {
- // The GLX extension spec doesn't define what the UST is (not even its
- // unit). Simply assume UST is a simple CLOCK_MONOTONIC usec value. This
- // is what Mesa does, and what the Google EGL extension seems to imply
- // (they mention CLOCK_MONOTONIC, but not the unit).
- // The swap buffer call happened "some" but very small time ago, so we
- // can get away with querying the current time. There is also the
- // implicit assumption that mpv's timer and the UST use the same clock
- // (which it does on POSIX).
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts))
- return;
- uint64_t now_monotonic = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
- uint64_t ust_mp_time = mp_time_us() - (now_monotonic - ust);
-
- // Assume this is exactly when the actual display event for this sbc
- // happened. This is subject to the race mentioned above.
- oml->last_sbc_mp_time = ust_mp_time;
- }
-
- // At least one frame needs to be actually displayed before
- // oml->last_sbc_mp_time is set.
- if (!sbc)
- return;
-
- // Extrapolate from the last sbc time (when a frame was actually displayed),
- // and by adding the number of frames that were queued since to it.
- // For every unit the sbc is smaller than user_sbc, the actual display
- // is one frame ahead (assumes oml_sync_swap() is called for every
- // vsync).
- oml->last_queue_display_time =
- oml->last_sbc_mp_time + (oml->user_sbc - sbc) * oml->vsync_duration;
-}
-
-void oml_sync_get_info(struct oml_sync *oml, struct vo_vsync_info *info)
-{
- if (!oml->state_ok)
- oml_sync_reset(oml);
- info->vsync_duration = oml->vsync_duration;
- info->skipped_vsyncs = oml->last_skipped_vsyncs;
- info->last_queue_display_time = oml->last_queue_display_time;
-}