[Spice-devel] [x11spice 3/4] Initial set of revisions to the dummy driver to add DRI and Present.

Jeremy White jwhite at codeweavers.com
Fri Apr 12 14:35:33 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>
---
 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                       | 291 +++++++++++++++++++++
 spice-video-dummy/src/dummy.h                      |  11 +-
 spice-video-dummy/src/present.c                    | 104 ++++++++
 .../src/{dummy_driver.c => spicedummy_driver.c}    |  88 ++++++-
 9 files changed, 530 insertions(+), 34 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} (86%)

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..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..0994b1e
--- /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)
+{
+    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(&region, &box, 0);
+
+    dummy_dri2_copy_region(drawable, &region, 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 09cd917..b0a8a9a 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
 {
@@ -52,8 +59,10 @@ 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))
-
diff --git a/spice-video-dummy/src/present.c b/spice-video-dummy/src/present.c
new file mode 100644
index 0000000..44bab1f
--- /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 "dummy.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_driver.c b/spice-video-dummy/src/spicedummy_driver.c
similarity index 86%
rename from spice-video-dummy/src/dummy_driver.c
rename to spice-video-dummy/src/spicedummy_driver.c
index 9e29fe7..cdb3bfa 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>
@@ -64,8 +66,8 @@ static Bool	dummyDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
 /* 				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
@@ -101,17 +103,21 @@ _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 },
-    { -1,                  NULL,           OPTV_NONE,	{0}, FALSE }
+    { 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 }
 };
 
 #ifdef XFree86LOADER
@@ -120,7 +126,7 @@ static MODULESETUPPROTO(dummySetup);
 
 static XF86ModuleVersionInfo dummyVersRec =
 {
-	"dummy",
+	"spicedummy",
 	MODULEVENDORSTRING,
 	MODINFOSTRING1,
 	MODINFOSTRING2,
@@ -136,7 +142,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)
@@ -202,7 +208,7 @@ DUMMYAvailableOptions(int chipid, int busid)
 static void
 DUMMYIdentify(int flags)
 {
-    xf86PrintChipsets(DUMMY_NAME, "Driver for Dummy chipsets",
+    xf86PrintChipsets(DUMMY_NAME, "Spice Driver for Dummy chipsets",
 			DUMMYChipsets);
 }
 
@@ -260,6 +266,49 @@ 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;\
@@ -355,6 +404,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",
@@ -562,6 +614,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)
@@ -621,6 +679,15 @@ 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);
@@ -649,6 +716,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