summaryrefslogtreecommitdiff
path: root/xserver/randr
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2017-12-08 15:02:03 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2017-12-08 15:02:03 +0000
commite2e6e25be1cbd7ecc45bbd9130c4527f7715e547 (patch)
tree85e40fcfbc819cb0394346c69db478a22e9ed122 /xserver/randr
parent63d0911c1d9f1be4f8755144bced468fcbc398a6 (diff)
Update to xserver 1.19.5.
Tested by bru@, jsg@ and others
Diffstat (limited to 'xserver/randr')
-rw-r--r--xserver/randr/Makefile.in14
-rw-r--r--xserver/randr/randr.c56
-rw-r--r--xserver/randr/randrstr.h25
-rw-r--r--xserver/randr/rrcrtc.c294
-rw-r--r--xserver/randr/rrmonitor.c17
-rw-r--r--xserver/randr/rroutput.c10
-rw-r--r--xserver/randr/rrprovider.c110
-rw-r--r--xserver/randr/rrscreen.c15
-rw-r--r--xserver/randr/rrxinerama.c7
9 files changed, 425 insertions, 123 deletions
diff --git a/xserver/randr/Makefile.in b/xserver/randr/Makefile.in
index 87e6d12ef..222ad36c1 100644
--- a/xserver/randr/Makefile.in
+++ b/xserver/randr/Makefile.in
@@ -57,9 +57,10 @@ DIST_COMMON = $(am__sdk_HEADERS_DIST) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -340,6 +341,9 @@ PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PROJECTROOT = @PROJECTROOT@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
PYTHON3 = @PYTHON3@
RANLIB = @RANLIB@
RAWCPP = @RAWCPP@
@@ -370,7 +374,10 @@ UDEV_LIBS = @UDEV_LIBS@
UTILS_SYS_LIBS = @UTILS_SYS_LIBS@
VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@
VERSION = @VERSION@
+WAYLAND_PROTOCOLS_DATADIR = @WAYLAND_PROTOCOLS_DATADIR@
WAYLAND_SCANNER = @WAYLAND_SCANNER@
+WINDOWSDRI_CFLAGS = @WINDOWSDRI_CFLAGS@
+WINDOWSDRI_LIBS = @WINDOWSDRI_LIBS@
WINDOWSWM_CFLAGS = @WINDOWSWM_CFLAGS@
WINDOWSWM_LIBS = @WINDOWSWM_LIBS@
WINDRES = @WINDRES@
@@ -465,6 +472,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
diff --git a/xserver/randr/randr.c b/xserver/randr/randr.c
index ad1dda227..0138dc100 100644
--- a/xserver/randr/randr.c
+++ b/xserver/randr/randr.c
@@ -483,7 +483,10 @@ TellChanged(WindowPtr pWin, void *value)
RRDeliverCrtcEvent(client, pWin, crtc);
}
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pSlaveScrPriv = rrGetScrPriv(iter);
for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i];
@@ -502,7 +505,10 @@ TellChanged(WindowPtr pWin, void *value)
RRDeliverOutputEvent(client, pWin, output);
}
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pSlaveScrPriv = rrGetScrPriv(iter);
for (i = 0; i < pSlaveScrPriv->numOutputs; i++) {
RROutputPtr output = pSlaveScrPriv->outputs[i];
@@ -514,17 +520,7 @@ TellChanged(WindowPtr pWin, void *value)
}
if (pRREvent->mask & RRProviderChangeNotifyMask) {
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- if (pSlaveScrPriv->provider->changed)
- RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- if (pSlaveScrPriv->provider->changed)
- RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
pSlaveScrPriv = rrGetScrPriv(iter);
if (pSlaveScrPriv->provider->changed)
RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
@@ -584,6 +580,18 @@ RRTellChanged(ScreenPtr pScreen)
mastersp = pScrPriv;
}
+ xorg_list_for_each_entry(iter, &master->slave_list, slave_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+
+ if (!iter->is_output_slave)
+ continue;
+
+ if (CompareTimeStamps(mastersp->lastSetTime,
+ pSlaveScrPriv->lastSetTime) == EARLIER) {
+ mastersp->lastSetTime = pSlaveScrPriv->lastSetTime;
+ }
+ }
+
if (mastersp->changed) {
UpdateCurrentTimeIf();
if (mastersp->configChanged) {
@@ -602,21 +610,15 @@ RRTellChanged(ScreenPtr pScreen)
for (i = 0; i < pScrPriv->numCrtcs; i++)
pScrPriv->crtcs[i]->changed = FALSE;
- xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- pSlaveScrPriv->provider->changed = FALSE;
- for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
- pSlaveScrPriv->outputs[i]->changed = FALSE;
- for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
- pSlaveScrPriv->crtcs[i]->changed = FALSE;
- }
- xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) {
- pSlaveScrPriv = rrGetScrPriv(iter);
- pSlaveScrPriv->provider->changed = FALSE;
- }
- xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &master->slave_list, slave_head) {
pSlaveScrPriv = rrGetScrPriv(iter);
pSlaveScrPriv->provider->changed = FALSE;
+ if (iter->is_output_slave) {
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
+ pSlaveScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
+ pSlaveScrPriv->crtcs[i]->changed = FALSE;
+ }
}
if (mastersp->layoutChanged) {
@@ -676,6 +678,7 @@ ProcRRDispatch(ClientPtr client)
REQUEST(xReq);
if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
return BadRequest;
+ UpdateCurrentTimeIf();
return (*ProcRandrVector[stuff->data]) (client);
}
@@ -685,5 +688,6 @@ SProcRRDispatch(ClientPtr client)
REQUEST(xReq);
if (stuff->data >= RRNumberRequests || !SProcRandrVector[stuff->data])
return BadRequest;
+ UpdateCurrentTimeIf();
return (*SProcRandrVector[stuff->data]) (client);
}
diff --git a/xserver/randr/randrstr.h b/xserver/randr/randrstr.h
index 472721a5a..706e9a7b0 100644
--- a/xserver/randr/randrstr.h
+++ b/xserver/randr/randrstr.h
@@ -130,6 +130,7 @@ struct _rrCrtc {
struct pict_f_transform f_inverse;
PixmapPtr scanout_pixmap;
+ PixmapPtr scanout_pixmap_back;
};
struct _rrOutput {
@@ -278,6 +279,19 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
typedef Bool (*RRCrtcSetScanoutPixmapProcPtr)(RRCrtcPtr crtc, PixmapPtr pixmap);
+typedef Bool (*RRStartFlippingPixmapTrackingProcPtr)(RRCrtcPtr, PixmapPtr,
+ PixmapPtr, PixmapPtr,
+ int x, int y,
+ int dst_x, int dst_y,
+ Rotation rotation);
+
+typedef Bool (*RREnableSharedPixmapFlippingProcPtr)(RRCrtcPtr,
+ PixmapPtr front,
+ PixmapPtr back);
+
+typedef void (*RRDisableSharedPixmapFlippingProcPtr)(RRCrtcPtr);
+
+
typedef struct _rrScrPriv {
/*
* 'public' part of the structure; DDXen fill this in
@@ -304,6 +318,10 @@ typedef struct _rrScrPriv {
/* TODO #if RANDR_15_INTERFACE */
RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap;
+ RRStartFlippingPixmapTrackingProcPtr rrStartFlippingPixmapTracking;
+ RREnableSharedPixmapFlippingProcPtr rrEnableSharedPixmapFlipping;
+ RRDisableSharedPixmapFlippingProcPtr rrDisableSharedPixmapFlipping;
+
RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource;
RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink;
RRProviderGetPropertyProcPtr rrProviderGetProperty;
@@ -708,6 +726,12 @@ extern _X_EXPORT Bool
RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable);
/*
+ * Return if the screen has any scanout_pixmap's attached
+ */
+extern _X_EXPORT Bool
+ RRHasScanoutPixmap(ScreenPtr pScreen);
+
+/*
* Crtc dispatch
*/
@@ -917,6 +941,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/xserver/randr/rrcrtc.c b/xserver/randr/rrcrtc.c
index 9bc456bdc..401a1c178 100644
--- a/xserver/randr/rrcrtc.c
+++ b/xserver/randr/rrcrtc.c
@@ -25,6 +25,8 @@
#include "swaprep.h"
#include "mipointer.h"
+#include <X11/Xatom.h>
+
RESTYPE RRCrtcType;
/*
@@ -279,7 +281,7 @@ crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
*left = crtc->x;
*top = crtc->y;
- switch (crtc->rotation) {
+ switch (crtc->rotation & 0xf) {
case RR_Rotate_0:
case RR_Rotate_180:
default:
@@ -361,52 +363,160 @@ RRComputeContiguity(ScreenPtr pScreen)
pScrPriv->discontiguous = discontiguous;
}
-void
-RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
-{
+static void
+rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
ScreenPtr master = crtc->pScreen->current_master;
- PixmapPtr mscreenpix;
- rrScrPriv(crtc->pScreen);
- mscreenpix = master->GetScreenPixmap(master);
-
- pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
- if (crtc->scanout_pixmap) {
- master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
+ if (master && pPixmap->master_pixmap) {
/*
* Unref the pixmap twice: once for the original reference, and once
* for the reference implicitly added by PixmapShareToSlave.
*/
- master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
- master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap);
- crtc->pScreen->DestroyPixmap(crtc->scanout_pixmap);
+ PixmapUnshareSlavePixmap(pPixmap);
+
+ master->DestroyPixmap(pPixmap->master_pixmap);
+ master->DestroyPixmap(pPixmap->master_pixmap);
}
- crtc->scanout_pixmap = NULL;
+
+ crtc->pScreen->DestroyPixmap(pPixmap);
+}
+
+void
+RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
+{
+ rrScrPriv(crtc->pScreen);
+
+ if (crtc->scanout_pixmap) {
+ ScreenPtr master = crtc->pScreen->current_master;
+ PixmapPtr mscreenpix = master->GetScreenPixmap(master);
+
+ if (crtc->scanout_pixmap_back) {
+ pScrPriv->rrDisableSharedPixmapFlipping(crtc);
+
+ master->StopFlippingPixmapTracking(mscreenpix,
+ crtc->scanout_pixmap,
+ crtc->scanout_pixmap_back);
+
+ rrDestroySharedPixmap(crtc, crtc->scanout_pixmap_back);
+ crtc->scanout_pixmap_back = NULL;
+ }
+ else {
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
+ master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
+ }
+
+ rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
+ crtc->scanout_pixmap = NULL;
+ }
+
RRCrtcChanged(crtc, TRUE);
}
-static Bool
-rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
+static PixmapPtr
+rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
+ int width, int height, int depth,
int x, int y, Rotation rotation)
{
PixmapPtr mpix, spix;
+
+ mpix = master->CreatePixmap(master, width, height, depth,
+ CREATE_PIXMAP_USAGE_SHARED);
+ if (!mpix)
+ return NULL;
+
+ spix = PixmapShareToSlave(mpix, crtc->pScreen);
+ if (spix == NULL) {
+ master->DestroyPixmap(mpix);
+ return NULL;
+ }
+
+ return spix;
+}
+
+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, Bool sync,
+ int numOutputs, RROutputPtr * outputs)
+{
ScreenPtr master = crtc->pScreen->current_master;
- Bool ret;
+ rrScrPrivPtr pMasterScrPriv = rrGetScrPriv(master);
+ rrScrPrivPtr pSlaveScrPriv = rrGetScrPriv(crtc->pScreen);
+
int depth;
PixmapPtr mscreenpix;
- PixmapPtr protopix = master->GetScreenPixmap(master);
- rrScrPriv(crtc->pScreen);
-
- /* create a pixmap on the master screen,
- then get a shared handle for it
- create a shared pixmap on the slave screen using the handle
- set the master screen to do dirty updates to the shared pixmap
- from the screen pixmap.
- set slave screen to scanout shared linear pixmap
+ PixmapPtr spix_front;
+
+ /* Create a pixmap on the master screen, then get a shared handle for it.
+ Create a shared pixmap on the slave screen using the handle.
+
+ If sync == FALSE --
+ Set slave screen to scanout shared linear pixmap.
+ Set the master screen to do dirty updates to the shared pixmap
+ from the screen pixmap on its own accord.
+
+ If sync == TRUE --
+ If any of the below steps fail, clean up and fall back to sync == FALSE.
+ Create another shared pixmap on the slave screen using the handle.
+ Set slave screen to prepare for scanout and flipping between shared
+ linear pixmaps.
+ Set the master screen to do dirty updates to the shared pixmaps from the
+ screen pixmap when prompted to by us or the slave.
+ Prompt the master to do a dirty update on the first shared pixmap, then
+ defer to the slave.
*/
mscreenpix = master->GetScreenPixmap(master);
- depth = protopix->drawable.depth;
+ depth = mscreenpix->drawable.depth;
if (crtc->scanout_pixmap)
RRCrtcDetachScanoutPixmap(crtc);
@@ -415,26 +525,71 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height,
return TRUE;
}
- mpix = master->CreatePixmap(master, width, height, depth,
- CREATE_PIXMAP_USAGE_SHARED);
- if (!mpix)
+ spix_front = rrCreateSharedPixmap(crtc, master,
+ width, height, depth,
+ x, y, rotation);
+ if (spix_front == NULL) {
return FALSE;
+ }
- spix = PixmapShareToSlave(mpix, crtc->pScreen);
- if (spix == NULL) {
- master->DestroyPixmap(mpix);
- return FALSE;
+ /* Both source and sink must support required ABI funcs for flipping */
+ if (sync &&
+ pSlaveScrPriv->rrEnableSharedPixmapFlipping &&
+ pSlaveScrPriv->rrDisableSharedPixmapFlipping &&
+ pMasterScrPriv->rrStartFlippingPixmapTracking &&
+ master->PresentSharedPixmap &&
+ master->StopFlippingPixmapTracking) {
+
+ PixmapPtr spix_back = rrCreateSharedPixmap(crtc, master,
+ width, height, depth,
+ x, y, rotation);
+ if (spix_back == NULL)
+ goto fail;
+
+ if (!pSlaveScrPriv->rrEnableSharedPixmapFlipping(crtc,
+ spix_front, spix_back))
+ goto fail;
+
+ crtc->scanout_pixmap = spix_front;
+ crtc->scanout_pixmap_back = spix_back;
+
+ if (!pMasterScrPriv->rrStartFlippingPixmapTracking(crtc, mscreenpix,
+ spix_front,
+ spix_back,
+ x, y, 0, 0,
+ rotation)) {
+ pSlaveScrPriv->rrDisableSharedPixmapFlipping(crtc);
+ goto fail;
+ }
+
+ master->PresentSharedPixmap(spix_front);
+
+ return TRUE;
+
+fail: /* If flipping funcs fail, just fall back to unsynchronized */
+ if (spix_back)
+ rrDestroySharedPixmap(crtc, spix_back);
+
+ crtc->scanout_pixmap = NULL;
+ crtc->scanout_pixmap_back = NULL;
}
- ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
- if (ret == FALSE) {
+ 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);
ErrorF("randr: failed to set shadow slave pixmap\n");
return FALSE;
}
+ crtc->scanout_pixmap = spix_front;
- crtc->scanout_pixmap = spix;
+ master->StartPixmapTracking(mscreenpix, spix_front, x, y, 0, 0, rotation);
- master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation);
return TRUE;
}
@@ -499,8 +654,12 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
RegionUnion(&total_region, &total_region, &new_crtc_region);
}
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
rrScrPrivPtr slave_priv = rrGetScrPriv(slave);
+
+ if (!slave->is_output_slave)
+ continue;
+
for (c = 0; c < slave_priv->numCrtcs; c++) {
RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
@@ -527,8 +686,14 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
}
newsize = RegionExtents(&total_region);
- new_width = newsize->x2 - newsize->x1;
- new_height = newsize->y2 - newsize->y1;
+ new_width = newsize->x2;
+ new_height = newsize->y2;
+
+ if (new_width < screen_pixmap->drawable.width)
+ new_width = screen_pixmap->drawable.width;
+
+ if (new_height < screen_pixmap->drawable.height)
+ new_height = screen_pixmap->drawable.height;
if (new_width == screen_pixmap->drawable.width &&
new_height == screen_pixmap->drawable.height) {
@@ -592,7 +757,10 @@ RRCrtcSet(RRCrtcPtr crtc,
return FALSE;
if (pScreen->current_master) {
- ret = rrCreateSharedPixmap(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
@@ -675,9 +843,8 @@ RRCrtcGetTransform(RRCrtcPtr crtc)
Bool
RRCrtcPendingTransform(RRCrtcPtr crtc)
{
- return memcmp(&crtc->client_current_transform.transform,
- &crtc->client_pending_transform.transform,
- sizeof(PictTransform)) != 0;
+ return !RRTransformEqual(&crtc->client_current_transform,
+ &crtc->client_pending_transform);
}
/*
@@ -1673,7 +1840,10 @@ RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
if (ret == TRUE)
return;
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
ret = check_all_screen_crtcs(slave, x, y);
if (ret == TRUE)
return;
@@ -1684,7 +1854,10 @@ RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x,
if (ret == TRUE)
return;
- xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
ret = constrain_all_screen_crtcs(pDev, slave, x, y);
if (ret == TRUE)
return;
@@ -1714,6 +1887,12 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
if (!crtc->scanout_pixmap && !enable)
continue;
+ /* not supported with double buffering, needs ABI change for 2 ppix */
+ if (crtc->scanout_pixmap_back) {
+ ret = FALSE;
+ continue;
+ }
+
size_fits = (crtc->mode &&
crtc->x == pDrawable->x &&
crtc->y == pDrawable->y &&
@@ -1771,3 +1950,22 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
return ret;
}
+
+Bool
+RRHasScanoutPixmap(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ int i;
+
+ if (!pScreen->is_output_slave)
+ return FALSE;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ if (crtc->scanout_pixmap)
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/xserver/randr/rrmonitor.c b/xserver/randr/rrmonitor.c
index ba310eaa4..3f6e03e7d 100644
--- a/xserver/randr/rrmonitor.c
+++ b/xserver/randr/rrmonitor.c
@@ -202,8 +202,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
/* Count the number of crtcs in this and any slave screens */
numCrtcs = pScrPriv->numCrtcs;
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
rrScrPrivPtr pSlavePriv;
+
+ if (!slave->is_output_slave)
+ continue;
+
pSlavePriv = rrGetScrPriv(slave);
numCrtcs += pSlavePriv->numCrtcs;
}
@@ -220,8 +224,12 @@ RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
}
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
rrScrPrivPtr pSlavePriv;
+
+ if (!slave->is_output_slave)
+ continue;
+
pSlavePriv = rrGetScrPriv(slave);
for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
if (pSlavePriv->crtcs[sc]->mode != NULL)
@@ -471,7 +479,10 @@ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
return BadValue;
}
- xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(slave, &screen->slave_list, slave_head) {
+ if (!slave->is_output_slave)
+ continue;
+
if (RRMonitorMatchesOutputName(slave, monitor->name)) {
client->errorValue = monitor->name;
return BadValue;
diff --git a/xserver/randr/rroutput.c b/xserver/randr/rroutput.c
index 686ae49a6..a8efec409 100644
--- a/xserver/randr/rroutput.c
+++ b/xserver/randr/rroutput.c
@@ -570,12 +570,10 @@ ProcRRSetOutputPrimary(ClientPtr client)
RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
xorg_list_for_each_entry(slave,
- &pWin->drawable.pScreen->output_slave_list,
- output_head) {
- rrScrPrivPtr pSlavePriv;
- pSlavePriv = rrGetScrPriv(slave);
-
- RRSetPrimaryOutput(slave, pSlavePriv, output);
+ &pWin->drawable.pScreen->slave_list,
+ slave_head) {
+ if (slave->is_output_slave)
+ RRSetPrimaryOutput(slave, rrGetScrPriv(slave), output);
}
}
diff --git a/xserver/randr/rrprovider.c b/xserver/randr/rrprovider.c
index 5329f410b..e4bc2bf6a 100644
--- a/xserver/randr/rrprovider.c
+++ b/xserver/randr/rrprovider.c
@@ -25,6 +25,8 @@
#include "randrstr.h"
#include "swaprep.h"
+#include <X11/Xatom.h>
+
RESTYPE RRProviderType;
/*
@@ -72,15 +74,7 @@ ProcRRGetProviders (ClientPtr client)
if (pScrPriv->provider)
total_providers++;
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- pScrPriv = rrGetScrPriv(iter);
- total_providers += pScrPriv->provider ? 1 : 0;
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- pScrPriv = rrGetScrPriv(iter);
- total_providers += pScrPriv->provider ? 1 : 0;
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
pScrPriv = rrGetScrPriv(iter);
total_providers += pScrPriv->provider ? 1 : 0;
}
@@ -116,13 +110,7 @@ ProcRRGetProviders (ClientPtr client)
providers = (RRProvider *)extra;
ADD_PROVIDER(pScreen);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
- ADD_PROVIDER(iter);
- }
- xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
- ADD_PROVIDER(iter);
- }
- xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
ADD_PROVIDER(iter);
}
}
@@ -182,12 +170,13 @@ ProcRRGetProviderInfo (ClientPtr client)
/* count associated providers */
if (provider->offload_sink)
rep.nAssociatedProviders++;
- if (provider->output_source)
- rep.nAssociatedProviders++;
- xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)
- rep.nAssociatedProviders++;
- xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)
+ if (provider->output_source &&
+ provider->output_source != provider->offload_sink)
rep.nAssociatedProviders++;
+ xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) {
+ if (provscreen->is_output_slave || provscreen->is_offload_slave)
+ rep.nAssociatedProviders++;
+ }
rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
(rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
@@ -237,27 +226,22 @@ ProcRRGetProviderInfo (ClientPtr client)
swapl(&prov_cap[i]);
i++;
}
- xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(provscreen, &pScreen->slave_list, slave_head) {
+ if (!provscreen->is_output_slave && !provscreen->is_offload_slave)
+ continue;
pScrProvPriv = rrGetScrPriv(provscreen);
providers[i] = pScrProvPriv->provider->id;
if (client->swapped)
swapl(&providers[i]);
- prov_cap[i] = RR_Capability_SinkOutput;
+ prov_cap[i] = 0;
+ if (provscreen->is_output_slave)
+ prov_cap[i] |= RR_Capability_SinkOutput;
+ if (provscreen->is_offload_slave)
+ prov_cap[i] |= RR_Capability_SourceOffload;
if (client->swapped)
swapl(&prov_cap[i]);
i++;
}
- xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) {
- pScrProvPriv = rrGetScrPriv(provscreen);
- providers[i] = pScrProvPriv->provider->id;
- if (client->swapped)
- swapl(&providers[i]);
- prov_cap[i] = RR_Capability_SourceOffload;
- if (client->swapped)
- swapl(&prov_cap[i]);
- i++;
- }
-
memcpy(name, provider->name, rep.nameLength);
if (client->swapped) {
@@ -277,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)
{
@@ -302,8 +338,13 @@ ProcRRSetProviderOutputSource(ClientPtr client)
pScreen = provider->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
+ if (!pScreen->isGPU)
+ return BadValue;
+
pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
+ RRInitPrimeSyncProps(pScreen);
+
provider->changed = TRUE;
RRSetChanged(pScreen);
@@ -379,6 +420,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name,
void
RRProviderDestroy (RRProviderPtr provider)
{
+ RRFiniPrimeSyncProps(provider->pScreen);
FreeResource (provider->id, 0);
}
diff --git a/xserver/randr/rrscreen.c b/xserver/randr/rrscreen.c
index d0ca91e0e..d6c499580 100644
--- a/xserver/randr/rrscreen.c
+++ b/xserver/randr/rrscreen.c
@@ -41,6 +41,9 @@ RREditConnectionInfo(ScreenPtr pScreen)
int screen = 0;
int d;
+ if (ConnectionInfo == NULL)
+ return;
+
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof(xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
@@ -391,7 +394,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
update_totals(pScreen, pScrPriv);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pScrPriv = rrGetScrPriv(iter);
if (query)
@@ -447,7 +453,10 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
}
update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
- xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ xorg_list_for_each_entry(iter, &pScreen->slave_list, slave_head) {
+ if (!iter->is_output_slave)
+ continue;
+
pScrPriv = rrGetScrPriv(iter);
update_arrays(iter, pScrPriv, primary_crtc, has_primary);
@@ -500,7 +509,7 @@ rrGetScreenResources(ClientPtr client, Bool query)
if (!RRGetInfo(pScreen, query))
return BadAlloc;
- if (!xorg_list_is_empty(&pScreen->output_slave_list))
+ if (pScreen->output_slaves)
return rrGetMultiScreenResources(client, query, pScreen);
if (!pScrPriv) {
diff --git a/xserver/randr/rrxinerama.c b/xserver/randr/rrxinerama.c
index b6e9586d7..8f499dfa9 100644
--- a/xserver/randr/rrxinerama.c
+++ b/xserver/randr/rrxinerama.c
@@ -260,6 +260,13 @@ RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor)
scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1;
scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1;
+ if (client->swapped) {
+ swaps(&scratch.x_org);
+ swaps(&scratch.y_org);
+ swaps(&scratch.width);
+ swaps(&scratch.height);
+ }
+
WriteToClient(client, sz_XineramaScreenInfo, &scratch);
}