[Spice-devel] [PATCH v3 x11spice 3/5] Initial set of revisions to the dummy driver to add DRI and Present.
Jeremy White
jwhite at codeweavers.com
Thu May 2 22:12:09 UTC 2019
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 at codeweavers.com>
---
v2: Apply Spice style
v3: Refine Spice style, disable console keyboard and mouse in default
xorg.conf, share an inline function to return microseconds,
more visibly disable glamor when the render node is unavailable,
leave dummy.h as dummy.h
---
spice-video-dummy/.gitignore | 9 +
spice-video-dummy/README.md | 15 +-
spice-video-dummy/configure.ac | 12 +-
spice-video-dummy/spicedummy.conf | 30 +++
spice-video-dummy/src/Makefile.am | 16 +-
spice-video-dummy/src/dri2.c | 291 +++++++++++++++++++++
spice-video-dummy/src/dummy.h | 21 ++
spice-video-dummy/src/present.c | 102 ++++++++
.../src/{dummy_driver.c => spicedummy_driver.c} | 84 +++++-
9 files changed, 549 insertions(+), 31 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_driver.c => spicedummy_driver.c} (87%)
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..ad2016c
--- /dev/null
+++ b/spice-video-dummy/spicedummy.conf
@@ -0,0 +1,30 @@
+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 "InputDevice"
+ Identifier "dummy_mouse"
+ Option "CorePointer" "true"
+ Driver "void"
+EndSection
+
+Section "InputDevice"
+ Identifier "dummy_keyboard"
+ Option "CoreKeyboard" "true"
+ Driver "void"
+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..6befa46 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 \
+ dummy.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..759749c
--- /dev/null
+++ b/spice-video-dummy/src/dri2.c
@@ -0,0 +1,291 @@
+/*
+ * 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 "dummy.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)
+{
+ *ust = dummy_gettime_us();
+ *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.h b/spice-video-dummy/src/dummy.h
index 65710ef..d8cac83 100644
--- a/spice-video-dummy/src/dummy.h
+++ b/spice-video-dummy/src/dummy.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,7 +57,21 @@ 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 */
#define DUMMYPTR(p) ((DUMMYPtr)((p)->driverPrivate))
+
+static inline 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;
+}
diff --git a/spice-video-dummy/src/present.c b/spice-video-dummy/src/present.c
new file mode 100644
index 0000000..81fcc5b
--- /dev/null
+++ b/spice-video-dummy/src/present.c
@@ -0,0 +1,102 @@
+/*
+ * 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 "dummy.h"
+#include "present.h"
+
+static RRCrtcRec *
+dummy_present_get_crtc(WindowRec * window)
+{
+ return NULL;
+}
+
+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_driver.c b/spice-video-dummy/src/spicedummy_driver.c
similarity index 87%
rename from spice-video-dummy/src/dummy_driver.c
rename to spice-video-dummy/src/spicedummy_driver.c
index 46cde90..9b38b21 100644
--- a/spice-video-dummy/src/dummy_driver.c
+++ b/spice-video-dummy/src/spicedummy_driver.c
@@ -33,6 +33,8 @@
* Driver data structures.
*/
#include "dummy.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)
@@ -200,7 +206,7 @@ DUMMYAvailableOptions(int chipid, int busid)
static void
DUMMYIdentify(int flags)
{
- xf86PrintChipsets(DUMMY_NAME, "Driver for Dummy chipsets", DUMMYChipsets);
+ xf86PrintChipsets(DUMMY_NAME, "Spice Driver for Dummy chipsets", DUMMYChipsets);
}
/* Mandatory */
@@ -255,6 +261,50 @@ 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));
+ else
+ xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Using %s.\n", device_path);
+
+ 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")) || dummy->fd == -1) {
+ 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;\
@@ -348,6 +398,9 @@ 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);
@@ -546,6 +599,12 @@ 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)
@@ -601,6 +660,14 @@ 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);
@@ -629,6 +696,9 @@ 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
More information about the Spice-devel
mailing list