summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-09-02 17:30:15 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-09-02 19:50:11 +0100
commit88d43dc2aea1ee4b8a3248bf442f5be362b32fbe (patch)
treec25be67e07315b5f00daae7e668cd2c699d31abc /tools
parent1b07f16ffeb3152817e9e4f77ca0f2c403fb9040 (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.c159
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;