Mesa (7.8-gles): egl: Implement EGL_NOK_swap_region

Kristian Høgsberg krh at kemper.freedesktop.org
Fri May 14 19:23:46 UTC 2010


Module: Mesa
Branch: 7.8-gles
Commit: 61cc9a7538f8ebab39f236576114ec30f974d4f5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=61cc9a7538f8ebab39f236576114ec30f974d4f5

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu May  6 22:01:35 2010 -0400

egl: Implement EGL_NOK_swap_region

This extension adds a new function which provides an alternative to
eglSwapBuffers. eglSwapBuffersRegionNOK accepts two new parameters in
addition to those in eglSwapBuffers. The new parameters consist of a
pointer to a list of 4-integer blocks defining rectangles (x, y,
width, height) and an integer specifying the number of rectangles in
the list.

---

 include/EGL/eglext.h            |   12 ++++++++++
 src/egl/drivers/dri2/egl_dri2.c |   47 +++++++++++++++++++++++++++++++++++++-
 src/egl/main/eglapi.c           |   32 ++++++++++++++++++++++++++
 src/egl/main/eglapi.h           |    7 +++++
 src/egl/main/egldisplay.h       |    1 +
 src/egl/main/eglmisc.c          |    1 +
 6 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index a9e598d..61626d2 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -227,6 +227,18 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLCont
 #define EGL_CONTEXT_PRIORITY_LOW_IMG		0x3103
 #endif
 
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
+#endif
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint* rects);
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 6386737..82f409d 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -51,6 +51,8 @@
 #include "eglsurface.h"
 #include "eglimage.h"
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
 struct dri2_egl_driver
 {
    _EGLDriver base;
@@ -778,6 +780,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
    disp->Extensions.KHR_image_pixmap = EGL_TRUE;
    disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
    disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+   disp->Extensions.NOK_swap_region = EGL_TRUE;
 
    /* we're supporting EGL 1.4 */
    *major = 1;
@@ -1067,7 +1070,8 @@ dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
 }
 
 static EGLBoolean
-dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
+		 _EGLSurface *draw, xcb_xfixes_region_t region)
 {
    struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
@@ -1099,7 +1103,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
 
    cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
 					   dri2_surf->drawable,
-					   dri2_surf->region,
+					   region,
 					   XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
 					   XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
    free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
@@ -1107,6 +1111,44 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
    return EGL_TRUE;
 }
 
+static EGLBoolean
+dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+   return dri2_copy_region(drv, disp, draw, dri2_surf->region);
+}
+
+static EGLBoolean
+dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
+			 EGLint numRects, const EGLint *rects)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+   EGLBoolean ret;
+   xcb_xfixes_region_t region;
+   xcb_rectangle_t rectangles[16];
+   int i;
+
+   if (numRects > ARRAY_SIZE(rectangles))
+      return dri2_copy_region(drv, disp, draw, dri2_surf->region);
+
+   /* FIXME: Invert y here? */
+   for (i = 0; i < numRects; i++) {
+      rectangles[i].x = rects[i * 4];
+      rectangles[i].y = rects[i * 4 + 1];
+      rectangles[i].width = rects[i * 4 + 2];
+      rectangles[i].height = rects[i * 4 + 3];
+   }
+
+   region = xcb_generate_id(dri2_dpy->conn);
+   xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles);
+   ret = dri2_copy_region(drv, disp, draw, region);
+   xcb_xfixes_destroy_region(dri2_dpy->conn, region);
+
+   return ret;
+}
+
 /*
  * Called from eglGetProcAddress() via drv->API.GetProcAddress().
  */
@@ -1415,6 +1457,7 @@ _eglMain(const char *args)
    dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image;
    dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
    dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
+   dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
 
    dri2_drv->base.Name = "DRI2";
    dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index f57dda8..923992d 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -838,6 +838,9 @@ eglGetProcAddress(const char *procname)
       { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
       { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
 #endif /* EGL_KHR_image_base */
+#ifdef EGL_NOK_swap_region
+      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
+#endif
       { NULL, NULL }
    };
    EGLint i;
@@ -1246,3 +1249,32 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 
 
 #endif /* EGL_KHR_image_base */
+
+
+#ifdef EGL_NOK_swap_region
+
+EGLBoolean
+eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
+			EGLint numRects, const EGLint *rects)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+   /* surface must be bound to current context in EGL 1.4 */
+   if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+
+   if (drv->API.SwapBuffersRegionNOK)
+      ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
+   else
+      ret = drv->API.SwapBuffers(drv, disp, surf);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+#endif /* EGL_NOK_swap_region */
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index 3e2ba8d..d8c8b49 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -76,6 +76,9 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
 typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
 #endif /* EGL_KHR_image_base */
 
+#ifdef EGL_NOK_swap_region
+typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
+#endif
 
 /**
  * The API dispatcher jumps through these functions
@@ -134,6 +137,10 @@ struct _egl_api
    CreateImageKHR_t CreateImageKHR;
    DestroyImageKHR_t DestroyImageKHR;
 #endif /* EGL_KHR_image_base */
+
+#ifdef EGL_NOK_swap_region
+   SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
+#endif
 };
 
 #endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 21bf22b..0b7f9d8 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -46,6 +46,7 @@ struct _egl_extensions
    EGLBoolean KHR_gl_texture_cubemap_image;
    EGLBoolean KHR_gl_texture_3D_image;
    EGLBoolean KHR_gl_renderbuffer_image;
+   EGLBoolean NOK_swap_region;
 
    char String[_EGL_MAX_EXTENSIONS_LEN];
 };
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 984e426..82ddb6c 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -96,6 +96,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
    _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
 
+   _EGL_CHECK_EXTENSION(NOK_swap_region);
 #undef _EGL_CHECK_EXTENSION
 }
 




More information about the mesa-commit mailing list