xf86-video-intel: tools/virtual.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Sep 1 08:46:00 PDT 2013


 tools/virtual.c |   81 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 30 deletions(-)

New commits:
commit 7e6472cfccb66d961efa3acbdbfa4057413cbcaf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 1 16:44:14 2013 +0100

    intel-virtual-output: Rebuild pointers after realloc
    
    If reallocs gives us a new memory block, we need to update everything
    that pointed into the old blocks.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/tools/virtual.c b/tools/virtual.c
index 9bbd390..e2654ff 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -1378,9 +1378,23 @@ static int add_display(struct context *ctx, Display *dpy)
 	struct display *display;
 
 	if (is_power_of_2(ctx->ndisplay)) {
-		ctx->display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display));
-		if (ctx->display == NULL)
+		struct display *new_display;
+
+		new_display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display));
+		if (new_display == NULL)
 			return -ENOMEM;
+
+		if (new_display != ctx->display) {
+			int n;
+
+			for (n = 0; n < ctx->nclone; n++) {
+				struct clone *clone = &ctx->clones[n];
+				clone->src.display = new_display + (clone->src.display - ctx->display);
+				clone->dst.display = new_display + (clone->dst.display - ctx->display);
+			}
+		}
+
+		ctx->display = new_display;
 	}
 
 	display = memset(&ctx->display[ctx->ndisplay++], 0, sizeof(struct display));
@@ -1540,26 +1554,6 @@ static int context_init(struct context *ctx)
 	return 0;
 }
 
-static void context_build_lists(struct context *ctx)
-{
-	int n, m;
-
-	for (n = 1; n < ctx->ndisplay; n++) {
-		struct display *d = &ctx->display[n];
-
-		d->clone = NULL;
-		for (m = 0; m < ctx->nclone; m++) {
-			struct clone *c = &ctx->clones[m];
-
-			if (c->dst.display != d)
-				continue;
-
-			c->next = d->clone;
-			d->clone = c;
-		}
-	}
-}
-
 static int add_fd(struct context *ctx, int fd)
 {
 	if (fd < 0)
@@ -1591,12 +1585,39 @@ static void display_init_randr_hpd(struct display *display)
 		XRRSelectInput(display->dpy, display->root, RROutputChangeNotifyMask);
 }
 
+static void rebuild_clones(struct context *ctx)
+{
+	int n, m;
+
+	for (n = 1; n < ctx->ndisplay; n++) {
+		struct display *d = &ctx->display[n];
+
+		d->clone = NULL;
+		for (m = 0; m < ctx->nclone; m++) {
+			struct clone *c = &ctx->clones[m];
+
+			if (c->dst.display != d)
+				continue;
+
+			c->next = d->clone;
+			d->clone = c;
+		}
+	}
+}
+
 static struct clone *add_clone(struct context *ctx)
 {
 	if (is_power_of_2(ctx->nclone)) {
-		ctx->clones = realloc(ctx->clones, 2*ctx->nclone*sizeof(struct clone));
-		if (ctx->clones == NULL)
+		struct clone *new_clones;
+
+		new_clones = realloc(ctx->clones, 2*ctx->nclone*sizeof(struct clone));
+		if (new_clones == NULL)
 			return NULL;
+
+		if (new_clones != ctx->clones)
+			rebuild_clones(ctx);
+
+		ctx->clones = new_clones;
 	}
 
 	return memset(&ctx->clones[ctx->nclone++], 0, sizeof(struct clone));
@@ -1625,6 +1646,8 @@ static int last_display_add_clones(struct context *ctx)
 		struct clone *clone = add_clone(ctx);
 
 		clone->depth = 24;
+		clone->next = display->clone;
+		display->clone = clone;
 
 		sprintf(buf, "VIRTUAL%d", ctx->nclone);
 		ret = clone_output_init(clone, &clone->src, ctx->display, buf, claim_virtual(ctx->display, buf));
@@ -1664,19 +1687,17 @@ static int last_display_add_clones(struct context *ctx)
 static int last_display_clone(struct context *ctx, int fd)
 {
 	if (fd < 0)
-		goto err;
+		return fd;
 
 	fd = add_fd(ctx, fd);
 	if (fd < 0)
-		goto err;
+		return fd;
 
 	fd = last_display_add_clones(ctx);
 	if (fd)
-		goto err;
+		return fd;
 
-err:
-	context_build_lists(ctx);
-	return fd;
+	return 0;
 }
 
 static int first_display_has_singleton(struct context *ctx)


More information about the xorg-commit mailing list