xf86-video-intel: 3 commits - tools/virtual.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Sep 2 11:52:52 PDT 2013
tools/virtual.c | 207 +++++++++++++++++++++++++++++++++-----------------------
1 file changed, 125 insertions(+), 82 deletions(-)
New commits:
commit 5af9d69485a241156c343b67a741bc024e3f6edf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 2 19:50:17 2013 +0100
intel-virtual-output: Reorder the fds
We can't place the record fd at after the displays as we may wish to
clone more displays later and use the simplification that they are in a
linear, contiguous block at the end of the fd array.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/tools/virtual.c b/tools/virtual.c
index 39812bc..1beccac 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -2302,6 +2302,12 @@ int main(int argc, char **argv)
XRRSelectInput(ctx.display->dpy, ctx.display->root, RRScreenChangeNotifyMask);
XFixesSelectCursorInput(ctx.display->dpy, ctx.display->root, XFixesDisplayCursorNotifyMask);
+ ret = add_fd(&ctx, record_mouse(&ctx));
+ if (ret) {
+ fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy));
+ return -ret;
+ }
+
open = fail = 0;
for (i = optind; i < argc; i++) {
ret = last_display_clone(&ctx, display_open(&ctx, argv[i]));
@@ -2332,12 +2338,6 @@ int main(int argc, char **argv)
if (open == 0)
return fail ? ECONNREFUSED : 0;
- ret = add_fd(&ctx, record_mouse(&ctx));
- if (ret) {
- fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy));
- return -ret;
- }
-
if (daemonize && daemon(0, 0))
return EINVAL;
@@ -2346,18 +2346,26 @@ int main(int argc, char **argv)
XEvent e;
int reconfigure = 0;
+ DBG(("polling - enable timer? %d, nfd=%d\n", enable_timer, ctx.nfd));
ret = poll(ctx.pfd + !enable_timer, ctx.nfd - !enable_timer, -1);
if (ret <= 0)
break;
+ /* pfd[0] is the timer, pfd[1] is the local display, pfd[2] is the mouse, pfd[3+] are the remotes */
+
+ DBG(("poll reports %d fd awake\n", ret));
if (ctx.pfd[1].revents) {
int damaged = 0;
+ DBG(("%s woken up\n", DisplayString(ctx.display[0].dpy)));
do {
XNextEvent(ctx.display->dpy, &e);
if (e.type == ctx.display->damage_event + XDamageNotify ) {
const XDamageNotifyEvent *de = (const XDamageNotifyEvent *)&e;
+ DBG(("%s damaged: (%d, %d)x(%d, %d)\n",
+ DisplayString(ctx.display->dpy),
+ de->area.x, de->area.y, de->area.width, de->area.height));
for (i = 0; i < ctx.nclone; i++)
clone_damage(&ctx.clones[i], &de->area);
if (!enable_timer)
@@ -2375,6 +2383,8 @@ int main(int argc, char **argv)
XFree(cur);
} else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) {
+ DBG(("%s screen changed (reconfigure pending? %d)\n",
+ DisplayString(ctx.display->dpy), reconfigure));
reconfigure = 1;
if (!enable_timer)
enable_timer = read(ctx.timer, &count, sizeof(count)) > 0;
@@ -2405,13 +2415,15 @@ int main(int argc, char **argv)
}
for (i = 1; ret && i < ctx.ndisplay; i++) {
- if (ctx.pfd[i+1].revents == 0)
+ if (ctx.pfd[i+2].revents == 0)
continue;
+ DBG(("%s woken up\n", DisplayString(ctx.display[i].dpy)));
do {
XNextEvent(ctx.display[i].dpy, &e);
- if (ctx.display[i].rr_event && e.type == ctx.display[i].rr_event + RRNotify) {
+ DBG(("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type));
+ if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) {
XRRNotifyEvent *re = (XRRNotifyEvent *)&e;
if (re->subtype == RRNotify_OutputChange) {
XRROutputPropertyNotifyEvent *ro = (XRROutputPropertyNotifyEvent *)re;
@@ -2424,7 +2436,7 @@ int main(int argc, char **argv)
}
}
}
- } while (XPending(ctx.display[i].dpy) || poll(&ctx.pfd[i+1], 1, 0) > 0);
+ } while (XPending(ctx.display[i].dpy) || poll(&ctx.pfd[i+2], 1, 0) > 0);
ret--;
}
commit 88d43dc2aea1ee4b8a3248bf442f5be362b32fbe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 2 17:30:15 2013 +0100
intel-virtual-output: Refactor the image resizing code
And add lots of debug and robustness.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/tools/virtual.c b/tools/virtual.c
index b4d4460..39812bc 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -94,6 +94,7 @@ struct display {
int cursor;
int flush;
+ int send;
};
struct output {
@@ -109,7 +110,7 @@ struct output {
Pixmap pixmap;
GC gc;
- int serial;
+ long serial;
int use_shm;
int use_shm_pixmap;
@@ -203,10 +204,6 @@ can_use_shm(Display *dpy,
XSync(dpy, False);
has_shm = success && _x_error_occurred == 0;
- codes = XInitExtension(dpy, SHMNAME);
- if (codes == NULL)
- has_pixmap = 0;
-
/* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent,
* the Xserver may crash if it does not take care when processing
* the event type. For instance versions of Xorg prior to 1.11.1
@@ -218,12 +215,11 @@ can_use_shm(Display *dpy,
*
* Remove the SendEvent bit (0x80) before doing range checks on event type.
*/
- if (has_pixmap &&
- xlib_vendor_is_xorg(dpy) &&
+ codes = XInitExtension(dpy, SHMNAME);
+ if (xlib_vendor_is_xorg(dpy) &&
VendorRelease(dpy) < XORG_VERSION_ENCODE(1,11,0,1))
- has_pixmap = 0;
-
- if (has_pixmap) {
+ codes = 0;
+ if (codes) {
XShmCompletionEvent e;
e.type = codes->first_event;
@@ -237,23 +233,19 @@ can_use_shm(Display *dpy,
e.offset = 0;
XSendEvent(dpy, e.drawable, False, 0, (XEvent *)&e);
-
XSync(dpy, False);
- has_pixmap = _x_error_occurred == 0;
- }
- if (success)
- XShmDetach(dpy, &shm);
+ if (_x_error_occurred == 0) {
+ *shm_opcode = codes->major_opcode;
+ *shm_event = codes->first_event;
+ *shm_pixmap = has_pixmap;
+ }
+ }
+ XShmDetach(dpy, &shm);
shmctl(shm.shmid, IPC_RMID, NULL);
shmdt(shm.shmaddr);
- if (has_pixmap) {
- *shm_opcode = codes->major_opcode;
- *shm_event = codes->first_event;
- *shm_pixmap = has_pixmap;
- }
-
return has_shm;
}
@@ -555,6 +547,7 @@ static void init_image(struct clone *clone)
image->bits_per_pixel = 16;
break;
}
+ image->obdata = (char *)&clone->shm;
ret = XInitImage(image);
assert(ret);
@@ -1015,6 +1008,9 @@ static int clone_output_init(struct clone *clone, struct output *output,
output->use_shm = display->has_shm;
output->use_shm_pixmap = display->has_shm_pixmap;
+ DBG(("%s-%s use shm? %d (use shm pixmap? %d)\n",
+ DisplayString(dpy), name, display->has_shm, display->has_shm_pixmap));
+
depth = output->use_shm ? display->depth : 16;
if (depth < clone->depth)
clone->depth = depth;
@@ -1022,26 +1018,11 @@ static int clone_output_init(struct clone *clone, struct output *output,
return 0;
}
-static void send_shm(struct output *o, int serial)
+static void ximage_set_size(XImage *image, int width, int height)
{
- XShmCompletionEvent e;
-
- if (o->display->shm_event == 0) {
- XSync(o->dpy, False);
- return;
- }
-
- e.type = o->display->shm_event;
- e.send_event = 1;
- e.serial = serial;
- e.drawable = o->pixmap;
- e.major_code = o->display->shm_opcode;
- e.minor_code = X_ShmPutImage;
- e.shmseg = 0;
- e.offset = 0;
-
- XSendEvent(o->dpy, o->window, False, 0, (XEvent *)&e);
- o->serial = serial;
+ image->width = width;
+ image->height = height;
+ image->bytes_per_line = stride_for_depth(width, image->depth);
}
static void get_src(struct clone *c, const XRectangle *clip)
@@ -1058,15 +1039,11 @@ static void get_src(struct clone *c, const XRectangle *clip)
if (c->src.use_shm_pixmap) {
XSync(c->src.dpy, False);
} else if (c->src.use_shm) {
- c->image.width = clip->width;
- c->image.height = clip->height;
- c->image.obdata = (char *)&c->shm;
+ ximage_set_size(&c->image, clip->width, clip->height);
XShmGetImage(c->src.dpy, c->src.pixmap, &c->image,
clip->x, clip->y, AllPlanes);
} else {
- c->image.width = c->width;
- c->image.height = c->height;
- c->image.obdata = 0;
+ ximage_set_size(&c->image, c->width, c->height);
XGetSubImage(c->src.dpy, c->src.pixmap,
clip->x, clip->y, clip->width, clip->height,
AllPlanes, ZPixmap,
@@ -1079,15 +1056,11 @@ static void get_src(struct clone *c, const XRectangle *clip)
0, 0);
XSync(c->src.dpy, False);
} else if (c->src.use_shm) {
- c->image.width = clip->width;
- c->image.height = clip->height;
- c->image.obdata = (char *)&c->shm;
+ ximage_set_size(&c->image, clip->width, clip->height);
XShmGetImage(c->src.dpy, c->src.window, &c->image,
clip->x, clip->y, AllPlanes);
} else {
- c->image.width = c->width;
- c->image.height = c->height;
- c->image.obdata = 0;
+ ximage_set_size(&c->image, c->width, c->height);
XGetSubImage(c->src.dpy, c->src.window,
clip->x, clip->y, clip->width, clip->height,
AllPlanes, ZPixmap,
@@ -1100,46 +1073,48 @@ static void put_dst(struct clone *c, const XRectangle *clip)
DBG(("%s-%s put_dst(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name,
clip->x, clip->y, clip->width, clip->height));
if (c->dst.use_render) {
- int serial;
if (c->dst.use_shm_pixmap) {
+ DBG(("%s-%s using SHM pixmap composite\n",
+ DisplayString(c->dst.dpy), c->dst.name));
} else if (c->dst.use_shm) {
- c->image.width = clip->width;
- c->image.height = clip->height;
- c->image.obdata = (char *)&c->shm;
+ DBG(("%s-%s using SHM image composite\n",
+ DisplayString(c->dst.dpy), c->dst.name));
+ ximage_set_size(&c->image, clip->width, clip->height);
XShmPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
0, 0,
0, 0,
clip->width, clip->height,
False);
} else {
- c->image.width = c->width;
- c->image.height = c->height;
- c->image.obdata = 0;
+ DBG(("%s-%s using composite\n",
+ DisplayString(c->dst.dpy), c->dst.name));
+ ximage_set_size(&c->image, c->width, c->height);
XPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image,
0, 0,
0, 0,
clip->width, clip->height);
}
- serial = NextRequest(c->dst.dpy);
+ c->dst.serial = NextRequest(c->dst.dpy);
XRenderComposite(c->dst.dpy, PictOpSrc,
c->dst.pix_picture, 0, c->dst.win_picture,
0, 0,
0, 0,
clip->x, clip->y,
clip->width, clip->height);
- if (c->dst.use_shm)
- send_shm(&c->dst, serial);
+ c->dst.display->send |= c->dst.use_shm;
} else if (c->dst.pixmap) {
- int serial = NextRequest(c->dst.dpy);
+ DBG(("%s-%s using SHM pixmap\n",
+ DisplayString(c->dst.dpy), c->dst.name));
+ c->dst.serial = NextRequest(c->dst.dpy);
XCopyArea(c->dst.dpy, c->dst.pixmap, c->dst.window, c->dst.gc,
0, 0,
clip->width, clip->height,
clip->x, clip->y);
- send_shm(&c->dst, serial);
+ c->dst.display->send = 1;
} else if (c->dst.use_shm) {
- c->image.width = clip->width;
- c->image.height = clip->height;
- c->image.obdata = (char *)&c->shm;
+ DBG(("%s-%s using SHM image\n",
+ DisplayString(c->dst.dpy), c->dst.name));
+ ximage_set_size(&c->image, clip->width, clip->height);
c->dst.serial = NextRequest(c->dst.dpy);
XShmPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
0, 0,
@@ -1147,9 +1122,9 @@ static void put_dst(struct clone *c, const XRectangle *clip)
clip->width, clip->height,
True);
} else {
- c->image.width = c->width;
- c->image.height = c->height;
- c->image.obdata = 0;
+ DBG(("%s-%s using image\n",
+ DisplayString(c->dst.dpy), c->dst.name));
+ ximage_set_size(&c->image, c->width, c->height);
XPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image,
0, 0,
clip->x, clip->y,
@@ -1164,8 +1139,12 @@ static int clone_paint(struct clone *c)
{
XRectangle clip;
- DBG(("%s-%s paint clone\n",
- DisplayString(c->dst.dpy), c->dst.name));
+ DBG(("%s-%s paint clone, damaged (%d, %d), (%d, %d) [(%d, %d), (%d, %d)]\n",
+ DisplayString(c->dst.dpy), c->dst.name,
+ c->damaged.x1, c->damaged.y1,
+ c->damaged.x2, c->damaged.y2,
+ c->src.x, c->src.y,
+ c->src.x + c->width, c->src.y + c->height));
if (c->damaged.x1 < c->src.x)
c->damaged.x1 = c->src.x;
@@ -1181,6 +1160,9 @@ static int clone_paint(struct clone *c)
if (c->damaged.y2 <= c->damaged.y1)
goto done;
+ DBG(("%s-%s is damaged, last SHM serial: %ld, now %ld\n",
+ DisplayString(c->dst.dpy), c->dst.name,
+ (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy)));
if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy))
return EAGAIN;
@@ -2137,9 +2119,42 @@ static int first_display_register_as_singleton(struct context *ctx)
} while (1);
}
+static void display_flush_send(struct display *display)
+{
+ XShmCompletionEvent e;
+
+ if (!display->send)
+ return;
+
+ DBG(("%s flushing send (serial now %ld) (has shm send? %d)\n",
+ DisplayString(display->dpy),
+ (long)NextRequest(display->dpy),
+ display->shm_event));
+
+ if (display->shm_event == 0) {
+ XSync(display->dpy, False);
+ display->flush = 0;
+ return;
+ }
+
+ e.type = display->shm_event;
+ e.send_event = 1;
+ e.serial = 0;
+ e.drawable = display->root;
+ e.major_code = display->shm_opcode;
+ e.minor_code = X_ShmPutImage;
+ e.shmseg = 0;
+ e.offset = 0;
+
+ XSendEvent(display->dpy, display->root, False, 0, (XEvent *)&e);
+ display->send = 0;
+ display->flush = 1;
+}
+
static void display_flush(struct display *display)
{
display_flush_cursor(display);
+ display_flush_send(display);
if (!display->flush)
return;
commit 1b07f16ffeb3152817e9e4f77ca0f2c403fb9040
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 2 18:10:27 2013 +0100
intel-virtual-overlay: Fix logic inversion from previous commit
"if (!active == 0)"
Whoops, but keep the debugging that highlighted the error.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/tools/virtual.c b/tools/virtual.c
index ba443b2..b4d4460 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -690,6 +690,8 @@ static void context_update(struct context *ctx)
int context_changed = 0;
int i, n;
+ DBG(("%s\n", __func__));
+
res = XRRGetScreenResourcesCurrent(dpy, ctx->display->root);
if (res == NULL)
return;
@@ -709,6 +711,11 @@ static void context_update(struct context *ctx)
if (o->crtc)
c = XRRGetCrtcInfo(dpy, res, o->crtc);
if (c) {
+ DBG(("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> (x=%d, y=%d, rotation=%d, mode=%ld)\n",
+ DisplayString(ctx->display->dpy), output->name,
+ output->x, output->y, output->rotation, output->mode.id,
+ c->x, c->y, output->rotation, c->mode));
+
changed |= output->rotation |= c->rotation;
output->rotation = c->rotation;
@@ -721,6 +728,10 @@ static void context_update(struct context *ctx)
changed |= output->mode.id != mode;
mode = c->mode;
XRRFreeCrtcInfo(c);
+ } else {
+ DBG(("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> off\n",
+ DisplayString(ctx->display->dpy), output->name,
+ output->x, output->y, output->rotation, output->mode.id));
}
output->rr_crtc = o->crtc;
XRRFreeOutputInfo(o);
@@ -739,12 +750,16 @@ static void context_update(struct context *ctx)
output->mode.id = 0;
}
+ DBG(("%s-%s changed? %d\n",
+ DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed));
+
if (changed)
clone_init_xfer(&ctx->clones[n]);
context_changed |= changed;
}
XRRFreeScreenResources(res);
+ DBG(("%s changed? %d\n", DisplayString(ctx->display->dpy), context_changed));
if (!context_changed)
return;
@@ -753,7 +768,7 @@ static void context_update(struct context *ctx)
struct clone *clone;
int x1, x2, y1, y2;
- if (!display->rr_active == 0)
+ if (display->rr_active == 0)
continue;
x1 = y1 = INT_MAX;
@@ -994,6 +1009,7 @@ static int clone_output_init(struct clone *clone, struct output *output,
output->dpy = dpy;
output->rr_output = rr_output;
+ output->rotation = RR_Rotate_0;
output->window = display->root;
output->use_shm = display->has_shm;
More information about the xorg-commit
mailing list