I do not want to loose the momentum on the subject. I did several Kernel tests and I am fine with the current implementation.
The user side is really simple and does not require too much engineering.
Standard drmvblank structure is used. A unique request type is introduced (0x40) to tell the Kernel to output the scanout position. The sequence parameter must be set to 0 (mandatory at the moment). The scanout position is returned immediately in the reply part of the structure (vbl.reply.sequence).
The call to drmWaitVBlank with type 0x40 returns 0 if the scanout patch is present. This make the code compatible with patched and non patched kernels. Stock kernel will always return a negative value.
The following code outputs the scanline position before every waitvblank call.
--- drawogl.cpp_awk_ori 2019-01-14 16:47:34.701281847 +0100
+++ drawogl.cpp 2019-01-25 10:56:09.505507539 +0100
@@ -1413,8 +1413,19 @@
if (video_config.waitvsync && m_fd)
{
drmVBlank vbl;
+ // - Returns sequence as a positive number while in active scanout area.
+ // - Returns sequence as a negative number inside vblank, counting the number of scanlines to go until end of vblank, e.g., -1 means "one scanline until start of active scanout / end of vblank."
memset(&vbl, 0, sizeof(vbl));
- vbl.request.type = DRM_VBLANK_RELATIVE;
+ vbl.request.type = (drmVBlankSeqType) 0x40;
+ vbl.request.sequence = 0;
+ int ret = 0;
+ ret=drmWaitVBlank(m_fd, &vbl);
+ if (ret != 0)
+ osd_printf_verbose("drm get scanout failed, code %d\n", ret);
+ osd_printf_verbose("Current scanout position is %d\n",vbl.reply.sequence);
+
+ memset(&vbl, 0, sizeof(vbl));
+ vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 1;
if (drmWaitVBlank(m_fd, &vbl) != 0)
osd_printf_verbose("drmWaitVBlank failed\n");