xf86-video-intel: 3 commits - src/intel_display.c src/intel_driver.c src/intel.h src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna_glyphs.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Jun 12 07:19:59 PDT 2012


 src/intel.h           |    1 
 src/intel_display.c   |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/intel_driver.c    |    6 +-
 src/sna/sna.h         |    1 
 src/sna/sna_display.c |   10 +++
 src/sna/sna_driver.c  |    3 +
 src/sna/sna_glyphs.c  |   16 +-----
 7 files changed, 152 insertions(+), 14 deletions(-)

New commits:
commit 3b9b64c7c9b5b0bfaafb97c9a9fe5849bbb412da
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Jun 12 10:26:34 2012 +0100

    uxa: do copy fb at startup.
    
    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. [ickle: The
    earliest version I've found had krh's fingerprints on it, though it may
    still have been a joint effort.]
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    [ickle: improve error handling, only copy the fb during initial takeover]

diff --git a/src/intel.h b/src/intel.h
index 20d8282..caf07bb 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -368,6 +368,7 @@ extern void intel_mode_fini(intel_screen_private *intel);
 extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
 extern int intel_crtc_id(xf86CrtcPtr crtc);
 extern int intel_output_dpms_status(xf86OutputPtr output);
+extern void intel_copy_fb(ScrnInfoPtr scrn);
 
 enum DRI2FrameEventType {
 	DRI2_SWAP,
diff --git a/src/intel_display.c b/src/intel_display.c
index 6f3f7e6..8de6344 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <poll.h>
+#include <sys/ioctl.h>
 
 #include "xorgVersion.h"
 
@@ -45,6 +46,8 @@
 #include "X11/Xatom.h"
 #include "X11/extensions/dpmsconst.h"
 #include "xf86DDC.h"
+#include "fb.h"
+#include "uxa.h"
 
 #include "intel_glamor.h"
 
@@ -1748,3 +1751,129 @@ Bool intel_crtc_on(xf86CrtcPtr crtc)
 
 	return ret;
 }
+
+static PixmapPtr
+intel_create_pixmap_for_bo(ScreenPtr pScreen, dri_bo *bo,
+			   int width, int height,
+			   int depth, int bpp,
+			   int pitch)
+{
+	PixmapPtr pixmap;
+
+	pixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, 0);
+	if (pixmap == NullPixmap)
+		return pixmap;
+
+	if (!pScreen->ModifyPixmapHeader(pixmap,
+					 width, height,
+					 depth, bpp,
+					 pitch, NULL)) {
+		pScreen->DestroyPixmap(pixmap);
+		return NullPixmap;
+	}
+
+	intel_set_pixmap_bo(pixmap, bo);
+	return pixmap;
+}
+
+static PixmapPtr
+intel_create_pixmap_for_fbcon(ScrnInfoPtr scrn, int fbcon_id)
+{
+	ScreenPtr pScreen = xf86ScrnToScreen(scrn);
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	struct intel_mode *mode = intel->modes;
+	int fd = mode->fd;
+	drmModeFBPtr fbcon;
+	struct drm_gem_flink flink;
+	drm_intel_bo *bo;
+	PixmapPtr pixmap = NullPixmap;
+
+	fbcon = drmModeGetFB(fd, fbcon_id);
+	if (fbcon == NULL)
+		return NULL;
+
+	if (fbcon->depth != scrn->depth ||
+	    fbcon->width != scrn->virtualX ||
+	    fbcon->height != scrn->virtualY)
+		goto out_free_fb;
+
+	flink.handle = fbcon->handle;
+	if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't flink fbcon handle\n");
+		goto out_free_fb;
+	}
+
+	bo = drm_intel_bo_gem_create_from_name(intel->bufmgr,
+					       "fbcon", flink.name);
+	if (bo == NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate bo for fbcon handle\n");
+		goto out_free_fb;
+	}
+
+	pixmap = intel_create_pixmap_for_bo(pScreen, bo,
+					    fbcon->width, fbcon->height,
+					    fbcon->depth, fbcon->bpp,
+					    fbcon->pitch);
+	if (pixmap == NullPixmap)
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate pixmap fbcon contents\n");
+	drm_intel_bo_unreference(bo);
+out_free_fb:
+	drmModeFreeFB(fbcon);
+
+	return pixmap;
+}
+
+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, fbcon_id;
+
+	if (intel->force_fallback)
+		return;
+
+	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)
+		return;
+
+	src = intel_create_pixmap_for_fbcon(scrn, fbcon_id);
+	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);
+	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);
+	pScreen->canDoBGNoneRoot = TRUE;
+
+cleanup_dst:
+	(*pScreen->DestroyPixmap)(dst);
+cleanup_src:
+	(*pScreen->DestroyPixmap)(src);
+}
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 67cec48..8962a11 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -167,7 +167,11 @@ static Bool i830CreateScreenResources(ScreenPtr screen)
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
 
-	return intel_uxa_create_screen_resources(screen);
+	if (!intel_uxa_create_screen_resources(screen))
+		return FALSE;
+
+	intel_copy_fb(scrn);
+	return TRUE;
 }
 
 static void PreInitCleanup(ScrnInfoPtr scrn)
commit b6525702b9ffd21beb8ea6bb10a8ad5ce7f9de14
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 12 11:59:31 2012 +0100

    sna: Hook up AdjustFrame()
    
    Looks to be unused by the core, just a solitary invocation in an obscure
    extension it seems. However the implementation looks trivial so
    incorporate it until it is finally removed, just in case.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 16bdf13..9453c20 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -301,6 +301,7 @@ struct sna {
 };
 
 Bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
+void sna_mode_adjust_frame(struct sna *sna, int x, int y);
 extern void sna_mode_remove_fb(struct sna *sna);
 extern void sna_mode_update(struct sna *sna);
 extern void sna_mode_fini(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 7926f8f..37709ee 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -765,6 +765,16 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	return TRUE;
 }
 
+void sna_mode_adjust_frame(struct sna *sna, int x, int y)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	xf86OutputPtr output = config->output[config->compat_output];
+	xf86CrtcPtr crtc = output->crtc;
+
+	if (crtc && crtc->enabled)
+		sna_crtc_set_mode_major(crtc, &crtc->mode, crtc->rotation, x, y);
+}
+
 static void
 sna_crtc_hide_cursor(xf86CrtcPtr crtc)
 {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 64132b5..e585205 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -943,6 +943,9 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
 
 static void sna_adjust_frame(ADJUST_FRAME_ARGS_DECL)
 {
+	SCRN_INFO_PTR(arg);
+	DBG(("%s(%d, %d)\n", __FUNCTION__, x, y));
+	sna_mode_adjust_frame(to_sna(scrn), x, y);
 }
 
 static void sna_free_screen(FREE_SCREEN_ARGS_DECL)
commit 7b281d1300127d65392aaadbbe2299fa9e1749a9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 12 10:37:04 2012 +0100

    sna: Remove a pair of empty stub functions
    
    The export wrappers for the glyph cache constructor/destructor existed
    in case there was a need to add more routines. Since that never
    happened, remove the extra step of indirection.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index ca70e76..63a6287 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -114,7 +114,7 @@ static inline struct sna_glyph *sna_glyph(GlyphPtr glyph)
 
 #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
 
-static void unrealize_glyph_caches(struct sna *sna)
+void sna_glyphs_close(struct sna *sna)
 {
 	struct sna_render *render = &sna->render;
 	unsigned int i;
@@ -150,7 +150,7 @@ static void unrealize_glyph_caches(struct sna *sna)
  * This function allocates the storage pixmap, and then fills in the
  * rest of the allocated structures for all caches with the given format.
  */
-static Bool realize_glyph_caches(struct sna *sna)
+Bool sna_glyphs_create(struct sna *sna)
 {
 	ScreenPtr screen = sna->scrn->pScreen;
 	pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
@@ -221,7 +221,7 @@ static Bool realize_glyph_caches(struct sna *sna)
 	return sna->render.white_image && sna->render.white_picture;
 
 bail:
-	unrealize_glyph_caches(sna);
+	sna_glyphs_close(sna);
 	return FALSE;
 }
 
@@ -1032,11 +1032,6 @@ next_glyph:
 	return TRUE;
 }
 
-Bool sna_glyphs_create(struct sna *sna)
-{
-	return realize_glyph_caches(sna);
-}
-
 static PictFormatPtr
 glyphs_format(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
@@ -1424,8 +1419,3 @@ sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 		priv->atlas = NULL;
 	}
 }
-
-void sna_glyphs_close(struct sna *sna)
-{
-	unrealize_glyph_caches(sna);
-}


More information about the xorg-commit mailing list