diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-02 17:30:15 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-02 19:50:11 +0100 |
commit | 88d43dc2aea1ee4b8a3248bf442f5be362b32fbe (patch) | |
tree | c25be67e07315b5f00daae7e668cd2c699d31abc /tools | |
parent | 1b07f16ffeb3152817e9e4f77ca0f2c403fb9040 (diff) |
intel-virtual-output: Refactor the image resizing code
And add lots of debug and robustness.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/virtual.c | 159 |
1 files changed, 87 insertions, 72 deletions
diff --git a/tools/virtual.c b/tools/virtual.c index b4d4460e..39812bcf 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; |