summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredrik Höglund <[email protected]>2011-12-14 21:06:29 +0100
committerChia-I Wu <[email protected]>2011-12-15 15:02:56 +0800
commita06f58fee5dbf0054fb363e759d30cf13c4bbab9 (patch)
tree1c6e72e45ee0ae6714ff5179ccf5c5819dcaf0e3
parentfa0f70e45ed1b69c0e72588a061bc30fd9ad371e (diff)
st/egl: Implement EGL_NOK_swap_region for x11
v2: inline x11_drawable_copy_buffers(). Signed-off-by: Fredrik Höglund <[email protected]> [olv: s/inline/INLINE/]
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c36
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c21
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.h14
3 files changed, 51 insertions, 20 deletions
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 47547446ffd..9ea3b807be9 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -313,22 +313,35 @@ dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
}
static boolean
-dri2_surface_swap_buffers(struct native_surface *nsurf)
+dri2_surface_swap_buffers(struct native_surface *nsurf, int num_rects,
+ const int *rects)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
/* copy to front buffer */
- if (dri2surf->have_back)
- x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
- 0, 0, dri2surf->width, dri2surf->height,
- DRI2BufferBackLeft, DRI2BufferFrontLeft);
+ if (dri2surf->have_back) {
+ if (num_rects > 0)
+ x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
+ num_rects, rects,
+ DRI2BufferBackLeft, DRI2BufferFrontLeft);
+ else
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferBackLeft, DRI2BufferFrontLeft);
+ }
/* and update fake front buffer */
- if (dri2surf->have_fake)
- x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
- 0, 0, dri2surf->width, dri2surf->height,
- DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ if (dri2surf->have_fake) {
+ if (num_rects > 0)
+ x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
+ num_rects, rects,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ else
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ }
/* force buffers to be updated in next validation call */
if (!dri2_surface_receive_events(&dri2surf->base)) {
@@ -354,7 +367,7 @@ dri2_surface_present(struct native_surface *nsurf,
ret = dri2_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
- ret = dri2_surface_swap_buffers(nsurf);
+ ret = dri2_surface_swap_buffers(nsurf, ctrl->num_rects, ctrl->rects);
break;
default:
ret = FALSE;
@@ -722,6 +735,9 @@ dri2_display_get_param(struct native_display *ndpy,
/* DRI2CopyRegion is used */
val = TRUE;
break;
+ case NATIVE_PARAM_PRESENT_REGION:
+ val = TRUE;
+ break;
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index 6155b4d03c0..1e20f941c81 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -341,21 +341,24 @@ x11_drawable_enable_dri2(struct x11_screen *xscr,
* Copy between buffers of the DRI2 drawable.
*/
void
-x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
- int x, int y, int width, int height,
- int src_buf, int dst_buf)
+x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
+ int num_rects, const int *rects,
+ int src_buf, int dst_buf)
{
- XRectangle rect;
XserverRegion region;
+ XRectangle *rectangles = CALLOC(num_rects, sizeof(XRectangle));
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
+ for (int i = 0; i < num_rects; i++) {
+ rectangles[i].x = rects[i * 4 + 0];
+ rectangles[i].y = rects[i * 4 + 1];
+ rectangles[i].width = rects[i * 4 + 2];
+ rectangles[i].height = rects[i * 4 + 3];
+ }
- region = XFixesCreateRegion(xscr->dpy, &rect, 1);
+ region = XFixesCreateRegion(xscr->dpy, rectangles, num_rects);
DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
XFixesDestroyRegion(xscr->dpy, region);
+ FREE(rectangles);
}
/**
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h
index acf1300e9d1..ad7aa97bd0c 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -108,9 +108,21 @@ x11_drawable_enable_dri2(struct x11_screen *xscr,
Drawable drawable, boolean on);
void
+x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
+ int num_rects, const int *rects,
+ int src_buf, int dst_buf);
+
+/**
+ * Copy between buffers of the DRI2 drawable.
+ */
+static INLINE void
x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
int x, int y, int width, int height,
- int src_buf, int dst_buf);
+ int src_buf, int dst_buf)
+{
+ int rect[4] = { x, y, width, height };
+ x11_drawable_copy_buffers_region(xscr, drawable, 1, rect, src_buf, dst_buf);
+}
struct x11_drawable_buffer *
x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,