This makes the dummy driver similar to the mode setting driver. This work was done by Henri Verbeet, which was in turn based heavily on the Xorg modesetting driver. Signed-off-by: Jeremy White <jwhite@xxxxxxxxxxxxxxx> --- spice-video-dummy/.gitignore | 9 + spice-video-dummy/README.md | 15 +- spice-video-dummy/configure.ac | 12 +- spice-video-dummy/spicedummy.conf | 18 ++ spice-video-dummy/src/Makefile.am | 16 +- spice-video-dummy/src/dri2.c | 288 +++++++++++++++++++++ spice-video-dummy/src/dummy_cursor.c | 2 +- spice-video-dummy/src/present.c | 104 ++++++++ spice-video-dummy/src/{dummy.h => spicedummy.h} | 10 + .../src/{dummy_driver.c => spicedummy_driver.c} | 82 +++++- 10 files changed, 523 insertions(+), 33 deletions(-) create mode 100644 spice-video-dummy/.gitignore create mode 100644 spice-video-dummy/spicedummy.conf create mode 100644 spice-video-dummy/src/dri2.c create mode 100644 spice-video-dummy/src/present.c rename spice-video-dummy/src/{dummy.h => spicedummy.h} (83%) rename spice-video-dummy/src/{dummy_driver.c => spicedummy_driver.c} (88%) diff --git a/spice-video-dummy/.gitignore b/spice-video-dummy/.gitignore new file mode 100644 index 0000000..9b4b11f --- /dev/null +++ b/spice-video-dummy/.gitignore @@ -0,0 +1,9 @@ +config.h +config.h.in +libtool +ltmain.sh +stamp-h1 +src/.libs +*.o +*.lo +*.la diff --git a/spice-video-dummy/README.md b/spice-video-dummy/README.md index 2a84bc3..3e77e4d 100644 --- a/spice-video-dummy/README.md +++ b/spice-video-dummy/README.md @@ -1,18 +1,15 @@ -xf86-video-dummy - virtual/offscreen frame buffer driver for the Xorg X server +spice-video-dummy - virtual/offscreen frame buffer driver for the Xorg X server ------------------------------------------------------------------------------ All questions regarding this software should be directed at the -Xorg mailing list: +spice-devel mailing list: - https://lists.x.org/mailman/listinfo/xorg + https://lists.freedesktop.org/mailman/listinfo/spice-devel -The master development code repository can be found at: +This driver originated with the dummy driver from: https://gitlab.freedesktop.org/xorg/driver/xf86-video-dummy -Please submit bug reports and requests to merge patches there. - -For patch submission instructions, see: - - https://www.x.org/wiki/Development/Documentation/SubmittingPatches +and modified to be similar to the mode setting driver: + https://gitlab.freedesktop.org/xorg/xserver/tree/master/hw/xfree86/drivers/modesetting diff --git a/spice-video-dummy/configure.ac b/spice-video-dummy/configure.ac index 2ca0327..e85b7e5 100644 --- a/spice-video-dummy/configure.ac +++ b/spice-video-dummy/configure.ac @@ -22,10 +22,10 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([xf86-video-dummy], - [0.3.8], - [https://gitlab.freedesktop.org/xorg/driver/xf86-video-dummy/issues], - [xf86-video-dummy]) +AC_INIT([spice-video-dummy], + [1.1], + [https://gitlab.freedesktop.org/spice/x11spice/issues], + [spice-video-dummy]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR(.) @@ -61,10 +61,6 @@ PKG_CHECK_MODULES(XORG, [xorg-server >= 1.4.99.901] xproto fontsproto $REQUIRED_ # Checks for libraries. - -DRIVER_NAME=dummy -AC_SUBST([DRIVER_NAME]) - AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/spice-video-dummy/spicedummy.conf b/spice-video-dummy/spicedummy.conf new file mode 100644 index 0000000..950dd6f --- /dev/null +++ b/spice-video-dummy/spicedummy.conf @@ -0,0 +1,18 @@ +Section "Device" + Identifier "SpiceDummy" + Driver "spicedummy" + # The SWcursor option enables a software cursor. Default false. + #Option "SWcursor" "false" + # AccelMethod can be glamor (the default), or none. + #Option "AccelMethod" "glamor" + # kmsdev specifies which framebuffer device to use, default /dev/dri/renderD128 + #Option "kmsdev" "/dev/dri/renderD128" + VideoRam 16384 +EndSection + +Section "Screen" + IDentifier "SpiceDummy" + SubSection "Display" + Virtual 1920 1200 + EndSubSection +EndSection diff --git a/spice-video-dummy/src/Makefile.am b/spice-video-dummy/src/Makefile.am index c0d82e0..3c03409 100644 --- a/spice-video-dummy/src/Makefile.am +++ b/spice-video-dummy/src/Makefile.am @@ -27,13 +27,15 @@ AM_CFLAGS = $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) -dummy_drv_la_LTLIBRARIES = dummy_drv.la -dummy_drv_la_LDFLAGS = -module -avoid-version -dummy_drv_la_LIBADD = $(XORG_LIBS) -dummy_drv_ladir = @moduledir@/drivers +spicedummy_drv_la_LTLIBRARIES = spicedummy_drv.la +spicedummy_drv_la_LDFLAGS = -module -avoid-version +spicedummy_drv_la_LIBADD = $(XORG_LIBS) +spicedummy_drv_ladir = @moduledir@/drivers -dummy_drv_la_SOURCES = \ +spicedummy_drv_la_SOURCES = \ compat-api.h \ + dri2.c \ dummy_cursor.c \ - dummy_driver.c \ - dummy.h + spicedummy_driver.c \ + spicedummy.h \ + present.c diff --git a/spice-video-dummy/src/dri2.c b/spice-video-dummy/src/dri2.c new file mode 100644 index 0000000..13b3200 --- /dev/null +++ b/spice-video-dummy/src/dri2.c @@ -0,0 +1,288 @@ +/* + * Copyright 2019 Henri Verbeet + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "spicedummy.h" +#include "dri2.h" +#include "xf86drm.h" + +struct dummy_dri2_buffer_private { + PixmapRec *pixmap; +}; + +static PixmapRec *dummy_get_drawable_pixmap(DrawableRec * drawable) +{ + const ScreenRec *screen = drawable->pScreen; + + if (drawable->type == DRAWABLE_PIXMAP) + return (PixmapRec *) drawable; + else + return screen->GetWindowPixmap((WindowRec *) drawable); +} + +static DRI2Buffer2Rec *dummy_dri2_create_buffer2(ScreenRec * screen, + DrawableRec * drawable, unsigned int attachment, + unsigned int format) +{ + const ScrnInfoRec *scrn = xf86ScreenToScrn(screen); + struct dummy_dri2_buffer_private *private; + DRI2Buffer2Rec *buffer; + PixmapRec *pixmap; + CARD16 pitch; + CARD32 size; + + if (!(buffer = calloc(1, sizeof(*buffer)))) + return NULL; + + if (!(private = calloc(1, sizeof(*private)))) { + free(buffer); + return NULL; + } + + pixmap = NULL; + if (attachment == DRI2BufferFrontLeft) { + pixmap = dummy_get_drawable_pixmap(drawable); + if (pixmap && pixmap->drawable.pScreen != screen) + pixmap = NULL; + if (pixmap) + ++pixmap->refcnt; + } + + if (!pixmap) { + switch (attachment) { + case DRI2BufferAccum: + case DRI2BufferBackLeft: + case DRI2BufferBackRight: + case DRI2BufferFakeFrontLeft: + case DRI2BufferFakeFrontRight: + case DRI2BufferFrontLeft: + case DRI2BufferFrontRight: + break; + + case DRI2BufferStencil: + case DRI2BufferDepth: + case DRI2BufferDepthStencil: + case DRI2BufferHiz: + default: + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Request for DRI2 buffer attachment %#x unsupported.\n", attachment); + free(private); + free(buffer); + return NULL; + } + + if (!(pixmap = screen->CreatePixmap(screen, drawable->width, + drawable->height, format ? format : drawable->depth, + 0))) { + free(private); + free(buffer); + return NULL; + } + } + + buffer->attachment = attachment; + buffer->cpp = pixmap->drawable.bitsPerPixel / 8; + buffer->format = format; + buffer->flags = 0; + + buffer->name = glamor_name_from_pixmap(pixmap, &pitch, &size); + buffer->pitch = pitch; + if (buffer->name == -1) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get DRI2 name for pixmap.\n"); + screen->DestroyPixmap(pixmap); + free(private); + free(buffer); + return NULL; + } + + buffer->driverPrivate = private; + private->pixmap = pixmap; + + return buffer; +} + +static DRI2Buffer2Rec *dummy_dri2_create_buffer(DrawableRec * drawable, unsigned int attachment, + unsigned int format) +{ + return dummy_dri2_create_buffer2(drawable->pScreen, drawable, attachment, format); +} + +static void dummy_dri2_destroy_buffer2(ScreenRec * unused, DrawableRec * unused2, + DRI2Buffer2Rec * buffer) +{ + struct dummy_dri2_buffer_private *private; + const ScreenRec *screen; + + if (!buffer) + return; + + if (!(private = buffer->driverPrivate)) { + free(buffer); + return; + } + + screen = private->pixmap->drawable.pScreen; + screen->DestroyPixmap(private->pixmap); + free(private); + free(buffer); +} + +static void dummy_dri2_destroy_buffer(DrawableRec * drawable, DRI2Buffer2Rec * buffer) +{ + dummy_dri2_destroy_buffer2(NULL, drawable, buffer); +} + +static void dummy_dri2_copy_region2(ScreenRec * screen, DrawableRec * drawable, + RegionRec * region, DRI2BufferRec * dst_buffer, + DRI2BufferRec * src_buffer) +{ + const struct dummy_dri2_buffer_private *src_priv = src_buffer->driverPrivate; + const struct dummy_dri2_buffer_private *dst_priv = dst_buffer->driverPrivate; + int off_x = 0, off_y = 0; + Bool translate = FALSE; + DrawableRec *src, *dst; + RegionRec *clip_region; + GC *gc; + + src = (src_buffer->attachment == DRI2BufferFrontLeft) ? drawable : &src_priv->pixmap->drawable; + dst = (dst_buffer->attachment == DRI2BufferFrontLeft) ? drawable : &dst_priv->pixmap->drawable; + + if (dst_buffer->attachment == DRI2BufferFrontLeft && drawable->pScreen != screen) { + if (!(dst = DRI2UpdatePrime(drawable, dst_buffer))) + return; + if (dst != drawable) + translate = TRUE; + } + + if (translate && drawable->type == DRAWABLE_WINDOW) { + const PixmapRec *pixmap = dummy_get_drawable_pixmap(drawable); + off_x = -pixmap->screen_x; + off_y = -pixmap->screen_y; + off_x += drawable->x; + off_y += drawable->y; + } + + if (!(gc = GetScratchGC(dst->depth, screen))) + return; + + clip_region = REGION_CREATE(screen, NULL, 0); + REGION_COPY(screen, clip_region, region); + if (translate) + REGION_TRANSLATE(screen, clip_region, off_x, off_y); + gc->funcs->ChangeClip(gc, CT_REGION, clip_region, 0); + ValidateGC(dst, gc); + + gc->ops->CopyArea(src, dst, gc, 0, 0, drawable->width, drawable->height, off_x, off_y); + + FreeScratchGC(gc); +} + +static void dummy_dri2_copy_region(DrawableRec * drawable, RegionRec * region, + DRI2BufferRec * dst_buffer, DRI2BufferRec * src_buffer) +{ + dummy_dri2_copy_region2(drawable->pScreen, drawable, region, dst_buffer, src_buffer); +} + +static int dummy_dri2_get_msc(DrawableRec * drawable, CARD64 * ust, CARD64 * msc) +{ + struct timespec tv; + + if (clock_gettime(CLOCK_MONOTONIC, &tv)) + *ust = 0; + else + *ust = (uint64_t) tv.tv_sec * 1000000 + tv.tv_nsec / 1000; + *msc = 0; + + return TRUE; +} + +static int dummy_dri2_schedule_wait_msc(ClientRec * client, DrawableRec * drawable, + CARD64 target_msc, CARD64 divisor, CARD64 remainder) +{ + DRI2WaitMSCComplete(client, drawable, target_msc, 0, 0); + + return TRUE; +} + +static int dummy_dri2_schedule_swap(ClientRec * client, DrawableRec * drawable, + DRI2BufferRec * front, DRI2BufferRec * back, + CARD64 * target_msc, CARD64 divisor, CARD64 remainder, + DRI2SwapEventPtr func, void *data) +{ + RegionRec region; + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = drawable->width; + box.y2 = drawable->height; + RegionInit(®ion, &box, 0); + + dummy_dri2_copy_region(drawable, ®ion, front, back); + DRI2SwapComplete(client, drawable, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); + *target_msc = 0; + + return TRUE; +} + +Bool dummy_dri2_screen_init(ScreenRec * screen) +{ + const ScrnInfoRec *scrn = xf86ScreenToScrn(screen); + const DUMMYRec *dummy = scrn->driverPrivate; + DRI2InfoRec info; + + if (!glamor_supports_pixmap_import_export(screen)) + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "DRI2: glamor lacks support for pixmap import/export\n"); + + if (!xf86LoaderCheckSymbol("DRI2Version")) + return FALSE; + + memset(&info, 0, sizeof(info)); + info.fd = dummy->fd; + info.driverName = NULL; + info.deviceName = drmGetDeviceNameFromFd2(dummy->fd); + + info.version = 9; + info.CreateBuffer = dummy_dri2_create_buffer; + info.DestroyBuffer = dummy_dri2_destroy_buffer; + info.CopyRegion = dummy_dri2_copy_region; + info.ScheduleSwap = dummy_dri2_schedule_swap; + info.GetMSC = dummy_dri2_get_msc; + info.ScheduleWaitMSC = dummy_dri2_schedule_wait_msc; + info.CreateBuffer2 = dummy_dri2_create_buffer2; + info.DestroyBuffer2 = dummy_dri2_destroy_buffer2; + info.CopyRegion2 = dummy_dri2_copy_region2; + + info.numDrivers = 0; + info.driverNames = NULL; + + return DRI2ScreenInit(screen, &info); +} + +void dummy_dri2_close_screen(ScreenRec * screen) +{ + DRI2CloseScreen(screen); +} diff --git a/spice-video-dummy/src/dummy_cursor.c b/spice-video-dummy/src/dummy_cursor.c index ccce442..5c680cb 100644 --- a/spice-video-dummy/src/dummy_cursor.c +++ b/spice-video-dummy/src/dummy_cursor.c @@ -9,7 +9,7 @@ #include "xf86Cursor.h" #include "cursorstr.h" /* Driver specific headers */ -#include "dummy.h" +#include "spicedummy.h" static void dummyShowCursor(ScrnInfoPtr pScrn) { diff --git a/spice-video-dummy/src/present.c b/spice-video-dummy/src/present.c new file mode 100644 index 0000000..33ac710 --- /dev/null +++ b/spice-video-dummy/src/present.c @@ -0,0 +1,104 @@ +/* + * Copyright 2019 Henri Verbeet + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "spicedummy.h" +#include "present.h" + +static RRCrtcRec *dummy_present_get_crtc(WindowRec * window) +{ + return NULL; +} + +static uint64_t dummy_gettime_us(void) +{ + struct timespec tv; + + if (clock_gettime(CLOCK_MONOTONIC, &tv)) + return 0; + + return (uint64_t) tv.tv_sec * 1000000 + tv.tv_nsec / 1000; +} + +static int dummy_present_get_ust_msc(RRCrtcRec * crtc, CARD64 * ust, CARD64 * msc) +{ + *ust = dummy_gettime_us(); + *msc = 0; + + return Success; +} + +static int dummy_present_queue_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t msc) +{ + present_event_notify(event_id, dummy_gettime_us(), msc); + + return Success; +} + +static void dummy_present_abort_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t msc) +{ +} + +static void dummy_present_flush(WindowRec * window) +{ + glamor_block_handler(window->drawable.pScreen); +} + +static Bool dummy_present_check_flip(RRCrtcRec * crtc, WindowRec * window, PixmapRec * pixmap, + Bool sync_flip) +{ + return FALSE; +} + +static Bool dummy_present_flip(RRCrtcRec * crtc, uint64_t event_id, + uint64_t target_msc, PixmapRec * pixmap, Bool sync_flip) +{ + return FALSE; +} + +static void dummy_present_unflip(ScreenRec * screen, uint64_t event_id) +{ + present_event_notify(event_id, 0, 0); +} + +Bool dummy_present_screen_init(ScreenRec * screen) +{ + static struct present_screen_info present_screen_info = { + .version = PRESENT_SCREEN_INFO_VERSION, + + .get_crtc = dummy_present_get_crtc, + .get_ust_msc = dummy_present_get_ust_msc, + .queue_vblank = dummy_present_queue_vblank, + .abort_vblank = dummy_present_abort_vblank, + .flush = dummy_present_flush, + + .capabilities = PresentCapabilityNone, + .check_flip = dummy_present_check_flip, + .flip = dummy_present_flip, + .unflip = dummy_present_unflip, + }; + + return present_screen_init(screen, &present_screen_info); +} diff --git a/spice-video-dummy/src/dummy.h b/spice-video-dummy/src/spicedummy.h similarity index 83% rename from spice-video-dummy/src/dummy.h rename to spice-video-dummy/src/spicedummy.h index 0c16591..ab4d2a1 100644 --- a/spice-video-dummy/src/dummy.h +++ b/spice-video-dummy/src/spicedummy.h @@ -13,6 +13,9 @@ #include "compat-api.h" +#define GLAMOR_FOR_XORG 1 +#include "glamor.h" + /* Supported chipsets */ typedef enum { DUMMY_CHIP @@ -28,6 +31,10 @@ extern Bool DUMMYCursorInit(ScreenPtr pScrn); extern void DUMMYShowCursor(ScrnInfoPtr pScrn); extern void DUMMYHideCursor(ScrnInfoPtr pScrn); +void dummy_dri2_close_screen(ScreenRec * screen); +Bool dummy_dri2_screen_init(ScreenRec * screen); +Bool dummy_present_screen_init(ScreenRec * screen); + /* globals */ typedef struct _color { int red; @@ -50,6 +57,9 @@ typedef struct dummyRec { dummy_colors colors[1024]; Bool(*CreateWindow) (); /* wrapped CreateWindow */ Bool prop; + + Bool glamor; + int fd; } DUMMYRec, *DUMMYPtr; /* The privates of the DUMMY driver */ diff --git a/spice-video-dummy/src/dummy_driver.c b/spice-video-dummy/src/spicedummy_driver.c similarity index 88% rename from spice-video-dummy/src/dummy_driver.c rename to spice-video-dummy/src/spicedummy_driver.c index 0696151..cad0619 100644 --- a/spice-video-dummy/src/dummy_driver.c +++ b/spice-video-dummy/src/spicedummy_driver.c @@ -32,7 +32,9 @@ /* * Driver data structures. */ -#include "dummy.h" +#include "spicedummy.h" +#include <fcntl.h> +#include <errno.h> /* These need to be checked */ #include <X11/X.h> @@ -62,8 +64,8 @@ static Bool dummyDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) /* int PowerManagementMode, int flags); */ #define DUMMY_VERSION 4000 -#define DUMMY_NAME "DUMMY" -#define DUMMY_DRIVER_NAME "dummy" +#define DUMMY_NAME "SPICEDUMMY" +#define DUMMY_DRIVER_NAME "spicedummy" #define DUMMY_MAJOR_VERSION PACKAGE_VERSION_MAJOR #define DUMMY_MINOR_VERSION PACKAGE_VERSION_MINOR @@ -99,16 +101,20 @@ _X_EXPORT DriverRec DUMMY = { }; static SymTabRec DUMMYChipsets[] = { - {DUMMY_CHIP, "dummy"}, + {DUMMY_CHIP, "spicedummy"}, {-1, NULL} }; typedef enum { - OPTION_SW_CURSOR + OPTION_SW_CURSOR, + OPTION_DEVICE_PATH, + OPTION_ACCEL_METHOD, } DUMMYOpts; static const OptionInfoRec DUMMYOptions[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE}, + {OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -117,7 +123,7 @@ static const OptionInfoRec DUMMYOptions[] = { static MODULESETUPPROTO(dummySetup); static XF86ModuleVersionInfo dummyVersRec = { - "dummy", + "spicedummy", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, @@ -133,7 +139,7 @@ static XF86ModuleVersionInfo dummyVersRec = { * This is the module init data. * Its name has to be the driver name followed by ModuleData */ -_X_EXPORT XF86ModuleData dummyModuleData = { &dummyVersRec, dummySetup, NULL }; +_X_EXPORT XF86ModuleData spicedummyModuleData = { &dummyVersRec, dummySetup, NULL }; static pointer dummySetup(pointer module, pointer opts, int *errmaj, int *errmin) { @@ -196,7 +202,7 @@ static const OptionInfoRec *DUMMYAvailableOptions(int chipid, int busid) /* Mandatory */ static void DUMMYIdentify(int flags) { - xf86PrintChipsets(DUMMY_NAME, "Driver for Dummy chipsets", DUMMYChipsets); + xf86PrintChipsets(DUMMY_NAME, "Spice Driver for Dummy chipsets", DUMMYChipsets); } /* Mandatory */ @@ -250,6 +256,46 @@ static Bool DUMMYProbe(DriverPtr drv, int flags) return foundScreen; } +static int dummy_open_render_node(const ScrnInfoRec * scrn) +{ + const DUMMYRec *dummy = scrn->driverPrivate; + const char *device_path; + int fd; + + if (!(device_path = xf86GetOptValString(dummy->Options, OPTION_DEVICE_PATH))) + device_path = "/dev/dri/renderD128"; + if ((fd = open(device_path, O_RDWR, 0)) == -1) + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "open %s: %s\n", device_path, strerror(errno)); + + return fd; +} + +static Bool dummy_enable_glamor(ScrnInfoRec * scrn) +{ + const DUMMYRec *dummy = scrn->driverPrivate; + const char *accel_method; + + if ((accel_method = xf86GetOptValString(dummy->Options, OPTION_ACCEL_METHOD)) + && strcmp(accel_method, "glamor")) { + xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Glamor disabled.\n"); + return FALSE; + } + + if (!xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to load glamor module.\n"); + return FALSE; + } + + if (!glamor_egl_init(scrn, dummy->fd)) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Glamor initialisation failed.\n"); + return FALSE; + } + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Glamor initialised.\n"); + + return TRUE; +} + #define RETURN \ { DUMMYFreeRec(pScrn);\ return FALSE;\ @@ -343,6 +389,9 @@ Bool DUMMYPreInit(ScrnInfoPtr pScrn, int flags) xf86GetOptValBool(dPtr->Options, OPTION_SW_CURSOR, &dPtr->swCursor); + dPtr->fd = dummy_open_render_node(pScrn); + dPtr->glamor = dummy_enable_glamor(pScrn); + if (device->videoRam != 0) { pScrn->videoRam = device->videoRam; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", pScrn->videoRam); @@ -540,6 +589,12 @@ static Bool DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) /* must be after RGB ordering fixed */ fbPictureInit(pScreen, 0, 0); + if (dPtr->glamor && !glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialise glamor at ScreenInit() time.\n"); + return FALSE; + } + xf86SetBlackWhitePixels(pScreen); if (dPtr->swCursor) @@ -595,6 +650,14 @@ static Bool DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) dPtr->CreateWindow = pScreen->CreateWindow; pScreen->CreateWindow = DUMMYCreateWindow; + if (dPtr->glamor) { + if (!dummy_dri2_screen_init(pScreen)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialise the DRI2 extension.\n"); + + if (!dummy_present_screen_init(pScreen)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialise the Present extension.\n"); + } + /* Report any unused options (only for the first generation) */ if (serverGeneration == 1) { xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -620,6 +683,9 @@ static Bool DUMMYCloseScreen(CLOSE_SCREEN_ARGS_DECL) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); DUMMYPtr dPtr = DUMMYPTR(pScrn); + if (dPtr->glamor) + dummy_dri2_close_screen(pScreen); + free(pScreen->GetScreenPixmap(pScreen)->devPrivate.ptr); if (dPtr->CursorInfo) -- 2.11.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel