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

Keith Packard
2014-07-24T23:18:28Z

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-aN4HjG94KOLQT0dZR+AlfA@public.gmane.org>
---
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

_______________________________________________
xorg-devel-go0+a7rfsptAfugRpC6u6w@public.gmane.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel