[PATCH xf86-video-amdgpu] Use a timer for unreferencing the all-black FB

Deucher, Alexander Alexander.Deucher at amd.com
Wed Aug 30 15:14:40 UTC 2017


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Wednesday, August 30, 2017 4:25 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-amdgpu] Use a timer for unreferencing the all-
> black FB
> 
> From: Michel Dänzer <michel.daenzer at amd.com>
> 
> 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: c16ff42f927d ("Make all active CRTCs scan out an all-black
>                       framebuffer in LeaveVT")
> (Ported from radeon commit 9d9c565c84601f4c6c73ad769f86491088683f7a)
> 
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/amdgpu_kms.c | 42 +++++++++++++++++++++++++++---------------
>  1 file changed, 27 insertions(+), 15 deletions(-)
> 
> diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
> index c3613eb8d..d82ead2ac 100644
> --- a/src/amdgpu_kms.c
> +++ b/src/amdgpu_kms.c
> @@ -1044,7 +1044,6 @@ static void
> AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
>  {
>  	SCREEN_PTR(arg);
>  	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> -	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
>  	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
>  	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
>  	int c;
> @@ -1053,21 +1052,8 @@ static void
> AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
>  	(*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
>  	pScreen->BlockHandler = AMDGPUBlockHandler_KMS;
> 
> -	if (!xf86ScreenToScrn(amdgpu_master_screen(pScreen))->vtSema) {
> -		/* Unreference the all-black FB created by
> AMDGPULeaveVT_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(pAMDGPUEnt->fd,
> &drmmode_crtc->fb,
> -					     NULL);
> -		}
> -
> +	if (!xf86ScreenToScrn(amdgpu_master_screen(pScreen))->vtSema)
>  		return;
> -	}
> 
>  	if (!amdgpu_is_gpu_screen(pScreen))
>  	{
> @@ -1629,6 +1615,30 @@ static void
> amdgpu_drop_drm_master(ScrnInfoPtr pScrn)
>  }
> 
> 
> +static
> +CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data)
> +{
> +	ScreenPtr screen = data;
> +	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
> +	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
> +	int c;
> +
> +	if (xf86ScreenToScrn(amdgpu_master_screen(screen))->vtSema)
> +		return 0;
> +
> +	/* Unreference the all-black FB created by AMDGPULeaveVT_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(pAMDGPUEnt->fd,
> &drmmode_crtc->fb, NULL);
> +	}
> +
> +	return 0;
> +}
> 
>  static Bool AMDGPUSaveScreen_KMS(ScreenPtr pScreen, int mode)
>  {
> @@ -2061,6 +2071,8 @@ void
> AMDGPULeaveVT_KMS(VT_FUNC_ARGS_DECL)
>  	}
>  	pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None,
> pAMDGPUEnt);
> 
> +	TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
> +
>  	xf86_hide_cursors(pScrn);
> 
>  	amdgpu_drop_drm_master(pScrn);
> --
> 2.14.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list