Hi Jakob,

This patch series adds support for GL_OES_EGL_image to st/mesa.  The first
patch implements st_manager::get_egl_image in st/egl.  The hook is used to
check and return an st_egl_image, which describes an EGLImageKHR.  The second
patch implements GL_OES_EGL_image in st/mesa, and the last patch adds a demo
for the new functionality.  I've tested it with egl_x11_i915.so, but it should
work with other hardware drivers.

Do you mind having a look at the patches, especially the first one?  I'd like
to hear your opinions before merging the patches, and going on to work on
EGLImage support in st/dri.

-- 
o...@lunarg.com
From 9dda3e2377abda21f6260c7cc2c2d6e9244e2685 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Fri, 12 Mar 2010 09:56:11 +0800
Subject: [PATCH 1/3] st/egl: Implement get_egl_image hook.

This hook may be used by rendering state trackers to implement EGLImage
extensions.
---
 src/gallium/state_trackers/egl/common/egl_g3d_st.c |   32 ++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index 3609409..a9343ea 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -85,6 +85,37 @@ egl_g3d_create_st_api(enum st_api_type api)
    return mod->create_api();
 }
 
+static boolean
+egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
+                                 struct st_egl_image *stimg)
+{
+   struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
+   EGLImageKHR handle = (EGLImageKHR) stimg->egl_image;
+   _EGLImage *img;
+   struct egl_g3d_image *gimg;
+
+   /* this is called from state trackers */
+   _eglLockMutex(&gsmapi->display->Mutex);
+
+   img = _eglLookupImage(handle, gsmapi->display);
+   if (!img) {
+      _eglUnlockMutex(&gsmapi->display->Mutex);
+      return FALSE;
+   }
+
+   gimg = egl_g3d_image(img);
+
+   stimg->texture = NULL;
+   pipe_texture_reference(&stimg->texture, gimg->texture);
+   stimg->face = gimg->face;
+   stimg->level = gimg->level;
+   stimg->zslice = gimg->zslice;
+
+   _eglUnlockMutex(&gsmapi->display->Mutex);
+
+   return TRUE;
+}
+
 struct st_manager *
 egl_g3d_create_st_manager(_EGLDisplay *dpy)
 {
@@ -96,6 +127,7 @@ egl_g3d_create_st_manager(_EGLDisplay *dpy)
       gsmapi->display = dpy;
 
       gsmapi->base.screen = gdpy->native->screen;
+      gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image;
    }
 
    return &gsmapi->base;;
-- 
1.7.0

From d36c035ccff06d188b244ee55d258b96a8abe184 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Thu, 25 Feb 2010 23:10:47 +0800
Subject: [PATCH 2/3] st/mesa: Implement GL_OES_EGL_image driver hooks.

Use st_manager::get_egl_image to look up GLeglImageOES and implement
EGLImageTargetTexture2D and EGLImageTargetRenderbufferStorage.
---
 src/mesa/SConscript                     |    1 +
 src/mesa/sources.mak                    |    1 +
 src/mesa/state_tracker/st_cb_eglimage.c |  160 +++++++++++++++++++++++++++++++
 src/mesa/state_tracker/st_cb_eglimage.h |   48 +++++++++
 src/mesa/state_tracker/st_context.c     |    3 +
 src/mesa/state_tracker/st_manager.c     |   28 ++++++
 src/mesa/state_tracker/st_manager.h     |    4 +
 7 files changed, 245 insertions(+), 0 deletions(-)
 create mode 100644 src/mesa/state_tracker/st_cb_eglimage.c
 create mode 100644 src/mesa/state_tracker/st_cb_eglimage.h

diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index c850854..d368b8b 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -166,6 +166,7 @@ if env['platform'] != 'winddk':
 		'state_tracker/st_cb_condrender.c',
 		'state_tracker/st_cb_flush.c',
 		'state_tracker/st_cb_drawpixels.c',
+		'state_tracker/st_cb_eglimage.c',
 		'state_tracker/st_cb_fbo.c',
 		'state_tracker/st_cb_feedback.c',
 		'state_tracker/st_cb_program.c',
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index d6ae696..15988ba 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -198,6 +198,7 @@ STATETRACKER_SOURCES = \
 	state_tracker/st_cb_condrender.c \
 	state_tracker/st_cb_flush.c \
 	state_tracker/st_cb_drawpixels.c \
+	state_tracker/st_cb_eglimage.c \
 	state_tracker/st_cb_fbo.c \
 	state_tracker/st_cb_feedback.c \
 	state_tracker/st_cb_program.c \
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
new file mode 100644
index 0000000..d8d9202
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -0,0 +1,160 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#include "main/texobj.h"
+#include "main/texfetch.h"
+#include "main/teximage.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "st_cb_eglimage.h"
+#include "st_cb_fbo.h"
+#include "st_texture.h"
+#include "st_format.h"
+#include "st_manager.h"
+
+#if FEATURE_OES_EGL_image
+
+/**
+ * Return the base format just like _mesa_base_fbo_format does.
+ */
+static GLenum
+st_pipe_format_to_base_format(enum pipe_format format)
+{
+   GLenum base_format;
+
+   if (util_format_is_depth_or_stencil(format)) {
+      if (util_format_is_depth_and_stencil(format)) {
+         base_format = GL_DEPTH_STENCIL;
+      }
+      else {
+         if (format == PIPE_FORMAT_S8_UNORM)
+            base_format = GL_STENCIL_INDEX;
+         else
+            base_format = GL_DEPTH_COMPONENT;
+      }
+   }
+   else {
+      /* is this enough? */
+      if (util_format_has_alpha(format))
+         base_format = GL_RGBA;
+      else
+         base_format = GL_RGB;
+   }
+
+   return base_format;
+}
+
+static void
+st_egl_image_target_renderbuffer_storage(GLcontext *ctx,
+					 struct gl_renderbuffer *rb,
+					 GLeglImageOES image_handle)
+{
+   struct st_context *st = ctx->st;
+   struct st_renderbuffer *strb = st_renderbuffer(rb);
+   struct pipe_surface *ps;
+   unsigned usage;
+
+   usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
+   ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
+   if (ps) {
+      strb->Base.Width = ps->width;
+      strb->Base.Height = ps->height;
+      strb->Base.Format = st_pipe_format_to_mesa_format(ps->format);
+      strb->Base.DataType = st_format_datatype(ps->format);
+      strb->Base._BaseFormat = st_pipe_format_to_base_format(ps->format);
+      strb->Base.InternalFormat = strb->Base._BaseFormat;
+
+      pipe_surface_reference(&strb->surface, ps);
+      pipe_texture_reference(&strb->texture, ps->texture);
+
+      pipe_surface_reference(&ps, NULL);
+   }
+}
+
+static void
+st_bind_surface(GLcontext *ctx, GLenum target,
+                struct gl_texture_object *texObj,
+                struct gl_texture_image *texImage,
+                struct pipe_surface *ps)
+{
+   struct st_texture_object *stObj;
+   struct st_texture_image *stImage;
+   GLenum internalFormat;
+
+   /* map pipe format to base format */
+   if (util_format_get_component_bits(ps->format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
+      internalFormat = GL_RGBA;
+   else
+      internalFormat = GL_RGB;
+
+   stObj = st_texture_object(texObj);
+   stImage = st_texture_image(texImage);
+
+   /* switch to surface based */
+   if (!stObj->surface_based) {
+      _mesa_clear_texture_object(ctx, texObj);
+      stObj->surface_based = GL_TRUE;
+   }
+
+   _mesa_init_teximage_fields(ctx, target, texImage,
+                              ps->width, ps->height, 1, 0, internalFormat);
+   texImage->TexFormat = st_pipe_format_to_mesa_format(ps->format);
+   _mesa_set_fetch_functions(texImage, 2);
+
+   stObj->pipe = ctx->st->pipe;
+   /* FIXME create a non-default sampler view from the pipe_surface? */
+   pipe_texture_reference(&stImage->pt, ps->texture);
+
+   _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+}
+
+static void
+st_egl_image_target_texture_2d(GLcontext *ctx, GLenum target,
+			       struct gl_texture_object *texObj,
+			       struct gl_texture_image *texImage,
+			       GLeglImageOES image_handle)
+{
+   struct st_context *st = ctx->st;
+   struct pipe_surface *ps;
+   unsigned usage;
+
+   usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
+   ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage);
+   if (ps) {
+      st_bind_surface(ctx, target, texObj, texImage, ps);
+      pipe_surface_reference(&ps, NULL);
+   }
+}
+
+void
+st_init_eglimage_functions(struct dd_function_table *functions)
+{
+   functions->EGLImageTargetTexture2D = st_egl_image_target_texture_2d;
+   functions->EGLImageTargetRenderbufferStorage = st_egl_image_target_renderbuffer_storage;
+}
+
+#endif /* FEATURE_OES_EGL_image */
diff --git a/src/mesa/state_tracker/st_cb_eglimage.h b/src/mesa/state_tracker/st_cb_eglimage.h
new file mode 100644
index 0000000..77e668d
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_eglimage.h
@@ -0,0 +1,48 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#ifndef ST_CB_EGLIMAGE_H
+#define ST_CB_EGLIMAGE_H
+
+#include "main/mtypes.h"
+#include "main/dd.h"
+
+#if FEATURE_OES_EGL_image
+
+extern void
+st_init_eglimage_functions(struct dd_function_table *functions);
+
+#else
+
+static INLINE void
+st_init_eglimage_functions(struct dd_function_table *functions)
+{
+}
+
+#endif
+
+#endif /* ST_CB_EGLIMAGE_H */
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 72f5a9c..8358059 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -46,6 +46,7 @@
 #if FEATURE_OES_draw_texture
 #include "st_cb_drawtex.h"
 #endif
+#include "st_cb_eglimage.h"
 #include "st_cb_fbo.h"
 #if FEATURE_feedback
 #include "st_cb_feedback.h"
@@ -359,6 +360,8 @@ void st_init_driver_functions(struct dd_function_table *functions)
    st_init_drawtex_functions(functions);
 #endif
 
+   st_init_eglimage_functions(functions);
+
    st_init_fbo_functions(functions);
 #if FEATURE_feedback
    st_init_feedback_functions(functions);
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index cac62e4..696d8aa 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -721,6 +721,34 @@ st_manager_flush_frontbuffer(struct st_context *st)
 }
 
 /**
+ * Return the surface of an EGLImage.
+ */
+struct pipe_surface *
+st_manager_get_egl_image_surface(struct st_context *st,
+                                 void *eglimg, unsigned usage)
+{
+   struct st_manager *smapi =
+      (struct st_manager *) st->iface.st_context_private;
+   struct st_egl_image stimg;
+   struct pipe_surface *ps;
+
+   if (!smapi || !smapi->get_egl_image)
+      return NULL;
+
+   memset(&stimg, 0, sizeof(stimg));
+   stimg.stctxi = &st->iface;
+   stimg.egl_image = eglimg;
+   if (!smapi->get_egl_image(smapi, &stimg))
+      return NULL;
+
+   ps = smapi->screen->get_tex_surface(smapi->screen,
+         stimg.texture, stimg.face, stimg.level, stimg.zslice, usage);
+   pipe_texture_reference(&stimg.texture, NULL);
+
+   return ps;
+}
+
+/**
  * Re-validate the framebuffers.
  */
 void
diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h
index a3f5199..0d3f8f7 100644
--- a/src/mesa/state_tracker/st_manager.h
+++ b/src/mesa/state_tracker/st_manager.h
@@ -31,6 +31,10 @@
 #include "state_tracker/st_api.h"
 #include "st_context.h"
 
+struct pipe_surface *
+st_manager_get_egl_image_surface(struct st_context *st,
+                                 void *eglimg, unsigned usage);
+
 void
 st_manager_flush_frontbuffer(struct st_context *st);
 
-- 
1.7.0

From 0a4ecd8e94c8c3ec72d26f6a30d43ed978c0c97e Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Mon, 1 Mar 2010 15:21:46 +0800
Subject: [PATCH 3/3] progs/es1: Add a demo for EGL_OES_image_pixmap.

The demo uses a Pixmap as its drawing area, and whatever is drawn on the
pixmap will be used as a texture to draw a cube.
---
 progs/es1/xegl/Makefile              |    4 +
 progs/es1/xegl/texture_from_pixmap.c |  579 ++++++++++++++++++++++++++++++++++
 2 files changed, 583 insertions(+), 0 deletions(-)
 create mode 100644 progs/es1/xegl/texture_from_pixmap.c

diff --git a/progs/es1/xegl/Makefile b/progs/es1/xegl/Makefile
index 6869c44..6e86d8b 100644
--- a/progs/es1/xegl/Makefile
+++ b/progs/es1/xegl/Makefile
@@ -27,6 +27,7 @@ PROGRAMS = \
 	pbuffer \
 	render_tex \
 	torus \
+	texture_from_pixmap \
 	tri \
 	two_win
 
@@ -72,6 +73,9 @@ two_win: two_win.o $(ES1_LIB_DEPS)
 	$(CC) $(CFLAGS) two_win.o $(ES1_LIBS) -o $@
 
 
+texture_from_pixmap: texture_from_pixmap.o $(ES1_LIB_DEPS)
+	$(CC) $(CFLAGS) texture_from_pixmap.o $(ES1_LIBS) -o $@
+
 tri: tri.o $(ES1_LIB_DEPS)
 	$(CC) $(CFLAGS) tri.o $(ES1_LIBS) -o $@
 
diff --git a/progs/es1/xegl/texture_from_pixmap.c b/progs/es1/xegl/texture_from_pixmap.c
new file mode 100644
index 0000000..abb8c28
--- /dev/null
+++ b/progs/es1/xegl/texture_from_pixmap.c
@@ -0,0 +1,579 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+/*
+ * This demo uses EGL_KHR_image_pixmap and GL_OES_EGL_image to demonstrate
+ * texture-from-pixmap.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h> /* for usleep */
+#include <sys/time.h> /* for gettimeofday */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+struct app_data {
+   /* native */
+   Display *xdpy;
+   Window canvas, cube;
+   Pixmap pix;
+   unsigned int width, height, depth;
+   GC fg, bg;
+
+   /* EGL */
+   EGLDisplay dpy;
+   EGLContext ctx;
+   EGLSurface surf;
+   EGLImageKHR img;
+
+   /* OpenGL ES */
+   GLuint texture;
+
+   PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
+   PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
+   PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
+
+   /* app state */
+   Bool loop;
+   Bool redraw, reshape;
+
+   struct {
+      Bool active;
+      unsigned long next_frame; /* in ms */
+      float view_rotx;
+      float view_roty;
+      float view_rotz;
+
+   } animate;
+
+   struct {
+      Bool active;
+      int x1, y1;
+      int x2, y2;
+   } paint;
+};
+
+static void
+gl_redraw(void)
+{
+   const GLfloat verts[4][2] = {
+      { -1, -1 },
+      {  1, -1 },
+      {  1,  1 },
+      { -1,  1 }
+   };
+   const GLfloat texcoords[4][2] = {
+      { 0, 1 },
+      { 1, 1 },
+      { 1, 0 },
+      { 0, 0 }
+   };
+   const GLfloat faces[6][4] = {
+      {   0, 0, 1, 0 },
+      {  90, 0, 1, 0 },
+      { 180, 0, 1, 0 },
+      { 270, 0, 1, 0 },
+      {  90, 1, 0, 0 },
+      { -90, 1, 0, 0 }
+   };
+   GLint i;
+
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glVertexPointer(2, GL_FLOAT, 0, verts);
+   glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
+
+   glEnableClientState(GL_VERTEX_ARRAY);
+   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+   for (i = 0; i < 6; i++) {
+      glPushMatrix();
+      glRotatef(faces[i][0], faces[i][1], faces[i][2], faces[i][3]);
+      glTranslatef(0, 0, 1.0);
+      glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+      glPopMatrix();
+   }
+
+   glDisableClientState(GL_VERTEX_ARRAY);
+   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+static void
+gl_reshape(int width, int height)
+{
+   GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+   glViewport(0, 0, width, height);
+
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
+   
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -10.0);
+}
+
+static void
+app_redraw(struct app_data *data)
+{
+   /* pixmap has changed */
+   if (data->reshape || data->paint.active) {
+      eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+      if (data->reshape) {
+         data->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
+               (GLeglImageOES) data->img);
+      }
+   }
+
+   XCopyArea(data->xdpy, data->pix, data->canvas, data->fg,
+         0, 0, data->width, data->height, 0, 0);
+
+   glPushMatrix();
+   glRotatef(data->animate.view_rotx, 1, 0, 0);
+   glRotatef(data->animate.view_roty, 0, 1, 0);
+   glRotatef(data->animate.view_rotz, 0, 0, 1);
+   gl_redraw();
+   glPopMatrix();
+
+   eglSwapBuffers(data->dpy, data->surf);
+}
+
+static void
+app_reshape(struct app_data *data)
+{
+   const EGLint img_attribs[] = {
+      EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+      EGL_NONE
+   };
+
+   XResizeWindow(data->xdpy, data->cube, data->width, data->height);
+   XMoveWindow(data->xdpy, data->cube, data->width, 0);
+
+   if (data->img)
+      data->eglDestroyImageKHR(data->dpy, data->img);
+   if (data->pix)
+      XFreePixmap(data->xdpy, data->pix);
+
+   data->pix = XCreatePixmap(data->xdpy, data->canvas, data->width, data->height, data->depth);
+   XFillRectangle(data->xdpy, data->pix, data->bg, 0, 0, data->width, data->height);
+
+   data->img = data->eglCreateImageKHR(data->dpy, EGL_NO_CONTEXT,
+         EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer) data->pix, img_attribs);
+
+   gl_reshape(data->width, data->height);
+}
+
+static void
+app_toggle_animate(struct app_data *data)
+{
+   data->animate.active = !data->animate.active;
+
+   if (data->animate.active) {
+      struct timeval tv;
+
+      gettimeofday(&tv, NULL);
+      data->animate.next_frame = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+   }
+}
+
+static void
+app_next_event(struct app_data *data)
+{
+   XEvent event;
+
+   data->reshape = False;
+   data->redraw = False;
+   data->paint.active = False;
+
+   if (data->animate.active) {
+      struct timeval tv;
+      unsigned long now;
+
+      gettimeofday(&tv, NULL);
+      now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+      /* wait for next frame */
+      if (!XPending(data->xdpy) && now < data->animate.next_frame) {
+         usleep((data->animate.next_frame - now) * 1000);
+         gettimeofday(&tv, NULL);
+         now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+      }
+
+      while (now >= data->animate.next_frame) {
+         data->animate.view_rotx += 1.0;
+         data->animate.view_roty += 2.0;
+         data->animate.view_rotz += 1.5;
+
+         /* 30fps */
+         data->animate.next_frame += 1000 / 30;
+      }
+
+      /* check again in case there were events when sleeping */
+      if (!XPending(data->xdpy)) {
+         data->redraw = True;
+         return;
+      }
+   }
+
+   XNextEvent(data->xdpy, &event);
+
+   switch (event.type) {
+   case ConfigureNotify:
+      data->width = event.xconfigure.width / 2;
+      data->height = event.xconfigure.height;
+      data->reshape = True;
+      break;
+   case Expose:
+      data->redraw = True;
+      break;
+   case KeyPress:
+      {
+         int code;
+
+         code = XLookupKeysym(&event.xkey, 0);
+         switch (code) {
+         case XK_a:
+            app_toggle_animate(data);
+            break;
+         case XK_Escape:
+            data->loop = False;
+            break;
+         default:
+            break;
+         }
+      }
+      break;
+   case ButtonPress:
+      data->paint.x1 = data->paint.x2 = event.xbutton.x;
+      data->paint.y1 = data->paint.y2 = event.xbutton.y;
+      break;
+   case ButtonRelease:
+      data->paint.active = False;
+      break;
+   case MotionNotify:
+      data->paint.x1 = data->paint.x2;
+      data->paint.y1 = data->paint.y2;
+      data->paint.x2 = event.xmotion.x;
+      data->paint.y2 = event.xmotion.y;
+      data->paint.active = True;
+      break;
+   default:
+      break;
+   }
+
+   if (data->paint.active || data->reshape)
+      data->redraw = True;
+}
+
+static void
+app_init_gl(struct app_data *data)
+{
+   glClearColor(0.1, 0.1, 0.3, 0.0);
+   glColor4f(1.0, 1.0, 1.0, 1.0);
+
+   glGenTextures(1, &data->texture);
+
+   glBindTexture(GL_TEXTURE_2D, data->texture);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+   glEnable(GL_TEXTURE_2D);
+   glEnable(GL_DEPTH_TEST);
+}
+
+static Bool
+app_init_exts(struct app_data *data)
+{
+   const char *exts;
+
+   exts = eglQueryString(data->dpy, EGL_EXTENSIONS);
+   data->eglCreateImageKHR =
+      (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
+   data->eglDestroyImageKHR =
+      (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
+   if (!exts || !strstr(exts, "EGL_KHR_image_pixmap") ||
+       !data->eglCreateImageKHR || !data->eglDestroyImageKHR) {
+      printf("EGL does not support EGL_KHR_image_pixmap\n");
+      return False;
+   }
+
+   exts = (const char *) glGetString(GL_EXTENSIONS);
+   exts = "GL_OES_EGL_image"; /* XXX */
+   data->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
+      eglGetProcAddress("glEGLImageTargetTexture2DOES");
+   if (!exts || !strstr(exts, "GL_OES_EGL_image") ||
+       !data->glEGLImageTargetTexture2DOES) {
+      printf("OpenGL ES does not support GL_OES_EGL_image\n");
+      return False;
+   }
+
+   return True;
+}
+
+static void
+app_run(struct app_data *data)
+{
+   Window root;
+   int x, y;
+   unsigned int border;
+
+   if (!eglMakeCurrent(data->dpy, data->surf, data->surf, data->ctx))
+      return;
+
+   if (!app_init_exts(data))
+      return;
+
+   printf("Draw something on the left with the mouse!\n");
+
+   app_init_gl(data);
+
+   if (!XGetGeometry(data->xdpy, data->canvas, &root, &x, &y,
+            &data->width, &data->height, &border, &data->depth))
+      return;
+   data->width /= 2;
+
+   app_reshape(data);
+
+   XMapWindow(data->xdpy, data->canvas);
+   XMapWindow(data->xdpy, data->cube);
+
+   app_toggle_animate(data);
+   data->loop = True;
+
+   while (data->loop) {
+      app_next_event(data);
+
+      if (data->reshape)
+         app_reshape(data);
+      if (data->paint.active) {
+         XDrawLine(data->xdpy, data->pix, data->fg,
+               data->paint.x1, data->paint.y1,
+               data->paint.x2, data->paint.y2);
+      }
+
+      if (data->redraw)
+         app_redraw(data);
+   }
+
+   eglMakeCurrent(data->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+}
+
+static Bool
+make_x_window(struct app_data *data, const char *name,
+              int x, int y, int width, int height)
+{
+   static const EGLint attribs[] = {
+      EGL_RED_SIZE, 1,
+      EGL_GREEN_SIZE, 1,
+      EGL_BLUE_SIZE, 1,
+      EGL_DEPTH_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+      EGL_NONE
+   };
+   static const EGLint ctx_attribs[] = {
+      EGL_CONTEXT_CLIENT_VERSION, 1,
+      EGL_NONE
+   };
+   int scrnum;
+   XSetWindowAttributes attr;
+   unsigned long mask;
+   Window root;
+   Window win;
+   XVisualInfo *visInfo, visTemplate;
+   int num_visuals;
+   EGLConfig config;
+   EGLint num_configs;
+   EGLint vid;
+
+   scrnum = DefaultScreen( data->xdpy );
+   root = RootWindow( data->xdpy, scrnum );
+
+   if (!eglChooseConfig( data->dpy, attribs, &config, 1, &num_configs)) {
+      printf("Error: couldn't get an EGL visual config\n");
+      exit(1);
+   }
+
+   assert(config);
+   assert(num_configs > 0);
+
+   if (!eglGetConfigAttrib(data->dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
+      printf("Error: eglGetConfigAttrib() failed\n");
+      exit(1);
+   }
+
+   /* The X window visual must match the EGL config */
+   visTemplate.visualid = vid;
+   visInfo = XGetVisualInfo(data->xdpy, VisualIDMask, &visTemplate, &num_visuals);
+   if (!visInfo) {
+      printf("Error: couldn't get X visual\n");
+      exit(1);
+   }
+
+   /* window attributes */
+   attr.background_pixel = 0;
+   attr.border_pixel = 0;
+   attr.colormap = XCreateColormap( data->xdpy, root, visInfo->visual, AllocNone);
+   attr.event_mask = StructureNotifyMask | ExposureMask |
+                     KeyPressMask | ButtonPressMask | ButtonMotionMask;
+   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+   win = XCreateWindow( data->xdpy, root, 0, 0, width * 2, height,
+		        0, visInfo->depth, InputOutput,
+		        visInfo->visual, mask, &attr );
+
+   /* set hints and properties */
+   {
+      XSizeHints sizehints;
+      sizehints.x = x;
+      sizehints.y = y;
+      sizehints.width  = width;
+      sizehints.height = height;
+      sizehints.flags = USSize | USPosition;
+      XSetNormalHints(data->xdpy, win, &sizehints);
+      XSetStandardProperties(data->xdpy, win, name, name,
+                              None, (char **)NULL, 0, &sizehints);
+   }
+
+   data->canvas = win;
+
+   attr.event_mask = 0x0;
+   win = XCreateWindow( data->xdpy, win, width, 0, width, height,
+		        0, visInfo->depth, InputOutput,
+		        visInfo->visual, mask, &attr );
+   data->cube = win;
+
+   eglBindAPI(EGL_OPENGL_ES_API);
+
+   data->ctx = eglCreateContext(data->dpy, config, EGL_NO_CONTEXT, ctx_attribs );
+   if (!data->ctx) {
+      printf("Error: eglCreateContext failed\n");
+      exit(1);
+   }
+
+   data->surf = eglCreateWindowSurface(data->dpy, config, data->cube, NULL);
+   if (!data->surf) {
+      printf("Error: eglCreateWindowSurface failed\n");
+      exit(1);
+   }
+
+   XFree(visInfo);
+
+   return (data->canvas && data->cube && data->ctx && data->surf);
+}
+
+static void
+app_fini(struct app_data *data)
+{
+   if (data->img)
+      data->eglDestroyImageKHR(data->dpy, data->img);
+   if (data->pix)
+      XFreePixmap(data->xdpy, data->pix);
+
+   if (data->fg)
+      XFreeGC(data->xdpy, data->fg);
+   if (data->bg)
+      XFreeGC(data->xdpy, data->bg);
+
+   if (data->surf)
+      eglDestroySurface(data->dpy, data->surf);
+   if (data->ctx)
+      eglDestroyContext(data->dpy, data->ctx);
+
+   if (data->cube)
+      XDestroyWindow(data->xdpy, data->cube);
+   if (data->canvas)
+      XDestroyWindow(data->xdpy, data->canvas);
+
+   if (data->dpy)
+      eglTerminate(data->dpy);
+   if (data->xdpy)
+      XCloseDisplay(data->xdpy);
+}
+
+static Bool
+app_init(struct app_data *data, int argc, char **argv)
+{
+   XGCValues gc_vals;
+
+   memset(data, 0, sizeof(*data));
+
+   data->xdpy = XOpenDisplay(NULL);
+   if (!data->xdpy)
+      goto fail;
+
+   data->dpy = eglGetDisplay(data->xdpy);
+   if (!data->dpy || !eglInitialize(data->dpy, NULL, NULL))
+      goto fail;
+
+   if (!make_x_window(data, "EGLImage TFP", 0, 0, 300, 300))
+      goto fail;
+
+   gc_vals.function = GXcopy;
+   gc_vals.foreground = WhitePixel(data->xdpy, DefaultScreen(data->xdpy));
+   gc_vals.line_width = 3;
+   gc_vals.line_style = LineSolid;
+   gc_vals.fill_style = FillSolid;
+
+   data->fg = XCreateGC(data->xdpy, data->canvas,
+         GCFunction | GCForeground | GCLineWidth | GCLineStyle | GCFillStyle,
+         &gc_vals);
+   gc_vals.foreground = BlackPixel(data->xdpy, DefaultScreen(data->xdpy));
+   data->bg = XCreateGC(data->xdpy, data->canvas,
+         GCFunction | GCForeground | GCLineWidth | GCLineStyle | GCFillStyle,
+         &gc_vals);
+   if (!data->fg || !data->bg)
+      goto fail;
+
+   return True;
+
+fail:
+   app_fini(data);
+   return False;
+}
+
+int
+main(int argc, char **argv)
+{
+   struct app_data data;
+
+   if (app_init(&data, argc, argv)) {
+      app_run(&data);
+      app_fini(&data);
+   }
+
+   return 0;
+}
-- 
1.7.0

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to