EGL_KHR_swap_buffers_with_damage on X11 (DRI3)
VK_PRESENT_MODE_FIFO_RELAXED on X11
GLX_EXT_swap_control for DRI2 and DRI3
+GLX_EXT_swap_control_tear for DRI3
extensions = psc->core->getExtensions(psc->driScreen);
__glXEnableDirectExtension(&psc->base, "GLX_EXT_swap_control");
+ __glXEnableDirectExtension(&psc->base, "GLX_EXT_swap_control_tear");
__glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
__glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
__glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
} else if (attribute == GLX_MAX_SWAP_INTERVAL_EXT) {
*value = INT_MAX;
return 0;
+ } else if (attribute == GLX_LATE_SWAPS_TEAR_EXT) {
+ *value = __glXExtensionBitIsEnabled(pdraw->psc,
+ EXT_swap_control_tear_bit);
+ return 0;
}
}
#endif
return;
}
- if (interval < 0) {
+ if (interval < 0 &&
+ !__glXExtensionBitIsEnabled(pdraw->psc, EXT_swap_control_tear_bit)) {
__glXSendError(dpy, BadValue, interval, 0, True);
return;
}
{ GLX(EXT_framebuffer_sRGB), VER(0,0), Y, Y, N, N },
{ GLX(EXT_import_context), VER(0,0), Y, Y, N, N },
{ GLX(EXT_swap_control), VER(0,0), Y, N, N, Y },
+ { GLX(EXT_swap_control_tear), VER(0,0), Y, N, N, Y },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
{ GLX(EXT_visual_info), VER(0,0), Y, Y, N, N },
{ GLX(EXT_visual_rating), VER(0,0), Y, Y, N, N },
EXT_framebuffer_sRGB_bit,
EXT_import_context_bit,
EXT_swap_control_bit,
+ EXT_swap_control_tear_bit,
EXT_texture_from_pixmap_bit,
EXT_visual_info_bit,
EXT_visual_rating_bit,
*/
++draw->send_sbc;
if (target_msc == 0 && divisor == 0 && remainder == 0)
- target_msc = draw->msc + draw->swap_interval *
+ target_msc = draw->msc + abs(draw->swap_interval) *
(draw->send_sbc - draw->recv_sbc);
else if (divisor == 0 && remainder > 0) {
/* From the GLX_OML_sync_control spec:
* "If <interval> is set to a value of 0, buffer swaps are not
* synchronized to a video frame."
*
+ * From GLX_EXT_swap_control_tear:
+ *
+ * "If <interval> is negative, the minimum number of video frames
+ * between buffer swaps is the absolute value of <interval>. In this
+ * case, if abs(<interval>) video frames have already passed from
+ * the previous swap when the swap is ready to be performed, the
+ * swap will occur without synchronization to a video frame."
+ *
* Implementation note: It is possible to enable triple buffering
* behaviour by not using XCB_PRESENT_OPTION_ASYNC, but this should not be
* the default.
*/
- if (draw->swap_interval == 0)
+ if (draw->swap_interval <= 0)
options |= XCB_PRESENT_OPTION_ASYNC;
/* If we need to populate the new back, but need to reuse the back