[PATCH 06/11] randr: Add ability to turn PRIME sync off

Alex Goins agoins at nvidia.com
Wed Nov 25 18:39:30 PST 2015


Adds an output parameter to disable PRIME synchronization.

Output parameter is created when the user calls 'xrandr
--setprovideroutputsource <sink> <source>' to prevent polluting output
parameters of non-PRIME configurations.

Defaults to on, so if the user wants PRIME synchronization they don't need
to do anything.

If the user wishes to disable PRIME synchronization when they first set up
PRIME, they can run 'xrandr --output <output> --set "PRIME Synchronization"
0' after running 'xrandr --setprovideroutputsource <sink> <source>', but
before 'xrandr --auto'.

If the user wishes to enable or disable PRIME synchronization after PRIME
has already been set up, they can run 'xrandr --output <output> --set
"PRIME Synchronization" <0 or 1>' at any time, it will trigger a modeset,
tear down and setup PRIME in the configuration they requested on CRTCs
associated with that output.

randrstr.h:
    Add central definition of the output property name.

rrcrtc.c:
    Add function rrPixmapSharingSyncProp() to query the status of the
    output property.

    Add 'sync' parameter to rrSetupPixmapSharing(), which when false will
    use single buffering even if the required ABI functions are supported.
    Changes rrSetupPixmapSharing() to only report an error if falling back
    to single buffering when the user requested synchronization.

    Change RRCrtcSet() to use rrPixmapSharingSyncProp() to query the status
    of the output property and feed it into rrSetupPixmapSharing() using
    the 'sync' parameter.

rrprovider.c:
    Add RR(Init/Fini)PrimeSyncProps(), functions to create and destroy the
    PRIME synchronization output property.

    Add a call to RRInitPrimeSyncProps() in
    ProcRRSetProviderOutputSource(), such that the output property is
    created when the user requests PRIME.

    Add a call to RRFiniPrimeSyncProps() in RRProviderDestroy().

Signed-off-by: Alex Goins <agoins at nvidia.com>
---
 randr/randrstr.h   |  1 +
 randr/rrcrtc.c     | 34 ++++++++++++++++++++++++++++++----
 randr/rrprovider.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/randr/randrstr.h b/randr/randrstr.h
index c6b0627..5128e34 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -918,6 +918,7 @@ extern _X_EXPORT int
  ProcRRDeleteOutputProperty(ClientPtr client);
 
 /* rrprovider.c */
+#define PRIME_SYNC_PROP         "PRIME Synchronization"
 extern _X_EXPORT void
 RRProviderInitErrorValue(void);
 
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index ef8c63e..a6b56f4 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -439,8 +439,30 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
 }
 
 static Bool
+rrPixmapSharingSyncProp(int numOutputs, RROutputPtr * outputs)
+{
+    /* Determine if the user wants prime syncing */
+    int o;
+    const char *syncStr = PRIME_SYNC_PROP;
+    Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE);
+    if (syncProp == None)
+        return TRUE;
+
+    for (o = 0; o < numOutputs; o++) {
+        RRPropertyValuePtr val;
+        if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE))) {
+            /* If one output doesn't want sync, no sync */
+            if(val->data && !(*(char *) val->data))
+                return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static Bool
 rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
-                     int x, int y, Rotation rotation)
+                     int x, int y, Rotation rotation, Bool sync)
 {
     ScreenPtr master = crtc->pScreen->current_master;
     int depth;
@@ -481,7 +503,8 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
     crtc->scanout_pixmap = spix_front;
 
     /* Both source and sink must support required ABI funcs for flipping */
-    if (crtc->pScreen->EnableSharedPixmapFlipping &&
+    if (sync &&
+        crtc->pScreen->EnableSharedPixmapFlipping &&
         crtc->pScreen->DisableSharedPixmapFlipping &&
         master->StartFlippingPixmapTracking &&
         master->PresentTrackedFlippingPixmap &&
@@ -508,7 +531,8 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
     }
 
 nosync:
-    ErrorF("randr: falling back to unsynchronized pixmap sharing\n");
+    if (sync) /* Wanted sync, didn't get it */
+        ErrorF("randr: falling back to unsynchronized pixmap sharing\n");
 
     master->StartPixmapTracking(mscreenpix, spix_front, x, y, 0, 0, rotation);
 
@@ -669,7 +693,9 @@ RRCrtcSet(RRCrtcPtr crtc,
                 return FALSE;
 
             if (pScreen->current_master) {
-                ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
+                Bool sync = rrPixmapSharingSyncProp(numOutputs, outputs);
+                ret = rrSetupPixmapSharing(crtc, width, height,
+                                           x, y, rotation, sync);
             }
         }
 #if RANDR_12_INTERFACE
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index bbb8e51..2ed8c0b 100644
--- a/randr/rrprovider.c
+++ b/randr/rrprovider.c
@@ -25,6 +25,8 @@
 #include "randrstr.h"
 #include "swaprep.h"
 
+#include <X11/Xatom.h>
+
 RESTYPE RRProviderType;
 
 /*
@@ -277,6 +279,46 @@ ProcRRGetProviderInfo (ClientPtr client)
     return Success;
 }
 
+static void
+RRInitPrimeSyncProps(ScreenPtr pScreen)
+{
+    rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
+
+    const char *syncStr = PRIME_SYNC_PROP;
+    Atom syncProp = MakeAtom(syncStr, strlen(syncStr), TRUE);
+
+    int defaultVal = TRUE;
+    int validVals[2] = {FALSE, TRUE};
+
+    int i;
+    for (i = 0; i < pScrPriv->numOutputs; i++) {
+        if (!RRQueryOutputProperty(pScrPriv->outputs[i], syncProp)) {
+            RRConfigureOutputProperty(pScrPriv->outputs[i], syncProp,
+                                      TRUE, FALSE, FALSE,
+                                      2, &validVals[0]);
+            RRChangeOutputProperty(pScrPriv->outputs[i], syncProp, XA_INTEGER,
+                                   8, PropModeReplace, 1, &defaultVal,
+                                   FALSE, FALSE);
+        }
+    }
+}
+
+static void
+RRFiniPrimeSyncProps(ScreenPtr pScreen)
+{
+    rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
+    int i;
+
+    const char *syncStr = PRIME_SYNC_PROP;
+    Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE);
+    if (syncProp == None)
+        return;
+
+    for (i = 0; i < pScrPriv->numOutputs; i++) {
+        RRDeleteOutputProperty(pScrPriv->outputs[i], syncProp);
+    }
+}
+
 int
 ProcRRSetProviderOutputSource(ClientPtr client)
 {
@@ -304,6 +346,8 @@ ProcRRSetProviderOutputSource(ClientPtr client)
 
     pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
 
+    RRInitPrimeSyncProps(pScreen);
+
     provider->changed = TRUE;
     RRSetChanged(pScreen);
 
@@ -377,6 +421,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name,
 void
 RRProviderDestroy (RRProviderPtr provider)
 {
+    RRFiniPrimeSyncProps(provider->pScreen);
     FreeResource (provider->id, 0);
 }
 
-- 
1.9.1



More information about the xorg-devel mailing list