Mesa (7.8-gles): egl: Implement EGL_NOK_texture_from_pixmap

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


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

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

egl: Implement EGL_NOK_texture_from_pixmap

This extension allows a color buffer to be used for both rendering and
texturing.  EGL allows the use of color buffers of pbuffer drawables
for texturing, this extension extends this to allow the use of color
buffers of pixmaps too.

---

 include/EGL/eglext.h            |    7 +++++++
 src/egl/drivers/dri2/egl_dri2.c |   24 ++++++------------------
 src/egl/main/eglconfig.c        |    9 ++++++++-
 src/egl/main/eglconfig.h        |   23 ++++++++++++++++++-----
 src/egl/main/egldisplay.h       |    1 +
 src/egl/main/eglmisc.c          |    1 +
 src/egl/main/eglsurface.c       |   23 +++++++++++++++++++----
 src/egl/main/eglsurface.h       |    2 +-
 8 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index 61626d2..e9f5a49 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -239,6 +239,13 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #endif
 
 
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+
+#define EGL_Y_INVERTED_NOK			0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 82f409d..a7030f0 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -165,7 +165,7 @@ EGLint dri2_to_egl_attribute_map[] = {
    0,				/* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
    0,				/* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
    0,				/* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
-   0,				/* __DRI_ATTRIB_YINVERTED */
+   EGL_Y_INVERTED_NOK,		/* __DRI_ATTRIB_YINVERTED */
 };
 
 static void
@@ -781,6 +781,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
    disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
    disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
    disp->Extensions.NOK_swap_region = EGL_TRUE;
+   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
 
    /* we're supporting EGL 1.4 */
    *major = 1;
@@ -1229,19 +1230,8 @@ dri2_bind_tex_image(_EGLDriver *drv,
    ctx = _eglGetCurrentContext();
    dri2_ctx = dri2_egl_context(ctx);
 
-   if (buffer != EGL_BACK_BUFFER) {
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+   if (!_eglBindTexImage(drv, disp, surf, buffer))
       return EGL_FALSE;
-   }
-
-   /* We allow binding pixmaps too... Not conformat, but we can do it
-    * for free and it's useful for X compositors.  Supposedly there's
-    * a EGL_NOKIA_texture_from_pixmap extension that allows that, but
-    * I couldn't find it at this time. */
-   if ((dri2_surf->base.Type & (EGL_PBUFFER_BIT | EGL_PIXMAP_BIT)) == 0) {
-      _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
-      return EGL_FALSE;
-   }
 
    switch (dri2_surf->base.TextureFormat) {
    case EGL_TEXTURE_RGB:
@@ -1251,8 +1241,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
       format = __DRI_TEXTURE_FORMAT_RGBA;
       break;
    default:
-      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
-      return EGL_FALSE;
+      assert(0);
    }
 
    switch (dri2_surf->base.TextureTarget) {
@@ -1260,15 +1249,14 @@ dri2_bind_tex_image(_EGLDriver *drv,
       target = GL_TEXTURE_2D;
       break;
    default:
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
-      return EGL_FALSE;
+      assert(0);
    }
 
    (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
 					  target, format,
 					  dri2_surf->dri_drawable);
 
-   return dri2_surf->base.BoundToTexture = EGL_TRUE;
+   return EGL_TRUE;
 }
 
 static EGLBoolean
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index a659d19..fa947d7 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -223,7 +223,12 @@ static const struct {
                                     0 },
    { EGL_NONE,                      ATTRIB_TYPE_PSEUDO,
                                     ATTRIB_CRITERION_IGNORE,
-                                    0 }
+                                    0 },
+
+   { EGL_Y_INVERTED_NOK,            ATTRIB_TYPE_BOOLEAN,
+                                    ATTRIB_CRITERION_EXACT,
+                                    EGL_DONT_CARE },
+
 };
 
 
@@ -492,6 +497,8 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
    case EGL_MATCH_NATIVE_PIXMAP:
 #endif
       return EGL_FALSE;
+   case EGL_Y_INVERTED_NOK:
+      return conf->Display->Extensions.NOK_texture_from_pixmap;
    default:
       break;
    }
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index ced060f..ca63c40 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -8,16 +8,24 @@
 
 #define _EGL_CONFIG_FIRST_ATTRIB EGL_BUFFER_SIZE
 #define _EGL_CONFIG_LAST_ATTRIB EGL_CONFORMANT
-#define _EGL_CONFIG_NUM_ATTRIBS \
+#define _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS \
    (_EGL_CONFIG_LAST_ATTRIB - _EGL_CONFIG_FIRST_ATTRIB + 1)
 
-#define _EGL_CONFIG_STORAGE_SIZE _EGL_CONFIG_NUM_ATTRIBS
+/* Attributes outside the contiguous block:
+ *
+ *   EGL_Y_INVERTED_NOK
+ */
+#define _EGL_CONFIG_FIRST_EXTRA_ATTRIB _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS
+#define _EGL_CONFIG_NUM_EXTRA_ATTRIBS 1
+
+#define _EGL_CONFIG_NUM_ATTRIBS \
+   _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS + _EGL_CONFIG_NUM_EXTRA_ATTRIBS
 
 
 struct _egl_config
 {
    _EGLDisplay *Display;
-   EGLint Storage[_EGL_CONFIG_STORAGE_SIZE];
+   EGLint Storage[_EGL_CONFIG_NUM_ATTRIBS];
 };
 
 
@@ -37,10 +45,15 @@ _eglIndexConfig(const _EGLConfig *conf, EGLint key)
 {
    (void) conf;
    if (key >= _EGL_CONFIG_FIRST_ATTRIB &&
-       key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_ATTRIBS)
+       key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS)
       return key - _EGL_CONFIG_FIRST_ATTRIB;
-   else
+   
+   switch (key) {
+   case EGL_Y_INVERTED_NOK:
+      return _EGL_CONFIG_FIRST_EXTRA_ATTRIB;
+   default:
       return -1;
+   }
 }
 
 
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 0b7f9d8..42e305f 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -47,6 +47,7 @@ struct _egl_extensions
    EGLBoolean KHR_gl_texture_3D_image;
    EGLBoolean KHR_gl_renderbuffer_image;
    EGLBoolean NOK_swap_region;
+   EGLBoolean NOK_texture_from_pixmap;
 
    char String[_EGL_MAX_EXTENSIONS_LEN];
 };
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 82ddb6c..e62a9e7 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -97,6 +97,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
 
    _EGL_CHECK_EXTENSION(NOK_swap_region);
+   _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
 #undef _EGL_CHECK_EXTENSION
 }
 
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 8026a63..d46bdb0 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -36,12 +36,17 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
 static EGLint
 _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
 {
+   _EGLDisplay *dpy = surf->Resource.Display;
    EGLint type = surf->Type;
+   EGLint texture_type = EGL_PBUFFER_BIT;
    EGLint i, err = EGL_SUCCESS;
 
    if (!attrib_list)
       return EGL_SUCCESS;
 
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
       EGLint attr = attrib_list[i++];
       EGLint val = attrib_list[i];
@@ -125,7 +130,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->LargestPbuffer = !!val;
          break;
       case EGL_TEXTURE_FORMAT:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -143,7 +148,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->TextureFormat = val;
          break;
       case EGL_TEXTURE_TARGET:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -160,7 +165,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->TextureTarget = val;
          break;
       case EGL_MIPMAP_TEXTURE:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -452,11 +457,16 @@ EGLBoolean
 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint buffer)
 {
+   EGLint texture_type = EGL_PBUFFER_BIT;
+
    /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
 
-   if (surface->Type != EGL_PBUFFER_BIT) {
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
+   if (!(surface->Type & texture_type)) {
       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
       return EGL_FALSE;
    }
@@ -466,6 +476,11 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
       return EGL_FALSE;
    }
 
+   if (surface->TextureTarget == EGL_NO_TEXTURE) {
+      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+      return EGL_FALSE;
+   }
+
    if (buffer != EGL_BACK_BUFFER) {
       _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
       return EGL_FALSE;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 0a00035..8f520dc 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -83,7 +83,7 @@ extern EGLBoolean
 _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
 
 
-extern EGLBoolean
+PUBLIC extern EGLBoolean
 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
 
 




More information about the mesa-commit mailing list