xorg-x11-server/u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
Stefan Dirsch 540300e204 - Update to version 21.1.0
* The meson support is now fully mature. While autotools support
    will still be kept for this release series, it will be dropped
    afterwards.
  * Glamor support for Xvfb.
  * Variable refresh rate support in the modesetting driver.
  * XInput 2.4 support which adds touchpad gestures.
  * DMX DDX has been removed.
  * X server now correctly reports display DPI in more cases. This
    may affect rendering of client applications that have their own
    workarounds for hi-DPI screens.
  * A large number of small features and various bug fixes.
- updated xorg-server-provides
- supersedes patches
  * U_Fix-segfault-on-probing-a-non-PCI-platform-device-on.patch
  * U_dix-window-Use-ConfigureWindow-instead-of-MoveWindow.patch
  * U_glamor_egl-Reject-OpenGL-2.1-early-on.patch
  * u_render-Cast-color-masks-to-unsigned-long-before-shifting-them.patch
- refreshed patches
  * N_fix-dpi-values.diff
  * N_zap_warning_xserver.diff
  * u_modesetting-Fix-dirty-updates-for-sw-rotation.patch
  * u_randr-Do-not-crash-if-slave-screen-does-not-have-pro.patch
  * u_vesa-Add-VBEDPMSGetCapabilities-VBEDPMSGet.patch
- disabled n_xserver-optimus-autoconfig-hack.patch, which I believe is 
  superseded by:
  commit 078277e4d92f05a90c4715d61b89b9d9d38d68ea
  Author: Dave Airlie <airlied@redhat.com>
  Date:   Fri Aug 17 09:49:24 2012 +1000
    xf86: autobind GPUs to the screen
- added pkgconfig(libxcvt)
- cvt binary moved to libxcvt0 package

OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=804
2021-10-27 16:05:03 +00:00

165 lines
6.0 KiB
Diff

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(-)
Index: xorg-server-21.1.0/hw/xfree86/drivers/modesetting/driver.c
===================================================================
--- xorg-server-21.1.0.orig/hw/xfree86/drivers/modesetting/driver.c
+++ xorg-server-21.1.0/hw/xfree86/drivers/modesetting/driver.c
@@ -515,9 +515,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);
@@ -532,13 +564,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);
@@ -561,20 +589,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;
+ }
}
}
@@ -586,7 +625,7 @@ dispatch_dirty_pixmap(ScrnInfoPtr scrn,
DamagePtr damage = ppriv->secondary_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
Index: xorg-server-21.1.0/hw/xfree86/drivers/modesetting/drmmode_display.c
===================================================================
--- xorg-server-21.1.0.orig/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ xorg-server-21.1.0/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -627,7 +627,7 @@ drmmode_crtc_can_test_mode(xf86CrtcPtr c
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;
Index: xorg-server-21.1.0/hw/xfree86/drivers/modesetting/drmmode_display.h
===================================================================
--- xorg-server-21.1.0.orig/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ xorg-server-21.1.0/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -311,6 +311,8 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn,
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);
void drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled);