summaryrefslogtreecommitdiffstats
path: root/video/out/drm_common.c
diff options
context:
space:
mode:
authorAnton Kindestam <antonki@kth.se>2019-07-29 19:32:29 +0200
committerJan Ekström <jeebjp@gmail.com>2019-09-28 14:10:01 +0300
commit9538fb5a7af951e220f26c87c80aaaa2a5cfbc67 (patch)
tree36a1c191a061a18ddfad7fe1926ad6de4993ee34 /video/out/drm_common.c
parent77980c8184cdc62f964fd85fc6cbd3d79019ce7a (diff)
downloadmpv-9538fb5a7af951e220f26c87c80aaaa2a5cfbc67.tar.bz2
mpv-9538fb5a7af951e220f26c87c80aaaa2a5cfbc67.tar.xz
drm: refactor page_flipped callback
Avoid duplicating the same callback function in both context_drm_egl and vo_drm.
Diffstat (limited to 'video/out/drm_common.c')
-rw-r--r--video/out/drm_common.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/video/out/drm_common.c b/video/out/drm_common.c
index fb02130bb0..a7a0b2759f 100644
--- a/video/out/drm_common.c
+++ b/video/out/drm_common.c
@@ -25,13 +25,16 @@
#include <unistd.h>
#include <limits.h>
#include <math.h>
+#include <time.h>
#include "drm_common.h"
#include "common/common.h"
#include "common/msg.h"
#include "osdep/io.h"
+#include "osdep/timer.h"
#include "misc/ctype.h"
+#include "video/out/vo.h"
#define EVT_RELEASE 1
#define EVT_ACQUIRE 2
@@ -900,3 +903,48 @@ void vt_switcher_poll(struct vt_switcher *s, int timeout_ms)
break;
}
}
+
+void drm_pflip_cb(int fd, unsigned int msc, unsigned int sec,
+ unsigned int usec, void *data)
+{
+ struct drm_pflip_cb_closure *closure = data;
+
+ struct drm_vsync_tuple *vsync = closure->vsync;
+ // frame_vsync->ust is the timestamp of the pageflip that happened just before this flip was queued
+ // frame_vsync->msc is the sequence number of the pageflip that happened just before this flip was queued
+ // frame_vsync->sbc is the sequence number for the frame that was just flipped to screen
+ struct drm_vsync_tuple *frame_vsync = closure->frame_vsync;
+ struct vo_vsync_info *vsync_info = closure->vsync_info;
+
+ const bool ready =
+ (vsync->msc != 0) &&
+ (frame_vsync->ust != 0) && (frame_vsync->msc != 0);
+
+ const uint64_t ust = (sec * 1000000LL) + usec;
+
+ const unsigned int msc_since_last_flip = msc - vsync->msc;
+
+ vsync->ust = ust;
+ vsync->msc = msc;
+
+ if (ready) {
+ // Convert to mp_time
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ goto fail;
+ const uint64_t now_monotonic = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
+ const uint64_t ust_mp_time = mp_time_us() - (now_monotonic - vsync->ust);
+
+ const uint64_t ust_since_enqueue = vsync->ust - frame_vsync->ust;
+ const unsigned int msc_since_enqueue = vsync->msc - frame_vsync->msc;
+ const unsigned int sbc_since_enqueue = vsync->sbc - frame_vsync->sbc;
+
+ vsync_info->vsync_duration = ust_since_enqueue / msc_since_enqueue;
+ vsync_info->skipped_vsyncs = msc_since_last_flip - 1; // Valid iff swap_buffers is called every vsync
+ vsync_info->last_queue_display_time = ust_mp_time + (sbc_since_enqueue * vsync_info->vsync_duration);
+ }
+
+fail:
+ *closure->waiting_for_flip = false;
+ talloc_free(closure);
+}