[Spice-devel] Experimental patch to enable Deferred FPS mode for the qemu qxl driver.

Jeremy White jwhite at codeweavers.com
Mon Jan 28 12:46:49 PST 2013


When I decided to try to understand what was going on with Gnome
fallback, I hacked the Deferred FPS mode into working with a qemu
system.

This is not quite ready for prime time, but should make for
interesting testing.

My rather biased sense is that it's an improvement over the normal mode.

Cheers,

Jeremy


---
 configure.ac      |   15 ++++++---------
 src/Makefile.am   |    2 ++
 src/dfps.c        |   40 +++++++++++++++++++++++++++++++++++++++-
 src/dfps.h        |    1 +
 src/qxl.h         |   11 +++++------
 src/qxl_driver.c  |   31 ++++++++++---------------------
 src/qxl_surface.c |    5 ++++-
 7 files changed, 67 insertions(+), 38 deletions(-)

diff --git a/configure.ac b/configure.ac
index 48904a2..1aba1c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,16 +92,13 @@ AC_ARG_ENABLE(xspice,
    fi
 ])
 
-if test "x$enable_xspice" = "xyes"; then
-    PKG_CHECK_MODULES([SPICE], [spice-server >= 0.6.3],
-    [
-        AC_SUBST(SPICE_CFLAGS)
-        AC_SUBST(SPICE_LIBS)
-    ],
+PKG_CHECK_MODULES([SPICE], [spice-server >= 0.6.3],
+[
+    AC_SUBST(SPICE_CFLAGS)
+    AC_SUBST(SPICE_LIBS)
+],
 )
-else
-    enable_xspice=no
-fi
+
 AM_CONDITIONAL(BUILD_XSPICE, test "x$enable_xspice" = "xyes")
 AM_CONDITIONAL(BUILD_QXL, test "x$enable_qxl" = "xyes")
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 6950ba5..08674b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,7 @@ AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNF
 if BUILD_QXL
 qxl_drv_la_LTLIBRARIES = qxl_drv.la
 qxl_drv_la_LDFLAGS = -module -avoid-version
+qxl_drv_la_CFLAGS = $(AM_CFLAGS) $(SPICE_CFLAGS)
 qxl_drv_ladir = @moduledir@/drivers
 
 qxl_drv_la_LIBADD = uxa/libuxa.la
@@ -51,6 +52,7 @@ qxl_drv_la_SOURCES =				\
 	qxl_option_helpers.c		\
 	qxl_option_helpers.h		\
 	qxl_edid.c			\
+	dfps.c				        \
 	compat-api.h
 endif
 
diff --git a/src/dfps.c b/src/dfps.c
index e5a2273..5fd6964 100644
--- a/src/dfps.c
+++ b/src/dfps.c
@@ -53,6 +53,44 @@ struct dfps_info_t
     GCPtr       pgc;
 };
 
+typedef struct SpiceTimer {
+    OsTimerPtr xorg_timer;
+    SpiceTimerFunc func;
+    void *opaque; // also stored in xorg_timer, but needed for timer_start
+} Timer;
+
+static CARD32 xorg_timer_callback(
+    OsTimerPtr xorg_timer,
+    CARD32 time,
+    pointer arg)
+{
+    SpiceTimer *timer = (SpiceTimer*)arg;
+
+    timer->func(timer->opaque);
+    return 0; // if non zero xorg does a TimerSet, we don't want that.
+}
+
+static SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque)
+{
+    SpiceTimer *timer = calloc(sizeof(SpiceTimer), 1);
+
+    timer->xorg_timer = TimerSet(NULL, 0, 1e9 /* TODO: infinity? */, xorg_timer_callback, timer);
+    timer->func = func;
+    timer->opaque = opaque;
+    return timer;
+}
+
+static void timer_start(SpiceTimer *timer, uint32_t ms)
+{
+    TimerSet(timer->xorg_timer, 0 /* flags */, ms, xorg_timer_callback, timer);
+}
+
+void dfps_start_ticker(qxl_screen_t *qxl)
+{
+    qxl->frames_timer = timer_add(dfps_ticker, qxl);
+    timer_start(qxl->frames_timer, 1000 / qxl->deferred_fps);
+}
+
 void dfps_ticker(void *opaque)
 {
     qxl_screen_t *qxl = (qxl_screen_t *) opaque;
@@ -68,7 +106,7 @@ void dfps_ticker(void *opaque)
         RegionUninit(&info->updated_region);
         RegionInit(&info->updated_region, NULL, 0);
     }
-    qxl->core->timer_start(qxl->frames_timer, 1000 / qxl->deferred_fps);
+    timer_start(qxl->frames_timer, 1000 / qxl->deferred_fps);
 }
 
 
diff --git a/src/dfps.h b/src/dfps.h
index ea38a46..3f3336a 100644
--- a/src/dfps.h
+++ b/src/dfps.h
@@ -24,6 +24,7 @@
 
 typedef struct dfps_info_t dfps_info_t;
 
+void dfps_start_ticker(qxl_screen_t *qxl);
 void dfps_ticker(void *opaque);
 void dfps_set_uxa_functions(qxl_screen_t *qxl, ScreenPtr screen);
 
diff --git a/src/qxl.h b/src/qxl.h
index 8e2802a..c301e0a 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -26,9 +26,7 @@
 #include <stdint.h>
 
 #include <spice/qxl_dev.h>
-#ifdef XSPICE
 #include <spice.h>
-#endif
 
 #include "compiler.h"
 #include "xf86.h"
@@ -104,6 +102,7 @@ enum {
     OPTION_ENABLE_FALLBACK_CACHE,
     OPTION_ENABLE_SURFACES,
     OPTION_NUM_HEADS,
+    OPTION_SPICE_DEFERRED_FPS,
 #ifdef XSPICE
     OPTION_SPICE_PORT,
     OPTION_SPICE_TLS_PORT,
@@ -127,7 +126,6 @@ enum {
     OPTION_SPICE_TLS_CIPHERS,
     OPTION_SPICE_CACERT_FILE,
     OPTION_SPICE_DH_FILE,
-    OPTION_SPICE_DEFERRED_FPS,
     OPTION_SPICE_EXIT_ON_DISCONNECT,
 #endif
     OPTION_COUNT,
@@ -237,12 +235,13 @@ struct _qxl_screen_t
     int				enable_fallback_cache;
     int				enable_surfaces;
     
+    SpiceCoreInterface *core;
+    SpiceTimer *        frames_timer;
+
 #ifdef XSPICE
     /* XSpice specific */
     struct QXLRom		shadow_rom;    /* Parameter RAM */
     SpiceServer *       spice_server;
-    SpiceCoreInterface *core;
-    SpiceTimer *        frames_timer;
 
     QXLWorker *         worker;
     int                 worker_running;
@@ -266,8 +265,8 @@ struct _qxl_screen_t
         uint8_t        *data, *flipped;
     } guest_primary;
 
-    uint32_t           deferred_fps;
 #endif /* XSPICE */
+    uint32_t           deferred_fps;
 };
 
 typedef struct qxl_output_private {
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index e1893dc..e951ccc 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -44,20 +44,19 @@
 
 #include "mspace.h"
 
+#include <spice.h>
 #include "qxl.h"
 #include "assert.h"
 #include "qxl_option_helpers.h"
 #include <spice/protocol.h>
 
-#ifdef XSPICE
 #include "spiceqxl_driver.h"
+#include "spiceqxl_spice_server.h"
 #include "spiceqxl_main_loop.h"
 #include "spiceqxl_display.h"
 #include "spiceqxl_inputs.h"
 #include "spiceqxl_io_port.h"
-#include "spiceqxl_spice_server.h"
 #include "dfps.h"
-#endif /* XSPICE */
 
 extern void compat_init_scrn (ScrnInfoPtr);
 
@@ -79,6 +78,8 @@ const OptionInfoRec DefaultOptions[] =
       "EnableSurfaces",           OPTV_BOOLEAN, { 0 }, TRUE },
     { OPTION_NUM_HEADS,
       "NumHeads",                 OPTV_INTEGER, { 4 }, FALSE },
+    { OPTION_SPICE_DEFERRED_FPS,
+      "SpiceDeferredFPS",         OPTV_INTEGER, { 15 }, FALSE},
 #ifdef XSPICE
     { OPTION_SPICE_PORT,
       "SpicePort",                OPTV_INTEGER,   {5900}, FALSE },
@@ -125,8 +126,6 @@ const OptionInfoRec DefaultOptions[] =
       "SpiceCacertFile",          OPTV_STRING,    {0}, FALSE},
     { OPTION_SPICE_DH_FILE,
       "SpiceDhFile",              OPTV_STRING,    {0}, FALSE},
-    { OPTION_SPICE_DEFERRED_FPS,
-      "SpiceDeferredFPS",         OPTV_INTEGER,   {0}, FALSE},
     { OPTION_SPICE_EXIT_ON_DISCONNECT,
       "SpiceExitOnDisconnect",    OPTV_BOOLEAN,   {0}, FALSE},
 #endif
@@ -988,9 +987,7 @@ qxl_resize_primary_to_virtual (qxl_screen_t *qxl)
     {
 	PixmapPtr root = pScreen->GetScreenPixmap (pScreen);
 
-#ifdef XSPICE
         if (qxl->deferred_fps <= 0)
-#endif
         {
             qxl_surface_t *surf;
 
@@ -1203,9 +1200,7 @@ qxl_create_screen_resources (ScreenPtr pScreen)
     
     pPixmap = pScreen->GetScreenPixmap (pScreen);
 
-#ifdef XSPICE
     if (qxl->deferred_fps <= 0)
-#endif
     {
         set_screen_pixmap_header (pScreen);
 
@@ -1680,11 +1675,9 @@ setup_uxa (qxl_screen_t *qxl, ScreenPtr screen)
     qxl->uxa->uxa_major = 1;
     qxl->uxa->uxa_minor = 0;
 
-#ifdef XSPICE
     if (qxl->deferred_fps)
         dfps_set_uxa_functions(qxl, screen);
     else
-#endif
         set_uxa_functions(qxl, screen);
 
     if (!uxa_driver_init (screen, qxl->uxa))
@@ -1722,11 +1715,6 @@ spiceqxl_screen_init (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
 	qxl_add_spice_display_interface (qxl);
 	qxl->worker->start (qxl->worker);
 	qxl->worker_running = TRUE;
-        if (qxl->deferred_fps)
-        {
-            qxl->frames_timer = qxl->core->timer_add(dfps_ticker, qxl);
-            qxl->core->timer_start(qxl->frames_timer, 1000 / qxl->deferred_fps);
-        }
     }
     qxl->spice_server = qxl->spice_server;
 }
@@ -1757,7 +1745,7 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
     VisualPtr      visual;
     
     CHECK_POINT ();
-    
+
     assert (qxl->pScrn == pScrn);
     
     if (!qxl_map_memory (qxl, pScrn->scrnIndex))
@@ -1888,6 +1876,11 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
     /* bounds" */
     xf86RandR12SetTransformSupport (pScreen, TRUE);
     
+    if (qxl->deferred_fps)
+    {
+        dfps_start_ticker(qxl);
+    }
+
     return TRUE;
     
 out:
@@ -1940,9 +1933,7 @@ qxl_leave_vt (VT_FUNC_ARGS_DECL)
 
     pScrn->EnableDisableFBAccess (XF86_SCRN_ARG (pScrn), FALSE);
 
-#ifdef XSPICE
     if (qxl->deferred_fps <= 0)
-#endif
         qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
 
     ioport_write (qxl, QXL_IO_RESET, 0);
@@ -2431,13 +2422,11 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags)
     qxl->num_heads =
         get_int_option (qxl->options, OPTION_NUM_HEADS, "QXL_NUM_HEADS");
     
-#ifdef XSPICE
     qxl->deferred_fps = get_int_option(qxl->options, OPTION_SPICE_DEFERRED_FPS, "XSPICE_DEFERRED_FPS");
     if (qxl->deferred_fps > 0)
         xf86DrvMsg(scrnIndex, X_INFO, "Deferred FPS: %d\n", qxl->deferred_fps);
     else
         xf86DrvMsg(scrnIndex, X_INFO, "Deferred Frames: Disabled\n");
-#endif
 
     xf86DrvMsg (scrnIndex, X_INFO, "Offscreen Surfaces: %s\n",
                 qxl->enable_surfaces ? "Enabled" : "Disabled");
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 3da9079..f6de4d0 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -1137,7 +1137,10 @@ qxl_surface_upload_primary_regions(qxl_screen_t *qxl, PixmapPtr pixmap, RegionRe
 
     while (n_boxes--)
     {
-        upload_one_primary_region(qxl, pixmap, boxes);
+        if (boxes->x2 > boxes->x1 && boxes->y2 > boxes->y1)
+            upload_one_primary_region(qxl, pixmap, boxes);
+        else
+            ErrorF("JPW skipping boxes %d, %d to %d, %d\n", boxes->x1, boxes->y1, boxes->x2, boxes->y2);
         boxes++;
     }
 }
-- 
1.7.10.4




More information about the Spice-devel mailing list