Commit bdd1e22c authored by Aaron Plattner's avatar Aaron Plattner Committed by Keith Packard

xfree86: detach scanout pixmaps when detaching output GPUs

Commit 8f4640bd fixed a bit of a
chicken-and-egg problem by detaching GPU screens when their providers
are destroyed, which happens before CloseScreen is called.  However,
this created a new problem: the GPU screen tears down its RandR crtc
objects during CloseScreen and if one of them is active, it tries to
detach the scanout pixmap then.  This crashes because
RRCrtcDetachScanoutPixmap tries to get the master screen's screen
pixmap, but crtc->pScreen->current_master is already NULL at that
point.

It doesn't make sense for an unbound GPU screen to still be scanning
out its former master screen's pixmap, so detach them first when the
provider is destroyed.
Signed-off-by: Aaron Plattner's avatarAaron Plattner <aplattner@nvidia.com>
Reviewed-by: default avatarDave Airlie <airlied@redhat.com>
Signed-off-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
parent 43ac0491
...@@ -1771,6 +1771,19 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn) ...@@ -1771,6 +1771,19 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn)
return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
} }
static void
xf86DetachOutputGPU(ScreenPtr pScreen)
{
rrScrPrivPtr rp = rrGetScrPriv(pScreen);
int i;
/* make sure there are no attached shared scanout pixmaps first */
for (i = 0; i < rp->numCrtcs; i++)
RRCrtcDetachScanoutPixmap(rp->crtcs[i]);
DetachOutputGPU(pScreen);
}
static Bool static Bool
xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen, xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen,
RRProviderPtr provider, RRProviderPtr provider,
...@@ -1780,7 +1793,7 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen, ...@@ -1780,7 +1793,7 @@ xf86RandR14ProviderSetOutputSource(ScreenPtr pScreen,
if (provider->output_source) { if (provider->output_source) {
ScreenPtr cmScreen = pScreen->current_master; ScreenPtr cmScreen = pScreen->current_master;
DetachOutputGPU(pScreen); xf86DetachOutputGPU(pScreen);
AttachUnboundGPU(cmScreen, pScreen); AttachUnboundGPU(cmScreen, pScreen);
} }
provider->output_source = NULL; provider->output_source = NULL;
...@@ -1808,7 +1821,7 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen, ...@@ -1808,7 +1821,7 @@ xf86RandR14ProviderSetOffloadSink(ScreenPtr pScreen,
if (!sink_provider) { if (!sink_provider) {
if (provider->offload_sink) { if (provider->offload_sink) {
ScreenPtr cmScreen = pScreen->current_master; ScreenPtr cmScreen = pScreen->current_master;
DetachOutputGPU(pScreen); xf86DetachOutputGPU(pScreen);
AttachUnboundGPU(cmScreen, pScreen); AttachUnboundGPU(cmScreen, pScreen);
} }
...@@ -1899,7 +1912,7 @@ xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider) ...@@ -1899,7 +1912,7 @@ xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider)
RRSetChanged(screen); RRSetChanged(screen);
} }
else if (config->randr_provider->output_source) { else if (config->randr_provider->output_source) {
DetachOutputGPU(screen); xf86DetachOutputGPU(screen);
config->randr_provider->output_source = NULL; config->randr_provider->output_source = NULL;
RRSetChanged(screen); RRSetChanged(screen);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment