rebase and fix merge conflicts

This commit is contained in:
mattmcclaskey
2023-06-30 12:51:01 -04:00
99 changed files with 2467 additions and 329 deletions

View File

@@ -30,10 +30,14 @@ bin_PROGRAMS = Xvnc
man1_MANS = Xvnc.man
Xvnc_SOURCES = xvnc.c \
Xvnc_SOURCES = xvnc.c dri3.c \
$(top_srcdir)/Xi/stubs.c $(top_srcdir)/mi/miinitext.c \
$(top_srcdir)/fb/fbcmap_mi.c buildtime.c
if DRI3
XVNC_SYS_LIBS += -lgbm
endif
# Xvnc contains no C++ sources so automake doesn't understand that we
# need to use the C++ compiler to link things. This is the upstream
# recommendation for coaxing automake.
@@ -44,7 +48,8 @@ Xvnc_CPPFLAGS = $(XVNC_CPPFLAGS) -DKASMVNC -DNO_MODULE_EXTS \
-DXVNCEXTRAVERSION="\".$(KASMVNC_COMMIT_ID)\"" \
-DXFree86Server -DVENDOR_RELEASE="$(VENDOR_RELEASE)" \
-DVENDOR_STRING="\"$(VENDOR_STRING)\"" -I$(KASMVNC_SRCDIR)/common -I$(KASMVNC_SRCDIR)/unix/common \
-I$(top_srcdir)/include ${XSERVERLIBS_CFLAGS} -I$(includedir)
-I$(top_srcdir)/include ${XSERVERLIBS_CFLAGS} -I$(includedir) \
-I$(top_srcdir)/dri3 @LIBDRM_CFLAGS@
Xvnc_LDADD = $(XVNC_LIBS) libvnccommon.la $(COMMON_LIBS) \
$(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XVNC_SYS_LIBS) -lX11 -lwebp -lssl -lcrypto -lcrypt

View File

@@ -286,6 +286,15 @@ be either \fB0\fP (off), \fB1\fP (always) or \fB2\fP (auto). Default is
\fB2\fP.
.
.TP
.B \-hw3d
Enable hardware 3d acceleration. Default is software (llvmpipe usually).
.
.TP
.B \-drinode \fIpath\fP
Use another path instead of /dev/dri/renderD128. You may need this if you have
more than one GPU.
.
.TP
.B \-ZlibLevel \fIlevel\fP
Zlib compression level for ZRLE encoding (it does not affect Tight encoding).
Acceptable values are between 0 and 9. Default is to use the standard
@@ -346,6 +355,28 @@ Log clipboard and keyboard actions. Info logs just clipboard direction and size,
verbose adds the contents for both.
.
.TP
.B \-DLP_WatermarkImage \fIpath/to/file.png\fP
Add a watermark. The PNG file should be greyscale, black is treated as transparent
and white as opaque.
.
.TP
.B \-DLP_WatermarkLocation \fIx,y\fP
Place the watermark at this position from the corner. Positive numbers are from top-left,
negative from bottom-right. Negative numbers count from the bottom-right edge of the image.
If not set, the watermark will be centered. Cannot be used together with repeat.
.
.TP
.B \-DLP_WatermarkRepeatSpace \fInum\fP
If set, repeat the watermark over the entire image, with \fBnum\fP pixels between
repetitions. Cannot be used together with location.
.
.TP
.B \-DLP_WatermarkTint \fIr,g,b,a\fP
Tint the greyscale watermark by this color. Default is 255,255,255,255 - full white.
The color components can be used to colorize the greyscale watermark, and the alpha
can be used to make it fainter.
.
.TP
.B \-selfBench
Run a set of self-benchmarks and exit.
.

279
unix/xserver/hw/vnc/dri3.c Normal file
View File

@@ -0,0 +1,279 @@
/* Copyright (c) 2023 Kasm
*
* 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
#ifdef DRI3
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <X11/X.h>
#include <X11/Xmd.h>
#include <dri3.h>
#include <drm_fourcc.h>
#include <fb.h>
#include <gcstruct.h>
#include <gbm.h>
extern const char *driNode;
static struct priv_t {
struct gbm_device *gbm;
int fd;
} priv;
struct gbm_pixmap {
struct gbm_bo *bo;
};
typedef struct gbm_pixmap gbm_pixmap;
static DevPrivateKeyRec dri3_pixmap_private_key;
static struct timeval start;
static int
xvnc_dri3_open_client(ClientPtr client,
ScreenPtr screen,
RRProviderPtr provider,
int *pfd)
{
int fd = open(driNode, O_RDWR | O_CLOEXEC);
if (fd < 0)
return BadAlloc;
*pfd = fd;
return Success;
}
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);
/* fallthrough */
case 32:
return GBM_FORMAT_ARGB8888;
}
}
static void dri3_pixmap_set_private(PixmapPtr pixmap, gbm_pixmap *gp)
{
dixSetPrivate(&pixmap->devPrivates, &dri3_pixmap_private_key, gp);
}
static gbm_pixmap *gbm_pixmap_get(PixmapPtr pixmap)
{
return dixLookupPrivate(&pixmap->devPrivates, &dri3_pixmap_private_key);
}
static PixmapPtr
create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, CARD8 depth)
{
PixmapPtr pixmap;
gbm_pixmap *gp = calloc(1, sizeof(gbm_pixmap));
if (!gp)
return NULL;
pixmap = screen->CreatePixmap(screen, gbm_bo_get_width(bo), gbm_bo_get_height(bo),
depth, CREATE_PIXMAP_USAGE_SCRATCH);
if (!pixmap)
return NULL;
gp->bo = bo;
dri3_pixmap_set_private(pixmap, gp);
return pixmap;
}
static PixmapPtr
xvnc_pixmap_from_fds(ScreenPtr screen, CARD8 num_fds, const int *fds,
CARD16 width, CARD16 height,
const CARD32 *strides, const CARD32 *offsets,
CARD8 depth, CARD8 bpp, uint64_t modifier)
{
struct gbm_bo *bo = NULL;
PixmapPtr pixmap;
if (width == 0 || height == 0 || num_fds == 0 ||
depth < 15 || bpp != BitsPerPixel(depth) ||
strides[0] < width * bpp / 8)
return NULL;
if (num_fds == 1) {
struct gbm_import_fd_data data;
data.fd = fds[0];
data.width = width;
data.height = height;
data.stride = strides[0];
data.format = gbm_format_for_depth(depth);
bo = gbm_bo_import(priv.gbm, GBM_BO_IMPORT_FD, &data,
GBM_BO_USE_RENDERING);
if (!bo)
return NULL;
} else {
return NULL;
}
pixmap = create_pixmap_for_bo(screen, bo, depth);
if (pixmap == NULL) {
gbm_bo_destroy(bo);
return NULL;
}
return pixmap;
}
static int
xvnc_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
uint64_t *modifier)
{
gbm_pixmap *gp = gbm_pixmap_get(pixmap);
if (!gp)
return 0;
fds[0] = gbm_bo_get_fd(gp->bo);
strides[0] = gbm_bo_get_stride(gp->bo);
offsets[0] = 0;
*modifier = DRM_FORMAT_MOD_INVALID;
return 1;
}
static Bool
xvnc_get_formats(ScreenPtr screen,
CARD32 *num_formats, CARD32 **formats)
{
ErrorF("xvnc_get_formats\n");
return FALSE;
}
static Bool
xvnc_get_modifiers(ScreenPtr screen, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers)
{
ErrorF("xvnc_get_modifiers\n");
return FALSE;
}
static Bool
xvnc_get_drawable_modifiers(DrawablePtr draw, uint32_t format,
uint32_t *num_modifiers, uint64_t **modifiers)
{
ErrorF("xvnc_get_drawable_modifiers\n");
return FALSE;
}
static const dri3_screen_info_rec xvnc_dri3_info = {
.version = 2,
.open = NULL,
.pixmap_from_fds = xvnc_pixmap_from_fds,
.fds_from_pixmap = xvnc_fds_from_pixmap,
.open_client = xvnc_dri3_open_client,
.get_formats = xvnc_get_formats,
.get_modifiers = xvnc_get_modifiers,
.get_drawable_modifiers = xvnc_get_drawable_modifiers,
};
void xvnc_sync_dri3_pixmap(PixmapPtr pixmap)
{
// There doesn't seem to be a good hook or sync point, so we do it manually
// here, right before Present copies from the pixmap
DrawablePtr pDraw;
GCPtr gc;
void *ptr;
uint32_t stride, w, h;
void *opaque = NULL;
// We may not be running on hw if there's a compositor using PRESENT on llvmpipe
if (!driNode)
return;
gbm_pixmap *gp = gbm_pixmap_get(pixmap);
if (!gp) {
//ErrorF("Present tried to copy from a non-dri3 pixmap\n");
return;
}
w = gbm_bo_get_width(gp->bo);
h = gbm_bo_get_height(gp->bo);
ptr = gbm_bo_map(gp->bo, 0, 0, w, h,
GBM_BO_TRANSFER_READ, &stride, &opaque);
if (!ptr) {
ErrorF("gbm map failed, errno %d\n", errno);
return;
}
pDraw = &pixmap->drawable;
if ((gc = GetScratchGC(pDraw->depth, pDraw->pScreen))) {
ValidateGC(pDraw, gc);
//gc->ops->PutImage(pDraw, gc, pDraw->depth, 0, 0, w, h, 0, ZPixmap, data);
fbPutZImage(pDraw, fbGetCompositeClip(gc), gc->alu, fbGetGCPrivate(gc)->pm,
0, 0, w, h, ptr, stride / sizeof(FbStip));
FreeScratchGC(gc);
}
gbm_bo_unmap(gp->bo, opaque);
}
void xvnc_init_dri3(void)
{
memset(&priv, 0, sizeof(priv));
gettimeofday(&start, NULL);
if (!dixRegisterPrivateKey(&dri3_pixmap_private_key, PRIVATE_PIXMAP, 0))
FatalError("dix\n");
if (!driNode)
driNode = "/dev/dri/renderD128";
priv.fd = open(driNode, O_RDWR | O_CLOEXEC);
if (!priv.fd)
FatalError("Failed to open %s\n", driNode);
priv.gbm = gbm_create_device(priv.fd);
if (!priv.gbm)
FatalError("Failed to create gbm\n");
if (!dri3_screen_init(screenInfo.screens[0], &xvnc_dri3_info))
FatalError("Couldn't init dri3\n");
}
#endif // DRI3

View File

@@ -37,6 +37,7 @@
#include <rfb/Hostname.h>
#include <rfb/Region.h>
#include <rfb/ledStates.h>
#include <rfb/Watermark.h>
#include <network/iceip.h>
#include <network/TcpSocket.h>
#include <network/UnixSocket.h>
@@ -232,6 +233,9 @@ void vncExtensionInit(void)
dummyY < 16)
vncFatalError("Invalid value to %s", Server::maxVideoResolution.getName());
if (!watermarkInit())
vncFatalError("Invalid watermark params");
pipe(wakeuppipe);
const int flags = fcntl(wakeuppipe[0], F_GETFL, 0);
fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK);

View File

@@ -51,7 +51,7 @@ struct dlp_mimetype_t {
char mime[32];
};
unsigned dlp_num_mimetypes();
unsigned dlp_num_mimetypes(void);
const char *dlp_get_mimetype(const unsigned i);
extern int vncInetdSock;
@@ -70,7 +70,7 @@ int vncGetSendPrimary(void);
void vncUpdateDesktopName(void);
void vncAnnounceClipboard(int available);
void vncClearBinaryClipboardData();
void vncClearBinaryClipboardData(void);
void vncSendBinaryClipboardData(const char* mime, const unsigned char *data,
const unsigned len);
void vncGetBinaryClipboardData(const char *mime, const unsigned char **ptr,

View File

@@ -75,6 +75,12 @@ from the X Consortium.
#include <sys/ipc.h>
#include <sys/shm.h>
#endif /* HAS_SHM */
#ifdef MITSHM
#include "shmint.h"
#endif
#ifdef HAVE_XSHMFENCE
#include <misyncshm.h>
#endif
#include "dix.h"
#include "os.h"
#include "miline.h"
@@ -90,7 +96,7 @@ from the X Consortium.
#include "version-config.h"
#include "site.h"
#define XVNCVERSION "KasmVNC 0.9"
#define XVNCVERSION "KasmVNC 1.1.0"
#define XVNCCOPYRIGHT ("Copyright (C) 1999-2018 KasmVNC Team and many others (see README.me)\n" \
"See http://kasmweb.com for information on KasmVNC.\n")
@@ -152,6 +158,8 @@ typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB } fbMemType;
static fbMemType fbmemtype = NORMAL_MEMORY_FB;
static int lastScreen = -1;
static Bool Render = TRUE;
static Bool hw3d = FALSE;
const char *driNode = NULL;
static Bool displaySpecified = FALSE;
static char displayNumStr[16];
@@ -420,6 +428,8 @@ void ddxUseMsg(void)
ErrorF("+/-render turn on/off RENDER extension support"
"(default on)\n");
#endif
ErrorF("-hw3d enable hardware 3d acceleration\n");
ErrorF("-drinode path use another card than /dev/dri/renderD128\n");
ErrorF("-linebias n adjust thin line pixelization\n");
ErrorF("-blackpixel n pixel value for black\n");
ErrorF("-whitepixel n pixel value for white\n");
@@ -560,6 +570,20 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 1;
}
if (strcmp (argv[i], "-hw3d") == 0)
{
hw3d = TRUE;
return 1;
}
if (strcmp (argv[i], "-drinode") == 0)
{
fail_unless_args(argc, i, 1);
++i;
driNode = argv[i];
return 2;
}
if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
{
Pixel pix;
@@ -1563,7 +1587,7 @@ int vncRandRCreateScreenOutputs(int scrIdx, int extraOutputs)
/* Creating and modifying modes, used by XserverDesktop and init here */
int vncRandRCanCreateModes()
int vncRandRCanCreateModes(void)
{
return 1;
}
@@ -1772,6 +1796,15 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
ret = fbPictureInit (pScreen, 0, 0);
#endif
#ifdef MITSHM
ShmRegisterFbFuncs(pScreen);
#endif
#ifdef HAVE_XSHMFENCE
if (!miSyncShmScreenInit(pScreen))
return FALSE;
#endif
if (!ret) return FALSE;
#if XORG < 110
@@ -1871,8 +1904,8 @@ static void vfbClientStateChange(CallbackListPtr *a, void *b, void *c) {
dispatchException &= ~DE_RESET;
}
}
#if XORG >= 113
#if XORG >= 113 && XORG < 120
#ifdef GLXEXT
extern void GlxExtensionInit(void);
@@ -1884,6 +1917,10 @@ static ExtensionModule glxExt = {
#endif
#endif
#ifdef DRI3
extern void xvnc_init_dri3(void);
#endif
void
InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
{
@@ -1960,6 +1997,14 @@ InitOutput(ScreenInfo *scrInfo, int argc, char **argv)
if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
FatalError("AddCallback failed\n");
}
if (hw3d) {
#ifdef DRI3
xvnc_init_dri3();
#else
FatalError("DRI3 disabled at compile time\n");
#endif
}
} /* end InitOutput */
/* this is just to get the server to link on AIX */