diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2018-08-28 19:00:23 +0100 |
---|---|---|
committer | Jon Turney <jon.turney@dronecode.org.uk> | 2018-08-28 19:00:23 +0100 |
commit | b561176bffc9fda559c121ce639bee78c3ab2d8f (patch) | |
tree | e898090837845a87d63b243d9e2a018af924ddce | |
parent | 352e8a53ef0f5ad2777b792622e52e6e80dc7bb8 (diff) | |
parent | 1508ea68065b7976dbf56039f9b20dcaf0394431 (diff) |
Merge tag 'xorg-server-1.20.1' into cygwin-release-1.20
xorg-server-1.20.1
45 files changed, 785 insertions, 436 deletions
diff --git a/Xext/dpms.c b/Xext/dpms.c index efa715428..e43a37974 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -45,9 +45,9 @@ Equipment Corporation. CARD16 DPMSPowerLevel = 0; Bool DPMSDisabledSwitch = FALSE; -CARD32 DPMSStandbyTime; -CARD32 DPMSSuspendTime; -CARD32 DPMSOffTime; +CARD32 DPMSStandbyTime = -1; +CARD32 DPMSSuspendTime = -1; +CARD32 DPMSOffTime = -1; Bool DPMSEnabled; Bool @@ -432,7 +432,15 @@ DPMSCloseDownExtension(ExtensionEntry *e) void DPMSExtensionInit(void) { - DPMSStandbyTime = DPMSSuspendTime = DPMSOffTime = ScreenSaverTime; +#define CONDITIONALLY_SET_DPMS_TIMEOUT(_timeout_value_) \ + if (_timeout_value_ == -1) { /* not yet set from config */ \ + _timeout_value_ = ScreenSaverTime; \ + } + + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSStandbyTime) + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSSuspendTime) + CONDITIONALLY_SET_DPMS_TIMEOUT(DPMSOffTime) + DPMSPowerLevel = DPMSModeOn; DPMSEnabled = DPMSSupported(); diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c index 844ea49ce..bd9c45b03 100644 --- a/Xext/panoramiX.c +++ b/Xext/panoramiX.c @@ -751,11 +751,7 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth) PanoramiXNumDepths, sizeof(DepthRec)); PanoramiXDepths[j].depth = pDepth->depth; PanoramiXDepths[j].numVids = 0; - /* XXX suboptimal, should grow these dynamically */ - if (pDepth->numVids) - PanoramiXDepths[j].vids = xallocarray(pDepth->numVids, sizeof(VisualID)); - else - PanoramiXDepths[j].vids = NULL; + PanoramiXDepths[j].vids = NULL; } static void @@ -796,6 +792,9 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual) for (k = 0; k < PanoramiXNumDepths; k++) { if (PanoramiXDepths[k].depth == pVisual->nplanes) { + PanoramiXDepths[k].vids = reallocarray(PanoramiXDepths[k].vids, + PanoramiXDepths[k].numVids + 1, + sizeof(VisualID)); PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; PanoramiXDepths[k].numVids++; break; diff --git a/Xext/shm.c b/Xext/shm.c index fc8441c43..896a966e3 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -1302,9 +1302,14 @@ static int ProcShmDispatch(ClientPtr client) { REQUEST(xReq); - switch (stuff->data) { - case X_ShmQueryVersion: + + if (stuff->data == X_ShmQueryVersion) return ProcShmQueryVersion(client); + + if (!client->local) + return BadRequest; + + switch (stuff->data) { case X_ShmAttach: return ProcShmAttach(client); case X_ShmDetach: @@ -1461,9 +1466,14 @@ static int _X_COLD SProcShmDispatch(ClientPtr client) { REQUEST(xReq); - switch (stuff->data) { - case X_ShmQueryVersion: + + if (stuff->data == X_ShmQueryVersion) return SProcShmQueryVersion(client); + + if (!client->local) + return BadRequest; + + switch (stuff->data) { case X_ShmAttach: return SProcShmAttach(client); case X_ShmDetach: diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index c0000f909..fbb51fe81 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -238,6 +238,18 @@ SizeDeviceClasses(DeviceIntPtr dev) } /** + * Get pointers to button information areas holding button mask and labels. + */ +static void +ButtonInfoData(xXIButtonInfo *info, int *mask_words, unsigned char **mask, + Atom **atoms) +{ + *mask_words = bytes_to_int32(bits_to_bytes(info->num_buttons)); + *mask = (unsigned char*) &info[1]; + *atoms = (Atom*) ((*mask) + (*mask_words) * 4); +} + +/** * Write button information into info. * @return Number of bytes written into info. */ @@ -245,21 +257,20 @@ int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) { unsigned char *bits; + Atom *labels; int mask_len; int i; if (!dev || !dev->button) return 0; - mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); - info->type = ButtonClass; info->num_buttons = dev->button->numButtons; + ButtonInfoData(info, &mask_len, &bits, &labels); info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + info->num_buttons + mask_len; info->sourceid = dev->button->sourceid; - bits = (unsigned char *) &info[1]; memset(bits, 0, mask_len * 4); if (reportState) @@ -267,8 +278,7 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) if (BitIsOn(dev->button->down, i)) SetBit(bits, i); - bits += mask_len * 4; - memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); + memcpy(labels, dev->button->labels, dev->button->numButtons * sizeof(Atom)); return info->length * 4; } @@ -277,13 +287,17 @@ static void SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info) { Atom *btn; + int mask_len; + unsigned char *mask; + int i; + ButtonInfoData(info, &mask_len, &mask, &btn); swaps(&info->type); swaps(&info->length); swaps(&info->sourceid); - for (i = 0, btn = (Atom *) &info[1]; i < info->num_buttons; i++, btn++) + for (i = 0 ; i < info->num_buttons; i++, btn++) swapl(btn); swaps(&info->num_buttons); @@ -369,6 +383,9 @@ SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo * info) swapl(&info->min.frac); swapl(&info->max.integral); swapl(&info->max.frac); + swapl(&info->value.integral); + swapl(&info->value.frac); + swapl(&info->resolution); swaps(&info->number); swaps(&info->sourceid); } diff --git a/configure.ac b/configure.ac index 6d2231284..071da3ce7 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.20.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2018-05-10" -RELEASE_NAME="Avocado Toast" +AC_INIT([xorg-server], 1.20.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2018-08-07" +RELEASE_NAME="Kale Salad" AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -1916,9 +1916,6 @@ if test "x$XORG" = xyes; then XORG_OS_SUBDIR="linux" linux_acpi="no" case $host_cpu in - alpha*) - linux_alpha=yes - ;; i*86|amd64*|x86_64*|ia64*) linux_acpi=$enable_linux_acpi ;; @@ -2083,7 +2080,6 @@ AM_CONDITIONAL([XORG], [test "x$XORG" = xyes]) AM_CONDITIONAL([XORG_BUS_PCI], [test "x$PCI" = xyes]) AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes]) AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes]) -AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes]) AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes]) AM_CONDITIONAL([LNXAPM], [test "x$linux_apm" = xyes]) AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes]) diff --git a/exa/exa_render.c b/exa/exa_render.c index 50a9a659e..9fbfdfca2 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -291,7 +291,8 @@ exaTryDriverSolidFill(PicturePtr pSrc, pixel = exaGetPixmapFirstPixel(pSrcPix); } else - miRenderColorToPixel(pSrc->pFormat, + miRenderColorToPixel(PictureMatchFormat(pDst->pDrawable->pScreen, 32, + pSrc->format), &pSrc->pSourcePict->solidFill.fullcolor, &pixel); diff --git a/glamor/glamor.c b/glamor/glamor.c index 86935ed98..9bf1707de 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -563,6 +563,14 @@ glamor_init(ScreenPtr screen, unsigned int flags) if (!glamor_check_instruction_count(gl_version)) goto fail; + + /* Glamor rendering assumes that platforms with GLSL 130+ + * have instanced arrays, but this is not always the case. + * etnaviv offers GLSL 140 with OpenGL 2.1. + */ + if (glamor_priv->glsl_version >= 130 && + !epoxy_has_gl_extension("GL_ARB_instanced_arrays")) + glamor_priv->glsl_version = 120; } else { if (gl_version < 20) { ErrorF("Require Open GLES2.0 or later.\n"); @@ -818,56 +826,66 @@ glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format, return TRUE; } -_X_EXPORT int -glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, - uint32_t *strides, uint32_t *offsets, - uint64_t *modifier) +static int +_glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, + uint32_t *strides, uint32_t *offsets, + CARD32 *size, uint64_t *modifier) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); if (!glamor_priv->dri3_enabled) - return -1; + return 0; switch (pixmap_priv->type) { case GLAMOR_TEXTURE_DRM: case GLAMOR_TEXTURE_ONLY: if (!glamor_pixmap_ensure_fbo(pixmap, pixmap->drawable.depth == 30 ? GL_RGB10_A2 : GL_RGBA, 0)) - return -1; - return glamor_egl_fds_from_pixmap(screen, pixmap, fds, - strides, offsets, - modifier); + return 0; + + if (modifier) { + return glamor_egl_fds_from_pixmap(screen, pixmap, fds, + strides, offsets, + modifier); + } else { + CARD16 stride; + + fds[0] = glamor_egl_fd_from_pixmap(screen, pixmap, &stride, size); + strides[0] = stride; + + return fds[0] >= 0; + } default: break; } - return -1; + return 0; +} + +_X_EXPORT int +glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, + uint32_t *strides, uint32_t *offsets, + uint64_t *modifier) +{ + return _glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, + NULL, modifier); } _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { + int fd; int ret; - int fds[4]; - uint32_t strides[4], offsets[4]; - uint64_t modifier; - - ret = glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets, - &modifier); + uint32_t stride32; - /* Pixmaps with multi-planes/modifier are not supported in this interface */ - if (ret > 1) { - while (ret > 0) - close(fds[--ret]); + ret = _glamor_fds_from_pixmap(screen, pixmap, &fd, &stride32, NULL, size, + NULL); + if (ret != 1) return -1; - } - - ret = fds[0]; - *stride = strides[0]; - *size = pixmap->drawable.height * *stride; - return ret; + *stride = stride32; + return fd; } _X_EXPORT int diff --git a/glamor/glamor.h b/glamor/glamor.h index 06e11506f..09e9c895c 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -141,7 +141,7 @@ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back); -/* The DDX is not supposed to call these three functions */ +/* The DDX is not supposed to call these four functions */ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen); extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *, uint32_t *, uint32_t *, @@ -150,6 +150,7 @@ extern _X_EXPORT int glamor_egl_fd_name_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen); +extern _X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr, PixmapPtr, CARD16 *, CARD32 *); /* @glamor_supports_pixmap_import_export: Returns whether * glamor_fds_from_pixmap(), glamor_name_from_pixmap(), and diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 123e9f28d..0edfa111c 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -99,8 +99,18 @@ glamor_get_flink_name(int fd, int handle, int *name) struct drm_gem_flink flink; flink.handle = handle; - if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) - return FALSE; + if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + + /* + * Assume non-GEM kernels have names identical to the handle + */ + if (errno == ENODEV) { + *name = handle; + return TRUE; + } else { + return FALSE; + } + } *name = flink.name; return TRUE; } @@ -402,7 +412,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, #endif } -static int +_X_EXPORT int glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c index aae909e9f..91ab9a7ae 100644 --- a/glamor/glamor_egl_stubs.c +++ b/glamor/glamor_egl_stubs.c @@ -51,3 +51,10 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, { return 0; } + +int +glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ + return -1; +} diff --git a/glx/vndcmds.c b/glx/vndcmds.c index 493e2bfc0..45b1eafaa 100644 --- a/glx/vndcmds.c +++ b/glx/vndcmds.c @@ -50,7 +50,7 @@ typedef struct GlxVendorPrivDispatchRec { static GlxServerDispatchProc dispatchFuncs[OPCODE_ARRAY_LEN] = {}; static HashTable vendorPrivHash = NULL; static HtGenericHashSetupRec vendorPrivSetup = { - .keySize = sizeof(void*) + .keySize = sizeof(CARD32) }; static int DispatchBadRequest(ClientPtr client) diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 57c8b8dd4..9aeaea1a6 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -108,14 +108,14 @@ endif install-exec-hook: (cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) Xorg$(EXEEXT) X) if INSTALL_SETUID - chown root $(DESTDIR)$(bindir)/Xorg + chown 0 $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg endif if SUID_WRAPPER $(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR) mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg ${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg - -chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap + -chown 0 $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap endif uninstall-local: diff --git a/hw/xfree86/common/compiler.h b/hw/xfree86/common/compiler.h index eea29dfb5..7144c6a27 100644 --- a/hw/xfree86/common/compiler.h +++ b/hw/xfree86/common/compiler.h @@ -986,33 +986,64 @@ inl(unsigned PORT_SIZE port) #endif #ifdef __alpha__ -/* entry points for Mmio memory access routines */ -extern _X_EXPORT int (*xf86ReadMmio8) (void *, unsigned long); -extern _X_EXPORT int (*xf86ReadMmio16) (void *, unsigned long); -extern _X_EXPORT int (*xf86ReadMmio32) (void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio8) (int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio16) (int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio32) (int, void *, unsigned long); +static inline int +xf86ReadMmio8(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD8 *) ((unsigned long) Base + (Offset)); +} + +static inline int +xf86ReadMmio16(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD16 *) ((unsigned long) Base + (Offset)); +} + +static inline int +xf86ReadMmio32(void *Base, unsigned long Offset) +{ + mem_barrier(); + return *(CARD32 *) ((unsigned long) Base + (Offset)); +} + +static inline void +xf86WriteMmio8(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD8 *) ((unsigned long) Base + (Offset)) = Value; +} + +static inline void +xf86WriteMmio16(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD16 *) ((unsigned long) Base + (Offset)) = Value; +} + +static inline void +xf86WriteMmio32(int Value, void *Base, unsigned long Offset) +{ + write_mem_barrier(); + *(CARD32 *) ((unsigned long) Base + (Offset)) = Value; +} + extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int); extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); /* Some macros to hide the system dependencies for MMIO accesses */ /* Changed to kill noise generated by gcc's -Wcast-align */ -#define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) -#define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) -#define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) - -#define MMIO_OUT32(base, offset, val) \ - do { \ - write_mem_barrier(); \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \ - } while (0) +#define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) +#define MMIO_IN16(base, offset) xf86ReadMmio16(base, offset) +#define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) #define MMIO_OUT8(base, offset, val) \ - (*xf86WriteMmio8)((CARD8)(val), base, offset) + xf86WriteMmio8((CARD8)(val), base, offset) #define MMIO_OUT16(base, offset, val) \ - (*xf86WriteMmio16)((CARD16)(val), base, offset) + xf86WriteMmio16((CARD16)(val), base, offset) +#define MMIO_OUT32(base, offset, val) \ + xf86WriteMmio32((CARD32)(val), base, offset) #elif defined(__powerpc__) || defined(__sparc__) /* diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index e890f05c2..7cc7401a2 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -53,6 +53,8 @@ DevPrivateKeyRec xf86ScreenKeyRec; ScrnInfoPtr *xf86Screens = NULL; /* List of ScrnInfos */ ScrnInfoPtr *xf86GPUScreens = NULL; /* List of ScrnInfos */ +int xf86DRMMasterFd = -1; /* Command line argument for DRM master file descriptor */ + const unsigned char byte_reversed[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 4fe2b5f33..393af3900 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -93,6 +93,7 @@ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */ extern ScrnInfoPtr *xf86GPUScreens; /* List of pointers to ScrnInfoRecs */ extern int xf86NumGPUScreens; +extern _X_EXPORT int xf86DRMMasterFd; /* Command line argument for DRM master file descriptor */ #ifndef DEFAULT_VERBOSE #define DEFAULT_VERBOSE 0 #endif diff --git a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h index 20c15837a..2ec8a1e24 100644 --- a/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h +++ b/hw/xfree86/dri2/pci_ids/radeonsi_pci_ids.h @@ -205,3 +205,33 @@ CHIPSET(0x67CF, POLARIS10_, POLARIS10) CHIPSET(0x67DF, POLARIS10_, POLARIS10) CHIPSET(0x98E4, STONEY_, STONEY) + +CHIPSET(0x6980, POLARIS12_, POLARIS12) +CHIPSET(0x6981, POLARIS12_, POLARIS12) +CHIPSET(0x6985, POLARIS12_, POLARIS12) +CHIPSET(0x6986, POLARIS12_, POLARIS12) +CHIPSET(0x6987, POLARIS12_, POLARIS12) +CHIPSET(0x6995, POLARIS12_, POLARIS12) +CHIPSET(0x6997, POLARIS12_, POLARIS12) +CHIPSET(0x699F, POLARIS12_, POLARIS12) + +CHIPSET(0x694C, VEGAM_, VEGAM) +CHIPSET(0x694E, VEGAM_, VEGAM) + +CHIPSET(0x6860, VEGA10_, VEGA10) +CHIPSET(0x6861, VEGA10_, VEGA10) +CHIPSET(0x6862, VEGA10_, VEGA10) +CHIPSET(0x6863, VEGA10_, VEGA10) +CHIPSET(0x6864, VEGA10_, VEGA10) +CHIPSET(0x6867, VEGA10_, VEGA10) +CHIPSET(0x6868, VEGA10_, VEGA10) +CHIPSET(0x687F, VEGA10_, VEGA10) +CHIPSET(0x686C, VEGA10_, VEGA10) + +CHIPSET(0x69A0, VEGA12_, VEGA12) +CHIPSET(0x69A1, VEGA12_, VEGA12) +CHIPSET(0x69A2, VEGA12_, VEGA12) +CHIPSET(0x69A3, VEGA12_, VEGA12) +CHIPSET(0x69AF, VEGA12_, VEGA12) + +CHIPSET(0x15DD, RAVEN_, RAVEN) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 5d8906d63..9362370c3 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -36,6 +36,7 @@ #include <unistd.h> #include <fcntl.h> #include "xf86.h" +#include "xf86Priv.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" @@ -195,17 +196,30 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn) } static int +get_passed_fd(void) +{ + if (xf86DRMMasterFd >= 0) { + xf86DrvMsg(-1, X_INFO, "Using passed DRM master file descriptor %d\n", xf86DRMMasterFd); + return dup(xf86DRMMasterFd); + } + return -1; +} + +static int open_hw(const char *dev) { int fd; + if ((fd = get_passed_fd()) != -1) + return fd; + if (dev) - fd = open(dev, O_RDWR, 0); + fd = open(dev, O_RDWR | O_CLOEXEC, 0); else { dev = getenv("KMSDEVICE"); - if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { + if ((NULL == dev) || ((fd = open(dev, O_RDWR | O_CLOEXEC, 0)) == -1)) { dev = "/dev/dri/card0"; - fd = open(dev, O_RDWR, 0); + fd = open(dev, O_RDWR | O_CLOEXEC, 0); } } if (fd == -1) @@ -818,6 +832,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn) return TRUE; } + ms->fd_passed = FALSE; + if ((ms->fd = get_passed_fd()) >= 0) { + ms->fd_passed = TRUE; + return TRUE; + } + #ifdef XSERVER_PLATFORM_BUS if (pEnt->location.type == BUS_PLATFORM) { #ifdef XF86_PDEV_SERVER_FD @@ -920,7 +940,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) "Using 24bpp hw front buffer with 32bpp shadow\n"); defaultbpp = 32; } else { - ms->drmmode.kbpp = defaultbpp; + ms->drmmode.kbpp = 0; } bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; @@ -941,6 +961,8 @@ PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } xf86PrintDepthBpp(pScrn); + if (!ms->drmmode.kbpp) + ms->drmmode.kbpp = pScrn->bitsPerPixel; /* Process the options */ xf86CollectOptions(pScrn, NULL); @@ -1014,8 +1036,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) #endif } - ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - ret |= drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); + ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1); ms->atomic_modeset = (ret == 0); ms->kms_has_modifiers = FALSE; @@ -1502,6 +1523,9 @@ SetMaster(ScrnInfoPtr pScrn) return TRUE; #endif + if (ms->fd_passed) + return TRUE; + ret = drmSetMaster(ms->fd); if (ret) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", @@ -1754,7 +1778,8 @@ LeaveVT(ScrnInfoPtr pScrn) return; #endif - drmDropMaster(ms->fd); + if (!ms->fd_passed) + drmDropMaster(ms->fd); } /* @@ -1813,8 +1838,6 @@ CloseScreen(ScreenPtr pScreen) ms->drmmode.shadow_fb2 = NULL; } - drmmode_terminate_leases(pScrn, &ms->drmmode); - drmmode_uevent_fini(pScrn, &ms->drmmode); drmmode_free_bos(pScrn, &ms->drmmode); diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index 55f3400e2..c8db4b8a4 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -84,6 +84,7 @@ struct ms_drm_queue { typedef struct _modesettingRec { int fd; + Bool fd_passed; int Chipset; EntityInfoPtr pEnt; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 859a21a9d..f6f2e9fd1 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -604,6 +604,8 @@ drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y) drmmode_ptr drmmode = drmmode_crtc->drmmode; int ret; + *fb_id = 0; + if (drmmode_crtc->prime_pixmap) { if (!drmmode->reverse_prime_offload_mode) { msPixmapPrivPtr ppriv = @@ -695,18 +697,21 @@ drmmode_output_disable(xf86OutputPtr output) { modesettingPtr ms = modesettingPTR(output->scrn); drmmode_output_private_ptr drmmode_output = output->driver_private; + xf86CrtcPtr crtc = drmmode_output->current_crtc; drmModeAtomicReq *req = drmModeAtomicAlloc(); uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; - int ret; + int ret = 0; assert(ms->atomic_modeset); if (!req) return 1; - /* XXX Can we disable all outputs without disabling CRTC right away? */ - ret = connector_add_prop(req, drmmode_output, - DRMMODE_CONNECTOR_CRTC_ID, 0); + ret |= connector_add_prop(req, drmmode_output, + DRMMODE_CONNECTOR_CRTC_ID, 0); + if (crtc) + ret |= crtc_add_dpms_props(req, crtc, DPMSModeOff, NULL); + if (ret == 0) ret = drmModeAtomicCommit(ms->fd, req, flags, NULL); @@ -990,7 +995,7 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo, } #endif return drmModeAddFB(drmmode->fd, bo->width, bo->height, - drmmode->scrn->depth, drmmode->scrn->bitsPerPixel, + drmmode->scrn->depth, drmmode->kbpp, drmmode_bo_get_pitch(bo), drmmode_bo_get_handle(bo), fb_id); } @@ -1794,11 +1799,8 @@ drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } - ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, - drmmode->kbpp, - drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), - drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), - &drmmode_crtc->rotate_fb_id); + ret = drmmode_bo_import(drmmode, &drmmode_crtc->rotate_bo, + &drmmode_crtc->rotate_fb_id); if (ret) { ErrorF("failed to add rotate fb\n"); @@ -3251,6 +3253,9 @@ drmmode_create_lease(RRLeasePtr lease, int *fd) nobjects = ncrtc + noutput; + if (ms->atomic_modeset) + nobjects += ncrtc; /* account for planes as well */ + if (nobjects == 0) return BadValue; @@ -3267,12 +3272,14 @@ drmmode_create_lease(RRLeasePtr lease, int *fd) i = 0; - /* Add CRTC ids */ + /* Add CRTC and plane ids */ for (c = 0; c < ncrtc; c++) { xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; objects[i++] = drmmode_crtc->mode_crtc->crtc_id; + if (ms->atomic_modeset) + objects[i++] = drmmode_crtc->plane_id; } /* Add connector ids */ @@ -3320,23 +3327,6 @@ drmmode_terminate_lease(RRLeasePtr lease) } } -void -drmmode_terminate_leases(ScrnInfoPtr pScrn, drmmode_ptr drmmode) -{ - ScreenPtr screen = xf86ScrnToScreen(pScrn); - rrScrPrivPtr scr_priv = rrGetScrPriv(screen); - RRLeasePtr lease, next; - - xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) { - drmmode_lease_private_ptr lease_private = lease->devPrivate; - drmModeRevokeLease(drmmode->fd, lease_private->lessee_id); - free(lease_private); - lease->devPrivate = NULL; - RRLeaseTerminated(lease); - RRLeaseFree(lease); - } -} - static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { .resize = drmmode_xf86crtc_resize, .create_lease = drmmode_create_lease, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index e46a292d3..cde661450 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -272,8 +272,6 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); -extern void drmmode_terminate_leases(ScrnInfoPtr scrn, drmmode_ptr drmmode); - Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); void *drmmode_map_front_bo(drmmode_ptr drmmode); Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 4aa77a244..37a45bb3a 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -174,6 +174,32 @@ xf86CrtcInUse(xf86CrtcPtr crtc) return FALSE; } +/** + * Return whether the crtc is leased by a client + */ + +static Bool +xf86CrtcIsLeased(xf86CrtcPtr crtc) +{ + /* If the DIX structure hasn't been created, it can't have been leased */ + if (!crtc->randr_crtc) + return FALSE; + return RRCrtcIsLeased(crtc->randr_crtc); +} + +/** + * Return whether the output is leased by a client + */ + +static Bool +xf86OutputIsLeased(xf86OutputPtr output) +{ + /* If the DIX structure hasn't been created, it can't have been leased */ + if (!output->randr_output) + return FALSE; + return RROutputIsLeased(output->randr_output); +} + void xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen) { @@ -254,7 +280,7 @@ xf86CrtcSetModeTransform(xf86CrtcPtr crtc, DisplayModePtr mode, RRTransformRec saved_transform; Bool saved_transform_present; - crtc->enabled = xf86CrtcInUse(crtc) && !RRCrtcIsLeased(crtc->randr_crtc);; + crtc->enabled = xf86CrtcInUse(crtc) && !xf86CrtcIsLeased(crtc); /* We only hit this if someone explicitly sends a "disabled" modeset. */ if (!crtc->enabled) { @@ -412,7 +438,7 @@ xf86CrtcSetOrigin(xf86CrtcPtr crtc, int x, int y) crtc->x = x; crtc->y = y; - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) return; if (crtc->funcs->set_origin) { @@ -734,14 +760,11 @@ xf86CrtcCloseScreen(ScreenPtr screen) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o, c; - screen->CloseScreen = config->CloseScreen; - - xf86RotateCloseScreen(screen); - - xf86RandR12CloseScreen(screen); - - screen->CloseScreen(screen); - + /* The randr_output and randr_crtc pointers are already invalid as + * the DIX resources were freed when the associated resources were + * freed. Clear them now; referencing through them during the rest + * of the CloseScreen sequence will not end well. + */ for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -752,6 +775,15 @@ xf86CrtcCloseScreen(ScreenPtr screen) crtc->randr_crtc = NULL; } + + screen->CloseScreen = config->CloseScreen; + + xf86RotateCloseScreen(screen); + + xf86RandR12CloseScreen(screen); + + screen->CloseScreen(screen); + /* detach any providers */ if (config->randr_provider) { RRProviderDestroy(config->randr_provider); @@ -2656,7 +2688,7 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) static void xf86DisableCrtc(xf86CrtcPtr crtc) { - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) return; crtc->funcs->dpms(crtc, DPMSModeOff); @@ -2677,7 +2709,7 @@ xf86PrepareOutputs(ScrnInfoPtr scrn) for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; - if (RROutputIsLeased(output->randr_output)) + if (xf86OutputIsLeased(output)) continue; #if RANDR_GET_CRTC_INTERFACE @@ -2703,7 +2735,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn) uint32_t desired_outputs = 0, current_outputs = 0; int o; - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) continue; for (o = 0; o < config->num_output; o++) { @@ -2726,7 +2758,7 @@ xf86PrepareCrtcs(ScrnInfoPtr scrn) if (desired_outputs != current_outputs || !desired_outputs) xf86DisableCrtc(crtc); #else - if (RRCrtcIsLeased(crtc->randr_crtc)) + if (xf86CrtcIsLeased(crtc)) continue; xf86DisableCrtc(crtc); @@ -2964,7 +2996,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; - if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) + if (!xf86OutputIsLeased(output) && output->crtc != NULL) (*output->funcs->dpms) (output, mode); } } @@ -2980,7 +3012,7 @@ xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; - if (!RROutputIsLeased(output->randr_output) && output->crtc != NULL) + if (!xf86OutputIsLeased(output) && output->crtc != NULL) (*output->funcs->dpms) (output, mode); } } diff --git a/hw/xfree86/os-support/bsd/Makefile.am b/hw/xfree86/os-support/bsd/Makefile.am index b01ea5bca..66ac83805 100644 --- a/hw/xfree86/os-support/bsd/Makefile.am +++ b/hw/xfree86/os-support/bsd/Makefile.am @@ -26,8 +26,7 @@ endif if ALPHA_VIDEO # Cheat here and piggyback other alpha bits on ALPHA_VIDEO. ARCH_SOURCES = \ - alpha_video.c \ - bsd_ev56.c + alpha_video.c endif if ARM_VIDEO diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am index 26e40bb93..9b4535b53 100644 --- a/hw/xfree86/os-support/linux/Makefile.am +++ b/hw/xfree86/os-support/linux/Makefile.am @@ -1,13 +1,5 @@ noinst_LTLIBRARIES = liblinux.la -if LINUX_ALPHA -noinst_LTLIBRARIES += liblinuxev56.la - -liblinuxev56_la_CFLAGS = $(AM_CFLAGS) -mcpu=ev56 - -liblinuxev56_la_SOURCES = lnx_ev56.c -endif - if LNXACPI ACPI_SRCS = lnx_acpi.c if !LNXAPM @@ -39,7 +31,3 @@ liblinux_la_SOURCES = linux.h lnx_init.c lnx_video.c \ AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES) AM_CPPFLAGS = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS) - -if LINUX_ALPHA -liblinux_la_LIBADD = liblinuxev56.la -endif diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c index a00002464..039dc4a4d 100644 --- a/hw/xfree86/os-support/linux/lnx_init.c +++ b/hw/xfree86/os-support/linux/lnx_init.c @@ -346,6 +346,13 @@ xf86CloseConsole(void) close(xf86Info.consoleFd); /* make the vt-manager happy */ } +#define CHECK_FOR_REQUIRED_ARGUMENT() \ + if (((i + 1) >= argc) || (!argv[i + 1])) { \ + ErrorF("Required argument to %s not specified\n", argv[i]); \ + UseMsg(); \ + FatalError("Required argument to %s not specified\n", argv[i]); \ + } + int xf86ProcessArgument(int argc, char *argv[], int i) { @@ -366,6 +373,19 @@ xf86ProcessArgument(int argc, char *argv[], int i) } return 1; } + + if (!strcmp(argv[i], "-masterfd")) { + CHECK_FOR_REQUIRED_ARGUMENT(); + if (xf86PrivsElevated()) + FatalError("\nCannot specify -masterfd when server is setuid/setgid\n"); + if (sscanf(argv[++i], "%d", &xf86DRMMasterFd) != 1) { + UseMsg(); + xf86DRMMasterFd = -1; + return 0; + } + return 2; + } + return 0; } @@ -375,4 +395,5 @@ xf86UseMsg(void) ErrorF("vtXX use the specified VT number\n"); ErrorF("-keeptty "); ErrorF("don't detach controlling tty (for debugging only)\n"); + ErrorF("-masterfd <fd> use the specified fd as the DRM master fd (not if setuid/gid)\n"); } diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c index 11af52c46..70374ace8 100644 --- a/hw/xfree86/os-support/linux/lnx_platform.c +++ b/hw/xfree86/os-support/linux/lnx_platform.c @@ -43,7 +43,7 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) } if (fd == -1) - fd = open(path, O_RDWR, O_CLOEXEC); + fd = open(path, O_RDWR | O_CLOEXEC, 0); if (fd == -1) return FALSE; diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c index c09d71947..04e45092a 100644 --- a/hw/xfree86/os-support/linux/lnx_video.c +++ b/hw/xfree86/os-support/linux/lnx_video.c @@ -166,30 +166,3 @@ xf86DisableIO(void) ExtendedEnabled = FALSE; } - -#if defined (__alpha__) - -extern int readDense8(void *Base, register unsigned long Offset); -extern int readDense16(void *Base, register unsigned long Offset); -extern int readDense32(void *Base, register unsigned long Offset); -extern void - writeDense8(int Value, void *Base, register unsigned long Offset); -extern void - writeDense16(int Value, void *Base, register unsigned long Offset); -extern void - writeDense32(int Value, void *Base, register unsigned long Offset); - -void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset) - = writeDense8; -void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset) - = writeDense16; -void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset) - = writeDense32; -int (*xf86ReadMmio8) (void *Base, unsigned long Offset) - = readDense8; -int (*xf86ReadMmio16) (void *Base, unsigned long Offset) - = readDense16; -int (*xf86ReadMmio32) (void *Base, unsigned long Offset) - = readDense32; - -#endif /* __alpha__ */ diff --git a/hw/xfree86/os-support/meson.build b/hw/xfree86/os-support/meson.build index 901422786..b6e5c975d 100644 --- a/hw/xfree86/os-support/meson.build +++ b/hw/xfree86/os-support/meson.build @@ -100,7 +100,6 @@ elif host_machine.system().endswith('bsd') srcs_xorg_os_support += 'shared/ioperm_noop.c' elif host_machine.cpu_family() == 'alpha' srcs_xorg_os_support += 'bsd/alpha_video.c' - srcs_xorg_os_support += 'bsd/bsd_ev56.c' endif if host_machine.system() == 'freebsd' diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c index 8dd1cc304..9950be94d 100644 --- a/hw/xwayland/xwayland-glamor-eglstream.c +++ b/hw/xwayland/xwayland-glamor-eglstream.c @@ -187,6 +187,85 @@ xwl_eglstream_cleanup(struct xwl_screen *xwl_screen) free(xwl_eglstream); } +static Bool +xwl_glamor_egl_supports_device_probing(void) +{ + return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base"); +} + +static void ** +xwl_glamor_egl_get_devices(int *num_devices) +{ + EGLDeviceEXT *devices; + Bool ret; + int drm_dev_count = 0; + int i; + + if (!xwl_glamor_egl_supports_device_probing()) + return NULL; + + /* Get the number of devices */ + ret = eglQueryDevicesEXT(0, NULL, num_devices); + if (!ret || *num_devices < 1) + return NULL; + + devices = calloc(*num_devices, sizeof(EGLDeviceEXT)); + if (!devices) + return NULL; + + ret = eglQueryDevicesEXT(*num_devices, devices, num_devices); + if (!ret) + goto error; + + /* We're only ever going to care about devices that support + * EGL_EXT_device_drm, so filter out the ones that don't + */ + for (i = 0; i < *num_devices; i++) { + const char *extension_str = + eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS); + + if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm")) + continue; + + devices[drm_dev_count++] = devices[i]; + } + if (!drm_dev_count) + goto error; + + *num_devices = drm_dev_count; + devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count); + + return devices; + +error: + free(devices); + + return NULL; +} + +static Bool +xwl_glamor_egl_device_has_egl_extensions(void *device, + const char **ext_list, size_t size) +{ + EGLDisplay egl_display; + int i; + Bool has_exts = TRUE; + + egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device); + if (!egl_display || !eglInitialize(egl_display, NULL, NULL)) + return FALSE; + + for (i = 0; i < size; i++) { + if (!epoxy_has_egl_extension(egl_display, ext_list[i])) { + has_exts = FALSE; + break; + } + } + + eglTerminate(egl_display); + return has_exts; +} + static void xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap) { @@ -229,8 +308,6 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap) static struct wl_buffer * xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created) { /* XXX created? */ @@ -559,11 +636,11 @@ const struct wl_eglstream_display_listener eglstream_display_listener = { .swapinterval_override = xwl_eglstream_display_handle_swapinterval_override, }; -static void +static Bool xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, struct wl_registry *wl_registry, - const char *name, - uint32_t id, uint32_t version) + uint32_t id, const char *name, + uint32_t version) { struct xwl_eglstream_private *xwl_eglstream = xwl_eglstream_get(xwl_screen); @@ -575,10 +652,34 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen, wl_eglstream_display_add_listener(xwl_eglstream->display, &eglstream_display_listener, xwl_screen); + return TRUE; } else if (strcmp(name, "wl_eglstream_controller") == 0) { xwl_eglstream->controller = wl_registry_bind( wl_registry, id, &wl_eglstream_controller_interface, version); + return TRUE; + } + + /* no match */ + return FALSE; +} + +static Bool +xwl_glamor_eglstream_has_wl_interfaces(struct xwl_screen *xwl_screen) +{ + struct xwl_eglstream_private *xwl_eglstream = + xwl_eglstream_get(xwl_screen); + + if (xwl_eglstream->display == NULL) { + ErrorF("glamor: 'wl_eglstream_display' not supported\n"); + return FALSE; + } + + if (xwl_eglstream->controller == NULL) { + ErrorF("glamor: 'wl_eglstream_controller' not supported\n"); + return FALSE; } + + return TRUE; } static inline void @@ -691,6 +792,12 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen) goto error; } + if (!epoxy_has_egl_extension(xwl_screen->egl_display, + "EGL_IMG_context_priority")) { + ErrorF("EGL_IMG_context_priority not available\n"); + goto error; + } + eglChooseConfig(xwl_screen->egl_display, config_attribs, &config, 1, &n); if (!n) { ErrorF("No acceptable EGL configs found\n"); @@ -740,14 +847,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen) xwl_eglstream_get(xwl_screen); ScreenPtr screen = xwl_screen->screen; - if (!xwl_eglstream->controller) { - ErrorF("No eglstream controller was exposed in the wayland registry. " - "This means your version of nvidia's EGL wayland libraries " - "are too old, as we require support for this.\n"); - xwl_eglstream_cleanup(xwl_screen); - return FALSE; - } - /* We can just let glamor handle CreatePixmap */ screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap; @@ -792,23 +891,24 @@ out: return device; } -Bool +void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) { struct xwl_eglstream_private *xwl_eglstream; EGLDeviceEXT egl_device; + xwl_screen->eglstream_backend.is_available = FALSE; egl_device = xwl_eglstream_get_device(xwl_screen); if (egl_device == EGL_NO_DEVICE_EXT) - return FALSE; + return; if (!dixRegisterPrivateKey(&xwl_eglstream_private_key, PRIVATE_SCREEN, 0)) - return FALSE; + return; xwl_eglstream = calloc(sizeof(*xwl_eglstream), 1); if (!xwl_eglstream) { - ErrorF("Failed to allocate memory required to init eglstream support\n"); - return FALSE; + ErrorF("Failed to allocate memory required to init EGLStream support\n"); + return; } dixSetPrivate(&xwl_screen->screen->devPrivates, @@ -817,14 +917,12 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) xwl_eglstream->egl_device = egl_device; xorg_list_init(&xwl_eglstream->pending_streams); - xwl_screen->egl_backend.init_egl = xwl_glamor_eglstream_init_egl; - xwl_screen->egl_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry; - xwl_screen->egl_backend.init_screen = xwl_glamor_eglstream_init_screen; - xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap; - xwl_screen->egl_backend.post_damage = xwl_glamor_eglstream_post_damage; - xwl_screen->egl_backend.allow_commits = xwl_glamor_eglstream_allow_commits; - - ErrorF("glamor: Using nvidia's eglstream interface, direct rendering impossible.\n"); - ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n"); - return TRUE; + xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl; + xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry; + xwl_screen->eglstream_backend.has_wl_interfaces = xwl_glamor_eglstream_has_wl_interfaces; + xwl_screen->eglstream_backend.init_screen = xwl_glamor_eglstream_init_screen; + xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap; + xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage; + xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits; + xwl_screen->eglstream_backend.is_available = TRUE; } diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index 29325adac..06fcf5239 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -230,13 +230,13 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap) static struct wl_buffer * xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created) { struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); + unsigned short width = pixmap->drawable.width; + unsigned short height = pixmap->drawable.height; int prime_fd; int num_planes; uint32_t strides[4]; @@ -272,7 +272,7 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap, #else num_planes = 1; modifier = DRM_FORMAT_MOD_INVALID; - strides[0] = gbm_go_get_stride(xwl_pixmap->bo); + strides[0] = gbm_bo_get_stride(xwl_pixmap->bo); offsets[0] = 0; #endif @@ -517,6 +517,16 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, #endif } +/* Not actually used, just defined here so there's something for + * _glamor_egl_fds_from_pixmap() to link against + */ +_X_EXPORT int +glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ + return -1; +} + _X_EXPORT Bool glamor_get_formats(ScreenPtr screen, CARD32 *num_formats, CARD32 **formats) @@ -734,16 +744,42 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, return TRUE; } -static void +static Bool xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen, struct wl_registry *wl_registry, - const char *name, - uint32_t id, uint32_t version) + uint32_t id, const char *name, + uint32_t version) { - if (strcmp(name, "wl_drm") == 0) + if (strcmp(name, "wl_drm") == 0) { xwl_screen_set_drm_interface(xwl_screen, id, version); - else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) + return TRUE; + } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) { xwl_screen_set_dmabuf_interface(xwl_screen, id, version); + return TRUE; + } + + /* no match */ + return FALSE; +} + +static Bool +xwl_glamor_gbm_has_egl_extension(void) +{ + return (epoxy_has_egl_extension(NULL, "EGL_MESA_platform_gbm") || + epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm")); +} + +static Bool +xwl_glamor_gbm_has_wl_interfaces(struct xwl_screen *xwl_screen) +{ + struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); + + if (xwl_gbm->drm == NULL) { + ErrorF("glamor: 'wl_drm' not supported\n"); + return FALSE; + } + + return TRUE; } static Bool @@ -807,8 +843,10 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen) goto error; } - if (!epoxy_has_gl_extension("GL_OES_EGL_image")) + if (!epoxy_has_gl_extension("GL_OES_EGL_image")) { ErrorF("GL_OES_EGL_image not available\n"); + goto error; + } if (epoxy_has_egl_extension(xwl_screen->egl_display, "EXT_image_dma_buf_import") && @@ -835,11 +873,16 @@ error: static Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen) { + struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); + if (!dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) { ErrorF("Failed to initialize dri3\n"); goto error; } + if (xwl_gbm->fd_render_node) + goto skip_drm_auth; + if (!dixRegisterPrivateKey(&xwl_auth_state_private_key, PRIVATE_CLIENT, 0)) { ErrorF("Failed to register private key\n"); @@ -852,6 +895,7 @@ xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen) goto error; } +skip_drm_auth: xwl_screen->screen->CreatePixmap = xwl_glamor_gbm_create_pixmap; xwl_screen->screen->DestroyPixmap = xwl_glamor_gbm_destroy_pixmap; @@ -861,27 +905,32 @@ error: return FALSE; } -Bool +void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) { struct xwl_gbm_private *xwl_gbm; + xwl_screen->gbm_backend.is_available = FALSE; + + if (!xwl_glamor_gbm_has_egl_extension()) + return; + if (!dixRegisterPrivateKey(&xwl_gbm_private_key, PRIVATE_SCREEN, 0)) - return FALSE; + return; xwl_gbm = calloc(sizeof(*xwl_gbm), 1); if (!xwl_gbm) { ErrorF("glamor: Not enough memory to setup GBM, disabling\n"); - return FALSE; + return; } dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key, xwl_gbm); - xwl_screen->egl_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry; - xwl_screen->egl_backend.init_egl = xwl_glamor_gbm_init_egl; - xwl_screen->egl_backend.init_screen = xwl_glamor_gbm_init_screen; - xwl_screen->egl_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap; - - return TRUE; + xwl_screen->gbm_backend.init_wl_registry = xwl_glamor_gbm_init_wl_registry; + xwl_screen->gbm_backend.has_wl_interfaces = xwl_glamor_gbm_has_wl_interfaces; + xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl; + xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen; + xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap; + xwl_screen->gbm_backend.is_available = TRUE; } diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index cdca072ed..7ea6def61 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -52,88 +52,12 @@ xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen) xwl_screen->glamor_ctx->make_current(xwl_screen->glamor_ctx); } -Bool -xwl_glamor_egl_supports_device_probing(void) -{ - return epoxy_has_egl_extension(NULL, "EGL_EXT_device_base"); -} - -void ** -xwl_glamor_egl_get_devices(int *num_devices) -{ -#ifdef XWL_HAS_EGLSTREAM - EGLDeviceEXT *devices; - Bool ret; - int drm_dev_count = 0; - int i; - - /* Get the number of devices */ - ret = eglQueryDevicesEXT(0, NULL, num_devices); - if (!ret || *num_devices < 1) - return NULL; - - devices = calloc(*num_devices, sizeof(EGLDeviceEXT)); - if (!devices) - return NULL; - - ret = eglQueryDevicesEXT(*num_devices, devices, num_devices); - if (!ret) - goto error; - - /* We're only ever going to care about devices that support - * EGL_EXT_device_drm, so filter out the ones that don't - */ - for (i = 0; i < *num_devices; i++) { - const char *extension_str = - eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS); - - if (!epoxy_extension_in_string(extension_str, "EGL_EXT_device_drm")) - continue; - - devices[drm_dev_count++] = devices[i]; - } - if (!drm_dev_count) - goto error; - - *num_devices = drm_dev_count; - devices = realloc(devices, sizeof(EGLDeviceEXT) * drm_dev_count); - - return devices; - -error: - free(devices); -#endif - return NULL; -} - -Bool -xwl_glamor_egl_device_has_egl_extensions(void *device, - const char **ext_list, size_t size) -{ - EGLDisplay egl_display; - int i; - Bool has_exts = TRUE; - - egl_display = glamor_egl_get_display(EGL_PLATFORM_DEVICE_EXT, device); - if (!egl_display || !eglInitialize(egl_display, NULL, NULL)) - return FALSE; - - for (i = 0; i < size; i++) { - if (!epoxy_has_egl_extension(egl_display, ext_list[i])) { - has_exts = FALSE; - break; - } - } - - eglTerminate(egl_display); - return has_exts; -} - void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) { struct xwl_screen *xwl_screen = xwl_screen_get(screen); + glamor_enable_dri3(screen); glamor_ctx->ctx = xwl_screen->egl_context; glamor_ctx->display = xwl_screen->egl_display; @@ -148,24 +72,36 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen, uint32_t id, const char *interface, uint32_t version) { - if (xwl_screen->egl_backend.init_wl_registry) - xwl_screen->egl_backend.init_wl_registry(xwl_screen, registry, - interface, id, version); + if (xwl_screen->gbm_backend.is_available && + xwl_screen->gbm_backend.init_wl_registry(xwl_screen, + registry, + id, + interface, + version)); /* no-op */ + else if (xwl_screen->eglstream_backend.is_available && + xwl_screen->eglstream_backend.init_wl_registry(xwl_screen, + registry, + id, + interface, + version)); /* no-op */ +} + +Bool +xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen, + struct xwl_egl_backend *xwl_egl_backend) +{ + return xwl_egl_backend->has_wl_interfaces(xwl_screen); } struct wl_buffer * xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created) { struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); - if (xwl_screen->egl_backend.get_wl_buffer_for_pixmap) - return xwl_screen->egl_backend.get_wl_buffer_for_pixmap(pixmap, - width, - height, - created); + if (xwl_screen->egl_backend->get_wl_buffer_for_pixmap) + return xwl_screen->egl_backend->get_wl_buffer_for_pixmap(pixmap, + created); return NULL; } @@ -176,8 +112,8 @@ xwl_glamor_post_damage(struct xwl_window *xwl_window, { struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - if (xwl_screen->egl_backend.post_damage) - xwl_screen->egl_backend.post_damage(xwl_window, pixmap, region); + if (xwl_screen->egl_backend->post_damage) + xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region); } Bool @@ -185,8 +121,8 @@ xwl_glamor_allow_commits(struct xwl_window *xwl_window) { struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - if (xwl_screen->egl_backend.allow_commits) - return xwl_screen->egl_backend.allow_commits(xwl_window); + if (xwl_screen->egl_backend->allow_commits) + return xwl_screen->egl_backend->allow_commits(xwl_window); else return TRUE; } @@ -228,6 +164,68 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen, return 0; } +void +xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream) +{ +#ifdef GLAMOR_HAS_GBM + xwl_glamor_init_gbm(xwl_screen); + if (!xwl_screen->gbm_backend.is_available && !use_eglstream) + ErrorF("xwayland glamor: GBM backend (default) is not available\n"); +#endif +#ifdef XWL_HAS_EGLSTREAM + xwl_glamor_init_eglstream(xwl_screen); + if (!xwl_screen->eglstream_backend.is_available && use_eglstream) + ErrorF("xwayland glamor: EGLStream backend requested but not available\n"); +#endif +} + +static Bool +xwl_glamor_select_gbm_backend(struct xwl_screen *xwl_screen) +{ +#ifdef GLAMOR_HAS_GBM + if (xwl_screen->gbm_backend.is_available && + xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->gbm_backend)) { + xwl_screen->egl_backend = &xwl_screen->gbm_backend; + return TRUE; + } + else + ErrorF("Missing Wayland requirements for glamor GBM backend\n"); +#endif + + return FALSE; +} + +static Bool +xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen) +{ +#ifdef XWL_HAS_EGLSTREAM + if (xwl_screen->eglstream_backend.is_available && + xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) { + ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n"); + ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n"); + xwl_screen->egl_backend = &xwl_screen->eglstream_backend; + return TRUE; + } + else + ErrorF("Missing Wayland requirements for glamor EGLStream backend\n"); +#endif + + return FALSE; +} + +void +xwl_glamor_select_backend(struct xwl_screen *xwl_screen, Bool use_eglstream) +{ + if (use_eglstream) { + if (!xwl_glamor_select_eglstream_backend(xwl_screen)) + xwl_glamor_select_gbm_backend(xwl_screen); + } + else { + if (!xwl_glamor_select_gbm_backend(xwl_screen)) + xwl_glamor_select_eglstream_backend(xwl_screen); + } +} + Bool xwl_glamor_init(struct xwl_screen *xwl_screen) { @@ -240,7 +238,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) return FALSE; } - if (!xwl_screen->egl_backend.init_egl(xwl_screen)) { + if (!xwl_screen->egl_backend->init_egl(xwl_screen)) { ErrorF("EGL setup failed, disabling glamor\n"); return FALSE; } @@ -250,7 +248,7 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) return FALSE; } - if (!xwl_screen->egl_backend.init_screen(xwl_screen)) { + if (!xwl_screen->egl_backend->init_screen(xwl_screen)) { ErrorF("EGL backend init_screen() failed, disabling glamor\n"); return FALSE; } diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 48faeb142..0d2ec7890 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -38,6 +38,8 @@ RR_Reflect_X | \ RR_Reflect_Y) +static void xwl_output_get_xdg_output(struct xwl_output *xwl_output); + static Rotation wl_transform_to_xrandr(enum wl_output_transform transform) { @@ -211,6 +213,7 @@ apply_output_change(struct xwl_output *xwl_output) { struct xwl_screen *xwl_screen = xwl_output->xwl_screen; struct xwl_output *it; + int mode_width, mode_height; int width = 0, height = 0, has_this_output = 0; RRModePtr randr_mode; Bool need_rotate; @@ -222,7 +225,16 @@ apply_output_change(struct xwl_output *xwl_output) /* xdg-output sends output size in compositor space. so already rotated */ need_rotate = (xwl_output->xdg_output == NULL); - randr_mode = xwayland_cvt(xwl_output->width, xwl_output->height, + /* We need to rotate back the logical size for the mode */ + if (need_rotate || xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) { + mode_width = xwl_output->width; + mode_height = xwl_output->height; + } else { + mode_width = xwl_output->height; + mode_height = xwl_output->width; + } + + randr_mode = xwayland_cvt(mode_width, mode_height, xwl_output->refresh / 1000.0, 0, 0); RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); RRCrtcNotify(xwl_output->randr_crtc, randr_mode, @@ -435,7 +447,7 @@ xwl_screen_init_output(struct xwl_screen *xwl_screen) return TRUE; } -void +static void xwl_output_get_xdg_output(struct xwl_output *xwl_output) { struct xwl_screen *xwl_screen = xwl_output->xwl_screen; diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index b5ae80dcf..81e0eb9ce 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -440,7 +440,7 @@ xwl_present_flip(WindowPtr present_window, { struct xwl_window *xwl_window = xwl_window_from_window(present_window); struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window); - BoxPtr present_box, damage_box; + BoxPtr damage_box; Bool buffer_created; struct wl_buffer *buffer; struct xwl_present_event *event; @@ -448,7 +448,6 @@ xwl_present_flip(WindowPtr present_window, if (!xwl_window) return FALSE; - present_box = RegionExtents(&present_window->winSize); damage_box = RegionExtents(damage); event = malloc(sizeof *event); @@ -457,10 +456,7 @@ xwl_present_flip(WindowPtr present_window, xwl_window->present_window = present_window; - buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, - present_box->x2 - present_box->x1, - present_box->y2 - present_box->y1, - &buffer_created); + buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, &buffer_created); event->event_id = event_id; event->xwl_present_window = xwl_present_window; @@ -547,10 +543,9 @@ xwl_present_init(ScreenPtr screen) struct xwl_screen *xwl_screen = xwl_screen_get(screen); /* - * doesn't work with the streams backend. we don't have an explicit - * boolean for that, but we do know gbm doesn't fill in this hook... + * doesn't work with the EGLStream backend. */ - if (xwl_screen->egl_backend.post_damage != NULL) + if (xwl_screen->egl_backend == &xwl_screen->eglstream_backend) return FALSE; if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0)) diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 1d6b49979..96b4db18c 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -96,9 +96,7 @@ ddxUseMsg(void) ErrorF("-rootless run rootless, requires wm support\n"); ErrorF("-wm fd create X client for wm on given fd\n"); ErrorF("-listen fd add give fd as a listen socket\n"); -#ifdef XWL_HAS_EGLSTREAM ErrorF("-eglstream use eglstream backend for nvidia GPUs\n"); -#endif } int @@ -117,11 +115,9 @@ ddxProcessArgument(int argc, char *argv[], int i) else if (strcmp(argv[i], "-shm") == 0) { return 1; } -#ifdef XWL_HAS_EGLSTREAM else if (strcmp(argv[i], "-eglstream") == 0) { return 1; } -#endif return 0; } @@ -682,8 +678,6 @@ xwl_window_post_damage(struct xwl_window *xwl_window) #ifdef XWL_HAS_GLAMOR if (xwl_screen->glamor) buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, - pixmap->drawable.width, - pixmap->drawable.height, NULL); else #endif @@ -741,7 +735,7 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) continue; #ifdef XWL_HAS_GLAMOR - if (!xwl_glamor_allow_commits(xwl_window)) + if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window)) continue; #endif @@ -943,9 +937,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) struct xwl_screen *xwl_screen; Pixel red_mask, blue_mask, green_mask; int ret, bpc, green_bpc, i; -#ifdef XWL_HAS_EGLSTREAM Bool use_eglstreams = FALSE; -#endif xwl_screen = calloc(1, sizeof *xwl_screen); if (xwl_screen == NULL) @@ -988,28 +980,18 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) else if (strcmp(argv[i], "-shm") == 0) { xwl_screen->glamor = 0; } -#ifdef XWL_HAS_EGLSTREAM else if (strcmp(argv[i], "-eglstream") == 0) { +#ifdef XWL_HAS_EGLSTREAM use_eglstreams = TRUE; - } +#else + ErrorF("xwayland glamor: this build does not have EGLStream support\n"); #endif + } } #ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor) { -#ifdef XWL_HAS_EGLSTREAM - if (use_eglstreams) { - if (!xwl_glamor_init_eglstream(xwl_screen)) { - ErrorF("xwayland glamor: failed to setup eglstream backend, falling back to swaccel\n"); - xwl_screen->glamor = 0; - } - } else -#endif - if (!xwl_glamor_init_gbm(xwl_screen)) { - ErrorF("xwayland glamor: failed to setup GBM backend, falling back to sw accel\n"); - xwl_screen->glamor = 0; - } - } + if (xwl_screen->glamor) + xwl_glamor_init_backends(xwl_screen, use_eglstreams); #endif /* In rootless mode, we don't have any screen storage, and the only @@ -1095,9 +1077,13 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) return FALSE; #ifdef XWL_HAS_GLAMOR - if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) { - ErrorF("Failed to initialize glamor, falling back to sw\n"); - xwl_screen->glamor = 0; + if (xwl_screen->glamor) { + xwl_glamor_select_backend(xwl_screen, use_eglstreams); + + if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) { + ErrorF("Failed to initialize glamor, falling back to sw\n"); + xwl_screen->glamor = 0; + } } if (xwl_screen->glamor && xwl_screen->rootless) @@ -1134,6 +1120,10 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen); + wl_display_roundtrip(xwl_screen->display); + while (xwl_screen->expecting_event) + wl_display_roundtrip(xwl_screen->display); + return ret; } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 25112e2cb..d70ad54bf 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -57,6 +57,60 @@ struct xwl_format { struct xwl_pixmap; struct xwl_window; +struct xwl_screen; + +struct xwl_egl_backend { + /* Set by the backend if available */ + Bool is_available; + + /* Called once for each interface in the global registry. Backends + * should use this to bind to any wayland interfaces they need. + */ + Bool (*init_wl_registry)(struct xwl_screen *xwl_screen, + struct wl_registry *wl_registry, + uint32_t id, const char *name, + uint32_t version); + + /* Check that the required Wayland interfaces are available. + */ + Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen); + + /* Called before glamor has been initialized. Backends should setup a + * valid, glamor compatible EGL context in this hook. + */ + Bool (*init_egl)(struct xwl_screen *xwl_screen); + + /* Called after glamor has been initialized, and after all of the + * common Xwayland DDX hooks have been connected. Backends should use + * this to setup any required wraps around X server callbacks like + * CreatePixmap. + */ + Bool (*init_screen)(struct xwl_screen *xwl_screen); + + /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for + * the given window/pixmap combo so that damage to the pixmap may be + * displayed on-screen. Backends should use this to create a new + * wl_buffer for a currently buffer-less pixmap, or simply return the + * pixmap they've prepared beforehand. + */ + struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap, + Bool *created); + + /* Called by Xwayland to perform any pre-wl_surface damage routines + * that are required by the backend. If your backend is poorly + * designed and lacks the ability to render directly to a surface, + * you should implement blitting from the glamor pixmap to the wayland + * pixmap here. Otherwise, this callback is optional. + */ + void (*post_damage)(struct xwl_window *xwl_window, + PixmapPtr pixmap, RegionPtr region); + + /* Called by Xwayland to confirm with the egl backend that the given + * pixmap is completely setup and ready for display on-screen. This + * callback is optional. + */ + Bool (*allow_commits)(struct xwl_window *xwl_window); +}; struct xwl_screen { int width; @@ -109,55 +163,10 @@ struct xwl_screen { struct xwl_format *formats; void *egl_display, *egl_context; - /* the current backend for creating pixmaps on wayland */ - struct { - /* Called once for each interface in the global registry. Backends - * should use this to bind to any wayland interfaces they need. This - * callback is optional. - */ - void (*init_wl_registry)(struct xwl_screen *xwl_screen, - struct wl_registry *wl_registry, - const char *name, uint32_t id, - uint32_t version); - - /* Called before glamor has been initialized. Backends should setup a - * valid, glamor compatible EGL context in this hook. - */ - Bool (*init_egl)(struct xwl_screen *xwl_screen); - - /* Called after glamor has been initialized, and after all of the - * common Xwayland DDX hooks have been connected. Backends should use - * this to setup any required wraps around X server callbacks like - * CreatePixmap. - */ - Bool (*init_screen)(struct xwl_screen *xwl_screen); - - /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for - * the given window/pixmap combo so that damage to the pixmap may be - * displayed on-screen. Backends should use this to create a new - * wl_buffer for a currently buffer-less pixmap, or simply return the - * pixmap they've prepared beforehand. - */ - struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap, - unsigned short width, - unsigned short height, - Bool *created); - - /* Called by Xwayland to perform any pre-wl_surface damage routines - * that are required by the backend. If your backend is poorly - * designed and lacks the ability to render directly to a surface, - * you should implement blitting from the glamor pixmap to the wayland - * pixmap here. Otherwise, this callback is optional. - */ - void (*post_damage)(struct xwl_window *xwl_window, - PixmapPtr pixmap, RegionPtr region); - - /* Called by Xwayland to confirm with the egl backend that the given - * pixmap is completely setup and ready for display on-screen. This - * callback is optional. - */ - Bool (*allow_commits)(struct xwl_window *xwl_window); - } egl_backend; + struct xwl_egl_backend gbm_backend; + struct xwl_egl_backend eglstream_backend; + /* pointer to the current backend for creating pixmaps on wayland */ + struct xwl_egl_backend *egl_backend; struct glamor_context *glamor_ctx; @@ -414,7 +423,11 @@ PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height, Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap); struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap); - +#ifdef XWL_HAS_GLAMOR +void xwl_glamor_init_backends(struct xwl_screen *xwl_screen, + Bool use_eglstream); +void xwl_glamor_select_backend(struct xwl_screen *xwl_screen, + Bool use_eglstream); Bool xwl_glamor_init(struct xwl_screen *xwl_screen); Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, @@ -422,58 +435,51 @@ Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version); struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap, - unsigned short width, - unsigned short height, Bool *created); void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); +Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen, + struct xwl_egl_backend *xwl_egl_backend); void xwl_glamor_post_damage(struct xwl_window *xwl_window, PixmapPtr pixmap, RegionPtr region); Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window); +void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen); #ifdef GLAMOR_HAS_GBM Bool xwl_present_init(ScreenPtr screen); void xwl_present_cleanup(WindowPtr window); -#endif - -void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); - -void xwl_output_get_xdg_output(struct xwl_output *xwl_output); -void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); - -void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen); -Bool xwl_glamor_egl_supports_device_probing(void); -void **xwl_glamor_egl_get_devices(int *num_devices); -Bool xwl_glamor_egl_device_has_egl_extensions(void *device, - const char **ext_list, - size_t size); +#endif /* GLAMOR_HAS_GBM */ #ifdef XV /* glamor Xv Adaptor */ Bool xwl_glamor_xv_init(ScreenPtr pScreen); -#endif +#endif /* XV */ + +#endif /* XWL_HAS_GLAMOR */ + +void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen); + +void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen); #ifdef XF86VIDMODE void xwlVidModeExtensionInit(void); #endif #ifdef GLAMOR_HAS_GBM -Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); +void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); #else -static inline Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) +static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen) { - return FALSE; } #endif #ifdef XWL_HAS_EGLSTREAM -Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); +void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen); #else -static inline Bool xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) +static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen) { - return FALSE; } #endif diff --git a/include/meson.build b/include/meson.build index f76f557be..dfca3c340 100644 --- a/include/meson.build +++ b/include/meson.build @@ -153,10 +153,10 @@ conf_data.set('BUSFAULT', conf_data.get('HAVE_SIGACTION')) conf_data.set('_XTYPEDEF_POINTER', '1') conf_data.set('_XITYPEDEF_POINTER', '1') +conf_data.set('LISTEN_TCP', get_option('listen_tcp')) +conf_data.set('LISTEN_UNIX', get_option('listen_unix')) +conf_data.set('LISTEN_LOCAL', get_option('listen_local')) # XXX: Configurable? -conf_data.set('LISTEN_TCP', '1') -conf_data.set('LISTEN_UNIX', '1') -conf_data.set('LISTEN_LOCAL', '1') conf_data.set('XTRANS_SEND_FDS', '1') conf_data.set('TCPCONN', '1') diff --git a/meson.build b/meson.build index ff661f9d1..535634e7b 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project('xserver', 'c', 'buildtype=debugoptimized', 'c_std=gnu99', ], - version: '1.20.0', + version: '1.20.1', meson_version: '>= 0.42.0', ) add_project_arguments('-DHAVE_DIX_CONFIG_H', language: 'c') @@ -518,9 +518,9 @@ manpage_config.set('libmansuffix', '3') manpage_config.set('miscmansuffix', '7') manpage_config.set('filemansuffix', '5') manpage_config.set('logdir', log_dir) -manpage_config.set('datadir', get_option('datadir')) -manpage_config.set('mandir', get_option('mandir')) -manpage_config.set('sysconfdir', get_option('sysconfdir')) +manpage_config.set('datadir', join_paths(get_option('prefix'), get_option('datadir'))) +manpage_config.set('mandir', join_paths(get_option('prefix'), get_option('mandir'))) +manpage_config.set('sysconfdir', join_paths(get_option('prefix'), get_option('sysconfdir'))) manpage_config.set('xconfigdir', 'xorg.conf.d') manpage_config.set('xkbdir', xkb_dir) manpage_config.set('XKB_DFLT_RULES', get_option('xkb_default_rules')) diff --git a/meson_options.txt b/meson_options.txt index 86fca4668..3453b8df5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -45,6 +45,13 @@ option('vendor_name_short', type: 'string', value: 'X.Org') option('vendor_web', type: 'string', value: 'http://wiki.x.org') option('os_vendor', type: 'string', value: '') +option('listen_tcp', type: 'boolean', value: false, + description: 'Listen on TCP by default') +option('listen_unix', type: 'boolean', value: true, + description: 'Listen on Unix by default') +option('listen_local', type: 'boolean', value: true, + description: 'Listen on local by default') + option('int10', type: 'combo', choices: ['stub', 'x86emu', 'vm86', 'auto', 'false'], value: 'auto', description: 'Xorg int10 backend (default: usually x86emu)') diff --git a/os/WaitFor.c b/os/WaitFor.c index 7c7b1d2d4..dc33c1648 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -190,10 +190,11 @@ WaitForSomething(Bool are_ready) /* deal with any blocked jobs */ if (workQueue) { ProcessWorkQueue(); - are_ready = clients_are_ready(); } timeout = check_timers(); + are_ready = clients_are_ready(); + if (are_ready) timeout = 0; diff --git a/os/meson.build b/os/meson.build index f9b19d7a0..4c49d0964 100644 --- a/os/meson.build +++ b/os/meson.build @@ -56,9 +56,13 @@ endif rpc_dep = [] if get_option('secure-rpc') - # prefer libtirpc (if available), otherwise assume RPC functions are + # prefer libtirpc (if available), otherwise ensure RPC functions are # provided by libc. rpc_dep = dependency('libtirpc', required: false) + if not (rpc_dep.found() or cc.has_header('rpc/rpc.h')) + error('secure-rpc requested, but neither libtirpc or libc RPC support were found') + endif + srcs_os += 'rpcauth.c' endif diff --git a/present/present_wnmd.c b/present/present_wnmd.c index 80ffb014e..035ae8ffe 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -469,6 +469,10 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) PixmapPtr old_pixmap = screen->GetWindowPixmap(window); /* Replace window pixmap with flip pixmap */ +#ifdef COMPOSITE + vblank->pixmap->screen_x = old_pixmap->screen_x; + vblank->pixmap->screen_y = old_pixmap->screen_y; +#endif present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap); vblank->pixmap->refcnt++; dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id); diff --git a/randr/randr.c b/randr/randr.c index feb54bcc8..5db8b5ced 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -89,8 +89,12 @@ RRCloseScreen(ScreenPtr pScreen) { rrScrPriv(pScreen); int j; + RRLeasePtr lease, next; unwrap(pScrPriv, pScreen, CloseScreen); + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) + RRTerminateLease(lease); for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) RRCrtcDestroy(pScrPriv->crtcs[j]); for (j = pScrPriv->numOutputs - 1; j >= 0; j--) diff --git a/randr/randrstr.h b/randr/randrstr.h index f94174b54..2cede92e3 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -829,6 +829,9 @@ RRCrtcIsLeased(RRCrtcPtr crtc); extern _X_EXPORT Bool RROutputIsLeased(RROutputPtr output); +void +RRTerminateLease(RRLeasePtr lease); + Bool RRLeaseInit(void); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index d7d937e80..5d9026266 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -534,6 +534,7 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height, width, height, depth, x, y, rotation); if (spix_front == NULL) { + ErrorF("randr: failed to create shared pixmap\n"); return FALSE; } @@ -871,6 +872,17 @@ RRCrtcDestroyResource(void *value, XID pid) if (pScreen) { rrScrPriv(pScreen); int i; + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) { + int c; + for (c = 0; c < lease->numCrtcs; c++) { + if (lease->crtcs[c] == crtc) { + RRTerminateLease(lease); + break; + } + } + } for (i = 0; i < pScrPriv->numCrtcs; i++) { if (pScrPriv->crtcs[i] == crtc) { diff --git a/randr/rrlease.c b/randr/rrlease.c index b4a8827cc..e25d9ca99 100644 --- a/randr/rrlease.c +++ b/randr/rrlease.c @@ -169,7 +169,7 @@ RRLeaseFree(RRLeasePtr lease) * finished, which may be some time after this function returns * if the driver operation is asynchronous */ -static void +void RRTerminateLease(RRLeasePtr lease) { ScreenPtr screen = lease->screen; diff --git a/randr/rroutput.c b/randr/rroutput.c index 33300e1cc..e52ad7671 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -379,6 +379,17 @@ RROutputDestroyResource(void *value, XID pid) if (pScreen) { rrScrPriv(pScreen); int i; + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) { + int o; + for (o = 0; o < lease->numOutputs; o++) { + if (lease->outputs[o] == output) { + RRTerminateLease(lease); + break; + } + } + } if (pScrPriv->primaryOutput == output) pScrPriv->primaryOutput = NULL; |