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

Deucher, Alexander Alexander.Deucher at amd.com
Tue Aug 29 13:50:03 UTC 2017



> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Tuesday, August 29, 2017 5:18 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-ati] 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: 06a465484101 ("Make all active CRTCs scan out an all-black
>                       framebuffer in LeaveVT")
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

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

> ---
>  src/radeon_kms.c | 40 +++++++++++++++++++++++++++-------------
>  1 file changed, 27 insertions(+), 13 deletions(-)
> 
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index 5410c4208..01594c6ca 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);
> --
> 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