summaryrefslogtreecommitdiff
path: root/randr
diff options
context:
space:
mode:
authoragoins <agoins@nvidia.com>2016-06-16 20:06:48 -0700
committerAdam Jackson <ajax@redhat.com>2016-07-05 14:30:27 -0400
commitdf8e86931eb19c196ed2afc85d89525ef8cb711b (patch)
tree7c5a64d20fad06816218f10d747ad1a9cc99dfd3 /randr
parent60ad701a6a8cb9f1eacb72acfe2cb8d3b7a865dc (diff)
randr: Add ability to turn PRIME sync off
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, xrandr will trigger a modeset, which will 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 rrGetPixmapSharingSyncProp() to query the status of the output property. Add function rrSetPixmapSharingSyncProp() to set 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(). v1: Initial commit v2: Unchanged v3: Add /* TODO */ for handling different sources with different outputs Make rrSetupPixmapSharing() set the output property to 0 if it has to fall back, to avoid user confusion. Make rr(Get)PixmapSharingSyncProp() check the current value if there isn't a pending value v4: Unchanged v5: Unchanged v6: Rebase onto ToT v7: Unchanged Signed-off-by: Alex Goins <agoins@nvidia.com>
Diffstat (limited to 'randr')
-rw-r--r--randr/randrstr.h1
-rw-r--r--randr/rrcrtc.c70
-rw-r--r--randr/rrprovider.c57
3 files changed, 124 insertions, 4 deletions
diff --git a/randr/randrstr.h b/randr/randrstr.h
index ada1348d2..1baa91226 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -935,6 +935,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 089fc1a79..8fb2bca8a 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -25,6 +25,8 @@
#include "swaprep.h"
#include "mipointer.h"
+#include <X11/Xatom.h>
+
RESTYPE RRCrtcType;
/*
@@ -432,8 +434,59 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
}
static Bool
+rrGetPixmapSharingSyncProp(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;
+
+ /* If one output doesn't want sync, no sync */
+ for (o = 0; o < numOutputs; o++) {
+ RRPropertyValuePtr val;
+
+ /* Try pending value first, then current value */
+ if ((val = RRGetOutputProperty(outputs[o], syncProp, TRUE)) &&
+ val->data) {
+ if (!(*(char *) val->data))
+ return FALSE;
+ continue;
+ }
+
+ if ((val = RRGetOutputProperty(outputs[o], syncProp, FALSE)) &&
+ val->data) {
+ if (!(*(char *) val->data))
+ return FALSE;
+ continue;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+rrSetPixmapSharingSyncProp(char val, int numOutputs, RROutputPtr * outputs)
+{
+ int o;
+ const char *syncStr = PRIME_SYNC_PROP;
+ Atom syncProp = MakeAtom(syncStr, strlen(syncStr), FALSE);
+ if (syncProp == None)
+ return;
+
+ for (o = 0; o < numOutputs; o++) {
+ RRPropertyPtr prop = RRQueryOutputProperty(outputs[o], syncProp);
+ if (prop)
+ RRChangeOutputProperty(outputs[o], syncProp, XA_INTEGER,
+ 8, PropModeReplace, 1, &val, FALSE, TRUE);
+ }
+}
+
+static Bool
rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
- int x, int y, Rotation rotation)
+ int x, int y, Rotation rotation, Bool sync,
+ int numOutputs, RROutputPtr * outputs)
{
ScreenPtr master = crtc->pScreen->current_master;
rrScrPrivPtr pMasterScrPriv = rrGetScrPriv(master);
@@ -480,7 +533,8 @@ rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
}
/* Both source and sink must support required ABI funcs for flipping */
- if (pSlaveScrPriv->rrEnableSharedPixmapFlipping &&
+ if (sync &&
+ pSlaveScrPriv->rrEnableSharedPixmapFlipping &&
pSlaveScrPriv->rrDisableSharedPixmapFlipping &&
pMasterScrPriv->rrStartFlippingPixmapTracking &&
master->PresentSharedPixmap &&
@@ -520,7 +574,12 @@ fail: /* If flipping funcs fail, just fall back to unsynchronized */
crtc->scanout_pixmap_back = NULL;
}
- 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");
+
+ /* Set output property to 0 to indicate to user */
+ rrSetPixmapSharingSyncProp(0, numOutputs, outputs);
+ }
if (!pSlaveScrPriv->rrCrtcSetScanoutPixmap(crtc, spix_front)) {
rrDestroySharedPixmap(crtc, spix_front);
@@ -692,7 +751,10 @@ RRCrtcSet(RRCrtcPtr crtc,
return FALSE;
if (pScreen->current_master) {
- ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
+ Bool sync = rrGetPixmapSharingSyncProp(numOutputs, outputs);
+ ret = rrSetupPixmapSharing(crtc, width, height,
+ x, y, rotation, sync,
+ numOutputs, outputs);
}
}
#if RANDR_12_INTERFACE
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index 8ef47260c..f9df67e0b 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;
/*
@@ -259,6 +261,58 @@ ProcRRGetProviderInfo (ClientPtr client)
return Success;
}
+static void
+RRInitPrimeSyncProps(ScreenPtr pScreen)
+{
+ /*
+ * TODO: When adding support for different sources for different outputs,
+ * make sure this sets up the output properties only on outputs associated
+ * with the correct source provider.
+ */
+
+ 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)
+{
+ /*
+ * TODO: When adding support for different sources for different outputs,
+ * make sure this tears down the output properties only on outputs
+ * associated with the correct source provider.
+ */
+
+ 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)
{
@@ -286,6 +340,8 @@ ProcRRSetProviderOutputSource(ClientPtr client)
pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
+ RRInitPrimeSyncProps(pScreen);
+
provider->changed = TRUE;
RRSetChanged(pScreen);
@@ -361,6 +417,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name,
void
RRProviderDestroy (RRProviderPtr provider)
{
+ RRFiniPrimeSyncProps(provider->pScreen);
FreeResource (provider->id, 0);
}