guibuilder_pel7x64builder0
6 years ago
10 changed files with 1654 additions and 95 deletions
@ -0,0 +1,293 @@
@@ -0,0 +1,293 @@
|
||||
From 471289fa1dc359555ceed6302f7d9605ab6be3ea Mon Sep 17 00:00:00 2001 |
||||
From: Dave Airlie <airlied@redhat.com> |
||||
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 <airlied@gmail.com> |
||||
[hdegoede@redhat.com: Make configurable, fix with nvidia, submit upstream] |
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
||||
--- |
||||
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 |
||||
|
@ -0,0 +1,933 @@
@@ -0,0 +1,933 @@
|
||||
From e3891866bcb133289d923b645228d70d55c67706 Mon Sep 17 00:00:00 2001 |
||||
From: rpm-build <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 |
||||
|
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
From 722dc4717a4bb1c0ff84f45d0251e3e456476a28 Mon Sep 17 00:00:00 2001 |
||||
From: Adam Jackson <ajax@redhat.com> |
||||
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 |
||||
|
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
From b96e7972e90144a697401f393ae8e1e12b3e767c Mon Sep 17 00:00:00 2001 |
||||
From: Adam Jackson <ajax@redhat.com> |
||||
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 |
||||
|
@ -1,26 +1,27 @@
@@ -1,26 +1,27 @@
|
||||
From 5c7617de1777845d1609b301c0f470c90338d06f Mon Sep 17 00:00:00 2001 |
||||
From: rpm-build <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 <ajax@redhat.com> |
||||
Date: Tue, 29 May 2018 15:05:10 -0400 |
||||
Subject: [PATCH] xfree86: Don't autoconfigure vesa or fbdev |
||||
|
||||
Signed-off-by: Adam Jackson <ajax@redhat.com> |
||||
--- |
||||
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 |
||||
|
||||
|
@ -0,0 +1,190 @@
@@ -0,0 +1,190 @@
|
||||
From 326f992a90dae7a747da45626e588fa3c1dfa5dc Mon Sep 17 00:00:00 2001 |
||||
From: Ray Strode <rstrode@redhat.com> |
||||
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 |
||||
|
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
From c64865691df6d2ad18aeecaecb0cb9a94b5d71eb Mon Sep 17 00:00:00 2001 |
||||
From: Adam Jackson <ajax@redhat.com> |
||||
Date: Wed, 19 Sep 2018 10:56:29 -0400 |
||||
Subject: [PATCH] xwayland: Don't initialize glamor on llvmpipe |
||||
|
||||
Signed-off-by: Adam Jackson <ajax@redhat.com> |
||||
--- |
||||
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 |
||||
|
Loading…
Reference in new issue