forked from pool/xorg-x11-server
Accepting request 899464 from home:patrikjakobsson:branches:X11:XOrg
Modesetting: Fix dirty updates for sw rotation OBS-URL: https://build.opensuse.org/request/show/899464 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=793
This commit is contained in:
parent
90b3657e6e
commit
0dab94f9df
167
u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
Normal file
167
u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
Normal file
@ -0,0 +1,167 @@
|
||||
From 7d2802f13eecb38babeeb54ceae978a409b5c5d4 Mon Sep 17 00:00:00 2001
|
||||
From: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
|
||||
Date: Wed, 9 Jun 2021 20:58:59 +0200
|
||||
Subject: [PATCH] modesetting: Fix dirty updates for sw rotation
|
||||
Patch-Mainline: To be upstreamed
|
||||
References: bsc#1182955
|
||||
|
||||
Rotation is broken for all drm drivers not providing hardware rotation
|
||||
support. Drivers that give direct access to vram and not needing dirty
|
||||
updates still work but only by accident. The problem is caused by
|
||||
modesetting not sending the correct fb_id to drmModeDirtyFB() and
|
||||
passing the damage rects in the rotated state and not as the crtc
|
||||
expects them. This patch takes care of both problems.
|
||||
|
||||
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
|
||||
---
|
||||
hw/xfree86/drivers/modesetting/driver.c | 81 ++++++++++++++-----
|
||||
.../drivers/modesetting/drmmode_display.c | 2 +-
|
||||
.../drivers/modesetting/drmmode_display.h | 2 +
|
||||
3 files changed, 63 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
|
||||
index ef4a314..deca1ed 100644
|
||||
--- a/hw/xfree86/drivers/modesetting/driver.c
|
||||
+++ b/hw/xfree86/drivers/modesetting/driver.c
|
||||
@@ -503,9 +503,41 @@ GetRec(ScrnInfoPtr pScrn)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+rotate_clip(PixmapPtr pixmap, BoxPtr rect, drmModeClip *clip, Rotation rotation)
|
||||
+{
|
||||
+ int w = pixmap->drawable.width;
|
||||
+ int h = pixmap->drawable.height;
|
||||
+
|
||||
+ if (rotation == RR_Rotate_90) {
|
||||
+ /* Rotate 90 degrees counter clockwise */
|
||||
+ clip->x1 = rect->y1;
|
||||
+ clip->x2 = rect->y2;
|
||||
+ clip->y1 = w - rect->x2;
|
||||
+ clip->y2 = w - rect->x1;
|
||||
+ } else if (rotation == RR_Rotate_180) {
|
||||
+ /* Rotate 180 degrees */
|
||||
+ clip->x1 = w - rect->x2;
|
||||
+ clip->x2 = w - rect->x1;
|
||||
+ clip->y1 = h - rect->y2;
|
||||
+ clip->y2 = h - rect->y1;
|
||||
+ } else if (rotation == RR_Rotate_270) {
|
||||
+ /* Rotate 90 degrees clockwise */
|
||||
+ clip->x1 = h - rect->y2;
|
||||
+ clip->x2 = h - rect->y1;
|
||||
+ clip->y1 = rect->x1;
|
||||
+ clip->y2 = rect->x2;
|
||||
+ } else {
|
||||
+ clip->x1 = rect->x1;
|
||||
+ clip->x2 = rect->x2;
|
||||
+ clip->y1 = rect->y1;
|
||||
+ clip->y2 = rect->y2;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
-dispatch_dirty_region(ScrnInfoPtr scrn,
|
||||
- PixmapPtr pixmap, DamagePtr damage, int fb_id)
|
||||
+dispatch_dirty_region(ScrnInfoPtr scrn, xf86CrtcPtr crtc,
|
||||
+ PixmapPtr pixmap, DamagePtr damage, int fb_id)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(scrn);
|
||||
RegionPtr dirty = DamageRegion(damage);
|
||||
@@ -520,13 +552,9 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
|
||||
if (!clip)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* XXX no need for copy? */
|
||||
- for (i = 0; i < num_cliprects; i++, rect++) {
|
||||
- clip[i].x1 = rect->x1;
|
||||
- clip[i].y1 = rect->y1;
|
||||
- clip[i].x2 = rect->x2;
|
||||
- clip[i].y2 = rect->y2;
|
||||
- }
|
||||
+ /* Rotate and copy rects into clips */
|
||||
+ for (i = 0; i < num_cliprects; i++, rect++)
|
||||
+ rotate_clip(pixmap, rect, &clip[i], crtc->rotation);
|
||||
|
||||
/* TODO query connector property to see if this is needed */
|
||||
ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
|
||||
@@ -549,20 +577,31 @@ static void
|
||||
dispatch_dirty(ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
||||
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||
modesettingPtr ms = modesettingPTR(scrn);
|
||||
PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
|
||||
- int fb_id = ms->drmmode.fb_id;
|
||||
- int ret;
|
||||
+ uint32_t fb_id;
|
||||
+ int ret, c, x, y ;
|
||||
|
||||
- ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id);
|
||||
- if (ret == -EINVAL || ret == -ENOSYS) {
|
||||
- ms->dirty_enabled = FALSE;
|
||||
- DamageUnregister(ms->damage);
|
||||
- DamageDestroy(ms->damage);
|
||||
- ms->damage = NULL;
|
||||
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
||||
- "Disabling kernel dirty updates, not required.\n");
|
||||
- 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;
|
||||
+
|
||||
+ if (!drmmode_crtc)
|
||||
+ continue;
|
||||
+
|
||||
+ drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y);
|
||||
+
|
||||
+ ret = dispatch_dirty_region(scrn, crtc, pixmap, ms->damage, fb_id);
|
||||
+ if (ret == -EINVAL || ret == -ENOSYS) {
|
||||
+ ms->dirty_enabled = FALSE;
|
||||
+ DamageUnregister(ms->damage);
|
||||
+ DamageDestroy(ms->damage);
|
||||
+ ms->damage = NULL;
|
||||
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
||||
+ "Disabling kernel dirty updates, not required.\n");
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,7 +613,7 @@ dispatch_dirty_pixmap(ScrnInfoPtr scrn, xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
DamagePtr damage = ppriv->slave_damage;
|
||||
int fb_id = ppriv->fb_id;
|
||||
|
||||
- dispatch_dirty_region(scrn, ppix, damage, fb_id);
|
||||
+ dispatch_dirty_region(scrn, crtc, ppix, damage, fb_id);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
|
||||
index 88992f5..b29db12 100644
|
||||
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
|
||||
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
|
||||
@@ -598,7 +598,7 @@ drmmode_crtc_can_test_mode(xf86CrtcPtr crtc)
|
||||
return ms->atomic_modeset;
|
||||
}
|
||||
|
||||
-static Bool
|
||||
+Bool
|
||||
drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
|
||||
index 59d79e9..0ed96ab 100644
|
||||
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
|
||||
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
|
||||
@@ -297,6 +297,8 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||
|
||||
int drmmode_crtc_flip(xf86CrtcPtr crtc, uint32_t fb_id, uint32_t flags, void *data);
|
||||
|
||||
+Bool drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y);
|
||||
+
|
||||
void drmmode_set_dpms(ScrnInfoPtr scrn, int PowerManagementMode, int flags);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Jun 11 11:03:18 UTC 2021 - Patrik Jakobsson <patrik.jakobsson@suse.com>
|
||||
|
||||
- u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
|
||||
* Fixes broken rotation support for DRM drivers without hardware
|
||||
rotation support or direct vram access (bsc#1182955)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Apr 19 11:29:31 UTC 2021 - Stefan Dirsch <sndirsch@suse.com>
|
||||
|
||||
|
@ -157,7 +157,7 @@ Requires: libpixman-1-0 >= 0.24
|
||||
Requires: Mesa
|
||||
%if 0%{?suse_version} >= 1315
|
||||
Requires(post): update-alternatives
|
||||
Requires(postun): update-alternatives
|
||||
Requires(postun):update-alternatives
|
||||
%endif
|
||||
Provides: xorg-x11-server-glx
|
||||
Obsoletes: xorg-x11-server-glx
|
||||
@ -253,6 +253,8 @@ Patch1801: U_Fix-segfault-on-probing-a-non-PCI-platform-device-on.patch
|
||||
|
||||
Patch1900: u_no-lto-for-tests.patch
|
||||
|
||||
Patch1910: u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
|
||||
|
||||
%description
|
||||
This package contains the X.Org Server.
|
||||
|
||||
@ -405,6 +407,7 @@ sh %{SOURCE92} --verify . %{SOURCE91}
|
||||
%patch1600 -p1
|
||||
%patch1801 -p1
|
||||
%patch1900 -p1
|
||||
%patch1910 -p1
|
||||
|
||||
%build
|
||||
%global _lto_cflags %{?_lto_cflags} -ffat-lto-objects
|
||||
|
Loading…
Reference in New Issue
Block a user