0 files changed New commits: commit 8b312db7d1d98be67f0283d982428545cf948a66 Author: Adam Jackson <a...@redhat.com> Date: Tue Jul 19 13:27:08 2016 -0400
xserver 1.18.4 Signed-off-by: Adam Jackson <a...@redhat.com> diff --git a/configure.ac b/configure.ac index cfffcd8..868e859 100644 --- a/configure.ac +++ b/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.18.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2016-04-04" -RELEASE_NAME="Halloumi" +AC_INIT([xorg-server], 1.18.4, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2016-07-19" +RELEASE_NAME="Skordalia" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) commit 42a74080ffe93502904ede7555652f01ab11d12d Author: Michel Dänzer <michel.daen...@amd.com> Date: Wed Mar 30 18:23:04 2016 +0900 os: Use strtok instead of xstrtokenize in ComputeLocalClient Fixes leaking the memory pointed to by the members of the array returned by xstrtokenize. Reviewed-by: Adam Jackson <a...@redhat.com> (cherry picked from commit e156c0ccb530897d3a428255bd5585f7ea7b9b41) diff --git a/os/access.c b/os/access.c index 08c4fd0..dac6f49 100644 --- a/os/access.c +++ b/os/access.c @@ -1132,19 +1132,20 @@ ComputeLocalClient(ClientPtr client) * is forwarded from another host via SSH */ if (cmdname) { - char **cmd; + char *cmd = strdup(cmdname); Bool ret; /* Cut off any colon and whatever comes after it, see * https://lists.freedesktop.org/archives/xorg-devel/2015-December/048164.html */ - cmd = xstrtokenize(cmdname, ":"); + cmd = strtok(cmd, ":"); #if !defined(WIN32) || defined(__CYGWIN__) - cmd[0] = basename(cmd[0]); + ret = strcmp(basename(cmd), "ssh") != 0; +#else + ret = strcmp(cmd, "ssh") != 0; #endif - ret = strcmp(cmd[0], "ssh") != 0; free(cmd); return ret; commit 3c4cead499f10dabac20ab87728746ec41dae799 Author: Adam Jackson <a...@redhat.com> Date: Mon Mar 28 18:11:09 2016 +0900 os: Treat ssh as a non-local client (v4) By the time we get to ComputeLocalClient, we've already done NextAvailableClient → ReserveClientIds → DetermineClientCmd (assuming we're built with #define CLIENTIDS), so we can look up the name of the client process and refuse to treat ssh's X forwarding as if it were local. v2: (Michel Dänzer) * Only match "ssh" itself, not other executable names starting with that prefix. * Ignore executable path for the match. v3: (Michel Dänzer) * Use GetClientCmdName (Mark Kettenis) * Perform check on Windows as well, but only ignore path on Cygwin (Martin Peres, Emil Velikov, Jon Turney) v4: (Michel Dänzer) * Cut of any colon and whatever comes after it. (Adam Jackson) * Add bugzilla reference. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93261 Signed-off-by: Adam Jackson <a...@redhat.com> Signed-off-by: Michel Dänzer <michel.daen...@amd.com> (cherry picked from commit adefbaee499b9679c6cac21f52ec6545af2b36b5) diff --git a/os/access.c b/os/access.c index 2499a9f..08c4fd0 100644 --- a/os/access.c +++ b/os/access.c @@ -173,6 +173,10 @@ SOFTWARE. #endif /* WIN32 */ +#if !defined(WIN32) || defined(__CYGWIN__) +#include <libgen.h> +#endif + #define X_INCLUDE_NETDB_H #include <X11/Xos_r.h> @@ -1081,9 +1085,8 @@ ResetHosts(const char *display) } } -/* Is client on the local host */ -Bool -ComputeLocalClient(ClientPtr client) +static Bool +xtransLocalClient(ClientPtr client) { int alen, family, notused; Xtransaddr *from = NULL; @@ -1116,6 +1119,40 @@ ComputeLocalClient(ClientPtr client) return FALSE; } +/* Is client on the local host */ +Bool +ComputeLocalClient(ClientPtr client) +{ + const char *cmdname = GetClientCmdName(client); + + if (!xtransLocalClient(client)) + return FALSE; + + /* If the executable name is "ssh", assume that this client connection + * is forwarded from another host via SSH + */ + if (cmdname) { + char **cmd; + Bool ret; + + /* Cut off any colon and whatever comes after it, see + * https://lists.freedesktop.org/archives/xorg-devel/2015-December/048164.html + */ + cmd = xstrtokenize(cmdname, ":"); + +#if !defined(WIN32) || defined(__CYGWIN__) + cmd[0] = basename(cmd[0]); +#endif + + ret = strcmp(cmd[0], "ssh") != 0; + free(cmd); + + return ret; + } + + return TRUE; +} + /* * Return the uid and all gids of a connected local client * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds commit aebfc6ad9be5bd33b7e0a813d424c81d6214ab07 Author: Michel Dänzer <michel.daen...@amd.com> Date: Fri Jul 1 12:34:20 2016 +0900 glamor: Translate solid text background region after clipping Fixes incorrect clipping for redirected windows which don't happen to be located at the top left corner of the screen. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96742 Signed-off-by: Michel Dänzer <michel.daen...@amd.com> Reviewed-by: Adam Jackson <a...@redhat.com> (cherry picked from commit e8e36755abb17872d669b88d33ca9adc511029a0) diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c index c305305..cf165ca 100644 --- a/glamor/glamor_text.c +++ b/glamor/glamor_text.c @@ -446,16 +446,17 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc, glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); if (width >= 0) { - box.x1 = off_x + drawable->x + x; - box.x2 = off_x + drawable->x + x + width; + box.x1 = drawable->x + x; + box.x2 = drawable->x + x + width; } else { - box.x1 = off_x + drawable->x + x + width; - box.x2 = off_x + drawable->x + x; + box.x1 = drawable->x + x + width; + box.x2 = drawable->x + x; } - box.y1 = off_y + drawable->y + y - gc->font->info.fontAscent; - box.y2 = off_y + drawable->y + y + gc->font->info.fontDescent; + box.y1 = drawable->y + y - gc->font->info.fontAscent; + box.y2 = drawable->y + y + gc->font->info.fontDescent; RegionInit(®ion, &box, 1); RegionIntersect(®ion, ®ion, gc->pCompositeClip); + RegionTranslate(®ion, off_x, off_y); glamor_solid_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion), gc->bgPixel); RegionUninit(®ion); } commit 7a08d8d82007367a90197f9e9d549dbf0bc9ca2e Author: Adam Jackson <a...@redhat.com> Date: Tue Jul 12 10:04:18 2016 -0400 xfree86: Fix fallback driver sort order for Xorg -configure (v2) The intent here was that fallback drivers would be at the end of the list in order, but if a fallback driver happened to be at the end of the list already that's not what would happen. Rather than open-code something smarter, just use qsort. Note that qsort puts things in ascending order, so somewhat backwardsly fallbacks are greater than native drivers, and vesa is greater than modesetting. v2: Use strcmp to compare non-fallback drivers so we get a predictable result if your libc's qsort isn't stable (Keith Packard) Reviewed-by: Keith Packard <kei...@keithp.com> Signed-off-by: Adam Jackson <a...@redhat.com> (cherry picked from commit 32a9504c69183485b0b796fa3966cd1e39992365) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 07f8fb4..26591c6 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -518,33 +518,54 @@ xf86InputDriverlistFromConfig(void) return modulearray; } +static int +is_fallback(const char *s) +{ + /* later entries are less preferred */ + const char *fallback[5] = { "modesetting", "fbdev", "vesa", "wsfb", NULL }; + int i; + + for (i = 0; fallback[i]; i++) + if (strstr(s, fallback[i])) + return i; + + return -1; +} + +static int +driver_sort(const void *_l, const void *_r) +{ + const char *l = *(const char **)_l; + const char *r = *(const char **)_r; + int left = is_fallback(l); + int right = is_fallback(r); + + /* neither is a fallback, asciibetize */ + if (left == -1 && right == -1) + return strcmp(l, r); + + /* left is a fallback */ + if (left >= 0) + return 1; + + /* right is a fallback */ + if (right >= 0) + return -1; + + /* both are fallbacks, which is worse */ + return left - right; +} + static void fixup_video_driver_list(const char **drivers) { - static const char *fallback[5] = { "modesetting", "fbdev", "vesa", "wsfb", NULL }; - const char **end, **drv; - const char *x; - int i; + const char **end; /* walk to the end of the list */ for (end = drivers; *end && **end; end++); end--; - /* - * for each of the fallback drivers, if we find it in the list, - * swap it with the last available non-fallback driver. - */ - for (i = 0; fallback[i]; i++) { - for (drv = drivers; drv != end; drv++) { - if (strstr(*drv, fallback[i])) { - x = *drv; - *drv = *end; - *end = x; - end--; - break; - } - } - } + qsort(drivers, end - drivers, sizeof(const char *), driver_sort); } static const char ** commit 8ff830d1ea4c3572b8fb770009c73c40007e132a Author: Andrew Eikum <aei...@codeweavers.com> Date: Wed Jul 6 14:13:09 2016 -0500 shm: Also censor images returned by ShmGetImage We currently censor images from dix's GetImage, but not from ShmGetImage. This is a method to bypass XACE, creating a potential leak. We should censor in both methods. Reviewed-by: Adam Jackson <a...@redhat.com> Signed-off-by: Andrew Eikum <aei...@codeweavers.com> (cherry picked from commit 4926845a57fa8b53e18ea7d3434bf5539e9b7782) diff --git a/Xext/shm.c b/Xext/shm.c index b359a90..2a3448d 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -619,6 +619,7 @@ ProcShmGetImage(ClientPtr client) xShmGetImageReply xgi; ShmDescPtr shmdesc; VisualID visual = None; + RegionPtr pVisibleRegion = NULL; int rc; REQUEST(xShmGetImageReq); @@ -650,6 +651,9 @@ ProcShmGetImage(ClientPtr client) wBorderWidth((WindowPtr) pDraw) + (int) pDraw->height) return BadMatch; visual = wVisual(((WindowPtr) pDraw)); + pVisibleRegion = NotClippedByChildren((WindowPtr) pDraw); + if (pVisibleRegion) + RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y); } else { if (stuff->x < 0 || @@ -686,6 +690,11 @@ ProcShmGetImage(ClientPtr client) stuff->width, stuff->height, stuff->format, stuff->planeMask, shmdesc->addr + stuff->offset); + if (pVisibleRegion) + XaceCensorImage(client, pVisibleRegion, + PixmapBytePad(stuff->width, pDraw->depth), pDraw, + stuff->x, stuff->y, stuff->width, stuff->height, + stuff->format, shmdesc->addr + stuff->offset); } else { @@ -697,11 +706,19 @@ ProcShmGetImage(ClientPtr client) stuff->width, stuff->height, stuff->format, plane, shmdesc->addr + length); + if (pVisibleRegion) + XaceCensorImage(client, pVisibleRegion, + BitmapBytePad(stuff->width), pDraw, + stuff->x, stuff->y, stuff->width, stuff->height, + stuff->format, shmdesc->addr + length); length += lenPer; } } } + if (pVisibleRegion) + RegionDestroy(pVisibleRegion); + if (client->swapped) { swaps(&xgi.sequenceNumber); swapl(&xgi.length); commit d4cbb1155a79a3dc1dc74cc155dbcfc303273856 Author: Rui Matos <tiagoma...@gmail.com> Date: Wed Jul 13 19:19:09 2016 +0200 xwayland: Update RR state on wl_output.done instead of wl_output.mode Otherwise if the geometry changes but the mode doesn't we end up with the previous geometry from RR's point of view. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=768710 Reviewed-by: Jonas Ådahl <jad...@gmail.com> Signed-off-by: Rui Matos <tiagoma...@gmail.com> (cherry picked from commit cf6730c503f8090a5d1b80918fe253fc2c5bc090) diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 4903062..b66da13 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -98,7 +98,6 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, int width, int height, int refresh) { struct xwl_output *xwl_output = data; - RRModePtr randr_mode; if (!(flags & WL_OUTPUT_MODE_CURRENT)) return; @@ -111,13 +110,7 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, xwl_output->height = width; } - randr_mode = xwayland_cvt(width, height, refresh / 1000.0, 0, 0); - - RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); - - RRCrtcNotify(xwl_output->randr_crtc, randr_mode, - xwl_output->x, xwl_output->y, - xwl_output->rotation, NULL, 1, &xwl_output->randr_output); + xwl_output->refresh = refresh; } static inline void @@ -198,6 +191,14 @@ output_handle_done(void *data, struct wl_output *wl_output) struct xwl_output *it, *xwl_output = data; struct xwl_screen *xwl_screen = xwl_output->xwl_screen; int width = 0, height = 0, has_this_output = 0; + RRModePtr randr_mode; + + randr_mode = xwayland_cvt(xwl_output->width, xwl_output->height, + xwl_output->refresh / 1000.0, 0, 0); + RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); + RRCrtcNotify(xwl_output->randr_crtc, randr_mode, + xwl_output->x, xwl_output->y, + xwl_output->rotation, NULL, 1, &xwl_output->randr_output); xorg_list_for_each_entry(it, &xwl_screen->output_list, link) { /* output done event is sent even when some property diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 67b30cb..232d9f4 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -147,7 +147,7 @@ struct xwl_output { struct xwl_screen *xwl_screen; RROutputPtr randr_output; RRCrtcPtr randr_crtc; - int32_t x, y, width, height; + int32_t x, y, width, height, refresh; Rotation rotation; }; commit 65c5eab6000f108762b7ef6b63869525222ff99d Author: Michel Dänzer <michel.daen...@amd.com> Date: Tue Jun 28 17:22:47 2016 +0900 dix: Work around non-premultiplied ARGB cursor data Some games incorrectly use non-premultiplied ARGB cursor data, presumably because that's what Windows uses. On some hardware (and with SWcursor), this breaks areas of the cursor which are supposed to be transparent (and presumably also translucent areas, but that's less noticeable). This change checks for pixels with alpha == 0 and any non-alpha component != 0. If any such pixel is found, the data is assumed to be non-premultiplied and fixed up by multiplying the RGB components with the alpha component. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92309 Signed-off-by: Michel Dänzer <michel.daen...@amd.com> Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> (cherry picked from commit 401a8d6e1379133863e3271374dc21850d0d3cab) diff --git a/dix/cursor.c b/dix/cursor.c index e459456..25d6767 100644 --- a/dix/cursor.c +++ b/dix/cursor.c @@ -288,6 +288,29 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, goto error; *ppCurs = pCurs; + + if (argb) { + size_t i, size = bits->width * bits->height; + + for (i = 0; i < size; i++) { + if ((argb[i] & 0xff000000) == 0 && (argb[i] & 0xffffff) != 0) { + /* ARGB data doesn't seem pre-multiplied, fix it */ + for (i = 0; i < size; i++) { + CARD32 a, ar, ag, ab; + + a = argb[i] >> 24; + ar = a * ((argb[i] >> 16) & 0xff) / 0xff; + ag = a * ((argb[i] >> 8) & 0xff) / 0xff; + ab = a * (argb[i] & 0xff) / 0xff; + + argb[i] = a << 24 | ar << 16 | ag << 8 | ab; + } + + break; + } + } + } + return Success; error: commit c0b02ce45f48450d2896a424dc1eb9a2827ed4c5 Author: Hans De Goede <hdego...@redhat.com> Date: Thu Jul 7 10:55:04 2016 +0200 linux: Do not try to open /dev/vc/0, fix error msg when /dev/tty0 open fails /dev/vc/0 is a devfs thing which is long dead, so stop trying to open /dev/vc/0, besides being a (small) code cleanup this will also fix the "parse_vt_settings: Cannot open /dev/tty0 (%s)\n" error message to display the actual error, rather then the -ENOENT from also trying /dev/vc/0. BugLink: https://patchwork.freedesktop.org/patch/8768/ Reported-by: Chad Versace <chad.vers...@linux.intel.com> Suggested-by: Julien Cristau <jcris...@debian.org> Signed-off-by: Hans de Goede <hdego...@redhat.com> Reviewed-by: Julien Cristau <jcris...@debian.org> Reviewed-by: Chad Versace <chad.vers...@intel.com> (cherry picked from commit 033888e7766d226a179357d970223428c19c4b53) diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index 1ed213c..ca17493 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -93,7 +93,6 @@ linux_parse_vt_settings(int may_fail) struct vt_stat vts; struct stat st; MessageType from = X_PROBED; - const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; /* Only do this once */ static int vt_settings_parsed = 0; @@ -108,14 +107,7 @@ linux_parse_vt_settings(int may_fail) from = X_CMDLINE; } else { - - i = 0; - while (tty0[i] != NULL) { - if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0) - break; - i++; - } - + fd = open("/dev/tty0", O_WRONLY, 0); if (fd < 0) { if (may_fail) return 0; commit b377a806693ec86df1743d7ddd5a931c88050ebb Author: Adam Jackson <a...@redhat.com> Date: Mon Jul 18 12:46:51 2016 -0400 modesetting: resubmit dirty rects on EINVAL (v2) This error code can mean we're submitting more rects at once than the driver can handle. If that happens, resubmit one at a time. v2: Make the rect submit loop more error-proof (Walter Harms) Signed-off-by: Adam Jackson <a...@redhat.com> Reviewed-by: Michael Thayer <michael.tha...@oracle.com> (cherry picked from commit 4b311d23e84356bd0e9e736aeed7448dd6382118) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 6133d2d..14f80b3 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -502,6 +502,15 @@ dispatch_dirty_region(ScrnInfoPtr scrn, /* TODO query connector property to see if this is needed */ ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); + + /* if we're swamping it with work, try one at a time */ + if (ret == -EINVAL) { + for (i = 0; i < num_cliprects; i++) { + if ((ret = drmModeDirtyFB(ms->fd, fb_id, &clip[i], 1)) < 0) + break; + } + } + free(clip); DamageEmpty(damage); } commit f091528457cc62fa9bd6cd24aeebacffb7296419 Author: Dave Airlie <airl...@redhat.com> Date: Wed Jul 22 12:14:06 2015 -0400 modesetting: Implement 32->24 bpp conversion in shadow update 24bpp front buffers tend to be the least well tested path for client rendering. On the qemu cirrus emulation, and on some Matrox G200 server chips, the hardware can't do 32bpp at all. It's better to just allocate a 32bpp shadow and downconvert in the upload hook than expose a funky pixmap format to clients. [ajax: Ported from RHEL and separate modesetting driver, lifted kbpp into the drmmode struct, cleaned up commit message, fixed 16bpp] Reviewed-by: Adam Jackson <a...@redhat.com> Signed-off-by: Dave Airlied <airl...@redhat.com> Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> [hdego...@redhat.com: rebase, also use kbpp for rotate shadow fb] Signed-off-by: Hans de Goede <hdego...@redhat.com> (cherry picked from commit 21217d02168d1883b2d1f64399aec494f96a8b9d) diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am index 82c4f2f..ca7e05a 100644 --- a/hw/xfree86/drivers/modesetting/Makefile.am +++ b/hw/xfree86/drivers/modesetting/Makefile.am @@ -51,6 +51,8 @@ modesetting_drv_la_SOURCES = \ dumb_bo.c \ dumb_bo.h \ present.c \ + sh3224.c \ + sh3224.h \ vblank.c \ $(NULL) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index e7f6e8d..6133d2d 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -60,6 +60,7 @@ #endif #include "driver.h" +#include "sh3224.h" static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y); static Bool CloseScreen(ScreenPtr pScreen); @@ -662,6 +663,11 @@ try_enable_glamor(ScrnInfoPtr pScrn) ms->drmmode.glamor = FALSE; #ifdef GLAMOR + if (ms->drmmode.force_24_32) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cannot use glamor with 24bpp packed fb\n"); + return; + } + if (!do_glamor) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "glamor disabled\n"); return; @@ -810,10 +816,16 @@ PreInit(ScrnInfoPtr pScrn, int flags) ms->drmmode.fd = ms->fd; drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp); - if (defaultdepth == 24 && defaultbpp == 24) - bppflags = SupportConvert32to24 | Support24bppFb; - else - bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; + if (defaultdepth == 24 && defaultbpp == 24) { + ms->drmmode.force_24_32 = TRUE; + ms->drmmode.kbpp = 24; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using 24bpp hw front buffer with 32bpp shadow\n"); + defaultbpp = 32; + } else { + ms->drmmode.kbpp = defaultbpp; + } + bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; if (!xf86SetDepthBpp (pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags)) @@ -867,18 +879,24 @@ PreInit(ScrnInfoPtr pScrn, int flags) } else { Bool prefer_shadow = TRUE; - ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); - if (!ret) { - prefer_shadow = !!value; - } + if (ms->drmmode.force_24_32) { + prefer_shadow = TRUE; + ms->drmmode.shadow_enable = TRUE; + } else { + ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); + if (!ret) { + prefer_shadow = !!value; + } - ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->drmmode.Options, - OPTION_SHADOW_FB, - prefer_shadow); + ms->drmmode.shadow_enable = + xf86ReturnOptValBool(ms->drmmode.Options, OPTION_SHADOW_FB, + prefer_shadow); + } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB: preferred %s, enabled %s\n", prefer_shadow ? "YES" : "NO", + ms->drmmode.force_24_32 ? "FORCE" : ms->drmmode.shadow_enable ? "YES" : "NO"); ms->drmmode.pageflip = FALSE; @@ -950,7 +968,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, modesettingPtr ms = modesettingPTR(pScrn); int stride; - stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; + stride = (pScrn->displayWidth * ms->drmmode.kbpp) / 8; *size = stride; return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset); @@ -971,6 +989,7 @@ CreateScreenResources(ScreenPtr pScreen) Bool ret; void *pixels = NULL; int err; + Bool use_ms_shadow = ms->drmmode.force_24_32 && pScrn->bitsPerPixel == 32; pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); @@ -1002,7 +1021,8 @@ CreateScreenResources(ScreenPtr pScreen) FatalError("Couldn't adjust screen pixmap\n"); if (ms->drmmode.shadow_enable) { - if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked, + if (!shadowAdd(pScreen, rootPixmap, + use_ms_shadow ? ms_shadowUpdate32to24 : msUpdatePacked, msShadowWindow, 0, 0)) return FALSE; } diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index d2bc211..9c54310 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -408,7 +408,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (fb_id == 0) { ret = drmModeAddFB(drmmode->fd, pScrn->virtualX, pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel, + pScrn->depth, drmmode->kbpp, drmmode_bo_get_pitch(&drmmode->front_bo), drmmode_bo_get_handle(&drmmode->front_bo), &drmmode->fb_id); @@ -703,14 +703,14 @@ drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) int ret; if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo, - width, height, crtc->scrn->bitsPerPixel)) { + width, height, drmmode->kbpp)) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "Couldn't allocate shadow memory for rotated CRTC\n"); return NULL; } ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, - crtc->scrn->bitsPerPixel, + drmmode->kbpp, drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), &drmmode_crtc->rotate_fb_id); @@ -781,7 +781,7 @@ drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen, width, height, scrn->depth, - scrn->bitsPerPixel, + drmmode->kbpp, rotate_pitch, pPixData); @@ -1667,6 +1667,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) uint32_t old_fb_id; int i, pitch, old_width, old_height, old_pitch; int cpp = (scrn->bitsPerPixel + 7) / 8; + int kcpp = (drmmode->kbpp + 7) / 8; PixmapPtr ppix = screen->GetScreenPixmap(screen); void *new_pixels = NULL; @@ -1688,14 +1689,14 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) old_front = drmmode->front_bo; if (!drmmode_create_bo(drmmode, &drmmode->front_bo, - width, height, scrn->bitsPerPixel)) + width, height, drmmode->kbpp)) goto fail; pitch = drmmode_bo_get_pitch(&drmmode->front_bo); scrn->virtualX = width; scrn->virtualY = height; - scrn->displayWidth = pitch / cpp; + scrn->displayWidth = pitch / kcpp; ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, scrn->bitsPerPixel, pitch, @@ -1711,8 +1712,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) } if (drmmode->shadow_enable) { - uint32_t size = scrn->displayWidth * scrn->virtualY * - ((scrn->bitsPerPixel + 7) >> 3); + uint32_t size = scrn->displayWidth * scrn->virtualY * cpp; new_pixels = calloc(1, size); if (new_pixels == NULL) goto fail; @@ -1720,7 +1720,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) drmmode->shadow_fb = new_pixels; } - screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels); + screen->ModifyPixmapHeader(ppix, width, height, -1, -1, + scrn->displayWidth * cpp, new_pixels); if (!drmmode_glamor_handle_new_screen_pixmap(drmmode)) goto fail; @@ -1747,7 +1748,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) drmmode->front_bo = old_front; scrn->virtualX = old_width; scrn->virtualY = old_height; - scrn->displayWidth = old_pitch / cpp; + scrn->displayWidth = old_pitch / kcpp; drmmode->fb_id = old_fb_id; return FALSE; @@ -2103,7 +2104,7 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int width; int height; - int bpp = pScrn->bitsPerPixel; + int bpp = ms->drmmode.kbpp; int i; int cpp = (bpp + 7) / 8; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index fca68a6..9139ed4 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -48,6 +48,7 @@ typedef struct { unsigned fb_id; drmModeFBPtr mode_fb; int cpp; + int kbpp; ScrnInfoPtr scrn; struct gbm_device *gbm; @@ -67,6 +68,7 @@ typedef struct { Bool shadow_enable; /** Is Option "PageFlip" enabled? */ Bool pageflip; + Bool force_24_32; void *shadow_fb; /** diff --git a/hw/xfree86/drivers/modesetting/sh3224.c b/hw/xfree86/drivers/modesetting/sh3224.c new file mode 100644 index 0000000..a64a103 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/sh3224.c @@ -0,0 +1,140 @@ +/* + * + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include "dix-config.h" +#endif + +#include "shadow.h" +#include "fb.h" + +#include "sh3224.h" +#define Get8(a) ((CARD32) READ(a)) + +#if BITMAP_BIT_ORDER == MSBFirst +#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) (p)))) +#else +#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) ((p) >> 16)))) +#endif + +static void +sh24_32BltLine(CARD8 *srcLine, + CARD8 *dstLine, + int width) +{ + CARD32 *src; + CARD8 *dst; + int w; + CARD32 pixel; + + src = (CARD32 *) srcLine; + dst = dstLine; + w = width; + + while (((long)dst & 3) && w) { + w--; + pixel = READ(src++); + Put24(dst, pixel); + dst += 3; + } + /* Do four aligned pixels at a time */ + while (w >= 4) { + CARD32 s0, s1; + + s0 = READ(src++); + s1 = READ(src++); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *) dst, (s0 & 0xffffff) | (s1 << 24)); +#else + WRITE((CARD32 *) dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); +#endif + s0 = READ(src++); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *) (dst + 4), + ((s1 & 0xffffff) >> 8) | (s0 << 16)); +#else + WRITE((CARD32 *) (dst + 4), + (s1 << 16) | ((s0 & 0xffffff) >> 8)); +#endif + s1 = READ(src++); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *) (dst + 8), + ((s0 & 0xffffff) >> 16) | (s1 << 8)); +#else + WRITE((CARD32 *) (dst + 8), (s0 << 24) | (s1 & 0xffffff)); +#endif + dst += 12; + w -= 4; + } + while (w--) { + pixel = READ(src++); + Put24(dst, pixel); + dst += 3; + } +} + +void +ms_shadowUpdate32to24(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbStride shaStride; + int shaBpp; + _X_UNUSED int shaXoff, shaYoff; + int x, y, w, h; + CARD32 winSize; + FbBits *shaBase, *shaLine; + CARD8 *winBase = NULL, *winLine; + + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + + /* just get the initial window base + stride */ + winBase = (*pBuf->window)(pScreen, 0, 0, SHADOW_WINDOW_WRITE, + &winSize, pBuf->closure); + + while (nbox--) { + x = pbox->x1; + y = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + winLine = winBase + y * winSize + (x * 3); + shaLine = shaBase + y * shaStride + ((x * shaBpp) >> FB_SHIFT); + + while (h--) { + sh24_32BltLine((CARD8 *)shaLine, (CARD8 *)winLine, w); + winLine += winSize; + shaLine += shaStride; + }