st/egl: Add support for EGL_NOK_swap_region
authorFredrik Höglund <fredrik@kde.org>
Wed, 14 Dec 2011 20:06:28 +0000 (21:06 +0100)
committerChia-I Wu <olv@lunarg.com>
Thu, 15 Dec 2011 07:00:15 +0000 (15:00 +0800)
Backends indicate that they support this extension by returning
EGL_TRUE when native_display::get_param() is called with
NATIVE_PARAM_PRESENT_REGION and NATIVE_PARAM_PRESERVE_BUFFER.

native_present_control is extended to include the region that should
be presented. When native_present_control::num_rects is zero,
the whole surface is to be presented.

Signed-off-by: Fredrik Höglund <fredrik@kde.org>
src/gallium/state_trackers/egl/common/egl_g3d.c
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/native.h

index 182ce684ecd13e99e7055b919f3be1c52e200b78..53811b8fc88a5fc012ee20219f19b6a7d351e530 100644 (file)
@@ -606,6 +606,12 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
       dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
 #endif
 
+#ifdef EGL_NOK_swap_region
+   if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESENT_REGION) &&
+       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER))
+      dpy->Extensions.NOK_swap_region = EGL_TRUE;
+#endif
+
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
       goto fail;
index 911540e83f278c1ed404f67d9030e433c5286da6..2e3ead6c8f382f99e142b83c524d939f827f04b8 100644 (file)
@@ -546,7 +546,8 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
 }
 
 static EGLBoolean
-egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+             EGLint num_rects, const EGLint *rects, EGLBoolean preserve)
 {
    struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
    _EGLContext *ctx = _eglGetCurrentContext();
@@ -572,13 +573,34 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
 
    memset(&ctrl, 0, sizeof(ctrl));
    ctrl.natt = NATIVE_ATTACHMENT_BACK_LEFT;
-   ctrl.preserve = (gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED);
+   ctrl.preserve = preserve;
    ctrl.swap_interval = gsurf->base.SwapInterval;
    ctrl.premultiplied_alpha = (gsurf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE);
+   ctrl.num_rects = num_rects;
+   ctrl.rects = rects;
 
    return gsurf->native->present(gsurf->native, &ctrl);
 }
 
+static EGLBoolean
+egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+   return swap_buffers(drv, dpy, surf, 0, NULL,
+                       (gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED));
+}
+
+#ifdef EGL_NOK_swap_region
+static EGLBoolean
+egl_g3d_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+                            EGLint num_rects, const EGLint *rects)
+{
+   /* Note: y=0=top */
+   return swap_buffers(drv, dpy, surf, num_rects, rects, EGL_TRUE);
+}
+#endif /* EGL_NOK_swap_region */
+
 static EGLBoolean
 egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                      EGLNativePixmapType target)
@@ -867,4 +889,8 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
    drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
    drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
 #endif
+
+#ifdef EGL_NOK_swap_region
+   drv->API.SwapBuffersRegionNOK = egl_g3d_swap_buffers_region;
+#endif
 }
index ee24c220e79c9139b3143e13f6f2af2e55817ba0..312b079fa36161f2a81b685efcaa9a2a655c5a95 100644 (file)
@@ -81,7 +81,13 @@ enum native_param_type {
     * EGL_ALPHA_SIZE.  EGL_VG_ALPHA_FORMAT attribute of a surface will affect
     * how the surface is presented.
     */
-   NATIVE_PARAM_PREMULTIPLIED_ALPHA
+   NATIVE_PARAM_PREMULTIPLIED_ALPHA,
+
+   /**
+    * Return TRUE if native_surface::present supports presenting a partial
+    * surface.
+    */
+   NATIVE_PARAM_PRESENT_REGION
 };
 
 /**
@@ -99,6 +105,11 @@ struct native_present_control {
 
    /**< pixels use premultiplied alpha */
    boolean premultiplied_alpha;
+
+   /**< The region to present. y=0=top.
+        If num_rects is 0, the whole surface is to be presented */
+   int num_rects;
+   const int *rects; /* x, y, width, height */
 };
 
 struct native_surface {