summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-05-06 22:40:25 -0400
committerKristian Høgsberg <krh@bitplanet.net>2010-05-14 14:47:54 -0400
commit5dc0f49084f322dd8ff6eb585212eea8b50e3377 (patch)
treef7288e99843660480bfe670307a2e0b3a3835434
parent554e4fc26a64a90012b0d7dcc1205441273f214c (diff)
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.
-rw-r--r--include/EGL/eglext.h7
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c24
-rw-r--r--src/egl/main/eglconfig.c9
-rw-r--r--src/egl/main/eglconfig.h23
-rw-r--r--src/egl/main/egldisplay.h1
-rw-r--r--src/egl/main/eglmisc.c1
-rw-r--r--src/egl/main/eglsurface.c23
-rw-r--r--src/egl/main/eglsurface.h2
8 files changed, 61 insertions, 29 deletions
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index 61626d20df..e9f5a49b48 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 82f409d294..a7030f03db 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 a659d19c37..fa947d7688 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 ced060f779..ca63c40d3d 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 0b7f9d8303..42e305f91a 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 82ddb6cad9..e62a9e7de8 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 8026a6314d..d46bdb0672 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 0a00035730..8f520dcdf6 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);