diff options
-rw-r--r-- | contrib/packages/deb/ubuntu-focal/debian/rules | 2 | ||||
-rw-r--r-- | contrib/packages/deb/ubuntu-jammy/debian/rules | 4 | ||||
-rw-r--r-- | contrib/packages/deb/ubuntu-noble/debian/rules | 4 | ||||
-rw-r--r-- | contrib/packages/rpm/el7/SPECS/tigervnc.spec | 4 | ||||
-rw-r--r-- | contrib/packages/rpm/el8/SPECS/tigervnc.spec | 4 | ||||
-rw-r--r-- | contrib/packages/rpm/el9/SPECS/tigervnc.spec | 4 | ||||
-rw-r--r-- | unix/vncconfig/vncExt.h | 2 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/Makefile.am | 10 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/Xvnc.man | 6 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncDRI3.c | 537 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncDRI3.h | 43 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncDRI3Draw.c | 785 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/vncHooks.c | 69 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/xvnc.c | 21 | ||||
-rw-r--r-- | unix/xserver120.patch | 132 | ||||
-rw-r--r-- | unix/xserver21.1.1.patch | 38 | ||||
-rw-r--r-- | unix/xserver21.patch | 67 |
17 files changed, 1634 insertions, 98 deletions
diff --git a/contrib/packages/deb/ubuntu-focal/debian/rules b/contrib/packages/deb/ubuntu-focal/debian/rules index afb7830a..0245a065 100644 --- a/contrib/packages/deb/ubuntu-focal/debian/rules +++ b/contrib/packages/deb/ubuntu-focal/debian/rules @@ -102,7 +102,7 @@ config-stamp: xorg-source-stamp --enable-xdmcp \ --enable-xdm-auth-1 \ --enable-glx \ - --disable-dri --enable-dri2 --disable-dri3 \ + --disable-dri --enable-dri2 --enable-dri3 \ --enable-xinerama \ --enable-xf86vidmode \ --enable-xace \ diff --git a/contrib/packages/deb/ubuntu-jammy/debian/rules b/contrib/packages/deb/ubuntu-jammy/debian/rules index 02e798c9..1b4fd6f8 100644 --- a/contrib/packages/deb/ubuntu-jammy/debian/rules +++ b/contrib/packages/deb/ubuntu-jammy/debian/rules @@ -45,7 +45,7 @@ XORG_SOURCE_ARCHIVE = /usr/src/xorg-server.tar.xz xorg-source-stamp: $(XORG_SOURCE_ARCHIVE) tar -C unix/xserver -axf $(XORG_SOURCE_ARCHIVE) --strip-components=1 - cd unix/xserver && patch -p1 < ../xserver21.1.1.patch + cd unix/xserver && patch -p1 < ../xserver21.patch patch -p1 < debian/xorg-source-patches/516_tigervnc-xorg-manpages.patch touch xorg-source-stamp @@ -102,7 +102,7 @@ config-stamp: xorg-source-stamp --enable-xdmcp \ --enable-xdm-auth-1 \ --enable-glx \ - --disable-dri --enable-dri2 --disable-dri3 \ + --disable-dri --enable-dri2 --enable-dri3 \ --enable-xinerama \ --enable-xf86vidmode \ --enable-xace \ diff --git a/contrib/packages/deb/ubuntu-noble/debian/rules b/contrib/packages/deb/ubuntu-noble/debian/rules index 02e798c9..1b4fd6f8 100644 --- a/contrib/packages/deb/ubuntu-noble/debian/rules +++ b/contrib/packages/deb/ubuntu-noble/debian/rules @@ -45,7 +45,7 @@ XORG_SOURCE_ARCHIVE = /usr/src/xorg-server.tar.xz xorg-source-stamp: $(XORG_SOURCE_ARCHIVE) tar -C unix/xserver -axf $(XORG_SOURCE_ARCHIVE) --strip-components=1 - cd unix/xserver && patch -p1 < ../xserver21.1.1.patch + cd unix/xserver && patch -p1 < ../xserver21.patch patch -p1 < debian/xorg-source-patches/516_tigervnc-xorg-manpages.patch touch xorg-source-stamp @@ -102,7 +102,7 @@ config-stamp: xorg-source-stamp --enable-xdmcp \ --enable-xdm-auth-1 \ --enable-glx \ - --disable-dri --enable-dri2 --disable-dri3 \ + --disable-dri --enable-dri2 --enable-dri3 \ --enable-xinerama \ --enable-xf86vidmode \ --enable-xace \ diff --git a/contrib/packages/rpm/el7/SPECS/tigervnc.spec b/contrib/packages/rpm/el7/SPECS/tigervnc.spec index 38a5c49b..ee3baed8 100644 --- a/contrib/packages/rpm/el7/SPECS/tigervnc.spec +++ b/contrib/packages/rpm/el7/SPECS/tigervnc.spec @@ -27,7 +27,7 @@ BuildRequires: xorg-x11-server-source BuildRequires: libXext-devel, libX11-devel, libXi-devel, libXfixes-devel BuildRequires: libXdamage-devel, libXrandr-devel, libXt-devel, libXdmcp-devel BuildRequires: libXinerama-devel, mesa-libGL-devel, libxshmfence-devel -BuildRequires: pixman-devel, libdrm-devel, +BuildRequires: pixman-devel, libdrm-devel, mesa-libgbm-devel BuildRequires: xorg-x11-util-macros, xorg-x11-xtrans-devel, libXtst-devel BuildRequires: xorg-x11-font-utils BuildRequires: libXfont2-devel @@ -159,7 +159,7 @@ autoreconf -fiv --with-pic --disable-static \ --with-default-font-path="catalogue:%{_sysconfdir}/X11/fontpath.d,built-ins" \ --with-xkb-output=%{_localstatedir}/lib/xkb \ - --enable-glx --disable-dri --enable-dri2 --disable-dri3 \ + --enable-glx --disable-dri --enable-dri2 --enable-dri3 \ --disable-unit-tests \ --disable-config-hal \ --disable-config-udev \ diff --git a/contrib/packages/rpm/el8/SPECS/tigervnc.spec b/contrib/packages/rpm/el8/SPECS/tigervnc.spec index 619ad414..307e26f6 100644 --- a/contrib/packages/rpm/el8/SPECS/tigervnc.spec +++ b/contrib/packages/rpm/el8/SPECS/tigervnc.spec @@ -28,7 +28,7 @@ BuildRequires: xorg-x11-server-source BuildRequires: libXext-devel, libX11-devel, libXi-devel, libXfixes-devel BuildRequires: libXdamage-devel, libXrandr-devel, libXt-devel, libXdmcp-devel BuildRequires: libXinerama-devel, mesa-libGL-devel, libxshmfence-devel -BuildRequires: pixman-devel, libdrm-devel, +BuildRequires: pixman-devel, libdrm-devel, mesa-libgbm-devel BuildRequires: xorg-x11-util-macros, xorg-x11-xtrans-devel, libXtst-devel BuildRequires: xorg-x11-font-utils BuildRequires: libXfont2-devel @@ -152,7 +152,7 @@ autoreconf -fiv --with-pic --disable-static \ --with-default-font-path="catalogue:%{_sysconfdir}/X11/fontpath.d,built-ins" \ --with-xkb-output=%{_localstatedir}/lib/xkb \ - --enable-glx --disable-dri --enable-dri2 --disable-dri3 \ + --enable-glx --disable-dri --enable-dri2 --enable-dri3 \ --disable-unit-tests \ --disable-config-hal \ --disable-config-udev \ diff --git a/contrib/packages/rpm/el9/SPECS/tigervnc.spec b/contrib/packages/rpm/el9/SPECS/tigervnc.spec index 88d82dc4..5d120bc0 100644 --- a/contrib/packages/rpm/el9/SPECS/tigervnc.spec +++ b/contrib/packages/rpm/el9/SPECS/tigervnc.spec @@ -28,7 +28,7 @@ BuildRequires: xorg-x11-server-source BuildRequires: libXext-devel, libX11-devel, libXi-devel, libXfixes-devel BuildRequires: libXdamage-devel, libXrandr-devel, libXt-devel, libXdmcp-devel BuildRequires: libXinerama-devel, mesa-libGL-devel, libxshmfence-devel -BuildRequires: pixman-devel, libdrm-devel, +BuildRequires: pixman-devel, libdrm-devel, mesa-libgbm-devel BuildRequires: xorg-x11-util-macros, xorg-x11-xtrans-devel, libXtst-devel BuildRequires: libXfont2-devel # SELinux @@ -151,7 +151,7 @@ autoreconf -fiv --with-pic --disable-static \ --with-default-font-path="catalogue:%{_sysconfdir}/X11/fontpath.d,built-ins" \ --with-xkb-output=%{_localstatedir}/lib/xkb \ - --enable-glx --disable-dri --enable-dri2 --disable-dri3 \ + --enable-glx --disable-dri --enable-dri2 --enable-dri3 \ --disable-unit-tests \ --disable-config-hal \ --disable-config-udev \ diff --git a/unix/vncconfig/vncExt.h b/unix/vncconfig/vncExt.h index 4383248c..5de1685d 100644 --- a/unix/vncconfig/vncExt.h +++ b/unix/vncconfig/vncExt.h @@ -64,7 +64,7 @@ typedef struct { #ifdef _VNCEXT_PROTO_ -#define VNCEXTNAME "VNC-EXTENSION" +#define VNCEXTNAME "TIGERVNC" typedef struct { CARD8 reqType; /* always VncExtReqCode */ diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am index f9ed19d9..f9372183 100644 --- a/unix/xserver/hw/vnc/Makefile.am +++ b/unix/xserver/hw/vnc/Makefile.am @@ -42,6 +42,8 @@ Xvnc_SOURCES = xvnc.c \ # recommendation for coaxing automake. nodist_EXTRA_Xvnc_SOURCES = dummy.cxx +Xvnc_CPPFLAGS = $(AM_CPPFLAGS) + LOCAL_LIBS = \ $(XVNC_LIBS) \ $(XSERVER_LIBS) \ @@ -53,6 +55,14 @@ Xvnc_LDADD = $(LOCAL_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +if DRI3 +Xvnc_SOURCES += vncDRI3.h vncDRI3.c vncDRI3Draw.c +Xvnc_CPPFLAGS += \ + -I$(top_srcdir)/dri3 \ + $(GBM_CFLAGS) +Xvnc_LDADD += $(GBM_LIBS) +endif + libvnc_la_LTLIBRARIES = libvnc.la libvnc_ladir = $(moduledir)/extensions diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man index e43ba150..b9c429f7 100644 --- a/unix/xserver/hw/vnc/Xvnc.man +++ b/unix/xserver/hw/vnc/Xvnc.man @@ -46,6 +46,12 @@ Specify pixel format for server to use (BGRnnn or RGBnnn). The default for depth 16 is RGB565 and for depth 24 and 32 is RGB888. . .TP +.B \-rendernode \fIpath\fP +DRM render node to use for DRI3 GPU acceleration. Specify an empty path to +disable DRI3. Default is \fBauto\fP which makes \fBXvnc\fP pick a suitable +available render node. +. +.TP .B \-interface \fIIP address\fP Listen on interface. By default Xvnc listens on all available interfaces. . diff --git a/unix/xserver/hw/vnc/vncDRI3.c b/unix/xserver/hw/vnc/vncDRI3.c new file mode 100644 index 00000000..79b56f10 --- /dev/null +++ b/unix/xserver/hw/vnc/vncDRI3.c @@ -0,0 +1,537 @@ +/* Copyright 2024 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <glob.h> +#include <unistd.h> + +#ifdef HAVE_GBM +#include <gbm.h> +#endif + +#include "vncDRI3.h" +#include <dri3.h> +#include <fb.h> +#include <misyncshm.h> + +#ifdef FB_ACCESS_WRAPPER +#error "This code is not compatible with accessors" +#endif + +const char *renderNode = "auto"; + +static DevPrivateKeyRec vncDRI3ScreenPrivateKey; +static DevPrivateKeyRec vncDRI3PixmapPrivateKey; + +typedef struct vncDRI3ScreenPrivate { + CloseScreenProcPtr CloseScreen; + + DestroyPixmapProcPtr DestroyPixmap; + +#ifdef HAVE_GBM + const char *devicePath; + struct gbm_device *device; + int fd; +#endif +} vncDRI3ScreenPrivateRec, *vncDRI3ScreenPrivatePtr; + +typedef struct vncDRI3PixmapPrivate { +#ifdef HAVE_GBM + struct gbm_bo *bo; +#endif +} vncDRI3PixmapPrivateRec, *vncDRI3PixmapPrivatePtr; + +#define wrap(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +static inline vncDRI3ScreenPrivatePtr vncDRI3ScreenPrivate(ScreenPtr screen) +{ + return (vncDRI3ScreenPrivatePtr)dixLookupPrivate(&(screen)->devPrivates, &vncDRI3ScreenPrivateKey); +} + +static inline vncDRI3PixmapPrivatePtr vncDRI3PixmapPrivate(PixmapPtr pixmap) +{ + return (vncDRI3PixmapPrivatePtr)dixLookupPrivate(&(pixmap)->devPrivates, &vncDRI3PixmapPrivateKey); +} + +static int vncDRI3Open(ScreenPtr screen, RRProviderPtr provider, + int *fd) +{ +#ifdef HAVE_GBM + vncDRI3ScreenPrivatePtr screenPriv = vncDRI3ScreenPrivate(screen); + + *fd = open(screenPriv->devicePath, O_RDWR|O_CLOEXEC); + if (*fd < 0) + return BadAlloc; + + return Success; +#else + return BadAlloc; +#endif +} + +/* Taken from glamor */ +#ifdef HAVE_GBM +static uint32_t gbm_format_for_depth(CARD8 depth) +{ + switch (depth) { + case 16: + return GBM_FORMAT_RGB565; + case 24: + return GBM_FORMAT_XRGB8888; + case 30: + return GBM_FORMAT_ARGB2101010; + default: + ErrorF("unexpected depth: %d\n", depth); + case 32: + return GBM_FORMAT_ARGB8888; + } +} +#endif + +static PixmapPtr vncPixmapFromFd(ScreenPtr screen, int fd, + CARD16 width, CARD16 height, + CARD16 stride, CARD8 depth, + CARD8 bpp) +{ +#ifdef HAVE_GBM + vncDRI3ScreenPrivatePtr screenPriv = vncDRI3ScreenPrivate(screen); + vncDRI3PixmapPrivatePtr pixmapPriv; + + struct gbm_import_fd_data data; + struct gbm_bo *bo; + PixmapPtr pixmap; + + if (bpp != sizeof(FbBits)*8) { + ErrorF("Incompatible bits per pixel given for GPU buffer\n"); + return NULL; + } + + if ((stride % sizeof(FbBits)) != 0) { + ErrorF("Incompatible stride given for GPU buffer\n"); + return NULL; + } + + data.fd = fd; + data.width = width; + data.height = height; + data.stride = stride; + data.format = gbm_format_for_depth(depth); + + bo = gbm_bo_import(screenPriv->device, GBM_BO_IMPORT_FD, &data, + GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR); + if (bo == NULL) + return NULL; + + pixmap = screen->CreatePixmap(screen, width, height, depth, 0); + + pixmapPriv = vncDRI3PixmapPrivate(pixmap); + pixmapPriv->bo = bo; + + vncDRI3SyncPixmapFromGPU(pixmap); + + return pixmap; +#else + return NULL; +#endif +} + +static Bool vncDRI3DestroyPixmap(PixmapPtr pixmap) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + vncDRI3ScreenPrivatePtr screenPriv = vncDRI3ScreenPrivate(screen); + Bool ret; + +#ifdef HAVE_GBM + if (pixmap->refcnt == 1) { + vncDRI3PixmapPrivatePtr pixmapPriv = vncDRI3PixmapPrivate(pixmap); + + if (pixmapPriv->bo != NULL) { + gbm_bo_destroy(pixmapPriv->bo); + pixmapPriv->bo = NULL; + } + } +#endif + + unwrap(screenPriv, screen, DestroyPixmap); + ret = screen->DestroyPixmap(pixmap); + wrap(screenPriv, screen, DestroyPixmap, vncDRI3DestroyPixmap); + + return ret; +} + +#ifdef HAVE_GBM +static int vncDRI3FdFromPixmapVisitWindow(WindowPtr window, void *data) +{ + ScreenPtr screen = window->drawable.pScreen; + PixmapPtr pixmap = data; + + if ((*screen->GetWindowPixmap)(window) == pixmap) + window->drawable.serialNumber = NEXT_SERIAL_NUMBER; + + return WT_WALKCHILDREN; +} +#endif + +static int vncFdFromPixmap(ScreenPtr screen, PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) +{ +#ifdef HAVE_GBM + vncDRI3ScreenPrivatePtr screenPriv = vncDRI3ScreenPrivate(screen); + vncDRI3PixmapPrivatePtr pixmapPriv = vncDRI3PixmapPrivate(pixmap); + + if (pixmap->drawable.bitsPerPixel != sizeof(FbBits)*8) { + ErrorF("Incompatible bits per pixel given for pixmap\n"); + return -1; + } + + if (pixmapPriv->bo == NULL) { + /* GBM_BO_USE_LINEAR ? */ + pixmapPriv->bo = gbm_bo_create(screenPriv->device, + pixmap->drawable.width, + pixmap->drawable.height, + gbm_format_for_depth(pixmap->drawable.depth), + GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR); + if (pixmapPriv->bo == NULL) { + ErrorF("Failed to create GPU buffer: %s\n", strerror(errno)); + return -1; + } + + if ((gbm_bo_get_stride(pixmapPriv->bo) % sizeof(FbBits)) != 0) { + ErrorF("Incompatible stride for created GPU buffer\n"); + gbm_bo_destroy(pixmapPriv->bo); + pixmapPriv->bo = NULL; + return -1; + } + + /* Force re-validation of any gc:s */ + pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + WalkTree(screen, vncDRI3FdFromPixmapVisitWindow, pixmap); + } + + vncDRI3SyncPixmapToGPU(pixmap); + + *stride = gbm_bo_get_stride(pixmapPriv->bo); + /* FIXME */ + *size = *stride * gbm_bo_get_height(pixmapPriv->bo); + + return gbm_bo_get_fd(pixmapPriv->bo); +#else + return -1; +#endif +} + +Bool vncDRI3IsHardwarePixmap(PixmapPtr pixmap) +{ +#ifdef HAVE_GBM + vncDRI3PixmapPrivatePtr pixmapPriv = vncDRI3PixmapPrivate(pixmap); + return pixmapPriv->bo != NULL; +#else + return FALSE; +#endif +} + +Bool vncDRI3IsHardwareDrawable(DrawablePtr drawable) +{ + PixmapPtr pixmap; + int xoff, yoff; + + fbGetDrawablePixmap(drawable, pixmap, xoff, yoff); + (void)xoff; + (void)yoff; + + return vncDRI3IsHardwarePixmap(pixmap); +} + +Bool vncDRI3SyncPixmapToGPU(PixmapPtr pixmap) +{ +#ifdef HAVE_GBM + vncDRI3PixmapPrivatePtr pixmapPriv = vncDRI3PixmapPrivate(pixmap); + + int width, height; + + FbBits *bo_data; + uint32_t bo_stride; + void *map_data; + uint32_t bo_bpp; + + FbBits *pixmap_data; + int pixmap_stride; + int pixmap_bpp; + + pixman_bool_t ret; + + if (pixmapPriv->bo == NULL) + return TRUE; + + width = gbm_bo_get_width(pixmapPriv->bo); + height = gbm_bo_get_height(pixmapPriv->bo); + + map_data = NULL; + bo_data = gbm_bo_map(pixmapPriv->bo, 0, 0, width, height, + GBM_BO_TRANSFER_WRITE, &bo_stride, &map_data); + if (bo_data == NULL) { + ErrorF("Could not map GPU buffer: %s\n", strerror(errno)); + return FALSE; + } + + bo_bpp = gbm_bo_get_bpp(pixmapPriv->bo); + assert(bo_bpp == sizeof(FbBits)*8); + assert((bo_stride % (bo_bpp/8)) == 0); + + fbGetPixmapBitsData(pixmap, pixmap_data, + pixmap_stride, pixmap_bpp); + assert(pixmap_data != NULL); + assert(pixmap_bpp == sizeof(FbBits)*8); + + assert(bo_bpp == pixmap_bpp); + + /* Try accelerated copy first */ + ret = pixman_blt((uint32_t*)pixmap_data, (uint32_t*)bo_data, + pixmap_stride, bo_stride / (bo_bpp/8), + pixmap_bpp, bo_bpp, 0, 0, 0, 0, width, height); + if (!ret) { + /* Fall back to slow pure C version */ + fbBlt(pixmap_data, pixmap_stride, 0, + bo_data, bo_stride / (bo_bpp/8), 0, + width * bo_bpp, height, + GXcopy, FB_ALLONES, bo_bpp, FALSE, FALSE); + } + + gbm_bo_unmap(pixmapPriv->bo, map_data); +#endif + + return TRUE; +} + +Bool vncDRI3SyncPixmapFromGPU(PixmapPtr pixmap) +{ +#ifdef HAVE_GBM + vncDRI3PixmapPrivatePtr pixmapPriv = vncDRI3PixmapPrivate(pixmap); + + int width, height; + + FbBits *bo_data; + uint32_t bo_stride; + void *map_data; + uint32_t bo_bpp; + + FbBits *pixmap_data; + int pixmap_stride; + int pixmap_bpp; + + pixman_bool_t ret; + + if (pixmapPriv->bo == NULL) + return TRUE; + + width = gbm_bo_get_width(pixmapPriv->bo); + height = gbm_bo_get_height(pixmapPriv->bo); + + map_data = NULL; + bo_data = gbm_bo_map(pixmapPriv->bo, 0, 0, width, height, + GBM_BO_TRANSFER_READ, &bo_stride, &map_data); + if (bo_data == NULL) { + ErrorF("Could not map GPU buffer: %s\n", strerror(errno)); + return FALSE; + } + + bo_bpp = gbm_bo_get_bpp(pixmapPriv->bo); + assert(bo_bpp == sizeof(FbBits)*8); + assert((bo_stride % (bo_bpp/8)) == 0); + + fbGetPixmapBitsData(pixmap, pixmap_data, + pixmap_stride, pixmap_bpp); + assert(pixmap_data != NULL); + assert(pixmap_bpp == sizeof(FbBits)*8); + + assert(bo_bpp == pixmap_bpp); + + /* Try accelerated copy first */ + ret = pixman_blt((uint32_t*)bo_data, (uint32_t*)pixmap_data, + bo_stride / (bo_bpp/8), pixmap_stride, + bo_bpp, pixmap_bpp, 0, 0, 0, 0, width, height); + if (!ret) { + /* Fall back to slow pure C version */ + fbBlt(bo_data, bo_stride / (bo_bpp/8), 0, + pixmap_data, pixmap_stride, 0, + width * bo_bpp, height, + GXcopy, FB_ALLONES, bo_bpp, FALSE, FALSE); + } + + gbm_bo_unmap(pixmapPriv->bo, map_data); +#endif + + return TRUE; +} + +Bool vncDRI3SyncDrawableToGPU(DrawablePtr drawable) +{ + PixmapPtr pixmap; + int xoff, yoff; + + fbGetDrawablePixmap(drawable, pixmap, xoff, yoff); + (void)xoff; + (void)yoff; + + return vncDRI3SyncPixmapToGPU(pixmap); +} + +Bool vncDRI3SyncDrawableFromGPU(DrawablePtr drawable) +{ + PixmapPtr pixmap; + int xoff, yoff; + + fbGetDrawablePixmap(drawable, pixmap, xoff, yoff); + (void)xoff; + (void)yoff; + + return vncDRI3SyncPixmapFromGPU(pixmap); +} + +static const dri3_screen_info_rec vncDRI3ScreenInfo = { + .version = 1, + + .open = vncDRI3Open, + .pixmap_from_fd = vncPixmapFromFd, + .fd_from_pixmap = vncFdFromPixmap, +}; + +static Bool vncDRI3CloseScreen(ScreenPtr screen) +{ + vncDRI3ScreenPrivatePtr screenPriv = vncDRI3ScreenPrivate(screen); + + unwrap(screenPriv, screen, CloseScreen); + + unwrap(screenPriv, screen, DestroyPixmap); + +#ifdef HAVE_GBM + gbm_device_destroy(screenPriv->device); + screenPriv->device = NULL; + + close(screenPriv->fd); + screenPriv->fd = -1; +#endif + + return (*screen->CloseScreen)(screen); +} + +Bool vncDRI3Init(ScreenPtr screen) +{ + vncDRI3ScreenPrivatePtr screenPriv; + + /* + * We don't queue any gbm operations, so we don't have to do anything + * more than simply activate this extension. + */ +#ifdef HAVE_XSHMFENCE + if (!miSyncShmScreenInit(screen)) + return FALSE; +#endif + + /* Empty render node is interpreted as disabling DRI3 */ + if (renderNode[0] == '\0') + return TRUE; + + if ((renderNode[0] != '/') && + (strcasecmp(renderNode, "auto") != 0)) { + ErrorF("Invalid render node path \"%s\"\n", renderNode); + return FALSE; + } + + if (!dixRegisterPrivateKey(&vncDRI3ScreenPrivateKey, PRIVATE_SCREEN, + sizeof(vncDRI3ScreenPrivateRec))) + return FALSE; + if (!dixRegisterPrivateKey(&vncDRI3PixmapPrivateKey, PRIVATE_PIXMAP, + sizeof(vncDRI3PixmapPrivateRec))) + return FALSE; + + if (!vncDRI3DrawInit(screen)) + return FALSE; + +#ifdef HAVE_GBM + screenPriv = vncDRI3ScreenPrivate(screen); + + if (strcasecmp(renderNode, "auto") == 0) { + glob_t globbuf; + int ret; + + ret = glob("/dev/dri/renderD*", 0, NULL, &globbuf); + if (ret == GLOB_NOMATCH) { + ErrorF("Could not find any render nodes\n"); + return FALSE; + } + if (ret != 0) { + ErrorF("Failure enumerating render nodes\n"); + return FALSE; + } + + screenPriv->devicePath = NULL; + for (size_t i = 0;i < globbuf.gl_pathc;i++) { + if (access(globbuf.gl_pathv[i], R_OK|W_OK) == 0) { + screenPriv->devicePath = strdup(globbuf.gl_pathv[i]); + break; + } + } + + globfree(&globbuf); + + if (screenPriv->devicePath == NULL) { + ErrorF("Could not find any available render nodes\n"); + return FALSE; + } + } else { + screenPriv->devicePath = renderNode; + } + + screenPriv->fd = open(screenPriv->devicePath, O_RDWR|O_CLOEXEC); + if (screenPriv->fd < 0) { + ErrorF("Failed to open \"%s\": %s\n", + screenPriv->devicePath, strerror(errno)); + return FALSE; + } + + screenPriv->device = gbm_create_device(screenPriv->fd); + if (screenPriv->device == NULL) { + close(screenPriv->fd); + screenPriv->fd = -1; + ErrorF("Could create GPU render device\n"); + return FALSE; + } +#else + ErrorF("Built without GBM support\n"); + return FALSE; +#endif + + wrap(screenPriv, screen, CloseScreen, vncDRI3CloseScreen); + + wrap(screenPriv, screen, DestroyPixmap, vncDRI3DestroyPixmap); + + return dri3_screen_init(screen, &vncDRI3ScreenInfo); +} diff --git a/unix/xserver/hw/vnc/vncDRI3.h b/unix/xserver/hw/vnc/vncDRI3.h new file mode 100644 index 00000000..4f89a25a --- /dev/null +++ b/unix/xserver/hw/vnc/vncDRI3.h @@ -0,0 +1,43 @@ +/* Copyright 2024 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef __VNCDRI3_H__ +#define __VNCDRI3_H__ + +#ifdef DRI3 + +#include <dix.h> + +extern const char *renderNode; + +Bool vncDRI3Init(ScreenPtr screen); + +Bool vncDRI3IsHardwarePixmap(PixmapPtr pixmap); +Bool vncDRI3IsHardwareDrawable(DrawablePtr drawable); + +Bool vncDRI3SyncPixmapToGPU(PixmapPtr pixmap); +Bool vncDRI3SyncPixmapFromGPU(PixmapPtr pixmap); + +Bool vncDRI3SyncDrawableToGPU(DrawablePtr drawable); +Bool vncDRI3SyncDrawableFromGPU(DrawablePtr drawable); + +Bool vncDRI3DrawInit(ScreenPtr screen); + +#endif + +#endif diff --git a/unix/xserver/hw/vnc/vncDRI3Draw.c b/unix/xserver/hw/vnc/vncDRI3Draw.c new file mode 100644 index 00000000..8aa6625d --- /dev/null +++ b/unix/xserver/hw/vnc/vncDRI3Draw.c @@ -0,0 +1,785 @@ +/* Copyright 2024 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "vncDRI3.h" + +#include <fb.h> +#include <gcstruct.h> +#include <pixmapstr.h> + +static DevPrivateKeyRec vncDRI3DrawScreenPrivateKey; +static DevPrivateKeyRec vncDRI3GCPrivateKey; + +typedef struct vncDRI3DrawScreenPrivateRec { + CloseScreenProcPtr CloseScreen; + + CreateGCProcPtr CreateGC; + SourceValidateProcPtr SourceValidate; + + CompositeProcPtr Composite; + GlyphsProcPtr Glyphs; + CompositeRectsProcPtr CompositeRects; + TrapezoidsProcPtr Trapezoids; + TrianglesProcPtr Triangles; + TriStripProcPtr TriStrip; + TriFanProcPtr TriFan; +} vncDRI3DrawScreenPrivateRec, *vncDRI3DrawScreenPrivatePtr; + +typedef struct vncDRI3GCPrivateRec { + const GCFuncs *funcs; + const GCOps *ops; +} vncDRI3GCPrivateRec, *vncDRI3GCPrivatePtr; + +#define wrap(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +static inline vncDRI3DrawScreenPrivatePtr vncDRI3DrawScreenPrivate(ScreenPtr screen) +{ + return (vncDRI3DrawScreenPrivatePtr)dixLookupPrivate(&(screen)->devPrivates, &vncDRI3DrawScreenPrivateKey); +} + +static inline vncDRI3GCPrivatePtr vncDRI3GCPrivate(GCPtr gc) +{ + return (vncDRI3GCPrivatePtr)dixLookupPrivate(&(gc)->devPrivates, &vncDRI3GCPrivateKey); +} + +static GCFuncs vncDRI3GCFuncs; +static GCOps vncDRI3GCOps; + +/* GC functions */ + +static void vncDRI3ValidateGC(GCPtr gc, unsigned long changes, + DrawablePtr drawable) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + unwrap(gcPriv, gc, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, gc, ops); + + (*gc->funcs->ValidateGC)(gc, changes, drawable); + + if (vncDRI3IsHardwareDrawable(drawable)) { + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + } else { + gcPriv->ops = NULL; + } + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3ChangeGC(GCPtr gc, unsigned long mask) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + unwrap(gcPriv, gc, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, gc, ops); + (*gc->funcs->ChangeGC)(gc, mask); + if (gcPriv->ops != NULL) + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3CopyGC(GCPtr src, unsigned long mask, GCPtr dst) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(dst); + unwrap(gcPriv, dst, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, dst, ops); + (*dst->funcs->CopyGC)(src, mask, dst); + if (gcPriv->ops != NULL) + wrap(gcPriv, dst, ops, &vncDRI3GCOps); + wrap(gcPriv, dst, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3DestroyGC(GCPtr gc) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + unwrap(gcPriv, gc, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, gc, ops); + (*gc->funcs->DestroyGC)(gc); + if (gcPriv->ops != NULL) + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3ChangeClip(GCPtr gc, int type, void *value, int nrects) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + unwrap(gcPriv, gc, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, gc, ops); + (*gc->funcs->ChangeClip)(gc, type, value, nrects); + if (gcPriv->ops != NULL) + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3DestroyClip(GCPtr gc) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + unwrap(gcPriv, gc, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, gc, ops); + (*gc->funcs->DestroyClip)(gc); + if (gcPriv->ops != NULL) + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); +} + +static void vncDRI3CopyClip(GCPtr dst, GCPtr src) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(dst); + unwrap(gcPriv, dst, funcs); + if (gcPriv->ops != NULL) + unwrap(gcPriv, dst, ops); + (*dst->funcs->CopyClip)(dst, src); + if (gcPriv->ops != NULL) + wrap(gcPriv, dst, ops, &vncDRI3GCOps); + wrap(gcPriv, dst, funcs, &vncDRI3GCFuncs); +} + +/* GC operations */ + +static void vncDRI3FillSpans(DrawablePtr drawable, GCPtr gc, int nInit, + DDXPointPtr pptInit, int *pwidthInit, + int fSorted) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->FillSpans)(drawable, gc, nInit, pptInit, pwidthInit, fSorted); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3SetSpans(DrawablePtr drawable, GCPtr gc, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, + int fSorted) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->SetSpans)(drawable, gc, psrc, ppt, pwidth, nspans, fSorted); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PutImage(DrawablePtr drawable, GCPtr gc, int depth, + int x, int y, int w, int h, int leftPad, + int format, char *pBits) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PutImage)(drawable, gc, depth, x, y, w, h, leftPad, format, pBits); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static RegionPtr vncDRI3CopyArea(DrawablePtr src, DrawablePtr dst, + GCPtr gc, int srcx, int srcy, + int w, int h, int dstx, int dsty) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + RegionPtr ret; + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(dst); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + ret = (*gc->ops->CopyArea)(src, dst, gc, srcx, srcy, w, h, dstx, dsty); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(dst); + + return ret; +} + +static RegionPtr vncDRI3CopyPlane(DrawablePtr src, DrawablePtr dst, + GCPtr gc, int srcx, int srcy, + int w, int h, int dstx, int dsty, + unsigned long plane) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + RegionPtr ret; + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(dst); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + ret = (*gc->ops->CopyPlane)(src, dst, gc, srcx, srcy, w, h, dstx, dsty, plane); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(dst); + + return ret; +} + +static void vncDRI3PolyPoint(DrawablePtr drawable, GCPtr gc, int mode, + int npt, xPoint *pts) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyPoint)(drawable, gc, mode, npt, pts); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3Polylines(DrawablePtr drawable, GCPtr gc, int mode, + int npt, DDXPointPtr ppts) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->Polylines)(drawable, gc, mode, npt, ppts); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolySegment(DrawablePtr drawable, GCPtr gc, int nseg, + xSegment *segs) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolySegment)(drawable, gc, nseg, segs); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolyRectangle(DrawablePtr drawable, GCPtr gc, + int nrects, xRectangle *rects) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyRectangle)(drawable, gc, nrects, rects); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolyArc(DrawablePtr drawable, GCPtr gc, int narcs, + xArc *arcs) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyArc)(drawable, gc, narcs, arcs); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3FillPolygon(DrawablePtr drawable, GCPtr gc, + int shape, int mode, int count, + DDXPointPtr pts) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->FillPolygon)(drawable, gc, shape, mode, count, pts); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolyFillRect(DrawablePtr drawable, GCPtr gc, + int nrects, xRectangle *rects) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyFillRect)(drawable, gc, nrects, rects); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolyFillArc(DrawablePtr drawable, GCPtr gc, + int narcs, xArc *arcs) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyFillArc)(drawable, gc, narcs, arcs); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static int vncDRI3PolyText8(DrawablePtr drawable, GCPtr gc, + int x, int y, int count, char *chars) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + int ret; + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + ret = (*gc->ops->PolyText8)(drawable, gc, x, y, count, chars); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); + + return ret; +} + +static int vncDRI3PolyText16(DrawablePtr drawable, GCPtr gc, + int x, int y, int count, + unsigned short *chars) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + int ret; + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + ret = (*gc->ops->PolyText16)(drawable, gc, x, y, count, chars); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); + + return ret; +} + +static void vncDRI3ImageText8(DrawablePtr drawable, GCPtr gc, + int x, int y, int count, char *chars) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->ImageText8)(drawable, gc, x, y, count, chars); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3ImageText16(DrawablePtr drawable, GCPtr gc, + int x, int y, int count, + unsigned short *chars) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->ImageText16)(drawable, gc, x, y, count, chars); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3ImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, + int y, unsigned int nglyph, + CharInfoPtr *ppci, void * pglyphBase) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->ImageGlyphBlt)(drawable, gc, x, y, nglyph, ppci, pglyphBase); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, + int y, unsigned int nglyph, + CharInfoPtr *ppci, void * pglyphBase) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PolyGlyphBlt)(drawable, gc, x, y, nglyph, ppci, pglyphBase); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static void vncDRI3PushPixels(GCPtr gc, PixmapPtr pBitMap, + DrawablePtr drawable, + int w, int h, int x, int y) +{ + vncDRI3GCPrivatePtr gcPriv = vncDRI3GCPrivate(gc); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(gcPriv, gc, funcs); + unwrap(gcPriv, gc, ops); + (*gc->ops->PushPixels)(gc, pBitMap, drawable, w, h, x, y); + wrap(gcPriv, gc, ops, &vncDRI3GCOps); + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + vncDRI3SyncDrawableToGPU(drawable); +} + +static GCFuncs vncDRI3GCFuncs = { + .ValidateGC = vncDRI3ValidateGC, + .ChangeGC = vncDRI3ChangeGC, + .CopyGC = vncDRI3CopyGC, + .DestroyGC = vncDRI3DestroyGC, + .ChangeClip = vncDRI3ChangeClip, + .DestroyClip = vncDRI3DestroyClip, + .CopyClip = vncDRI3CopyClip, +}; + +static GCOps vncDRI3GCOps = { + .FillSpans = vncDRI3FillSpans, + .SetSpans = vncDRI3SetSpans, + .PutImage = vncDRI3PutImage, + .CopyArea = vncDRI3CopyArea, + .CopyPlane = vncDRI3CopyPlane, + .PolyPoint = vncDRI3PolyPoint, + .Polylines = vncDRI3Polylines, + .PolySegment = vncDRI3PolySegment, + .PolyRectangle = vncDRI3PolyRectangle, + .PolyArc = vncDRI3PolyArc, + .FillPolygon = vncDRI3FillPolygon, + .PolyFillRect = vncDRI3PolyFillRect, + .PolyFillArc = vncDRI3PolyFillArc, + .PolyText8 = vncDRI3PolyText8, + .PolyText16 = vncDRI3PolyText16, + .ImageText8 = vncDRI3ImageText8, + .ImageText16 = vncDRI3ImageText16, + .ImageGlyphBlt = vncDRI3ImageGlyphBlt, + .PolyGlyphBlt = vncDRI3PolyGlyphBlt, + .PushPixels = vncDRI3PushPixels, +}; + +static Bool vncDRI3CreateGC(GCPtr gc) +{ + ScreenPtr screen = gc->pScreen; + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + vncDRI3GCPrivatePtr gcPriv; + Bool ret; + + unwrap(screenPriv, screen, CreateGC); + ret = (*screen->CreateGC)(gc); + wrap(screenPriv, screen, CreateGC, vncDRI3CreateGC); + + gcPriv = vncDRI3GCPrivate(gc); + + wrap(gcPriv, gc, funcs, &vncDRI3GCFuncs); + + return ret; +} + +static void vncDRI3SourceValidate(DrawablePtr drawable, + int x, int y, + int width, int height, + unsigned int subWindowMode) +{ + ScreenPtr screen = drawable->pScreen; + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + /* FIXME: Compute what we need to sync */ + vncDRI3SyncDrawableFromGPU(drawable); + + unwrap(screenPriv, screen, SourceValidate); + screen->SourceValidate(drawable, x, y, width, height, subWindowMode); + wrap(screenPriv, screen, SourceValidate, vncDRI3SourceValidate); +} + +static void vncDRI3Composite(CARD8 op, PicturePtr pSrc, + PicturePtr pMask, PicturePtr pDst, + INT16 xSrc, INT16 ySrc, INT16 xMask, + INT16 yMask, INT16 xDst, INT16 yDst, + CARD16 width, CARD16 height) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, Composite); + (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); + wrap(screenPriv, ps, Composite, vncDRI3Composite); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3Glyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, INT16 ySrc, int nlists, + GlyphListPtr lists, GlyphPtr * glyphs) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, Glyphs); + (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, + nlists, lists, glyphs); + wrap(screenPriv, ps, Glyphs, vncDRI3Glyphs); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3CompositeRects(CARD8 op, PicturePtr pDst, + xRenderColor * color, int nRect, xRectangle *rects) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, CompositeRects); + (*ps->CompositeRects)(op, pDst, color, nRect, rects); + wrap(screenPriv, ps, CompositeRects, vncDRI3CompositeRects); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3Trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid * traps) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + /* FIXME: Rarely used, so we just sync everything */ + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, Trapezoids); + (*ps->Trapezoids)(op, pSrc, pDst, maskFormat, xSrc, ySrc, + ntrap, traps); + wrap(screenPriv, ps, Trapezoids, vncDRI3Trapezoids); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3Triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntri, xTriangle * tris) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + /* FIXME: Rarely used, so we just sync everything */ + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, Triangles); + (*ps->Triangles)(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); + wrap(screenPriv, ps, Triangles, vncDRI3Triangles); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3TriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int npoint, xPointFixed * points) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + /* FIXME: Rarely used, so we just sync everything */ + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, TriStrip); + (*ps->TriStrip)(op, pSrc, pDst, maskFormat, xSrc, ySrc, + npoint, points); + wrap(screenPriv, ps, TriStrip, vncDRI3TriStrip) + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static void vncDRI3TriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int npoint, xPointFixed * points) +{ + ScreenPtr screen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(screen); + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + + /* FIXME: Rarely used, so we just sync everything */ + vncDRI3SyncDrawableFromGPU(pDst->pDrawable); + + unwrap(screenPriv, ps, TriFan); + (*ps->TriFan)(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, points); + wrap(screenPriv, ps, TriFan, vncDRI3TriFan); + + vncDRI3SyncDrawableToGPU(pDst->pDrawable); +} + +static Bool vncDRI3DrawCloseScreen(ScreenPtr screen) +{ + vncDRI3DrawScreenPrivatePtr screenPriv = vncDRI3DrawScreenPrivate(screen); + PictureScreenPtr ps; + + unwrap(screenPriv, screen, CloseScreen); + + unwrap(screenPriv, screen, CreateGC); + unwrap(screenPriv, screen, SourceValidate); + + ps = GetPictureScreenIfSet(screen); + if (ps) { + unwrap(screenPriv, ps, Composite); + unwrap(screenPriv, ps, Glyphs); + unwrap(screenPriv, ps, CompositeRects); + unwrap(screenPriv, ps, Trapezoids); + unwrap(screenPriv, ps, Triangles); + unwrap(screenPriv, ps, TriStrip); + unwrap(screenPriv, ps, TriFan); + } + + return (*screen->CloseScreen)(screen); +} + +Bool vncDRI3DrawInit(ScreenPtr screen) +{ + vncDRI3DrawScreenPrivatePtr screenPriv; + PictureScreenPtr ps; + + if (!dixRegisterPrivateKey(&vncDRI3DrawScreenPrivateKey, + PRIVATE_SCREEN, + sizeof(vncDRI3DrawScreenPrivateRec))) + return FALSE; + if (!dixRegisterPrivateKey(&vncDRI3GCPrivateKey, PRIVATE_GC, + sizeof(vncDRI3GCPrivateRec))) + return FALSE; + + screenPriv = vncDRI3DrawScreenPrivate(screen); + + wrap(screenPriv, screen, CloseScreen, vncDRI3DrawCloseScreen); + + wrap(screenPriv, screen, CreateGC, vncDRI3CreateGC); + wrap(screenPriv, screen, SourceValidate, vncDRI3SourceValidate); + + ps = GetPictureScreenIfSet(screen); + if (ps) { + wrap(screenPriv, ps, Composite, vncDRI3Composite); + wrap(screenPriv, ps, Glyphs, vncDRI3Glyphs); + wrap(screenPriv, ps, CompositeRects, vncDRI3CompositeRects); + wrap(screenPriv, ps, Trapezoids, vncDRI3Trapezoids); + wrap(screenPriv, ps, Triangles, vncDRI3Triangles); + wrap(screenPriv, ps, TriStrip, vncDRI3TriStrip); + wrap(screenPriv, ps, TriFan, vncDRI3TriFan); + } + + return TRUE; +}
\ No newline at end of file diff --git a/unix/xserver/hw/vnc/vncHooks.c b/unix/xserver/hw/vnc/vncHooks.c index 3838c10d..7fe35ada 100644 --- a/unix/xserver/hw/vnc/vncHooks.c +++ b/unix/xserver/hw/vnc/vncHooks.c @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009-2017 Pierre Ossman for Cendio AB + * Copyright 2009-2024 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -469,39 +469,47 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) { int dx, dy; - BoxRec screen_box; - RegionRec copied, screen_rgn; + RegionRec copied; SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow); - RegionNull(&copied); - RegionCopy(&copied, pOldRegion); + if (is_visible(&pWin->drawable)) { + BoxRec screen_box; + RegionRec screen_rgn; - screen_box.x1 = 0; - screen_box.y1 = 0; - screen_box.x2 = pScreen->width; - screen_box.y2 = pScreen->height; + RegionNull(&copied); + RegionCopy(&copied, pOldRegion); - RegionInitBoxes(&screen_rgn, &screen_box, 1); + screen_box.x1 = 0; + screen_box.y1 = 0; + screen_box.x2 = pScreen->width; + screen_box.y2 = pScreen->height; - dx = pWin->drawable.x - ptOldOrg.x; - dy = pWin->drawable.y - ptOldOrg.y; + RegionInitBoxes(&screen_rgn, &screen_box, 1); - // RFB tracks copies in terms of destination rectangle, not source. - // We also need to copy with changes to the Window's clipping region. - // Finally, make sure we don't get copies to or from regions outside - // the framebuffer. - RegionIntersect(&copied, &copied, &screen_rgn); - RegionTranslate(&copied, dx, dy); - RegionIntersect(&copied, &copied, &screen_rgn); - RegionIntersect(&copied, &copied, &pWin->borderClip); + dx = pWin->drawable.x - ptOldOrg.x; + dy = pWin->drawable.y - ptOldOrg.y; + + // RFB tracks copies in terms of destination rectangle, not source. + // We also need to copy with changes to the Window's clipping region. + // Finally, make sure we don't get copies to or from regions outside + // the framebuffer. + RegionIntersect(&copied, &copied, &screen_rgn); + RegionTranslate(&copied, dx, dy); + RegionIntersect(&copied, &copied, &screen_rgn); + RegionIntersect(&copied, &copied, &pWin->borderClip); + + RegionUninit(&screen_rgn); + } else { + RegionNull(&copied); + dx = dy = 0; + } (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion); add_copied(pScreen, &copied, dx, dy); RegionUninit(&copied); - RegionUninit(&screen_rgn); SCREEN_EPILOGUE(CopyWindow); } @@ -512,18 +520,23 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures) { - BoxRec box; RegionRec reg; SCREEN_PROLOGUE(pWin->drawable.pScreen, ClearToBackground); - box.x1 = x + pWin->drawable.x; - box.y1 = y + pWin->drawable.y; - box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); - box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); + if (is_visible(&pWin->drawable)) { + BoxRec box; - RegionInitBoxes(®, &box, 1); - RegionIntersect(®, ®, &pWin->clipList); + box.x1 = x + pWin->drawable.x; + box.y1 = y + pWin->drawable.y; + box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width); + box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height); + + RegionInitBoxes(®, &box, 1); + RegionIntersect(®, ®, &pWin->clipList); + } else { + RegionNull(®); + } (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c index 4ee1cd1b..45da17fb 100644 --- a/unix/xserver/hw/vnc/xvnc.c +++ b/unix/xserver/hw/vnc/xvnc.c @@ -36,6 +36,7 @@ from the X Consortium. #include "RFBGlue.h" #include "XorgGlue.h" #include "RandrGlue.h" +#include "vncDRI3.h" #include "vncPresent.h" #include "xorg-version.h" @@ -222,6 +223,9 @@ ddxUseMsg(void) ErrorF("-inetd has been launched from inetd\n"); ErrorF ("-noclipboard disable clipboard settings modification via vncconfig utility\n"); +#ifdef DRI3 + ErrorF("-rendernode PATH DRM render node to use for DRI3\n"); +#endif ErrorF("-verbose [n] verbose startup messages\n"); ErrorF("-quiet minimal startup messages\n"); ErrorF("-version show the server version\n"); @@ -404,6 +408,15 @@ ddxProcessArgument(int argc, char *argv[], int i) return 1; } +#ifdef DRI3 + if (strcmp(argv[i], "-rendernode") == 0) { + CHECK_FOR_REQUIRED_ARGUMENTS(1); + ++i; + renderNode = argv[i]; + return 2; + } +#endif + if (!strcmp(argv[i], "-verbose")) { if (++i < argc && argv[i]) { char *end; @@ -1088,6 +1101,12 @@ vncScreenInit(ScreenPtr pScreen, int argc, char **argv) if (!ret) ErrorF("Failed to initialize Present extension\n"); +#ifdef DRI3 + ret = vncDRI3Init(pScreen); + if (!ret) + ErrorF("Failed to initialize DRI3 extension\n"); +#endif + return TRUE; } /* end vncScreenInit */ @@ -1110,7 +1129,7 @@ extern void GlxExtensionInit(void); #endif static const ExtensionModule vncExtensions[] = { - {vncExtensionInit, "VNC-EXTENSION", NULL}, + {vncExtensionInit, "TIGERVNC", NULL}, #ifdef GLXEXT #if XORG_OLDER_THAN(1, 20, 0) { GlxExtensionInit, "GLX", &noGlxExtension }, diff --git a/unix/xserver120.patch b/unix/xserver120.patch index 2f555eeb..9bc51822 100644 --- a/unix/xserver120.patch +++ b/unix/xserver120.patch @@ -1,7 +1,7 @@ -Index: xserver/configure.ac -=================================================================== ---- xserver.orig/configure.ac -+++ xserver/configure.ac +diff --git a/configure.ac b/configure.ac +index 0909cc5b4..c01873200 100644 +--- a/configure.ac ++++ b/configure.ac @@ -74,6 +74,7 @@ dnl forcing an entire recompile.x AC_CONFIG_HEADERS(include/version-config.h) @@ -10,17 +10,30 @@ Index: xserver/configure.ac AC_PROG_LN_S LT_PREREQ([2.2]) LT_INIT([disable-static win32-dll]) -@@ -1777,6 +1778,9 @@ if test "x$XVFB" = xyes; then +@@ -1735,6 +1736,14 @@ if test "x$XVFB" = xyes; then AC_SUBST([XVFB_SYS_LIBS]) fi +dnl Xvnc DDX +AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"]) +AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"]) ++ ++PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) ++if test "x$GBM" = xyes; then ++ AC_DEFINE(HAVE_GBM, 1, [Have GBM support]) ++fi dnl Xnest DDX -@@ -2565,6 +2571,7 @@ hw/dmx/Makefile +@@ -2058,7 +2067,6 @@ if test "x$GLAMOR" = xyes; then + [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DRIVER, 1, [Have GLAMOR_HAS_EGL_QUERY_DRIVER])], + []) + +- PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) + if test "x$GBM" = xyes; then + AC_DEFINE(GLAMOR_HAS_GBM, 1, + [Build glamor with GBM-based EGL support]) +@@ -2523,6 +2531,7 @@ hw/dmx/Makefile hw/dmx/man/Makefile hw/vfb/Makefile hw/vfb/man/Makefile @@ -28,17 +41,98 @@ Index: xserver/configure.ac hw/xnest/Makefile hw/xnest/man/Makefile hw/xwin/Makefile -Index: xserver/hw/Makefile.am -=================================================================== ---- xserver.orig/hw/Makefile.am -+++ xserver/hw/Makefile.am -@@ -38,7 +38,8 @@ SUBDIRS = \ - $(DMX_SUBDIRS) \ - $(KDRIVE_SUBDIRS) \ - $(XQUARTZ_SUBDIRS) \ -- $(XWAYLAND_SUBDIRS) -+ $(XWAYLAND_SUBDIRS) \ -+ vnc - - DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland +diff --git a/dri3/Makefile.am b/dri3/Makefile.am +index e47a734e0..99c3718a5 100644 +--- a/dri3/Makefile.am ++++ b/dri3/Makefile.am +@@ -1,7 +1,7 @@ + noinst_LTLIBRARIES = libdri3.la + AM_CFLAGS = \ +- -DHAVE_XORG_CONFIG_H \ +- @DIX_CFLAGS@ @XORG_CFLAGS@ ++ @DIX_CFLAGS@ \ ++ @LIBDRM_CFLAGS@ + + libdri3_la_SOURCES = \ + dri3.h \ +diff --git a/dri3/dri3.c b/dri3/dri3.c +index ba32facd7..191252969 100644 +--- a/dri3/dri3.c ++++ b/dri3/dri3.c +@@ -20,10 +20,6 @@ + * OF THIS SOFTWARE. + */ + +-#ifdef HAVE_XORG_CONFIG_H +-#include <xorg-config.h> +-#endif +- + #include "dri3_priv.h" + + #include <drm_fourcc.h> +diff --git a/dri3/dri3_priv.h b/dri3/dri3_priv.h +index b087a9529..f319d1770 100644 +--- a/dri3/dri3_priv.h ++++ b/dri3/dri3_priv.h +@@ -23,6 +23,7 @@ + #ifndef _DRI3PRIV_H_ + #define _DRI3PRIV_H_ + ++#include "dix-config.h" + #include <X11/X.h> + #include "scrnintstr.h" + #include "misc.h" +diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c +index 958877efa..687168930 100644 +--- a/dri3/dri3_request.c ++++ b/dri3/dri3_request.c +@@ -20,10 +20,6 @@ + * OF THIS SOFTWARE. + */ + +-#ifdef HAVE_XORG_CONFIG_H +-#include <xorg-config.h> +-#endif +- + #include "dri3_priv.h" + #include <syncsrv.h> + #include <unistd.h> +diff --git a/dri3/dri3_screen.c b/dri3/dri3_screen.c +index b98259753..3c7e5bf60 100644 +--- a/dri3/dri3_screen.c ++++ b/dri3/dri3_screen.c +@@ -20,10 +20,6 @@ + * OF THIS SOFTWARE. + */ + +-#ifdef HAVE_XORG_CONFIG_H +-#include <xorg-config.h> +-#endif +- + #include "dri3_priv.h" + #include <syncsdk.h> + #include <misync.h> +diff --git a/hw/Makefile.am b/hw/Makefile.am +index 19895dc77..3ecfa8b7a 100644 +--- a/hw/Makefile.am ++++ b/hw/Makefile.am +@@ -44,3 +44,5 @@ DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland + + relink: + $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done ++ ++SUBDIRS += vnc +diff --git a/include/dix-config.h.in b/include/dix-config.h.in +index f8fc67067..d53c4e72f 100644 +--- a/include/dix-config.h.in ++++ b/include/dix-config.h.in +@@ -83,6 +83,9 @@ + /* Define to 1 if you have the <fcntl.h> header file. */ + #undef HAVE_FCNTL_H + ++/* Have GBM support */ ++#undef HAVE_GBM ++ + /* Define to 1 if you have the `getdtablesize' function. */ + #undef HAVE_GETDTABLESIZE diff --git a/unix/xserver21.1.1.patch b/unix/xserver21.1.1.patch deleted file mode 100644 index 3fbaae51..00000000 --- a/unix/xserver21.1.1.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff -urpN xorg-server-1.20.0/configure.ac xorg-server-1.20.0/configure.ac ---- xorg-server-1.20.0/configure.ac 2018-05-10 09:32:34.000000000 -0700 -+++ xorg-server-1.20.0/configure.ac 2018-06-13 19:04:47.536413626 -0700 -@@ -74,6 +74,7 @@ dnl forcing an entire recompile.x - AC_CONFIG_HEADERS(include/version-config.h) - - AM_PROG_AS -+AC_PROG_CXX - AC_PROG_LN_S - LT_PREREQ([2.2]) - LT_INIT([disable-static win32-dll]) -@@ -1777,6 +1778,9 @@ if test "x$XVFB" = xyes; then - AC_SUBST([XVFB_SYS_LIBS]) - fi - -+dnl Xvnc DDX -+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"]) -+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"]) - - dnl Xnest DDX - -@@ -2565,6 +2571,7 @@ hw/dmx/Makefile - hw/dmx/man/Makefile - hw/vfb/Makefile - hw/vfb/man/Makefile -+hw/vnc/Makefile - hw/xnest/Makefile - hw/xnest/man/Makefile - hw/xwin/Makefile -diff -urpN xorg-server-1.20.0/hw/Makefile.am xorg-server-1.20.0/hw/Makefile.am ---- xorg-server-1.20.0/hw/Makefile.am 2018-05-10 09:32:34.000000000 -0700 -+++ xorg-server-1.20.0/hw/Makefile.am 2018-06-13 19:04:47.536413626 -0700 -@@ -44,3 +44,5 @@ - - relink: - $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done -+ -+SUBDIRS += vnc diff --git a/unix/xserver21.patch b/unix/xserver21.patch new file mode 100644 index 00000000..7f1e8d4f --- /dev/null +++ b/unix/xserver21.patch @@ -0,0 +1,67 @@ +diff --git a/configure.ac b/configure.ac +index fad7b5769..2c167de3d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -72,6 +72,7 @@ dnl forcing an entire recompile.x + AC_CONFIG_HEADERS(include/version-config.h) + + AM_PROG_AS ++AC_PROG_CXX + AC_PROG_LN_S + LT_PREREQ([2.2]) + LT_INIT([disable-static win32-dll]) +@@ -1720,6 +1721,14 @@ if test "x$XVFB" = xyes; then + AC_SUBST([XVFB_SYS_LIBS]) + fi + ++dnl Xvnc DDX ++AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"]) ++AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"]) ++ ++PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) ++if test "x$GBM" = xyes; then ++ AC_DEFINE(HAVE_GBM, 1, [Have GBM support]) ++fi + + dnl Xnest DDX + +@@ -2038,7 +2047,6 @@ if test "x$GLAMOR" = xyes; then + [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DRIVER, 1, [Have GLAMOR_HAS_EGL_QUERY_DRIVER])], + []) + +- PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) + if test "x$GBM" = xyes; then + AC_DEFINE(GLAMOR_HAS_GBM, 1, + [Build glamor with GBM-based EGL support]) +@@ -2346,6 +2354,7 @@ hw/xfree86/utils/man/Makefile + hw/xfree86/utils/gtf/Makefile + hw/vfb/Makefile + hw/vfb/man/Makefile ++hw/vnc/Makefile + hw/xnest/Makefile + hw/xnest/man/Makefile + hw/xwin/Makefile +diff --git a/hw/Makefile.am b/hw/Makefile.am +index 1749018fa..1172cd59b 100644 +--- a/hw/Makefile.am ++++ b/hw/Makefile.am +@@ -34,3 +34,5 @@ DIST_SUBDIRS = xfree86 vfb xnest xwin xquartz kdrive + + relink: + $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done ++ ++SUBDIRS += vnc +diff --git a/include/dix-config.h.in b/include/dix-config.h.in +index 382d70609..04a4fd263 100644 +--- a/include/dix-config.h.in ++++ b/include/dix-config.h.in +@@ -77,6 +77,9 @@ + /* Define to 1 if you have the <fcntl.h> header file. */ + #undef HAVE_FCNTL_H + ++/* Have GBM support */ ++#undef HAVE_GBM ++ + /* Define to 1 if you have the `getdtablesize' function. */ + #undef HAVE_GETDTABLESIZE + |