[PATCH 07/18] Delay initial modeset until root window contents are prepared
Eric Anholt
eric at anholt.net
Mon Aug 25 13:33:07 PDT 2014
Keith Packard <keithp at keithp.com> writes:
> Wait until the root window has been painted for the first time before
> doing the modeset. This avoids flashing black while the root window
> gets set up.
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
> src/uxa/intel.h | 2 ++
> src/uxa/intel_display.c | 39 ++++++++++++++++++---------------------
> src/uxa/intel_driver.c | 33 ++++++++++++++++++++++++++++-----
> 3 files changed, 48 insertions(+), 26 deletions(-)
>
> diff --git a/src/uxa/intel.h b/src/uxa/intel.h
> index ceb20ea..c8bdaf3 100644
> --- a/src/uxa/intel.h
> +++ b/src/uxa/intel.h
> @@ -235,6 +235,8 @@ typedef struct intel_screen_private {
> void (*batch_flush) (struct intel_screen_private *intel);
> void (*batch_commit_notify) (struct intel_screen_private *intel);
>
> + Bool need_entervt;
> +
> struct _UxaDriver *uxa_driver;
> int uxa_flags;
> Bool need_sync;
> diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
> index c9e7669..9720fc3 100644
> --- a/src/uxa/intel_display.c
> +++ b/src/uxa/intel_display.c
> @@ -2300,7 +2300,7 @@ void intel_copy_fb(ScrnInfoPtr scrn)
> ScreenPtr pScreen = xf86ScrnToScreen(scrn);
> intel_screen_private *intel = intel_get_screen_private(scrn);
> PixmapPtr src, dst;
> - unsigned int pitch = scrn->displayWidth * intel->cpp;
> + GCPtr gc;
> struct intel_crtc *intel_crtc;
> int i, fbcon_id;
>
> @@ -2320,30 +2320,27 @@ void intel_copy_fb(ScrnInfoPtr scrn)
> if (src == NULL)
> return;
>
> - /* We dont have a screen Pixmap yet */
> - dst = intel_create_pixmap_for_bo(pScreen, intel->front_buffer,
> - scrn->virtualX, scrn->virtualY,
> - scrn->depth, scrn->bitsPerPixel,
> - pitch);
> + dst = (*pScreen->GetScreenPixmap)(pScreen);
> +
> if (dst == NullPixmap)
> goto cleanup_src;
>
> - if (!intel->uxa_driver->prepare_copy(src, dst,
> - -1, -1,
> - GXcopy, FB_ALLONES))
> - goto cleanup_dst;
> -
> - intel->uxa_driver->copy(dst,
> - 0, 0,
> - 0, 0,
> - scrn->virtualX, scrn->virtualY);
> - intel->uxa_driver->done_copy(dst);
> -#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
> - pScreen->canDoBGNoneRoot = TRUE;
> -#endif
> + gc = GetScratchGC(scrn->depth, pScreen);
> +
> + if (!gc)
> + goto cleanup_src;
> +
> + ValidateGC(&dst->drawable, gc);
> +
> + (*gc->ops->CopyArea)(&src->drawable,
> + &dst->drawable,
> + gc,
> + 0, 0,
> + scrn->virtualX, scrn->virtualY,
> + 0, 0);
> +
> + FreeScratchGC(gc);
>
> -cleanup_dst:
> - (*pScreen->DestroyPixmap)(dst);
> cleanup_src:
> (*pScreen->DestroyPixmap)(src);
> }
> diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
> index a7ca906..d34c6d7 100644
> --- a/src/uxa/intel_driver.c
> +++ b/src/uxa/intel_driver.c
> @@ -165,7 +165,6 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
> if (!intel_uxa_create_screen_resources(screen))
> return FALSE;
>
> - intel_copy_fb(scrn);
> return TRUE;
> }
>
> @@ -699,6 +698,29 @@ I830BlockHandler(BLOCKHANDLER_ARGS_DECL)
>
> screen->BlockHandler = intel->BlockHandler;
>
> + /* At server init time, get the root window bits from fbcon if
> + * available and then update the protocol-level information
> + * for both RandR and XINERAMA
> + */
> + if (intel->need_entervt) {
> + intel->need_entervt = FALSE;
> +
> + if (screen->root->backgroundState == None)
> + intel_copy_fb(scrn);
What guarantees that no important rendering has happened before the
first BlockHandler, which would get overridden by intel_copy_fb()?
> + /* Must force it before EnterVT, so we are in control of VT and
> + * later memory should be bound when allocating, e.g rotate_mem */
> + scrn->vtSema = TRUE;
> +
> + if (!I830EnterVT(VT_FUNC_ARGS(0))) {
> + xf86DrvMsg(scrn->scrnIndex, X_ERROR,
> + "Failed to perform initial modeset.\n");
> + FatalError("Mode set failed\n");
> + }
> +
> + xf86RandR12CreateScreenResources(screen);
Delaying setting up things like pScreen->width/height and mmWidth/Height
until the first BlockHandler also seems really creepy.
> + }
> +
> (*screen->BlockHandler) (BLOCKHANDLER_ARGS);
I expected this patch overall to be "delay the first call to the kernel
for the actual modeset/flip until blockhandler", but it looks like
"delay modesetting-related probing and initial root window rendering to
the first blockhandler", which I don't feel a good reason to trust.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg-devel/attachments/20140825/4a610f36/attachment.sig>
More information about the xorg-devel
mailing list