[PATCH 07/18] Delay initial modeset until root window contents are prepared

Keith Packard keithp at keithp.com
Sat Aug 16 23:13:10 PDT 2014


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);
+
+                /* 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);
+        }
+
 	(*screen->BlockHandler) (BLOCKHANDLER_ARGS);
 
 	intel->BlockHandler = screen->BlockHandler;
@@ -1053,11 +1075,12 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 	I830UeventInit(scrn);
 #endif
 
-	/* 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;
+        /* Delay the call to I830EnterVT until
+         * the server is all ready to accept protocol requests.
+         */
+        intel->need_entervt = TRUE;
 
-	return I830EnterVT(VT_FUNC_ARGS(0));
+        return TRUE;
 }
 
 static void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL)
-- 
2.0.1



More information about the xorg-devel mailing list