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

Keith Packard keithp at keithp.com
Thu Jul 24 16:18:28 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  | 40 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index ae33938..fa2aa64 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -194,6 +194,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;
+
 #if USE_UXA
 	struct _UxaDriver *uxa_driver;
 	int uxa_flags;
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 1d4ba3c..758f01f 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -2319,7 +2319,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;
 
@@ -2339,30 +2339,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 316de64..0475a17 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -170,13 +170,19 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
         case ACCEL_GLAMOR:
                 if (!intel_glamor_create_screen_resources(screen))
                         return FALSE;
+#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
+                screen->canDoBGNoneRoot = TRUE;
+#endif
                 break;
 #endif
 #if USE_UXA
         case ACCEL_UXA:
                 if (!intel_uxa_create_screen_resources(screen))
                         return FALSE;
-                intel_copy_fb(scrn);
+#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
+                screen->canDoBGNoneRoot = TRUE;
+#endif
+                break;
 #endif
         case ACCEL_NONE:
                 if (!intel_none_create_screen_resources(screen))
@@ -830,6 +836,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;
@@ -1211,11 +1240,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