summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2017-08-29 18:07:51 +0900
committerMichel Dänzer <michel@daenzer.net>2017-08-29 18:07:51 +0900
commit9d9c565c84601f4c6c73ad769f86491088683f7a (patch)
tree1bd4a7cb1d28624346b14d5d069794bf91ec493a
parente4a3df19d588a4310fcb889ef34e205d0e92e4d7 (diff)
Use a timer for unreferencing the all-black FB
The timer fires 1 second after LeaveVT. This gives the next DRM master enough time to set up scanout of its own buffers. Fixes prolonged intermittent black screen when switching from Xorg to e.g. the GDM Wayland mode login VT. Fixes: 06a465484101 ("Make all active CRTCs scan out an all-black framebuffer in LeaveVT") Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--src/radeon_kms.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 5410c420..01594c6c 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1150,7 +1150,6 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
{
SCREEN_PTR(arg);
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
RADEONInfoPtr info = RADEONPTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int c;
@@ -1159,19 +1158,8 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
pScreen->BlockHandler = RADEONBlockHandler_KMS;
- if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) {
- /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After
- * this, there should be no FB left created by this driver.
- */
- for (c = 0; c < xf86_config->num_crtc; c++) {
- drmmode_crtc_private_ptr drmmode_crtc =
- xf86_config->crtc[c]->driver_private;
-
- drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL);
- }
-
+ if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema)
return;
- }
if (!radeon_is_gpu_screen(pScreen))
{
@@ -2473,6 +2461,30 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
return TRUE;
}
+static
+CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data)
+{
+ ScreenPtr screen = data;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ if (xf86ScreenToScrn(radeon_master_screen(screen))->vtSema)
+ return 0;
+
+ /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After
+ * this, there should be no FB left created by this driver.
+ */
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ drmmode_crtc_private_ptr drmmode_crtc =
+ xf86_config->crtc[c]->driver_private;
+
+ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL);
+ }
+
+ return 0;
+}
static void
pixmap_unref_fb(void *value, XID id, void *cdata)
@@ -2569,6 +2581,8 @@ void RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL)
}
pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt);
+ TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
+
xf86_hide_cursors (pScrn);
radeon_drop_drm_master(pScrn);