Hi,
I noticed the "TearFree" patch was merged upstream in the XOrg
modesetting driver. Long time ago when it was sent I patched it into
my local Xenocara and used it ever since. Zero issues, zero tearing.
Maybe let's consider adding it to Xenocara too? I am attaching the
patch, commit message is from my local git repo, I am of course NOT an
author. It adds the "TearFree" option to the modesetting section of
your xorg.conf.
Feel free to fetch it directly from the Merge Request, the real author
is https://gitlab.freedesktop.org/kerneltoast:
https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1006
I am just sending this as is, but I don't know enough about XOrg to
follow up with extra fixes to the code. I can only confirm that it
worked flawlessly on my Intel NUC 11 for a really long time.
Thanks,
Igor.
From ba437abd59efa8a18426748b5edd2ce7f67c5dbe Mon Sep 17 00:00:00 2001
From: Igor Petruk
Date: Sun, 4 Dec 2022 23:00:50 +
Subject: [PATCH] Added tearfree patch
---
xserver/dix/pixmap.c | 15 +-
.../hw/xfree86/drivers/modesetting/driver.c | 68 ++
.../hw/xfree86/drivers/modesetting/driver.h | 3 +
.../drivers/modesetting/drmmode_display.c | 202 ++
.../drivers/modesetting/drmmode_display.h | 16 ++
.../drivers/modesetting/modesetting.man | 11 +
.../hw/xfree86/drivers/modesetting/pageflip.c | 108 --
.../hw/xfree86/drivers/modesetting/present.c | 22 +-
xserver/hw/xfree86/modes/xf86Crtc.h | 5 +
xserver/hw/xfree86/modes/xf86Rotate.c | 22 +-
xserver/include/pixmap.h | 5 +
xserver/present/present.h | 4 +-
xserver/present/present_execute.c | 4 +-
xserver/present/present_priv.h| 1 +
xserver/present/present_scmd.c| 60 --
xserver/present/present_vblank.c | 12 ++
16 files changed, 465 insertions(+), 93 deletions(-)
diff --git a/xserver/dix/pixmap.c b/xserver/dix/pixmap.c
index 5a0146bbb..0b01c4ee0 100644
--- a/xserver/dix/pixmap.c
+++ b/xserver/dix/pixmap.c
@@ -262,12 +262,11 @@ PixmapStopDirtyTracking(DrawablePtr src, PixmapPtr secondary_dst)
return TRUE;
}
-static void
-PixmapDirtyCopyArea(PixmapPtr dst,
-PixmapDirtyUpdatePtr dirty,
+void
+PixmapDirtyCopyArea(PixmapPtr dst, DrawablePtr src,
+int x, int y, int dst_x, int dst_y,
RegionPtr dirty_region)
{
-DrawablePtr src = dirty->src;
ScreenPtr pScreen = src->pScreen;
int n;
BoxPtr b;
@@ -294,9 +293,8 @@ PixmapDirtyCopyArea(PixmapPtr dst,
h = dst_box.y2 - dst_box.y1;
pGC->ops->CopyArea(src, >drawable, pGC,
- dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h,
- dirty->dst_x + dst_box.x1,
- dirty->dst_y + dst_box.y1);
+ x + dst_box.x1, y + dst_box.y1, w, h,
+ dst_x + dst_box.x1, dst_y + dst_box.y1);
b++;
}
FreeScratchGC(pGC);
@@ -408,7 +406,8 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty)
RegionTranslate(, -dirty->x, -dirty->y);
if (!pScreen->root || dirty->rotation == RR_Rotate_0)
-PixmapDirtyCopyArea(dst, dirty, );
+PixmapDirtyCopyArea(dst, dirty->src, dirty->x, dirty->y,
+dirty->dst_x, dirty->dst_y, );
else
PixmapDirtyCompositeRotate(dst, dirty, );
pScreen->SourceValidate = SourceValidate;
diff --git a/xserver/hw/xfree86/drivers/modesetting/driver.c b/xserver/hw/xfree86/drivers/modesetting/driver.c
index 62d471a26..e7691645f 100644
--- a/xserver/hw/xfree86/drivers/modesetting/driver.c
+++ b/xserver/hw/xfree86/drivers/modesetting/driver.c
@@ -151,6 +151,7 @@ static const OptionInfoRec Options[] = {
{OPTION_VARIABLE_REFRESH, "VariableRefresh", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_USE_GAMMA_LUT, "UseGammaLUT", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_ASYNC_FLIP_SECONDARIES, "AsyncFlipSecondaries", OPTV_BOOLEAN, {0}, FALSE},
+{OPTION_TEARFREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -521,6 +522,64 @@ GetRec(ScrnInfoPtr pScrn)
return TRUE;
}
+static void
+ms_tearfree_update_damages(ScrnInfoPtr scrn, RegionPtr dirty)
+{
+xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+modesettingPtr ms = modesettingPTR(scrn);
+int c, i;
+
+if (!ms->drmmode.tearfree_enable)
+return;
+
+for (c = 0; c < xf86_config->num_crtc; c++) {
+xf86CrtcPtr crtc = xf86_config->crtc[c];
+drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+drmmode_tearfree_ptr trf = _crtc->tearfree;
+RegionRec region;
+
+/* Skip CRTCs which aren't using TearFree */
+if (!trf->buf[0].px)
+continue;
+
+/* Compute how much of the damage intersects with this CRTC */
+