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.
This commit is contained in:
Eric Anholt 2007-05-11 16:11:04 +00:00 committed by Zaheer Abbas Merali
parent 4128e375f1
commit 28713ecdf1
2 changed files with 87 additions and 83 deletions

View file

@ -1,3 +1,13 @@
2007-05-11 Zaheer Abbas Merali <<zaheerabbas at merali dot org>>
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.
2007-05-11 Tim-Philipp Müller <tim at centricular dot net>
* gst/wavparse/gstwavparse.c: (gst_wavparse_stream_headers):

View file

@ -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,50 +410,20 @@ 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;
XserverRegion parts;
XRectangle *rects;
int nrects;
#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);
}
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;
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;
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) {
GST_LOG_OBJECT (ximagesrc,
"Copying from last frame ximage->size: %d",
@ -463,6 +433,36 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
GST_BUFFER_SIZE (GST_BUFFER (ximage)));
have_frame = TRUE;
}
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,
"Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
@ -473,29 +473,21 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
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;
}
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);
rects[i].x, rects[i].y, rects[i].width, rects[i].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);
rects[i].x, rects[i].y,
rects[i].width, rects[i].height,
AllPlanes, ZPixmap, ximage->ximage, rects[i].x, rects[i].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;