From a06f58fee5dbf0054fb363e759d30cf13c4bbab9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fredrik=20H=C3=B6glund?= Date: Wed, 14 Dec 2011 21:06:29 +0100 Subject: [PATCH] st/egl: Implement EGL_NOK_swap_region for x11 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: inline x11_drawable_copy_buffers(). Signed-off-by: Fredrik Höglund [olv: s/inline/INLINE/] --- src/gallium/state_trackers/egl/x11/native_dri2.c | 36 +++++++++++++++++------- src/gallium/state_trackers/egl/x11/x11_screen.c | 21 ++++++++------ src/gallium/state_trackers/egl/x11/x11_screen.h | 14 ++++++++- 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 4754744..9ea3b80 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 6155b4d..1e20f94 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 acf1300..ad7aa97 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, -- 2.7.4