diff --git a/SOURCES/0001-autobind-GPUs-to-the-screen.patch b/SOURCES/0001-autobind-GPUs-to-the-screen.patch new file mode 100644 index 0000000..86b96a2 --- /dev/null +++ b/SOURCES/0001-autobind-GPUs-to-the-screen.patch @@ -0,0 +1,293 @@ +From 471289fa1dc359555ceed6302f7d9605ab6be3ea Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Mon, 2 Apr 2018 16:49:02 -0400 +Subject: [PATCH] autobind GPUs to the screen + +This is a modified version of a patch we've been carry-ing in Fedora and +RHEL for years now. This patch automatically adds secondary GPUs to the +master as output sink / offload source making e.g. the use of +slave-outputs just work, with requiring the user to manually run +"xrandr --setprovideroutputsource" before he can hookup an external +monitor to his hybrid graphics laptop. + +There is one problem with this patch, which is why it was not upstreamed +before. What to do when a secondary GPU gets detected really is a policy +decission (e.g. one may want to autobind PCI GPUs but not USB ones) and +as such should be under control of the Desktop Environment. + +Unconditionally adding autobinding support to the xserver will result +in races between the DE dealing with the hotplug of a secondary GPU +and the server itself dealing with it. + +However we've waited for years for any Desktop Environments to actually +start doing some sort of autoconfiguration of secondary GPUs and there +is still not a single DE dealing with this, so I believe that it is +time to upstream this now. + +To avoid potential future problems if any DEs get support for doing +secondary GPU configuration themselves, the new autobind functionality +is made optional. Since no DEs currently support doing this themselves it +is enabled by default. When DEs grow support for doing this themselves +they can disable the servers autobinding through the servers cmdline or a +xorg.conf snippet. + +Signed-off-by: Dave Airlie +[hdegoede@redhat.com: Make configurable, fix with nvidia, submit upstream] +Signed-off-by: Hans de Goede +--- + hw/xfree86/common/xf86Config.c | 19 +++++++++++++++++++ + hw/xfree86/common/xf86Globals.c | 2 ++ + hw/xfree86/common/xf86Init.c | 20 ++++++++++++++++++++ + hw/xfree86/common/xf86Priv.h | 1 + + hw/xfree86/common/xf86Privstr.h | 1 + + hw/xfree86/common/xf86platformBus.c | 4 ++++ + hw/xfree86/man/Xorg.man | 7 +++++++ + hw/xfree86/man/xorg.conf.man | 6 ++++++ + randr/randrstr.h | 3 +++ + randr/rrprovider.c | 22 ++++++++++++++++++++++ + 10 files changed, 85 insertions(+) + +diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c +index 2c1d335..d7d7c2e 100644 +--- a/hw/xfree86/common/xf86Config.c ++++ b/hw/xfree86/common/xf86Config.c +@@ -643,6 +643,7 @@ typedef enum { + FLAG_DRI2, + FLAG_USE_SIGIO, + FLAG_AUTO_ADD_GPU, ++ FLAG_AUTO_BIND_GPU, + FLAG_MAX_CLIENTS, + FLAG_IGLX, + FLAG_DEBUG, +@@ -699,6 +700,8 @@ static OptionInfoRec FlagOptions[] = { + {0}, FALSE}, + {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN, + {0}, FALSE}, ++ {FLAG_AUTO_BIND_GPU, "AutoBindGPU", OPTV_BOOLEAN, ++ {0}, FALSE}, + {FLAG_MAX_CLIENTS, "MaxClients", OPTV_INTEGER, + {0}, FALSE }, + {FLAG_IGLX, "IndirectGLX", OPTV_BOOLEAN, +@@ -779,6 +782,22 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) + } + xf86Msg(from, "%sutomatically adding GPU devices\n", + xf86Info.autoAddGPU ? "A" : "Not a"); ++ ++ if (xf86AutoBindGPUDisabled) { ++ xf86Info.autoBindGPU = FALSE; ++ from = X_CMDLINE; ++ } ++ else if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_BIND_GPU)) { ++ xf86GetOptValBool(FlagOptions, FLAG_AUTO_BIND_GPU, ++ &xf86Info.autoBindGPU); ++ from = X_CONFIG; ++ } ++ else { ++ from = X_DEFAULT; ++ } ++ xf86Msg(from, "%sutomatically binding GPU devices\n", ++ xf86Info.autoBindGPU ? "A" : "Not a"); ++ + /* + * Set things up based on the config file information. Some of these + * settings may be overridden later when the command line options are +diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c +index e890f05..7b27b4c 100644 +--- a/hw/xfree86/common/xf86Globals.c ++++ b/hw/xfree86/common/xf86Globals.c +@@ -131,6 +131,7 @@ xf86InfoRec xf86Info = { + #else + .autoAddGPU = FALSE, + #endif ++ .autoBindGPU = TRUE, + }; + + const char *xf86ConfigFile = NULL; +@@ -191,6 +192,7 @@ Bool xf86FlipPixels = FALSE; + Gamma xf86Gamma = { 0.0, 0.0, 0.0 }; + + Bool xf86AllowMouseOpenFail = FALSE; ++Bool xf86AutoBindGPUDisabled = FALSE; + + #ifdef XF86VIDMODE + Bool xf86VidModeDisabled = FALSE; +diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c +index ea42ec9..ec255b6 100644 +--- a/hw/xfree86/common/xf86Init.c ++++ b/hw/xfree86/common/xf86Init.c +@@ -76,6 +76,7 @@ + #include "xf86DDC.h" + #include "xf86Xinput.h" + #include "xf86InPriv.h" ++#include "xf86Crtc.h" + #include "picturestr.h" + #include "randrstr.h" + #include "glxvndabi.h" +@@ -237,6 +238,19 @@ xf86PrivsElevated(void) + return PrivsElevated(); + } + ++static void ++xf86AutoConfigOutputDevices(void) ++{ ++ int i; ++ ++ if (!xf86Info.autoBindGPU) ++ return; ++ ++ for (i = 0; i < xf86NumGPUScreens; i++) ++ RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]), ++ xf86ScrnToScreen(xf86Screens[0])); ++} ++ + static void + TrapSignals(void) + { +@@ -770,6 +784,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) + for (i = 0; i < xf86NumGPUScreens; i++) + AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen); + ++ xf86AutoConfigOutputDevices(); ++ + xf86VGAarbiterWrapFunctions(); + if (sigio_blocked) + input_unlock(); +@@ -1278,6 +1294,10 @@ ddxProcessArgument(int argc, char **argv, int i) + xf86Info.iglxFrom = X_CMDLINE; + return 0; + } ++ if (!strcmp(argv[i], "-noautoBindGPU")) { ++ xf86AutoBindGPUDisabled = TRUE; ++ return 1; ++ } + + /* OS-specific processing */ + return xf86ProcessArgument(argc, argv, i); +diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h +index 4fe2b5f..6566622 100644 +--- a/hw/xfree86/common/xf86Priv.h ++++ b/hw/xfree86/common/xf86Priv.h +@@ -46,6 +46,7 @@ + extern _X_EXPORT const char *xf86ConfigFile; + extern _X_EXPORT const char *xf86ConfigDir; + extern _X_EXPORT Bool xf86AllowMouseOpenFail; ++extern _X_EXPORT Bool xf86AutoBindGPUDisabled; + + #ifdef XF86VIDMODE + extern _X_EXPORT Bool xf86VidModeDisabled; +diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h +index 21c2e1f..6c71863 100644 +--- a/hw/xfree86/common/xf86Privstr.h ++++ b/hw/xfree86/common/xf86Privstr.h +@@ -98,6 +98,7 @@ typedef struct { + + Bool autoAddGPU; + const char *debug; ++ Bool autoBindGPU; + } xf86InfoRec, *xf86InfoPtr; + + /* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */ +diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c +index cef47da..913a324 100644 +--- a/hw/xfree86/common/xf86platformBus.c ++++ b/hw/xfree86/common/xf86platformBus.c +@@ -49,6 +49,7 @@ + #include "Pci.h" + #include "xf86platformBus.h" + #include "xf86Config.h" ++#include "xf86Crtc.h" + + #include "randrstr.h" + int platformSlotClaimed; +@@ -665,6 +666,9 @@ xf86platformAddDevice(int index) + } + /* attach unbound to 0 protocol screen */ + AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen); ++ if (xf86Info.autoBindGPU) ++ RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]), ++ xf86ScrnToScreen(xf86Screens[0])); + + RRResourcesChanged(xf86Screens[0]->pScreen); + RRTellChanged(xf86Screens[0]->pScreen); +diff --git a/hw/xfree86/man/Xorg.man b/hw/xfree86/man/Xorg.man +index 13a9dc3..745f986 100644 +--- a/hw/xfree86/man/Xorg.man ++++ b/hw/xfree86/man/Xorg.man +@@ -283,6 +283,13 @@ is a comma separated list of directories to search for + server modules. This option is only available when the server is run + as root (i.e, with real-uid 0). + .TP 8 ++.B \-noautoBindGPU ++Disable automatically setting secondary GPUs up as output sinks and offload ++sources. This is equivalent to setting the ++.B AutoBindGPU ++xorg.conf(__filemansuffix__) file option. To ++.B false. ++.TP 8 + .B \-nosilk + Disable Silken Mouse support. + .TP 8 +diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man +index 9589262..8d51e06 100644 +--- a/hw/xfree86/man/xorg.conf.man ++++ b/hw/xfree86/man/xorg.conf.man +@@ -672,6 +672,12 @@ Enabled by default. + If this option is disabled, then no GPU devices will be added from the udev + backend. Enabled by default. (May need to be disabled to setup Xinerama). + .TP 7 ++.BI "Option \*qAutoBindGPU\*q \*q" boolean \*q ++If enabled then secondary GPUs will be automatically set up as output-sinks and ++offload-sources. Making e.g. laptop outputs connected only to the secondary ++GPU directly available for use without needing to run ++"xrandr --setprovideroutputsource". Enabled by default. ++.TP 7 + .BI "Option \*qLog\*q \*q" string \*q + This option controls whether the log is flushed and/or synced to disk after + each message. +diff --git a/randr/randrstr.h b/randr/randrstr.h +index f94174b..092d726 100644 +--- a/randr/randrstr.h ++++ b/randr/randrstr.h +@@ -1039,6 +1039,9 @@ RRProviderLookup(XID id, RRProviderPtr *provider_p); + extern _X_EXPORT void + RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider); + ++extern _X_EXPORT void ++RRProviderAutoConfigGpuScreen(ScreenPtr pScreen, ScreenPtr masterScreen); ++ + /* rrproviderproperty.c */ + + extern _X_EXPORT void +diff --git a/randr/rrprovider.c b/randr/rrprovider.c +index e4bc2bf..e04c18f 100644 +--- a/randr/rrprovider.c ++++ b/randr/rrprovider.c +@@ -485,3 +485,25 @@ RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider) + + WriteEventsToClient(client, 1, (xEvent *) &pe); + } ++ ++void ++RRProviderAutoConfigGpuScreen(ScreenPtr pScreen, ScreenPtr masterScreen) ++{ ++ rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); ++ rrScrPrivPtr masterPriv = rrGetScrPriv(masterScreen); ++ RRProviderPtr provider = pScrPriv->provider; ++ RRProviderPtr master_provider = masterPriv->provider; ++ ++ if (!provider || !master_provider) ++ return; ++ ++ if ((provider->capabilities & RR_Capability_SinkOutput) && ++ (master_provider->capabilities & RR_Capability_SourceOutput)) { ++ pScrPriv->rrProviderSetOutputSource(pScreen, provider, master_provider); ++ RRInitPrimeSyncProps(pScreen); ++ } ++ ++ if ((provider->capabilities & RR_Capability_SourceOffload) && ++ (master_provider->capabilities & RR_Capability_SinkOffload)) ++ pScrPriv->rrProviderSetOffloadSink(pScreen, provider, master_provider); ++} +-- +2.16.2 + diff --git a/SOURCES/0001-composite-Implement-backing-store-Always.patch b/SOURCES/0001-composite-Implement-backing-store-Always.patch new file mode 100644 index 0000000..a3fff1a --- /dev/null +++ b/SOURCES/0001-composite-Implement-backing-store-Always.patch @@ -0,0 +1,933 @@ +From e3891866bcb133289d923b645228d70d55c67706 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 24 Jul 2018 09:36:38 -0400 +Subject: [PATCH] 0001-composite-Implement-backing-store-Always.patch + +--- + composite/compalloc.c | 2 +- + composite/compinit.c | 37 +++++++++--- + composite/compint.h | 8 +++ + composite/compwindow.c | 70 +++++++++++++++++++++- + dix/window.c | 78 ++++++++++++------------ + include/windowstr.h | 1 + + mi/mibitblt.c | 5 +- + mi/micopy.c | 7 +-- + mi/mivaltree.c | 132 ++++++++++++++++++++++------------------- + mi/miwindow.c | 30 +++++----- + 10 files changed, 236 insertions(+), 134 deletions(-) + +diff --git a/composite/compalloc.c b/composite/compalloc.c +index 05ffc7e..199c130 100644 +--- a/composite/compalloc.c ++++ b/composite/compalloc.c +@@ -106,7 +106,7 @@ compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin) + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pLayerWin = pWin; + +- if (!pWin->viewable) ++ if (!pWin->viewable && pWin->backingStore != Always) + return FALSE; + + (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); +diff --git a/composite/compinit.c b/composite/compinit.c +index 791fec9..2851bb8 100644 +--- a/composite/compinit.c ++++ b/composite/compinit.c +@@ -67,6 +67,7 @@ compCloseScreen(ScreenPtr pScreen) + pScreen->ConfigNotify = cs->ConfigNotify; + pScreen->MoveWindow = cs->MoveWindow; + pScreen->ResizeWindow = cs->ResizeWindow; ++ pScreen->MarkUnrealizedWindow = cs->MarkUnrealizedWindow; + pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; + + pScreen->ClipNotify = cs->ClipNotify; +@@ -74,6 +75,7 @@ compCloseScreen(ScreenPtr pScreen) + pScreen->RealizeWindow = cs->RealizeWindow; + pScreen->DestroyWindow = cs->DestroyWindow; + pScreen->CreateWindow = cs->CreateWindow; ++ pScreen->WindowExposures = cs->WindowExposures; + pScreen->CopyWindow = cs->CopyWindow; + pScreen->PositionWindow = cs->PositionWindow; + +@@ -105,18 +107,33 @@ compInstallColormap(ColormapPtr pColormap) + pScreen->InstallColormap = compInstallColormap; + } + ++static void ++compCheckPaintable(WindowPtr pWin) ++{ ++ pWin->paintable = pWin->viewable || pWin->backingStore == Always; ++} ++ + static void + compCheckBackingStore(WindowPtr pWin) + { +- if (pWin->backingStore != NotUseful && !pWin->backStorage) { +- compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); +- pWin->backStorage = TRUE; ++ Bool should = ++ (pWin->backingStore == Always) || ++ (pWin->backingStore == WhenMapped && pWin->viewable); ++ ++ if (should && !pWin->backStorage) { ++ compCheckPaintable(pWin); ++ if (Success == compRedirectWindow(serverClient, pWin, ++ CompositeRedirectAutomatic)) ++ pWin->backStorage = TRUE; + } +- else if (pWin->backingStore == NotUseful && pWin->backStorage) { +- compUnredirectWindow(serverClient, pWin, +- CompositeRedirectAutomatic); +- pWin->backStorage = FALSE; ++ else if (!should && pWin->backStorage) { ++ compCheckPaintable(pWin); ++ if (Success == compUnredirectWindow(serverClient, pWin, ++ CompositeRedirectAutomatic)) ++ pWin->backStorage = FALSE; + } ++ pWin->paintable = pWin->viewable || ++ (pWin->backingStore == Always && pWin->backStorage); + } + + /* Fake backing store via automatic redirection */ +@@ -421,6 +438,9 @@ compScreenInit(ScreenPtr pScreen) + cs->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = compUnrealizeWindow; + ++ cs->WindowExposures = pScreen->WindowExposures; ++ pScreen->WindowExposures = compWindowExposures; ++ + cs->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = compClipNotify; + +@@ -433,6 +453,9 @@ compScreenInit(ScreenPtr pScreen) + cs->ResizeWindow = pScreen->ResizeWindow; + pScreen->ResizeWindow = compResizeWindow; + ++ cs->MarkUnrealizedWindow = pScreen->MarkUnrealizedWindow; ++ pScreen->MarkUnrealizedWindow = compMarkUnrealizedWindow; ++ + cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; + pScreen->ChangeBorderWidth = compChangeBorderWidth; + +diff --git a/composite/compint.h b/composite/compint.h +index f05c2d8..e0c02ea 100644 +--- a/composite/compint.h ++++ b/composite/compint.h +@@ -131,6 +131,7 @@ typedef struct _CompScreen { + DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; ++ WindowExposuresProcPtr WindowExposures; + ClipNotifyProcPtr ClipNotify; + /* + * Called from ConfigureWindow, these +@@ -140,6 +141,7 @@ typedef struct _CompScreen { + ConfigNotifyProcPtr ConfigNotify; + MoveWindowProcPtr MoveWindow; + ResizeWindowProcPtr ResizeWindow; ++ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; + ChangeBorderWidthProcPtr ChangeBorderWidth; + /* + * Reparenting has an effect on Subwindows redirect +@@ -288,6 +290,9 @@ Bool + Bool + compUnrealizeWindow(WindowPtr pWin); + ++void ++compWindowExposures(WindowPtr pWin, RegionPtr reg); ++ + void + compClipNotify(WindowPtr pWin, int dx, int dy); + +@@ -299,6 +304,9 @@ void + compResizeWindow(WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib); + ++void ++ compMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure); ++ + void + compChangeBorderWidth(WindowPtr pWin, unsigned int border_width); + +diff --git a/composite/compwindow.c b/composite/compwindow.c +index bcd230c..19698b8 100644 +--- a/composite/compwindow.c ++++ b/composite/compwindow.c +@@ -152,8 +152,10 @@ compCheckRedirect(WindowPtr pWin) + CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); + Bool should; + +- should = pWin->realized && (pWin->drawable.class != InputOnly) && +- (cw != NULL) && (pWin->parent != NULL); ++ should = (pWin->realized || pWin->backingStore == Always) && ++ (pWin->drawable.class != InputOnly) && ++ (cw != NULL) && ++ (pWin->parent != NULL); + + /* Never redirect the overlay window */ + if (cs->pOverlayWin != NULL) { +@@ -290,6 +292,32 @@ compUnrealizeWindow(WindowPtr pWin) + return ret; + } + ++void ++compWindowExposures(WindowPtr pWin, RegionPtr reg) ++{ ++ ScreenPtr pScreen = pWin->drawable.pScreen; ++ CompScreenPtr cs = GetCompScreen(pScreen); ++ ++ pScreen->WindowExposures = cs->WindowExposures; ++ ++ if (pWin->backStorage) { ++ DamageDamageRegion(&pWin->drawable, reg); ++ ++ /* should be RegionEmpty but buggy apps expect an expose */ ++ { ++ BoxRec box = *RegionExtents(reg); ++ box.x2 = box.x1 + 1; ++ box.y2 = box.x1 + 1; ++ RegionReset(reg, &box); ++ } ++ } ++ ++ pScreen->WindowExposures(pWin, reg); ++ ++ cs->WindowExposures = pScreen->WindowExposures; ++ pScreen->WindowExposures = compWindowExposures; ++} ++ + /* + * Called after the borderClip for the window has settled down + * We use this to make sure our extra borderClip has the right origin +@@ -432,6 +460,36 @@ compChangeBorderWidth(WindowPtr pWin, unsigned int bw) + compCheckTree(pWin->drawable.pScreen); + } + ++/* ++ * pWin is the top-level window being unmapped, pChild is one of its ++ * (previously viewable) descendents. MUW under us will try to empty ++ * the child clip. ++ */ ++void ++compMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure) ++{ ++ Bool should = FALSE; ++ ++ if (pWin == pChild && pWin->backingStore == Always && pWin->backStorage) { ++ /* this is the top-level being unmapped, restore paintable */ ++ pWin->paintable = (pWin->drawable.class == InputOutput); ++ } else if (pChild->parent->paintable && pChild->mapped) { ++ pChild->paintable = (pWin->drawable.class == InputOutput); ++ } else { ++ should = TRUE; ++ } ++ ++ if (should) { ++ ScreenPtr pScreen = pWin->drawable.pScreen; ++ CompScreenPtr cs = GetCompScreen(pScreen); ++ ++ pScreen->MarkUnrealizedWindow = cs->MarkUnrealizedWindow; ++ (*pScreen->MarkUnrealizedWindow) (pChild, pWin, fromConfigure); ++ cs->MarkUnrealizedWindow = pScreen->MarkUnrealizedWindow; ++ pScreen->MarkUnrealizedWindow = compMarkUnrealizedWindow; ++ } ++} ++ + void + compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) + { +@@ -597,6 +655,14 @@ compDestroyWindow(WindowPtr pWin) + CompSubwindowsPtr csw; + Bool ret; + ++ /* ++ * Take down bs explicitly, to get ->backStorage cleared ++ */ ++ if (pWin->backingStore != NotUseful) { ++ pWin->backingStore = NotUseful; ++ pScreen->ChangeWindowAttributes(pWin, CWBackingStore); ++ } ++ + pScreen->DestroyWindow = cs->DestroyWindow; + while ((cw = GetCompWindow(pWin))) + FreeResource(cw->clients->id, RT_NONE); +diff --git a/dix/window.c b/dix/window.c +index ead4dc2..1247a56 100644 +--- a/dix/window.c ++++ b/dix/window.c +@@ -492,6 +492,7 @@ SetWindowToDefaults(WindowPtr pWin) + pWin->mapped = FALSE; /* off */ + pWin->realized = FALSE; /* off */ + pWin->viewable = FALSE; ++ pWin->paintable = FALSE; + pWin->visibility = VisibilityNotViewable; + pWin->overrideRedirect = FALSE; + pWin->saveUnder = FALSE; +@@ -1056,6 +1057,7 @@ CrushTree(WindowPtr pWin) + FreeResource(pChild->drawable.id, RT_WINDOW); + pSib = pChild->nextSib; + pChild->viewable = FALSE; ++ pChild->paintable = FALSE; + if (pChild->realized) { + pChild->realized = FALSE; + (*UnrealizeWindow) (pChild); +@@ -1587,7 +1589,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) + for the tile to be rotated, and the correct function selected. + */ + if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) +- && pWin->viewable && HasBorder(pWin)) { ++ && pWin->paintable && HasBorder(pWin)) { + RegionRec exposed; + + RegionNull(&exposed); +@@ -2161,7 +2163,7 @@ ReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) + { + /* Note that pSib might be NULL */ + +- Bool WasViewable = (Bool) pWin->viewable; ++ Bool WasPaintable = (Bool) pWin->paintable; + Bool anyMarked; + WindowPtr pFirstChange; + WindowPtr pLayerWin; +@@ -2173,7 +2175,7 @@ ReflectStackChange(WindowPtr pWin, WindowPtr pSib, VTKind kind) + + pFirstChange = MoveWindowInStack(pWin, pSib); + +- if (WasViewable) { ++ if (WasPaintable) { + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, + &pLayerWin); + if (pLayerWin != pWin) +@@ -2612,8 +2614,9 @@ RealizeTree(WindowPtr pWin) + pChild = pWin; + while (1) { + if (pChild->mapped) { +- pChild->realized = TRUE; ++ pChild->realized = pChild->parent->realized; + pChild->viewable = (pChild->drawable.class == InputOutput); ++ pChild->paintable = (pChild->drawable.class == InputOutput); + (*Realize) (pChild); + if (pChild->firstChild) { + pChild = pChild->firstChild; +@@ -2689,7 +2692,7 @@ MapWindow(WindowPtr pWin, ClientPtr client) + if (SubStrSend(pWin, pParent)) + DeliverMapNotify(pWin); + +- if (!pParent->realized) ++ if (!pParent->realized && !pParent->paintable) + return Success; + RealizeTree(pWin); + if (pWin->viewable) { +@@ -2711,6 +2714,7 @@ MapWindow(WindowPtr pWin, ClientPtr client) + pWin->mapped = TRUE; + pWin->realized = TRUE; /* for roots */ + pWin->viewable = pWin->drawable.class == InputOutput; ++ pWin->paintable = pWin->drawable.class == InputOutput; + /* We SHOULD check for an error value here XXX */ + (*pScreen->RealizeWindow) (pWin); + if (pScreen->ClipNotify) +@@ -2759,7 +2763,7 @@ MapSubwindows(WindowPtr pParent, ClientPtr client) + + if (!pFirstMapped) + pFirstMapped = pWin; +- if (pParent->realized) { ++ if (pParent->realized || pParent->paintable) { + RealizeTree(pWin); + if (pWin->viewable) { + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, +@@ -2817,6 +2821,7 @@ UnrealizeTree(WindowPtr pWin, Bool fromConfigure) + DeleteWindowFromAnyEvents(pChild, FALSE); + if (pChild->viewable) { + pChild->viewable = FALSE; ++ pChild->paintable = FALSE; + (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } +@@ -2856,7 +2861,7 @@ UnmapWindow(WindowPtr pWin, Bool fromConfigure) + { + WindowPtr pParent; + Bool wasRealized = (Bool) pWin->realized; +- Bool wasViewable = (Bool) pWin->viewable; ++ Bool wasPaintable = pWin->paintable; + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pLayerWin = pWin; + +@@ -2864,21 +2869,19 @@ UnmapWindow(WindowPtr pWin, Bool fromConfigure) + return Success; + if (SubStrSend(pWin, pParent)) + DeliverUnmapNotify(pWin, fromConfigure); +- if (wasViewable && !fromConfigure) { +- pWin->valdata = UnmapValData; ++ if (wasPaintable && !fromConfigure) { ++ (*pScreen->MarkWindow) (pWin); + (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin); + (*pScreen->MarkWindow) (pLayerWin->parent); + } + pWin->mapped = FALSE; + if (wasRealized) + UnrealizeTree(pWin, fromConfigure); +- if (wasViewable) { +- if (!fromConfigure) { +- (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); +- (*pScreen->HandleExposures) (pLayerWin->parent); +- if (pScreen->PostValidateTree) +- (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); +- } ++ if (wasPaintable && !fromConfigure) { ++ (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap); ++ (*pScreen->HandleExposures) (pLayerWin->parent); ++ if (pScreen->PostValidateTree) ++ (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap); + } + if (wasRealized && !fromConfigure) { + WindowsRestructured(); +@@ -2898,7 +2901,7 @@ UnmapSubwindows(WindowPtr pWin) + { + WindowPtr pChild, pHead; + Bool wasRealized = (Bool) pWin->realized; +- Bool wasViewable = (Bool) pWin->viewable; ++ Bool wasPaintable = pWin->paintable; + Bool anyMarked = FALSE; + Mask parentNotify; + WindowPtr pLayerWin = NULL; +@@ -2909,7 +2912,7 @@ UnmapSubwindows(WindowPtr pWin) + parentNotify = SubSend(pWin); + pHead = RealChildHead(pWin); + +- if (wasViewable) ++ if (wasPaintable) + pLayerWin = (*pScreen->GetLayerWindow) (pWin); + + for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) { +@@ -2917,7 +2920,7 @@ UnmapSubwindows(WindowPtr pWin) + if (parentNotify || StrSend(pChild)) + DeliverUnmapNotify(pChild, xFalse); + if (pChild->viewable) { +- pChild->valdata = UnmapValData; ++ (*pScreen->MarkWindow) (pChild); + anyMarked = TRUE; + } + pChild->mapped = FALSE; +@@ -2925,31 +2928,28 @@ UnmapSubwindows(WindowPtr pWin) + UnrealizeTree(pChild, FALSE); + } + } +- if (wasViewable) { +- if (anyMarked) { +- if (pLayerWin->parent == pWin) +- (*pScreen->MarkWindow) (pWin); +- else { +- WindowPtr ptmp; ++ if (wasPaintable && anyMarked) { ++ if (pLayerWin->parent == pWin) ++ (*pScreen->MarkWindow) (pWin); ++ else { ++ WindowPtr ptmp; + +- (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); +- (*pScreen->MarkWindow) (pLayerWin->parent); ++ (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); ++ (*pScreen->MarkWindow) (pLayerWin->parent); + +- /* Windows between pWin and pLayerWin may not have been marked */ +- ptmp = pWin; ++ /* Windows between pWin and pLayerWin may not have been marked */ ++ ptmp = pWin; + +- while (ptmp != pLayerWin->parent) { +- (*pScreen->MarkWindow) (ptmp); +- ptmp = ptmp->parent; +- } +- pHead = pWin->firstChild; ++ while (ptmp != pLayerWin->parent) { ++ (*pScreen->MarkWindow) (ptmp); ++ ptmp = ptmp->parent; + } +- (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); +- (*pScreen->HandleExposures) (pLayerWin->parent); +- if (pScreen->PostValidateTree) +- (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, +- VTUnmap); ++ pHead = pWin->firstChild; + } ++ (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap); ++ (*pScreen->HandleExposures) (pLayerWin->parent); ++ if (pScreen->PostValidateTree) ++ (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, VTUnmap); + } + if (wasRealized) { + WindowsRestructured(); +diff --git a/include/windowstr.h b/include/windowstr.h +index 4383dab..8a6ef24 100644 +--- a/include/windowstr.h ++++ b/include/windowstr.h +@@ -167,6 +167,7 @@ typedef struct _Window { + unsigned damagedDescendants:1; /* some descendants are damaged */ + unsigned inhibitBGPaint:1; /* paint the background? */ + #endif ++ unsigned paintable:1; + } WindowRec; + + /* +diff --git a/mi/mibitblt.c b/mi/mibitblt.c +index 28296a4..69735b0 100644 +--- a/mi/mibitblt.c ++++ b/mi/mibitblt.c +@@ -96,9 +96,8 @@ miCopyArea(DrawablePtr pSrcDrawable, + srcx = xIn + pSrcDrawable->x; + srcy = yIn + pSrcDrawable->y; + +- /* If the destination isn't realized, this is easy */ +- if (pDstDrawable->type == DRAWABLE_WINDOW && +- !((WindowPtr) pDstDrawable)->realized) ++ /* Bail early if we'd do no work */ ++ if (RegionNil(pGC->pCompositeClip)) + return NULL; + + /* clip the source */ +diff --git a/mi/micopy.c b/mi/micopy.c +index 12cdad4..65a8cf5 100644 +--- a/mi/micopy.c ++++ b/mi/micopy.c +@@ -152,12 +152,9 @@ miDoCopy(DrawablePtr pSrcDrawable, + Bool fastDst = FALSE; /* for fast clipping with one rect dest */ + Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ + +- /* Short cut for unmapped windows */ +- +- if (pDstDrawable->type == DRAWABLE_WINDOW && +- !((WindowPtr) pDstDrawable)->realized) { ++ /* Bail early if we'd do no work */ ++ if (RegionNil(pGC->pCompositeClip)) + return NULL; +- } + + if (pSrcDrawable->pScreen->SourceValidate) { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, +diff --git a/mi/mivaltree.c b/mi/mivaltree.c +index ea6889f..3f44b0f 100644 +--- a/mi/mivaltree.c ++++ b/mi/mivaltree.c +@@ -162,16 +162,28 @@ miShapedWindowIn(RegionPtr universe, RegionPtr bounding, + return rgnOUT; + } + ++static void ++setVisibility(WindowPtr pWin, int newVis) ++{ ++ if (pWin->visibility != newVis) { ++ pWin->visibility = newVis; ++ if ((pWin->eventMask | wOtherEventMasks(pWin)) & VisibilityChangeMask) ++ SendVisibilityNotify(pWin); ++ } ++} ++ + /* + * Manual redirected windows are treated as transparent; they do not obscure +- * siblings or parent windows ++ * siblings or parent windows. Likewise windows that are paintable but not ++ * mapped. + */ + +-#ifdef COMPOSITE +-#define TreatAsTransparent(w) ((w)->redirectDraw == RedirectDrawManual) +-#else +-#define TreatAsTransparent(w) FALSE +-#endif ++static Bool ++TreatAsTransparent(WindowPtr w) ++{ ++ return (w->redirectDraw == RedirectDrawManual) || ++ (w->paintable && !w->mapped); ++} + + #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ + HasBorder(w) && \ +@@ -181,7 +193,7 @@ miShapedWindowIn(RegionPtr universe, RegionPtr bounding, + *----------------------------------------------------------------------- + * miComputeClips -- + * Recompute the clipList, borderClip, exposed and borderExposed +- * regions for pParent and its children. Only viewable windows are ++ * regions for pParent and its children. Only paintable windows are + * taken into account. + * + * Results: +@@ -240,40 +252,41 @@ miComputeClips(WindowPtr pParent, + } + #endif + +- oldVis = pParent->visibility; +- switch (RegionContainsRect(universe, &borderSize)) { +- case rgnIN: +- newVis = VisibilityUnobscured; +- break; +- case rgnPART: +- newVis = VisibilityPartiallyObscured; +- { +- RegionPtr pBounding; ++ oldVis = newVis = pParent->visibility; ++ if (pParent->realized) { ++ switch (RegionContainsRect(universe, &borderSize)) { ++ case rgnIN: ++ newVis = VisibilityUnobscured; ++ break; ++ case rgnPART: ++ newVis = VisibilityPartiallyObscured; ++ { ++ RegionPtr pBounding; + +- if ((pBounding = wBoundingShape(pParent))) { +- switch (miShapedWindowIn(universe, pBounding, +- &borderSize, +- pParent->drawable.x, +- pParent->drawable.y)) { +- case rgnIN: +- newVis = VisibilityUnobscured; +- break; +- case rgnOUT: +- newVis = VisibilityFullyObscured; +- break; ++ if ((pBounding = wBoundingShape(pParent))) { ++ switch (miShapedWindowIn(universe, pBounding, ++ &borderSize, ++ pParent->drawable.x, ++ pParent->drawable.y)) { ++ case rgnIN: ++ newVis = VisibilityUnobscured; ++ break; ++ case rgnOUT: ++ newVis = VisibilityFullyObscured; ++ break; ++ } + } + } ++ break; ++ default: ++ newVis = VisibilityFullyObscured; ++ break; + } +- break; +- default: +- newVis = VisibilityFullyObscured; +- break; + } +- pParent->visibility = newVis; +- if (oldVis != newVis && +- ((pParent-> +- eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) +- SendVisibilityNotify(pParent); ++ else { ++ newVis = VisibilityNotViewable; ++ } ++ setVisibility(pParent, newVis); + + dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; + dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; +@@ -293,14 +306,13 @@ miComputeClips(WindowPtr pParent, + (oldVis == VisibilityUnobscured))) { + pChild = pParent; + while (1) { +- if (pChild->viewable) { ++ if (pChild->paintable) { + if (pChild->visibility != VisibilityFullyObscured) { + RegionTranslate(&pChild->borderClip, dx, dy); + RegionTranslate(&pChild->clipList, dx, dy); + pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pChild, dx, dy); +- + } + if (pChild->valdata) { + RegionNull(&pChild->valdata->after.borderExposed); +@@ -399,22 +411,22 @@ miComputeClips(WindowPtr pParent, + ((pChild->drawable.y == pParent->lastChild->drawable.y) && + (pChild->drawable.x < pParent->lastChild->drawable.x))) { + for (; pChild; pChild = pChild->nextSib) { +- if (pChild->viewable && !TreatAsTransparent(pChild)) ++ if (pChild->paintable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + else { + for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { +- if (pChild->viewable && !TreatAsTransparent(pChild)) ++ if (pChild->paintable && !TreatAsTransparent(pChild)) + RegionAppend(&childUnion, &pChild->borderSize); + } + } + RegionValidate(&childUnion, &overlap); + + for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { +- if (pChild->viewable) { ++ if (pChild->paintable) { + /* +- * If the child is viewable, we want to remove its extents ++ * If the child is paintable, we want to remove its extents + * from the current universe, but we only re-clip it if + * it's been marked. + */ +@@ -482,16 +494,11 @@ static void + miTreeObscured(WindowPtr pParent) + { + WindowPtr pChild; +- int oldVis; + + pChild = pParent; + while (1) { + if (pChild->viewable) { +- oldVis = pChild->visibility; +- if (oldVis != (pChild->visibility = VisibilityFullyObscured) && +- ((pChild-> +- eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) +- SendVisibilityNotify(pChild); ++ setVisibility(pChild, VisibilityFullyObscured); + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; +@@ -564,7 +571,7 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + ScreenPtr pScreen; + WindowPtr pWin; + Bool overlap; +- int viewvals; ++ int paintables = 0; + Bool forward; + + pScreen = pParent->drawable.pScreen; +@@ -581,7 +588,6 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + * children in their new configuration. + */ + RegionNull(&totalClip); +- viewvals = 0; + if (RegionBroken(&pParent->clipList) && !RegionBroken(&pParent->borderClip)) { + kind = VTBroken; + /* +@@ -593,12 +599,12 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + RegionIntersect(&totalClip, &totalClip, &pParent->winSize); + + for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib) { +- if (pWin->viewable && !TreatAsTransparent(pWin)) ++ if (pWin->paintable && !TreatAsTransparent(pWin)) + RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); + } + for (pWin = pChild; pWin; pWin = pWin->nextSib) +- if (pWin->valdata && pWin->viewable) +- viewvals++; ++ if (pWin->valdata && pWin->paintable) ++ paintables++; + + RegionEmpty(&pParent->clipList); + } +@@ -610,8 +616,8 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + for (pWin = pChild; pWin; pWin = pWin->nextSib) { + if (pWin->valdata) { + RegionAppend(&totalClip, getBorderClip(pWin)); +- if (pWin->viewable) +- viewvals++; ++ if (pWin->paintable) ++ paintables++; + } + } + } +@@ -621,8 +627,8 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + while (1) { + if (pWin->valdata) { + RegionAppend(&totalClip, getBorderClip(pWin)); +- if (pWin->viewable) +- viewvals++; ++ if (pWin->paintable) ++ paintables++; + } + if (pWin == pChild) + break; +@@ -642,7 +648,7 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + overlap = TRUE; + if (kind != VTStack) { + RegionUnion(&totalClip, &totalClip, &pParent->clipList); +- if (viewvals > 1) { ++ if (paintables > 1) { + /* + * precompute childUnion to discover whether any of them + * overlap. This seems redundant, but performance studies +@@ -653,14 +659,14 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + RegionNull(&childUnion); + if (forward) { + for (pWin = pChild; pWin; pWin = pWin->nextSib) +- if (pWin->valdata && pWin->viewable && ++ if (pWin->valdata && pWin->paintable && + !TreatAsTransparent(pWin)) + RegionAppend(&childUnion, &pWin->borderSize); + } + else { + pWin = pParent->lastChild; + while (1) { +- if (pWin->valdata && pWin->viewable && ++ if (pWin->valdata && pWin->paintable && + !TreatAsTransparent(pWin)) + RegionAppend(&childUnion, &pWin->borderSize); + if (pWin == pChild) +@@ -675,7 +681,7 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + } + + for (pWin = pChild; pWin != NullWindow; pWin = pWin->nextSib) { +- if (pWin->viewable) { ++ if (pWin->paintable) { + if (pWin->valdata) { + RegionIntersect(&childClip, &totalClip, &pWin->borderSize); + miComputeClips(pWin, pScreen, &childClip, kind, &exposed); +@@ -683,7 +689,8 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + RegionSubtract(&totalClip, &totalClip, &pWin->borderSize); + } + } +- else if (pWin->visibility == VisibilityNotViewable) { ++ else if (pWin->viewable && ++ pWin->visibility == VisibilityNotViewable) { + miTreeObscured(pWin); + } + } +@@ -693,6 +700,7 @@ miValidateTree(WindowPtr pParent, /* Parent to validate */ + if (pScreen->ClipNotify) + (*pScreen->ClipNotify) (pWin, 0, 0); + RegionEmpty(&pWin->borderClip); ++ free(pWin->valdata); + pWin->valdata = NULL; + } + } +diff --git a/mi/miwindow.c b/mi/miwindow.c +index 39c279e..1b910d9 100644 +--- a/mi/miwindow.c ++++ b/mi/miwindow.c +@@ -151,7 +151,7 @@ miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) + */ + pChild = pWin; + while (1) { +- if (pChild->viewable) { ++ if (pChild->paintable) { + if (RegionBroken(&pChild->winSize)) + SetWinSize(pChild); + if (RegionBroken(&pChild->borderSize)) +@@ -175,7 +175,7 @@ miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) + box = RegionExtents(&pWin->borderSize); + pLast = pChild->parent->lastChild; + while (1) { +- if (pChild->viewable) { ++ if (pChild->paintable) { + if (RegionBroken(&pChild->winSize)) + SetWinSize(pChild); + if (RegionBroken(&pChild->borderSize)) +@@ -244,7 +244,7 @@ void + miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) + { + WindowPtr pParent; +- Bool WasViewable = (Bool) (pWin->viewable); ++ Bool WasPaintable = pWin->paintable; + short bw; + RegionPtr oldRegion = NULL; + DDXPointRec oldpt; +@@ -261,7 +261,7 @@ miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) + + oldpt.x = pWin->drawable.x; + oldpt.y = pWin->drawable.y; +- if (WasViewable) { ++ if (WasPaintable) { + oldRegion = RegionCreate(NullBox, 1); + RegionCopy(oldRegion, &pWin->borderClip); + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); +@@ -280,7 +280,7 @@ miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) + + ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); + +- if (WasViewable) { ++ if (WasPaintable) { + if (pLayerWin == pWin) + anyMarked |= (*pScreen->MarkOverlappedWindows) + (pWin, windowToValidate, NULL); +@@ -343,7 +343,7 @@ miResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, + WindowPtr pSib) + { + WindowPtr pParent; +- Bool WasViewable = (Bool) (pWin->viewable); ++ Bool WasPaintable = pWin->paintable; + unsigned short width = pWin->drawable.width, height = pWin->drawable.height; + short oldx = pWin->drawable.x, oldy = pWin->drawable.y; + int bw = wBorderWidth(pWin); +@@ -373,7 +373,7 @@ miResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, + pScreen = pWin->drawable.pScreen; + newx = pParent->drawable.x + x + bw; + newy = pParent->drawable.y + y + bw; +- if (WasViewable) { ++ if (WasPaintable) { + anyMarked = FALSE; + /* + * save the visible region of the window +@@ -448,7 +448,7 @@ miResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, + + pFirstChange = MoveWindowInStack(pWin, pSib); + +- if (WasViewable) { ++ if (WasPaintable) { + pRegion = RegionCreate(NullBox, 1); + + if (pLayerWin == pWin) +@@ -474,7 +474,7 @@ miResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, + + GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); + +- if (WasViewable) { ++ if (WasPaintable) { + /* avoid the border */ + if (HasBorder(pWin)) { + int offx, offy, dx, dy; +@@ -636,13 +636,13 @@ miGetLayerWindow(WindowPtr pWin) + void + miSetShape(WindowPtr pWin, int kind) + { +- Bool WasViewable = (Bool) (pWin->viewable); ++ Bool WasPaintable = pWin->paintable; + ScreenPtr pScreen = pWin->drawable.pScreen; + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + + if (kind != ShapeInput) { +- if (WasViewable) { ++ if (WasPaintable) { + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, + &pLayerWin); + if (pWin->valdata) { +@@ -663,7 +663,7 @@ miSetShape(WindowPtr pWin, int kind) + + ResizeChildrenWinSize(pWin, 0, 0, 0, 0); + +- if (WasViewable) { ++ if (WasPaintable) { + anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); + + if (anyMarked) { +@@ -689,7 +689,7 @@ miChangeBorderWidth(WindowPtr pWin, unsigned int width) + int oldwidth; + Bool anyMarked = FALSE; + ScreenPtr pScreen; +- Bool WasViewable = (Bool) (pWin->viewable); ++ Bool WasPaintable = pWin->paintable; + Bool HadBorder; + WindowPtr pLayerWin; + +@@ -698,13 +698,13 @@ miChangeBorderWidth(WindowPtr pWin, unsigned int width) + return; + HadBorder = HasBorder(pWin); + pScreen = pWin->drawable.pScreen; +- if (WasViewable && width < oldwidth) ++ if (WasPaintable && width < oldwidth) + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); + + pWin->borderWidth = width; + SetBorderSize(pWin); + +- if (WasViewable) { ++ if (WasPaintable) { + if (width > oldwidth) { + anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, + &pLayerWin); +-- +2.17.0 + diff --git a/SOURCES/0001-glamor_egl-Don-t-initialize-on-llvmpipe.patch b/SOURCES/0001-glamor_egl-Don-t-initialize-on-llvmpipe.patch new file mode 100644 index 0000000..ab99365 --- /dev/null +++ b/SOURCES/0001-glamor_egl-Don-t-initialize-on-llvmpipe.patch @@ -0,0 +1,48 @@ +From 722dc4717a4bb1c0ff84f45d0251e3e456476a28 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Fri, 14 Sep 2018 11:33:43 -0400 +Subject: [PATCH xserver] glamor_egl: Don't initialize on llvmpipe + +--- + glamor/glamor_egl.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c +index df278b1a1a..2f06d6587d 100644 +--- a/glamor/glamor_egl.c ++++ b/glamor/glamor_egl.c +@@ -898,6 +898,7 @@ Bool + glamor_egl_init(ScrnInfoPtr scrn, int fd) + { + struct glamor_egl_screen_private *glamor_egl; ++ const GLubyte *renderer; + + glamor_egl = calloc(sizeof(*glamor_egl), 1); + if (glamor_egl == NULL) +@@ -992,6 +993,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) + "Failed to make EGL context current\n"); + goto error; + } ++ ++ renderer = glGetString(GL_RENDERER); ++ if (strstr(renderer, "llvmpipe")) { ++ xf86DrvMsg(scrn->scrnIndex, X_INFO, ++ "Refusing to try glamor on llvmpipe\n"); ++ goto error; ++ } ++ + /* + * Force the next glamor_make_current call to set the right context + * (in case of multiple GPUs using glamor) +@@ -1005,7 +1014,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) + } + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n", +- glGetString(GL_RENDERER)); ++ renderer); + + #ifdef GBM_BO_WITH_MODIFIERS + if (epoxy_has_egl_extension(glamor_egl->display, +-- +2.17.1 + diff --git a/SOURCES/0001-link-with-z-now.patch b/SOURCES/0001-link-with-z-now.patch index bbc09d5..aae9147 100644 --- a/SOURCES/0001-link-with-z-now.patch +++ b/SOURCES/0001-link-with-z-now.patch @@ -1,18 +1,17 @@ -From c24c9c3ac032c17dd63120d0adba1ef32edcf8dd Mon Sep 17 00:00:00 2001 +From 15a6d58414b85867f39237518f2b3bac7bba6a20 Mon Sep 17 00:00:00 2001 From: Adam Jackson -Date: Wed, 15 Apr 2015 12:44:49 -0400 +Date: Tue, 29 May 2018 15:11:54 -0400 Subject: [PATCH] link with -z now -Signed-off-by: Adam Jackson --- hw/xfree86/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am -index 27f2cc6..116eeb2 100644 +index a7a1be2..197701d 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am -@@ -79,7 +79,7 @@ Xorg_LDADD = \ +@@ -78,7 +78,7 @@ Xorg_LDADD = \ $(XSERVER_SYS_LIBS) Xorg_DEPENDENCIES = $(LOCAL_LIBS) @@ -20,7 +19,7 @@ index 27f2cc6..116eeb2 100644 +Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) -Wl,-z,now -pie if SUID_WRAPPER - wrapdir = $(SUID_WRAPPER_DIR) + wrapexecdir = $(SUID_WRAPPER_DIR) -- -2.1.0 +2.17.0 diff --git a/SOURCES/0001-linux-Make-platform-device-probe-less-fragile.patch b/SOURCES/0001-linux-Make-platform-device-probe-less-fragile.patch new file mode 100644 index 0000000..7eaf5c3 --- /dev/null +++ b/SOURCES/0001-linux-Make-platform-device-probe-less-fragile.patch @@ -0,0 +1,76 @@ +From b96e7972e90144a697401f393ae8e1e12b3e767c Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 18 Sep 2018 14:37:51 -0400 +Subject: [PATCH] linux: Make platform device probe less fragile + +If we have platform devices - and we usually do - we would really want +them to bind through the platform bus code not PCI. At the point where +get_drm_info runs, however, we haven't yet taken our own VT, which means +we can't perform drm "master" operations on the device. This is tragic, +because the operation we need to perform here is fishing the bus id out +of the kernel, which we can only do after drmSetInterfaceVersion, which +for some reason stores that knowledge on the device not the file handle +and thus needs master access. Since we fail, the probe logic gets very +confused. + +Fortunately we know the format of the busid string (it's our own, drm +copied it from xfree86), so we can scrape that out of the sysfs path. We +do still potentially do the whole SetInterfaceVersion dance later on, +but it's harmless at that point because we've taken the VT by then. + +This should all be vastly simplified, but that is not the cat we're +skinning today. +--- + hw/xfree86/os-support/linux/lnx_platform.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c +index 70374ac..cbf7dd2 100644 +--- a/hw/xfree86/os-support/linux/lnx_platform.c ++++ b/hw/xfree86/os-support/linux/lnx_platform.c +@@ -29,6 +29,9 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) + int fd; + int err = 0; + Bool paused, server_fd = FALSE; ++ const char pci_prefix[] = "/sys/devices/pci"; ++ ++ LogMessage(X_INFO, "Platform probe for %s\n", attribs->syspath); + + fd = systemd_logind_take_fd(attribs->major, attribs->minor, path, &paused); + if (fd != -1) { +@@ -53,13 +56,6 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) + sv.drm_dd_major = -1; /* Don't care */ + sv.drm_dd_minor = -1; /* Don't care */ + +- err = drmSetInterfaceVersion(fd, &sv); +- if (err) { +- xf86Msg(X_ERROR, "%s: failed to set DRM interface version 1.4: %s\n", +- path, strerror(-err)); +- goto out; +- } +- + /* for a delayed probe we've already added the device */ + if (delayed_index == -1) { + xf86_add_platform_device(attribs, FALSE); +@@ -69,9 +65,15 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) + if (server_fd) + xf86_platform_devices[delayed_index].flags |= XF86_PDEV_SERVER_FD; + +- buf = drmGetBusid(fd); +- xf86_platform_odev_attributes(delayed_index)->busid = XNFstrdup(buf); +- drmFreeBusid(buf); ++ /* parse out a bus id */ ++ if (!strncmp(attribs->syspath, pci_prefix, strlen(pci_prefix))) { ++ char *dbdf = attribs->syspath + strlen(pci_prefix) + strlen("XXXX:XX") + 1; ++ asprintf(&xf86_platform_odev_attributes(delayed_index)->busid, ++ "pci:%.12s", dbdf); ++ LogMessage(X_INFO, "Platform PCI device at %s\n", ++ xf86_platform_odev_attributes(delayed_index)->busid); ++ } ++ + + v = drmGetVersion(fd); + if (!v) { +-- +2.17.1 + diff --git a/SOURCES/0001-xfree86-Allow-mixed-fbdev-and-pci-setups.patch b/SOURCES/0001-xfree86-Allow-mixed-fbdev-and-pci-setups.patch index 7439e80..0ad784d 100644 --- a/SOURCES/0001-xfree86-Allow-mixed-fbdev-and-pci-setups.patch +++ b/SOURCES/0001-xfree86-Allow-mixed-fbdev-and-pci-setups.patch @@ -1,4 +1,4 @@ -From ca183b2a3c6e3877b93b6444acb1280356834a04 Mon Sep 17 00:00:00 2001 +From 3c12c28f448fa76d17e9009995c89f56cccb0abb Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 5 Aug 2014 12:16:31 -0400 Subject: [PATCH] xfree86: Allow mixed fbdev and pci setups @@ -31,18 +31,18 @@ goal. Signed-off-by: Adam Jackson --- - hw/xfree86/common/xf86Bus.c | 16 ---------------- + hw/xfree86/common/xf86Bus.c | 15 --------------- hw/xfree86/fbdevhw/fbdevhw.c | 18 +++++++++++++++--- - 2 files changed, 15 insertions(+), 19 deletions(-) + 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c -index d463e91..5adff0b 100644 +index 6bbf489..3186478 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c -@@ -548,22 +548,6 @@ xf86PostProbe(void) +@@ -536,21 +536,6 @@ xf86GetDevFromEntity(int entityIndex, int instance) + void + xf86PostProbe(void) { - int i; - - if (fbSlotClaimed && ( -#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) - sbusSlotClaimed || @@ -58,15 +58,14 @@ index d463e91..5adff0b 100644 - )) - FatalError("Cannot run in framebuffer mode. Please specify busIDs " - " for all framebuffer devices\n"); -- - for (i = 0; i < xf86NumEntities; i++) - if (xf86Entities[i]->entityInit) - xf86Entities[i]->entityInit(i, xf86Entities[i]->private); + } + + int diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c -index cbb4093..657fc49 100644 +index 0bd77df..a2cf78f 100644 --- a/hw/xfree86/fbdevhw/fbdevhw.c +++ b/hw/xfree86/fbdevhw/fbdevhw.c -@@ -347,7 +347,7 @@ fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) +@@ -351,7 +351,7 @@ fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) { int fd; @@ -75,7 +74,7 @@ index cbb4093..657fc49 100644 fd = fbdev_open_pci(pPci, namep); else fd = fbdev_open(-1, device, namep); -@@ -361,16 +361,28 @@ fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) +@@ -365,16 +365,28 @@ fbdevHWProbe(struct pci_device *pPci, char *device, char **namep) Bool fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device *pPci, char *device) { @@ -107,5 +106,5 @@ index cbb4093..657fc49 100644 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to open framebuffer device, consult warnings" -- -2.1.0 +2.17.0 diff --git a/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch b/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch index 4b6d617..e97e961 100644 --- a/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch +++ b/SOURCES/0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch @@ -1,26 +1,27 @@ -From 5c7617de1777845d1609b301c0f470c90338d06f Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Mon, 23 Oct 2017 14:48:51 -0400 -Subject: [PATCH] 0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch +From e4dce2bfaf4a61dd8a8ac099638489d4fdff9024 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 29 May 2018 15:05:10 -0400 +Subject: [PATCH] xfree86: Don't autoconfigure vesa or fbdev +Signed-off-by: Adam Jackson --- - hw/xfree86/common/xf86Config.c | 1 - - hw/xfree86/loader/loadmod.c | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) + hw/xfree86/loader/loadmod.c | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c -index 940f5fc..2f9d915 100644 +index a6356bd..1c1c2b1 100644 --- a/hw/xfree86/loader/loadmod.c +++ b/hw/xfree86/loader/loadmod.c -@@ -525,6 +525,8 @@ LoaderListDirs(const char **subdirlist, const char **patternlist) - if (!(stat(buf, &stat_buf) == 0 && - S_ISREG(stat_buf.st_mode))) - continue; -+ if (strstr(dp->d_name, "vesa") || strstr(dp->d_name, "fbdev")) -+ continue; - for (p = patterns; p->pattern; p++) { - if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && - match[1].rm_so != -1) { +@@ -383,6 +383,9 @@ LoaderListDir(const char *subdir, const char **patternlist) + strcpy(fp, dp->d_name); + if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode))) + continue; ++ if (!strcmp(subdir, "drivers") && ++ (strstr(dp->d_name, "vesa") || strstr(dp->d_name, "fbdev"))) ++ continue; + for (p = patterns; p->pattern; p++) { + if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && + match[1].rm_so != -1) { -- -2.14.2 +2.17.0 diff --git a/SOURCES/0001-xfree86-try-harder-to-span-on-multihead.patch b/SOURCES/0001-xfree86-try-harder-to-span-on-multihead.patch new file mode 100644 index 0000000..4303409 --- /dev/null +++ b/SOURCES/0001-xfree86-try-harder-to-span-on-multihead.patch @@ -0,0 +1,190 @@ +From 326f992a90dae7a747da45626e588fa3c1dfa5dc Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 21 Sep 2018 14:38:31 -0400 +Subject: [PATCH xserver] xfree86: try harder to span on multihead + +right now if one of the monitors can't give +it's native resolution because of bandwidth limitations, +X decides to avoid spanning and instead clone. + +That's suboptimal, spanning is normally the right +thing to do (with the exception of some projector +use cases and other edge cases) + +This commit tries harder to make spanning work. +--- + hw/xfree86/modes/xf86Crtc.c | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c +index 37a45bb3a..686cb51b8 100644 +--- a/hw/xfree86/modes/xf86Crtc.c ++++ b/hw/xfree86/modes/xf86Crtc.c +@@ -2132,135 +2132,160 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) + if (test->HDisplay != mode->HDisplay || + test->VDisplay != mode->VDisplay) { + test = NULL; + break; + } + } + + /* if we didn't match it on all outputs, try the next one */ + if (!test) + continue; + + /* if it's bigger than the last one, save it */ + if (!match || (test->HDisplay > match->HDisplay)) + match = test; + } + + /* return the biggest one found */ + return match; + } + + static int + numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled) + { + int i = 0, p; + + for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; + + return i; + } + ++static DisplayModePtr ++findReasonableMode(xf86CrtcConfigPtr config, xf86OutputPtr output, Bool *enabled, int width, int height) ++{ ++ DisplayModePtr mode = ++ xf86OutputHasPreferredMode(output, width, height); ++ ++ /* if there's no preferred mode, just try to find a reasonable one */ ++ if (!mode) { ++ float aspect = 0.0; ++ DisplayModePtr a = NULL, b = NULL; ++ ++ if (output->mm_height) ++ aspect = (float) output->mm_width / ++ (float) output->mm_height; ++ ++ a = bestModeForAspect(config, enabled, 4.0/3.0); ++ if (aspect) ++ b = bestModeForAspect(config, enabled, aspect); ++ ++ mode = biggestMode(a, b); ++ } ++ ++ return mode; ++} ++ + static Bool + xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) + { + int o; + int w = 0; + Bool has_tile = FALSE; + uint32_t configured_outputs; + + xf86GetOptValBool(config->options, OPTION_PREFER_CLONEMODE, + &scrn->preferClone); + if (scrn->preferClone) + return FALSE; + + if (numEnabledOutputs(config, enabled) < 2) + return FALSE; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = +- xf86OutputHasPreferredMode(config->output[o], width, height); ++ findReasonableMode(config, config->output[o], enabled, width, height); + + if (!mode) + return FALSE; + + w += mode->HDisplay; + } + + if (w > width) + return FALSE; + + w = 0; + configured_outputs = 0; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = +- xf86OutputHasPreferredMode(config->output[o], width, height); ++ findReasonableMode(config, config->output[o], enabled, width, height); + + if (configured_outputs & (1 << o)) + continue; + + if (config->output[o]->tile_info.group_id) { + has_tile = TRUE; + continue; + } + + config->output[o]->initial_x = w; + w += mode->HDisplay; + + configured_outputs |= (1 << o); + modes[o] = mode; + } + + if (has_tile) { + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + int ht, vt, ot; + int add_x, cur_x = w; + struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile; + if (configured_outputs & (1 << o)) + continue; + if (!tile_info->group_id) + continue; + + if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0) + continue; + + for (ht = 0; ht < tile_info->num_h_tile; ht++) { + int cur_y = 0; + add_x = 0; + for (vt = 0; vt < tile_info->num_v_tile; vt++) { + + for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) { +- + DisplayModePtr mode = +- xf86OutputHasPreferredMode(config->output[ot], width, height); ++ findReasonableMode(config, config->output[ot], enabled, width, height); ++ + if (!config->output[ot]->tile_info.group_id) + continue; + + this_tile = &config->output[ot]->tile_info; + if (this_tile->group_id != tile_info->group_id) + continue; + + if (this_tile->tile_h_loc != ht || + this_tile->tile_v_loc != vt) + continue; + + config->output[ot]->initial_x = cur_x; + config->output[ot]->initial_y = cur_y; + + if (vt == 0) + add_x = this_tile->tile_h_size; + cur_y += this_tile->tile_v_size; + configured_outputs |= (1 << ot); + modes[ot] = mode; + } + } + cur_x += add_x; + } + w = cur_x; + } + } + return TRUE; + } + + static Bool +-- +2.17.1 + diff --git a/SOURCES/0001-xwayland-Don-t-initialize-glamor-on-llvmpipe.patch b/SOURCES/0001-xwayland-Don-t-initialize-glamor-on-llvmpipe.patch new file mode 100644 index 0000000..e5c0300 --- /dev/null +++ b/SOURCES/0001-xwayland-Don-t-initialize-glamor-on-llvmpipe.patch @@ -0,0 +1,29 @@ +From c64865691df6d2ad18aeecaecb0cb9a94b5d71eb Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Wed, 19 Sep 2018 10:56:29 -0400 +Subject: [PATCH] xwayland: Don't initialize glamor on llvmpipe + +Signed-off-by: Adam Jackson +--- + hw/xwayland/xwayland-glamor-gbm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c +index 06fcf52..2144af7 100644 +--- a/hw/xwayland/xwayland-glamor-gbm.c ++++ b/hw/xwayland/xwayland-glamor-gbm.c +@@ -843,6 +843,11 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen) + goto error; + } + ++ if (strstr(glGetString(GL_RENDERER), "llvmpipe")) { ++ ErrorF("Refusing to try glamor with llvmpipe\n"); ++ goto error; ++ } ++ + if (!epoxy_has_gl_extension("GL_OES_EGL_image")) { + ErrorF("GL_OES_EGL_image not available\n"); + goto error; +-- +2.17.1 + diff --git a/SPECS/xorg-x11-server.spec b/SPECS/xorg-x11-server.spec index b7b30a3..c733fd6 100644 --- a/SPECS/xorg-x11-server.spec +++ b/SPECS/xorg-x11-server.spec @@ -16,7 +16,7 @@ # source because rpm is a terrible language. %global ansic_major 0 %global ansic_minor 4 -%global videodrv_major 23 +%global videodrv_major 24 %global videodrv_minor 0 %global xinput_major 24 %global xinput_minor 1 @@ -41,8 +41,8 @@ Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.19.5 -Release: 5%{?gitdate:.%{gitdate}}%{?dist} +Version: 1.20.1 +Release: 3%{?gitdate:.%{gitdate}}%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -90,53 +90,21 @@ Patch105: 0001-xfree86-Don-t-autoconfigure-vesa-or-fbdev.patch # Trivial things to never merge upstream ever: # This really could be done prettier. -Patch5002: xserver-1.4.99-ssh-isnt-local.patch -Patch5004: xserver-autobind-hotplug.patch +Patch5004: 0001-autobind-GPUs-to-the-screen.patch Patch5005: 0001-link-with-z-now.patch # Bug 1166989 - Tcl/tk Canvas draw error Patch9423: RFC-mi-reduce-missing-segments-on-large-ellipse.patch +# Patch9504: 0001-rpath-hack.patch +Patch9710: 0001-modesetting-software-cursor-hack.patch -# Bug 1374198 - Xephyr crashes when launched over ssh X forwarding from Windows -Patch9430: 0001-xephyr-Check-for-host-XVideo-support-before-trying-t.patch - -Patch9504: 0001-rpath-hack.patch - -Patch9701: 0001-miarc-Style-cleanup-for-miWideArc.patch -Patch9702: 0002-miarc-Make-the-caller-free-the-arc-span-data.patch -Patch9703: 0003-miarc-Cache-arc-span-data-for-dashed-arcs.patch +# Bug 1599885 - RFE: enable backing store's Always mode +Patch9750: 0001-composite-Implement-backing-store-Always.patch -Patch9710: 0001-modesetting-software-cursor-hack.patch -Patch9711: 0001-handle-NullCursor-to-avoid-crash.patch -Patch9712: 0001-xfixes-Remove-the-CursorCurrent-array.patch -Patch9715: 0001-modesetting-Fix-PCI-initialization-on-non-zero-domai.patch -Patch9716: 0001-xfree86-Fix-off-by-one-in-X-configure.patch - -# Backport tablet support for Xwayland - *NOT* in server-1.19-branch -Patch9901: 0001-xwayland-Depend-on-wayland-protocols-to-build-tablet.patch -Patch9902: 0002-xwayland-Bind-to-wp_tablet_manager-if-available-and-.patch -Patch9903: 0003-xwayland-Listen-for-wp_tablet_seat-events.patch -Patch9904: 0004-xwayland-Handle-wp_tablet-events.patch -Patch9905: 0005-xwayland-Handle-tablet_tool-events.patch -Patch9906: 0006-xwayland-handle-button-events-after-motion-events.patch -Patch9907: 0007-xwayland-Refactor-cursor-management-into-xwl_cursor.patch -Patch9908: 0008-xwayland-update-cursor-on-tablet-tools-in-proximity.patch -Patch9909: 0009-xwayland-add-tablet-pad-support.patch -Patch9910: 0010-xwayland-Unconditionally-initialize-lists-in-init_ta.patch -Patch9911: 0011-xwayland-Correct-off-by-one-error-in-tablet-button-n.patch -Patch9912: 0012-xwayland-Implement-tablet_tool_wheel-for-scrolling.patch -# Bug 1544442 -Patch9913: 0001-xwayland-Keep-separate-variables-for-pointer-and-tab.patch - -Patch9922: 0002-animcur-Use-fixed-size-screen-private.patch -Patch9923: 0003-animcur-Return-the-next-interval-directly-from-the-t.patch -Patch9924: 0004-animcur-Run-the-timer-from-the-device-not-the-screen.patch -Patch9925: 0005-animcur-Fix-transitions-between-animated-cursors.patch -Patch9926: 0006-animcur-Change-which-CursorPtr-we-save-in-external-s.patch - -# Additional debug feature, allow to disable glamor in Xwayland using -# an envvar, could be useful in el7 - *NOT* in server-1.19-branch -Patch9951: 0001-xwayland-add-envvar-XWAYLAND_NO_GLAMOR.patch +Patch9751: 0001-glamor_egl-Don-t-initialize-on-llvmpipe.patch +Patch9752: 0001-xwayland-Don-t-initialize-glamor-on-llvmpipe.patch +Patch9753: 0001-linux-Make-platform-device-probe-less-fragile.patch +Patch9754: 0001-xfree86-try-harder-to-span-on-multihead.patch %global moduledir %{_libdir}/xorg/modules %global drimoduledir %{_libdir}/dri @@ -188,7 +156,7 @@ BuildRequires: pkgconfig(epoxy) BuildRequires: libXv-devel BuildRequires: pixman-devel >= 0.30.0 BuildRequires: libpciaccess-devel >= 0.13.1 openssl-devel byacc flex -BuildRequires: mesa-libGL-devel >= 9.2 mesa-libgbm-devel mesa-libEGL-devel +BuildRequires: pkgconfig(libglvnd) pkgconfig(gl) pkgconfig(gbm) pkgconfig(egl) # XXX silly... BuildRequires: libdrm-devel >= 2.4.0 kernel-headers @@ -391,13 +359,6 @@ test `getminor extension` == %{extension_minor} %endif -### -sed -i 's/MAXSCREENS\t16/MAXSCREENS\t32/g' include/misc.h -sed -i 's/MAXGPUSCREENS\t16/MAXGPUSCREENS\t32/g' include/misc.h -sed -i 's/MAXCLIENTS\t2048/MAXCLIENTS\t4096/g' include/misc.h -sed -i 's/LIMITCLIENTS\t256/LIMITCLIENTS\t1024/g' include/misc.h -### - %build %global default_font_path "catalogue:/etc/X11/fontpath.d,built-ins" @@ -405,11 +366,13 @@ sed -i 's/LIMITCLIENTS\t256/LIMITCLIENTS\t1024/g' include/misc.h %if %{with_hw_servers} %global dri_flags --with-dri-driver-path=%{drimoduledir} --enable-dri --enable-dri2 --enable-dri3 --enable-glamor --enable-xshmfence %else -%global dri_flags --disable-dri +# this is mostly for s390's sake, and should be unnecessary, but who wants to +# try fixing configure.ac? nobody, that's who. +%global dri_flags --disable-dri --disable-dri2 --disable-dri3 --disable-glamor %endif # ick -sed -i 's/WAYLAND_SCANNER_RULES.*//g' configure.ac +# sed -i 's/WAYLAND_SCANNER_RULES.*//g' configure.ac # --with-pie ? autoreconf -f -v --install || exit 1 @@ -436,7 +399,7 @@ autoreconf -f -v --install || exit 1 %{?wayland} \ %{dri_flags} %{?bodhi_flags} \ ${CONFIGURE} - + make V=1 %{?_smp_mflags} %install @@ -492,6 +455,7 @@ find . -type f | egrep '.*\.(c|h|am|ac|inc|m4|h.in|pc.in|man.pre|pl|txt)$' | xargs tar cf - | (cd %{inst_srcdir} && tar xf -) # SLEDGEHAMMER find %{inst_srcdir}/hw/xfree86 -name \*.c -delete +find %{inst_srcdir}/hw/xwayland -name \*.[ch] -delete # Remove unwanted files/dirs { @@ -623,6 +587,33 @@ rm -rf $RPM_BUILD_ROOT %{xserver_source_dir} %changelog +* Mon Sep 24 2018 Adam Jackson - 1.20.1-3 +- Try harder to come up with an initial spanning configuration + +* Wed Sep 19 2018 Adam Jackson - 1.20.1-2 +- Make platform device probe a bit less fragile +- Disable glamor on llvmpipe + +* Thu Aug 09 2018 Adam Jackson - 1.20.1-1 +- xserver 1.20.1 +- Enable backing store's Always mode + +* Thu Jul 19 2018 Peter Hutterer 1.20.0-2 +- Fix glx vendor hash table key size +- Fix memory corruption during PanoramiX setup (#1601742) + +* Tue Jul 10 2018 Adam Jackson - 1.20.0-1 +- Fix 16bpp with modesetting driver + +* Wed Jun 27 2018 Lyude Paul - 1.20.0-0.3 +- Add patches for bz1591978 + +* Wed Jun 27 2018 Lyude Paul - 1.20.0-0.2 +- Add patches for bz1585252 + +* Tue May 29 2018 Adam Jackson - 1.20.0-0.1 +- Initial 1.20 rebuild + * Tue Feb 13 2018 Adam Jackson - 1.19.5-5 - Fix fetching animated cursor images with the XFIXES extension