xf86-video-intel: src/sna/Makefile.am src/sna/sna_display.c src/sna/sna_display_fake.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Mar 7 02:04:01 PST 2013


 src/sna/Makefile.am        |    1 
 src/sna/sna.h              |    1 
 src/sna/sna_display.c      |   25 ++-
 src/sna/sna_display_fake.c |  320 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 342 insertions(+), 5 deletions(-)

New commits:
commit 5f1c2b3b8bb062a4574e5114b09a33b7e4f0c811
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 7 09:40:06 2013 +0000

    sna: Supply a fake pipe to run completely headless
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index b5da0cf..0fbd19d 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -52,6 +52,7 @@ libsna_la_SOURCES = \
 	sna_damage.c \
 	sna_damage.h \
 	sna_display.c \
+	sna_display_fake.c \
 	sna_driver.c \
 	sna_glyphs.c \
 	sna_gradient.c \
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7dc838c..8f26be9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -305,6 +305,7 @@ struct sna {
 };
 
 bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
+bool sna_mode_fake_init(struct sna *sna);
 void sna_mode_adjust_frame(struct sna *sna, int x, int y);
 extern void sna_mode_update(struct sna *sna);
 extern void sna_mode_disable_unused(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 30160a5..be6c61d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -778,6 +778,9 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 	struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
 	struct drm_mode_crtc arg;
 
+	if (sna_crtc == NULL)
+		return;
+
 	DBG(("%s: disabling crtc [%d]\n", __FUNCTION__, sna_crtc->id));
 
 	memset(&arg, 0, sizeof(arg));
@@ -802,6 +805,9 @@ static void update_flush_interval(struct sna *sna)
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
 
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		if (!crtc->enabled) {
 			DBG(("%s: CRTC:%d (pipe %d) disabled\n",
 			     __FUNCTION__,i, to_sna_crtc(crtc)->pipe));
@@ -899,6 +905,9 @@ void sna_copy_fbcon(struct sna *sna)
 		struct sna_crtc *crtc = to_sna_crtc(xf86_config->crtc[i]);
 		struct drm_mode_crtc mode;
 
+		if (!crtc)
+			continue;
+
 		VG_CLEAR(mode);
 		mode.crtc_id = crtc->id;
 		if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
@@ -1444,7 +1453,7 @@ sna_crtc_destroy(xf86CrtcPtr crtc)
 
 #if HAS_PIXMAP_SHARING
 static Bool
-sna_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
+sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
 {
 	DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
 	     __FUNCTION__,to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe,
@@ -1465,7 +1474,7 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = {
 	.gamma_set = sna_crtc_gamma_set,
 	.destroy = sna_crtc_destroy,
 #if HAS_PIXMAP_SHARING
-	.set_scanout_pixmap = sna_set_scanout_pixmap,
+	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
 #endif
 };
 
@@ -2644,12 +2653,10 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 
 	mode->kmode = drmModeGetResources(sna->kgem.fd);
 	if (!mode->kmode)
-		return true;
+		return sna_mode_fake_init(sna);
 
 	xf86CrtcConfigInit(scrn, &sna_crtc_config_funcs);
 
-	set_size_range(sna);
-
 	for (i = 0; i < mode->kmode->count_crtcs; i++)
 		sna_crtc_init(scrn, mode, i);
 
@@ -2659,6 +2666,8 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 	if (!xf86IsEntityShared(scrn->entityList[0]))
 		sna_mode_compute_possible_clones(scrn);
 
+	set_size_range(sna);
+
 #if HAS_PIXMAP_SHARING
 	xf86ProviderSetup(scrn, NULL, "Intel");
 #endif
@@ -2757,6 +2766,9 @@ sna_covering_crtc(ScrnInfoPtr scrn,
 		BoxRec cover_box;
 		int coverage;
 
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		/* If the CRTC is off, treat it as not covering */
 		if (to_sna_crtc(crtc)->bo == NULL) {
 			DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c));
@@ -3038,6 +3050,9 @@ void sna_mode_update(struct sna *sna)
 	/* Validate CRTC attachments */
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
+		if (to_sna_crtc(crtc) == NULL)
+			continue;
+
 		if (!crtc->active || !sna_crtc_is_bound(sna, crtc))
 			sna_crtc_disable(crtc);
 	}
diff --git a/src/sna/sna_display_fake.c b/src/sna/sna_display_fake.c
new file mode 100644
index 0000000..775810a
--- /dev/null
+++ b/src/sna/sna_display_fake.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sna.h"
+
+static void
+sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+}
+
+static Bool
+sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+			Rotation rotation, int x, int y)
+{
+	return TRUE;
+}
+
+static void
+sna_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+sna_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+sna_crtc_hide_cursor(xf86CrtcPtr crtc)
+{
+}
+
+static void
+sna_crtc_show_cursor(xf86CrtcPtr crtc)
+{
+}
+
+static void
+sna_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static void
+sna_crtc_gamma_set(xf86CrtcPtr crtc,
+		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+}
+
+static void
+sna_crtc_destroy(xf86CrtcPtr crtc)
+{
+}
+
+#if HAS_PIXMAP_SHARING
+static Bool
+sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
+{
+	return TRUE;
+}
+#endif
+
+static const xf86CrtcFuncsRec sna_crtc_funcs = {
+	.dpms = sna_crtc_dpms,
+	.set_mode_major = sna_crtc_set_mode_major,
+	.set_cursor_colors = sna_crtc_set_cursor_colors,
+	.set_cursor_position = sna_crtc_set_cursor_position,
+	.show_cursor = sna_crtc_show_cursor,
+	.hide_cursor = sna_crtc_hide_cursor,
+	.load_cursor_argb = sna_crtc_load_cursor_argb,
+	.gamma_set = sna_crtc_gamma_set,
+	.destroy = sna_crtc_destroy,
+#if HAS_PIXMAP_SHARING
+	.set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
+#endif
+};
+
+static bool
+sna_crtc_fake(struct sna *sna)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+	xf86CrtcPtr crtc;
+
+	DBG(("%s\n", __FUNCTION__));
+
+	crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
+	if (crtc == NULL)
+		return false;
+
+	return true;
+}
+
+static void
+sna_output_create_resources(xf86OutputPtr output)
+{
+}
+
+static Bool
+sna_output_set_property(xf86OutputPtr output, Atom property,
+			    RRPropertyValuePtr value)
+{
+	return TRUE;
+}
+
+static Bool
+sna_output_get_property(xf86OutputPtr output, Atom property)
+{
+	return FALSE;
+}
+
+static void
+sna_output_dpms(xf86OutputPtr output, int dpms)
+{
+}
+
+static xf86OutputStatus
+sna_output_detect(xf86OutputPtr output)
+{
+	return XF86OutputStatusDisconnected;
+}
+
+static Bool
+sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+sna_output_get_modes(xf86OutputPtr output)
+{
+	return xf86GetDefaultModes();
+}
+
+static void
+sna_output_destroy(xf86OutputPtr output)
+{
+}
+
+static const xf86OutputFuncsRec sna_output_funcs = {
+	.create_resources = sna_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+	.set_property = sna_output_set_property,
+	.get_property = sna_output_get_property,
+#endif
+	.dpms = sna_output_dpms,
+	.detect = sna_output_detect,
+	.mode_valid = sna_output_mode_valid,
+
+	.get_modes = sna_output_get_modes,
+	.destroy = sna_output_destroy
+};
+
+static bool
+sna_output_fake(struct sna *sna)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+	xf86OutputPtr output;
+
+	output = xf86OutputCreate(scrn, &sna_output_funcs, "FAKE");
+	if (!output)
+		return false;
+
+	output->mm_width = 0;
+	output->mm_height = 0;
+
+	output->subpixel_order = SubPixelNone;
+
+	output->possible_crtcs = 1;
+	output->possible_clones = 0;
+	output->interlaceAllowed = FALSE;
+
+	return true;
+}
+
+struct sna_visit_set_pixmap_window {
+	PixmapPtr old, new;
+};
+
+static int
+sna_visit_set_window_pixmap(WindowPtr window, pointer data)
+{
+    struct sna_visit_set_pixmap_window *visit = data;
+    ScreenPtr screen = window->drawable.pScreen;
+
+    if (screen->GetWindowPixmap(window) == visit->old) {
+	    screen->SetWindowPixmap(window, visit->new);
+	    return WT_WALKCHILDREN;
+    }
+
+    return WT_DONTWALKCHILDREN;
+}
+
+static void
+migrate_dirty_tracking(struct sna *sna, PixmapPtr old_front)
+{
+#if HAS_PIXMAP_SHARING
+	ScreenPtr screen = sna->scrn->pScreen;
+	PixmapDirtyUpdatePtr dirty, safe;
+
+	xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) {
+		assert(dirty->src == old_front);
+		if (dirty->src != old_front)
+			continue;
+
+		DamageUnregister(&dirty->src->drawable, dirty->damage);
+		DamageDestroy(dirty->damage);
+
+		dirty->damage = DamageCreate(NULL, NULL,
+					     DamageReportNone,
+					     TRUE, screen, screen);
+		if (!dirty->damage) {
+			xorg_list_del(&dirty->ent);
+			free(dirty);
+			continue;
+		}
+
+		DamageRegister(&sna->front->drawable, dirty->damage);
+		dirty->src = sna->front;
+	}
+#endif
+}
+
+static Bool
+sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
+{
+	struct sna *sna = to_sna(scrn);
+	ScreenPtr screen = scrn->pScreen;
+	PixmapPtr old_front, new_front;
+
+	DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
+	     scrn->virtualX, scrn->virtualY,
+	     width, height));
+
+	if (scrn->virtualX == width && scrn->virtualY == height)
+		return TRUE;
+
+	assert(sna->front);
+	assert(screen->GetScreenPixmap(screen) == sna->front);
+
+	DBG(("%s: creating new framebuffer %dx%d\n",
+	     __FUNCTION__, width, height));
+
+	old_front = sna->front;
+	new_front = screen->CreatePixmap(screen,
+					 width, height, scrn->depth,
+					 SNA_CREATE_FB);
+	if (!new_front)
+		return FALSE;
+
+	sna->front = new_front;
+	scrn->virtualX = width;
+	scrn->virtualY = height;
+	scrn->displayWidth = width;
+
+	/* Open-coded screen->SetScreenPixmap */
+	migrate_dirty_tracking(sna, old_front);
+
+	if (root(screen)) {
+		struct sna_visit_set_pixmap_window visit;
+
+		visit.old = old_front;
+		visit.new = sna->front;
+		TraverseTree(root(screen), sna_visit_set_window_pixmap, &visit);
+		assert(screen->GetWindowPixmap(root(screen)) == sna->front);
+	}
+	screen->SetScreenPixmap(sna->front);
+	assert(screen->GetScreenPixmap(screen) == sna->front);
+
+	screen->DestroyPixmap(old_front);
+
+	return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
+	sna_crtc_resize
+};
+
+bool sna_mode_fake_init(struct sna *sna)
+{
+	ScrnInfoPtr scrn = sna->scrn;
+
+	xf86CrtcConfigInit(scrn, &sna_crtc_config_funcs);
+
+	if (!sna_crtc_fake(sna))
+		return false;
+
+	if (!sna_output_fake(sna))
+		return false;
+
+	xf86CrtcSetSizeRange(scrn, 320, 200, INT16_MAX, INT16_MAX);
+	xf86InitialConfiguration(scrn, TRUE);
+	return true;
+}


More information about the xorg-commit mailing list