[PATCH] intel/uxa: do copy fb at startup.

Chris Wilson chris at chris-wilson.co.uk
Tue Jun 12 03:23:22 PDT 2012


On Tue, 12 Jun 2012 10:26:34 +0100, Dave Airlie <airlied at gmail.com> wrote:
> Copy the current framebuffer for smooth wayland->gdm handoff.
> 
> This has been hanging around in Fedora for too long now, and we've
> dropped the feature a few times, and yes I know the Simpsons did it^W^W^W
> SNA does it.
> 
> I've updated the code to have some of the better fixes from nouveau.
> 
> I've no idea who wrote this code either, krh or ajax.

Looks like it shouldn't in principle suffer from the false errors that
permeate the Ubuntu logs, though it still emits an X_ERROR for sane
failure modes.
 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> +void intel_copy_fb(ScrnInfoPtr scrn)
> +{
> +	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
> +	ScreenPtr pScreen = xf86ScrnToScreen(scrn);
> +	intel_screen_private *intel = intel_get_screen_private(scrn);
> +	PixmapPtr src, dst;
> +	unsigned int pitch = scrn->displayWidth * intel->cpp;
> +	struct intel_crtc *intel_crtc;
> +	int i;
> +	int fbcon_id = 0;
> +	for (i = 0; i < xf86_config->num_crtc; i++) {
> +		intel_crtc = xf86_config->crtc[i]->driver_private;
> +		if (intel_crtc->mode_crtc->buffer_id)
> +			fbcon_id = intel_crtc->mode_crtc->buffer_id;
> +	}
> +	if (!fbcon_id)
> +		goto fallback;
> +
> +	src = intel_create_pixmap_for_fbcon(scrn, fbcon_id);
> +	if (src == NULL) {
> +		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
> +			   "Couldn't create pixmap for fbcon\n");
> +		return;
> +	}
> +
> +	/* We dont have a screen Pixmap yet */
> +	dst = GetScratchPixmapHeader(pScreen,
> +				     scrn->virtualX, scrn->virtualY,
> +				     scrn->depth, scrn->bitsPerPixel,
> +				     pitch,
> +				     NULL);
> +	intel_set_pixmap_bo(dst, intel->front_buffer);
> +
> +	intel->uxa_driver->prepare_copy(src, dst, -1, -1, GXcopy, FB_ALLONES);
> +
> +	intel->uxa_driver->copy(dst, 0, 0, 0, 0,
> +				scrn->virtualX, scrn->virtualY);
> +
> +	intel->uxa_driver->done_copy(dst);
> +
> +	/* I830EmitFlush(scrn); */
> +	intel_batch_submit(scrn);

Should be handled by the flush during mode change.

> +
> +	(*pScreen->DestroyPixmap)(src);
> +	(*pScreen->DestroyPixmap)(dst);

We've broken the symmetry here between GetScratchPixmapHeader and
FreeScratchPixmapHeader. Instead of using GetScratchPixmapHeader
allocate a 0x0 pixmap and ModifyPixmapHeader. A little function to wrap
a bo into a pixmap would help here.

> +
> +	pScreen->canDoBGNoneRoot = TRUE;

The prepare_copy could theoretically fail. So it needs error handling
and we need to let the core know that it needs to fill the background.
(Well, the conditions under which is could fail are likely fatal, but
there should at least be a check for a hung GPU somewhere in this path.)

> +	return;
> +fallback:
> +	return;
> +}
> diff --git a/src/intel_driver.c b/src/intel_driver.c
> index 67cec48..703c3a3 100644
> --- a/src/intel_driver.c
> +++ b/src/intel_driver.c
> @@ -83,6 +83,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
>  static void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL);
>  static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL);
>  static Bool I830EnterVT(VT_FUNC_ARGS_DECL);
> +static Bool I830EnterVT_copy(ScrnInfoPtr pScrn, Bool copy_fb);
>  
>  /* temporary */
>  extern void xf86SetCursor(ScreenPtr screen, CursorPtr pCurs, int x, int y);
> @@ -167,6 +168,7 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
>  	if (!(*screen->CreateScreenResources) (screen))
>  		return FALSE;
>  
> +	intel_copy_fb(scrn);
>  	return intel_uxa_create_screen_resources(screen);
>  }
>  
> @@ -1007,7 +1009,7 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
>  	 * later memory should be bound when allocating, e.g rotate_mem */
>  	scrn->vtSema = TRUE;
>  
> -	return I830EnterVT(VT_FUNC_ARGS(0));
> +	return I830EnterVT_copy(scrn, FALSE);
>  }
>  
>  static void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL)
> @@ -1048,9 +1050,8 @@ static void I830LeaveVT(VT_FUNC_ARGS_DECL)
>  /*
>   * This gets called when gaining control of the VT, and from ScreenInit().
>   */
> -static Bool I830EnterVT(VT_FUNC_ARGS_DECL)
> +static Bool I830EnterVT_copy(ScrnInfoPtr scrn, Bool copy_fb)
>  {
> -	SCRN_INFO_PTR(arg);
>  	intel_screen_private *intel = intel_get_screen_private(scrn);
>  	int ret;
>  
> @@ -1061,12 +1062,21 @@ static Bool I830EnterVT(VT_FUNC_ARGS_DECL)
>  			   strerror(errno));
>  	}
>  
> +	if (copy_fb)
> +		intel_copy_fb(scrn);
> +
>  	if (!xf86SetDesiredModes(scrn))
>  		return FALSE;
>  
>  	return TRUE;
>  }
>  
> +static Bool I830EnterVT(VT_FUNC_ARGS_DECL)
> +{
> +	SCRN_INFO_PTR(arg);
> +	return I830EnterVT_copy(scrn, TRUE);

We only want to copy the initial fb on startup not on every VT switch,
right?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the xorg-devel mailing list