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

Frediano Ziglio fziglio at redhat.com
Thu May 2 11:44:26 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                       | 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;

This seems a bit duplicated (clock_gettime and computation), maybe
an inline function in an header?
(not strong about).

> +    *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_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 */

weirly indended (not a problem of this patch).

>      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);

Do you want to continue here if fd == -1 ?
I think potentially you would have a crash setting up dri functions.
Maybe also glamor should be disabled if fd == -1 ?

> +    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)

Frediano


More information about the Spice-devel mailing list