summaryrefslogtreecommitdiffstats
path: root/sys/ximage
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2007-05-11 16:11:04 +0000
committerZaheer Abbas Merali <zaheerabbas@merali.org>2007-05-11 16:11:04 +0000
commit28713ecdf1ae07ace4eb5171fca7e626c86b455a (patch)
treeb13b479cbc0b6d9592a32afc965cb4c0fe3783d0 /sys/ximage
parent4128e375f1e3aa66f65a1469c1fb4f17e9d4d53d (diff)
sys/ximage/gstximagesrc.c (gst_ximage_src_open_display, gst_ximage_src_ximage_get):
Original commit message from CVS: Patch by: Eric Anholt * sys/ximage/gstximagesrc.c (gst_ximage_src_open_display, gst_ximage_src_ximage_get): Use union of all damage between frames to make it faster. Fixes bug #342463. Also fix crasher when cursor is at bottom right of window.
Diffstat (limited to 'sys/ximage')
-rw-r--r--sys/ximage/gstximagesrc.c152
1 files changed, 73 insertions, 79 deletions
diff --git a/sys/ximage/gstximagesrc.c b/sys/ximage/gstximagesrc.c
index fd814c4a..115a48b0 100644
--- a/sys/ximage/gstximagesrc.c
+++ b/sys/ximage/gstximagesrc.c
@@ -164,8 +164,7 @@ gst_ximage_src_open_display (GstXImageSrc * s, const gchar * name)
if (XDamageQueryExtension (s->xcontext->disp, &s->damage_event_base,
&error_base)) {
s->damage =
- XDamageCreate (s->xcontext->disp, s->xwindow,
- XDamageReportRawRectangles);
+ XDamageCreate (s->xcontext->disp, s->xwindow, XDamageReportNonEmpty);
if (s->damage != None) {
s->damage_region = XFixesCreateRegion (s->xcontext->disp, NULL, 0);
if (s->damage_region != None) {
@@ -399,7 +398,8 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
g_return_val_if_fail (GST_IS_XIMAGE_SRC (ximagesrc), NULL);
#ifdef HAVE_XDAMAGE
- if (ximagesrc->have_xdamage && ximagesrc->use_damage) {
+ if (ximagesrc->have_xdamage && ximagesrc->use_damage &&
+ ximagesrc->last_ximage != NULL) {
XEvent ev;
/* have_frame is TRUE when either the entire screen has been
@@ -410,92 +410,84 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
do {
XNextEvent (ximagesrc->xcontext->disp, &ev);
- if (ev.type == ximagesrc->damage_event_base + XDamageNotify) {
- XDamageNotifyEvent *dev = (XDamageNotifyEvent *) & ev;
-#ifdef HAVE_XSHM
- if (ximagesrc->xcontext->use_xshm &&
- dev->area.width == ximagesrc->xcontext->width &&
- dev->area.height == ximagesrc->xcontext->height) {
- GST_DEBUG_OBJECT (ximagesrc, "Entire screen was damaged");
- XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- ximage->ximage, ximagesrc->startx, ximagesrc->starty, AllPlanes);
- /* No need to collect more events */
- while (XPending (ximagesrc->xcontext->disp)) {
- XNextEvent (ximagesrc->xcontext->disp, &ev);
+ if (ev.type == ximagesrc->damage_event_base + XDamageNotify) {
+ XserverRegion parts;
+ XRectangle *rects;
+ int nrects;
+
+ parts = XFixesCreateRegion (ximagesrc->xcontext->disp, 0, 0);
+ XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None,
+ parts);
+ /* Now copy out all of the damaged rectangles. */
+ rects = XFixesFetchRegion (ximagesrc->xcontext->disp, parts, &nrects);
+ if (rects != NULL) {
+ int i;
+
+ if (!have_frame) {
+ GST_LOG_OBJECT (ximagesrc,
+ "Copying from last frame ximage->size: %d",
+ GST_BUFFER_SIZE (GST_BUFFER (ximage)));
+ memcpy (GST_BUFFER_DATA (GST_BUFFER (ximage)),
+ GST_BUFFER_DATA (GST_BUFFER (ximagesrc->last_ximage)),
+ GST_BUFFER_SIZE (GST_BUFFER (ximage)));
+ have_frame = TRUE;
}
- have_frame = TRUE;
- break;
- } else
-#endif
- {
- /* if we only want a small area, clip this damage region to
- * area we want */
- if (ximagesrc->endx > ximagesrc->startx &&
- ximagesrc->endy > ximagesrc->starty) {
- /* see if damage area intersects */
- if (dev->area.x + dev->area.width < ximagesrc->startx ||
- dev->area.x > ximagesrc->endx) {
- /* trivial reject */
- } else if (dev->area.y + dev->area.height < ximagesrc->starty ||
- dev->area.y > ximagesrc->endy) {
- /* trivial reject */
- } else {
- /* find intersect region */
- int startx, starty, width, height;
-
- startx = (dev->area.x < ximagesrc->startx) ? ximagesrc->startx :
- dev->area.x;
- starty = (dev->area.y < ximagesrc->starty) ? ximagesrc->starty :
- dev->area.y;
- width = (dev->area.x + dev->area.width < ximagesrc->endx) ?
- dev->area.x + dev->area.width - startx :
- ximagesrc->endx - startx;
- height = (dev->area.y + dev->area.height < ximagesrc->endy) ?
- dev->area.y + dev->area.height - starty : ximagesrc->endy -
- starty;
- if (!have_frame) {
+ for (i = 0; i < nrects; i++) {
+ GST_LOG_OBJECT (ximagesrc,
+ "Damaged sub-region @ %d,%d size %dx%d reported",
+ rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+
+ /* if we only want a small area, clip this damage region to
+ * area we want */
+ if (ximagesrc->endx > ximagesrc->startx &&
+ ximagesrc->endy > ximagesrc->starty) {
+ /* see if damage area intersects */
+ if (rects[i].x + rects[i].width < ximagesrc->startx ||
+ rects[i].x > ximagesrc->endx) {
+ /* trivial reject */
+ } else if (rects[i].y + rects[i].height < ximagesrc->starty ||
+ rects[i].y > ximagesrc->endy) {
+ /* trivial reject */
+ } else {
+ /* find intersect region */
+ int startx, starty, width, height;
+
+ startx = (rects[i].x < ximagesrc->startx) ? ximagesrc->startx :
+ rects[i].x;
+ starty = (rects[i].y < ximagesrc->starty) ? ximagesrc->starty :
+ rects[i].y;
+ width = (rects[i].x + rects[i].width < ximagesrc->endx) ?
+ rects[i].x + rects[i].width - startx :
+ ximagesrc->endx - startx;
+ height = (rects[i].y + rects[i].height < ximagesrc->endy) ?
+ rects[i].y + rects[i].height - starty : ximagesrc->endy -
+ starty;
+
GST_LOG_OBJECT (ximagesrc,
- "Copying from last frame ximage->size: %d",
- GST_BUFFER_SIZE (GST_BUFFER (ximage)));
- memcpy (GST_BUFFER_DATA (GST_BUFFER (ximage)),
- GST_BUFFER_DATA (GST_BUFFER (ximagesrc->last_ximage)),
- GST_BUFFER_SIZE (GST_BUFFER (ximage)));
- have_frame = TRUE;
+ "Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
+ startx, starty, width, height);
+ XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+ startx, starty, width, height, AllPlanes, ZPixmap,
+ ximage->ximage, startx - ximagesrc->startx,
+ starty - ximagesrc->starty);
}
+ } else {
GST_LOG_OBJECT (ximagesrc,
- "Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
- startx, starty, width, height);
+ "Retrieving damaged sub-region @ %d,%d size %dx%d",
+ rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- startx, starty, width, height, AllPlanes, ZPixmap,
- ximage->ximage, startx - ximagesrc->startx,
- starty - ximagesrc->starty);
- }
- } else {
- if (!have_frame) {
- GST_LOG_OBJECT (ximagesrc,
- "Copying from last frame ximage->size: %d",
- GST_BUFFER_SIZE (GST_BUFFER (ximage)));
- memcpy (GST_BUFFER_DATA (GST_BUFFER (ximage)),
- GST_BUFFER_DATA (GST_BUFFER (ximagesrc->last_ximage)),
- GST_BUFFER_SIZE (GST_BUFFER (ximage)));
- have_frame = TRUE;
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height,
+ AllPlanes, ZPixmap, ximage->ximage, rects[i].x, rects[i].y);
}
-
- GST_LOG_OBJECT (ximagesrc,
- "Retrieving damaged sub-region @ %d,%d size %dx%d",
- dev->area.x, dev->area.y, dev->area.width, dev->area.height);
-
- XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- dev->area.x, dev->area.y,
- dev->area.width, dev->area.height,
- AllPlanes, ZPixmap, ximage->ximage, dev->area.x, dev->area.y);
}
+ free (rects);
}
}
} while (XPending (ximagesrc->xcontext->disp));
- XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None, None);
if (!have_frame) {
GST_LOG_OBJECT (ximagesrc,
"Copying from last frame ximage->size: %d",
@@ -644,9 +636,11 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
ximagesrc->cursor_image->pixels[i] =
GUINT_TO_LE (ximagesrc->cursor_image->pixels[i]);
/* copy those pixels across */
- for (j = starty; j < starty + iheight && j < starty + ximagesrc->height;
+ for (j = starty;
+ j < starty + iheight && j < ximagesrc->starty + ximagesrc->height;
j++) {
- for (i = startx; i < startx + iwidth && i < startx + ximagesrc->width;
+ for (i = startx;
+ i < startx + iwidth && i < ximagesrc->startx + ximagesrc->width;
i++) {
guint8 *src, *dest;