API add: From <dunamis.park@samsung.com> - sungwoo
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 4 Apr 2011 10:23:12 +0000 (10:23 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 4 Apr 2011 10:23:12 +0000 (10:23 +0000)
  start of evas gl api (with compile warning fixes).

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@58318 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/Makefile.am
src/lib/canvas/Makefile.am
src/lib/include/evas_common.h
src/lib/include/evas_private.h
src/modules/engines/gl_common/evas_gl_common.h
src/modules/engines/gl_common/evas_gl_context.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/gl_x11/evas_engine.h
src/modules/engines/software_generic/evas_engine.c

index bdefc25..937f39c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Added vertical alignment support to textblock.
          API: evas_object_textblock_valign_set/get
+
+2011-04-04  Sung W. Park
+
+       * Added Evas OpenGL interface to be able to get an OpenGL API for
+        rendering to image objects. This is the beginning so not
+        totally functional yet.
index be84a2b..a4d54cc 100644 (file)
@@ -218,7 +218,7 @@ AM_CFLAGS = @WIN32_CFLAGS@
 
 lib_LTLIBRARIES = libevas.la
 
-includes_HEADERS = Evas.h
+includes_HEADERS = Evas.h Evas_GL.h
 includesdir = $(includedir)/evas-@VMAJ@
 
 libevas_la_SOURCES = main.c
index d5959fa..2acbdc7 100644 (file)
@@ -48,7 +48,8 @@ evas_stack.c \
 evas_async_events.c \
 evas_transform.c \
 evas_stats.c \
-evas_map.c
+evas_map.c \
+evas_gl.c
 
 libevas_canvas_la_LIBADD = @EVIL_LIBS@
 
index b84c1aa..6ba910a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <Eina.h>
 #include "Evas.h"
+#include "Evas_GL.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
index 4251d7d..8b8351e 100644 (file)
@@ -60,6 +60,7 @@ typedef struct _Evas_Post_Callback          Evas_Post_Callback;
 #define MAGIC_OBJ_SHAPE            0x72777773
 #define MAGIC_OBJ_CONTAINER        0x72777774
 #define MAGIC_OBJ_CUSTOM           0x72777775
+#define MAGIC_EVAS_GL              0x72777776
 
 #ifdef MAGIC_DEBUG
 # define MAGIC_CHECK_FAILED(o, t, m) \
@@ -684,6 +685,15 @@ struct _Evas_Func
    int  (*font_pen_coords_get)            (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
    Eina_Bool (*font_text_props_info_create)                (void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
    int  (*font_right_inset_get)                  (void *data, void *font, const Evas_Text_Props *text_props);
+
+   /* EFL-GL Glue Layer */
+   void *(*gl_surface_create)            (void *data, void *config, int w, int h);
+   int  (*gl_surface_destroy)            (void *data, void *surface);
+   void *(*gl_context_create)            (void *data, void *share_context);
+   int  (*gl_context_destroy)            (void *data, void *context);
+   int  (*gl_make_current)               (void *data, void *surface, void *context); 
+   void *(*gl_proc_address_get)          (void *data, const char *name);
+   int  (*gl_native_surface_get)         (void *data, void *surface, void *native_surface);
 };
 
 struct _Evas_Image_Load_Func
index bd2abe4..7a95edf 100644 (file)
@@ -187,7 +187,8 @@ struct _Evas_GL_Shared
       Eina_List       *atlas[33][3];
    } tex;
    
-   Eina_Hash          *native_hash;
+   Eina_Hash          *native_pm_hash;
+   Eina_Hash          *native_tex_hash;
    
    struct {
       Evas_GL_Program  rect;
index 2e7e79e..cf2fa1a 100644 (file)
@@ -743,7 +743,8 @@ evas_gl_common_context_new(void)
         // GLint loc = glGetUniformLocation(prog, "tex");
         // glUniform1iv(loc, 8, texes);
 
-        shared->native_hash = eina_hash_int32_new(NULL);
+        shared->native_pm_hash  = eina_hash_int32_new(NULL);
+        shared->native_tex_hash = eina_hash_int32_new(NULL);
      }
    gc->shared = shared;
    gc->shared->references++;
@@ -811,7 +812,8 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
                      evas_gl_texture_pool_empty(pt);
                }
           }
-        eina_hash_free(gc->shared->native_hash);
+        eina_hash_free(gc->shared->native_pm_hash);
+        eina_hash_free(gc->shared->native_tex_hash);
         free(gc->shared);
         shared = NULL;
      }
index 56347df..af48bf0 100644 (file)
@@ -12,7 +12,9 @@
 // GLX
 #endif
 
-typedef struct _Render_Engine Render_Engine;
+typedef struct _Render_Engine               Render_Engine;
+typedef struct _Render_Engine_GL_Surface    Render_Engine_GL_Surface;
+typedef struct _Render_Engine_GL_Context    Render_Engine_GL_Context;
 
 struct _Render_Engine
 {
@@ -30,6 +32,38 @@ struct _Render_Engine
    int vsync;
 };
 
+struct _Render_Engine_GL_Surface
+{
+   int     initialized;
+   int     w, h;
+   int     depth_bits;
+   int     stencil_bits;
+
+   // Render target texture/buffers
+   GLuint  rt_tex;
+   GLint   rt_internal_fmt;
+   GLenum  rt_fmt; 
+   GLuint  rb_depth;
+   GLenum  rb_depth_fmt;
+   GLuint  rb_stencil;
+   GLenum  rb_stencil_fmt;
+
+   Render_Engine_GL_Context   *current_ctx;
+};
+
+struct _Render_Engine_GL_Context
+{
+   int         initialized;
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   EGLContext  context;
+#else   
+   GLXContext  context;
+#endif
+   GLuint      fbo;     
+   
+   Render_Engine_GL_Surface   *current_sfc;
+};
+
 static int initted = 0;
 static int gl_wins = 0;
 
@@ -425,7 +459,7 @@ eng_setup(Evas *e, void *in)
      e->engine.data.context =
      e->engine.func->context_new(e->engine.data.output);
    eng_window_use(re->win);
-   
+
    re->vsync = 0;
    if (re->win->alpha)
      {
@@ -1070,7 +1104,8 @@ _native_bind_cb(void *data, void *image)
     }
   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
     {
-      // FIXME: implement
+      glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id); 
+      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
     }
 }
 
@@ -1101,7 +1136,8 @@ _native_unbind_cb(void *data, void *image)
     }
   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
     {
-      // FIXME: implement
+      glBindTexture(GL_TEXTURE_2D, 0); 
+      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
     }
 }
 
@@ -1111,12 +1147,12 @@ _native_free_cb(void *data, void *image)
   Render_Engine *re = data;
   Evas_GL_Image *im = image;
   Native *n = im->native.data;
-  uint32_t pmid;
+  uint32_t pmid, texid;
 
   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
     {
       pmid = n->pixmap;
-      eina_hash_del(re->win->gl_context->shared->native_hash, &pmid, im);
+      eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
       if (n->egl_surface)
         {
@@ -1159,7 +1195,8 @@ _native_free_cb(void *data, void *image)
     }
   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
     {
-      // FIXME: implement
+      texid = n->ns.data.opengl.texture_id;
+      eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
     }
   im->native.data        = NULL;
   im->native.func.data   = NULL;
@@ -1178,9 +1215,23 @@ eng_image_native_set(void *data, void *image, void *native)
   Visual *vis = NULL;
   Pixmap pm = 0;
   Native *n = NULL;
-  uint32_t pmid;
+  uint32_t pmid, texid;
+  unsigned int tex = 0;
+  unsigned int fbo = 0; 
   
-  if (!im) return NULL;
+  if (!im) 
+    {
+       if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL)) 
+         {
+            im = evas_gl_common_image_new_from_data(re->win->gl_context, 
+                                                    ns->data.opengl.w, 
+                                                    ns->data.opengl.h, 
+                                                    NULL, 1, 
+                                                    EVAS_COLORSPACE_ARGB8888);
+         } 
+       else 
+           return NULL;
+    }
   
   if (ns)
     {
@@ -1198,7 +1249,15 @@ eng_image_native_set(void *data, void *image, void *native)
         }
       else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
         {
-          // FIXME: implement
+          tex = ns->data.opengl.texture_id;
+          fbo = ns->data.opengl.framebuffer_id;
+          if (im->native.data)
+            {
+              Evas_Native_Surface *ens = im->native.data;
+              if ((ens->data.opengl.texture_id == tex) && 
+                  (ens->data.opengl.framebuffer_id == fbo))
+                return im;
+            }
         }
     }
   if ((!ns) && (!im->native.data)) return im;
@@ -1217,7 +1276,7 @@ eng_image_native_set(void *data, void *image, void *native)
   if (ns->type == EVAS_NATIVE_SURFACE_X11)
     {
       pmid = pm;
-      im2 = eina_hash_find(re->win->gl_context->shared->native_hash, &pmid);
+      im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
       if (im2 == im) return im;
       if (im2)
         {
@@ -1232,7 +1291,20 @@ eng_image_native_set(void *data, void *image, void *native)
     }
   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
     {
-      // FIXME: implement
+       texid = tex;
+       im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+              {
+                 evas_gl_common_image_ref(im2);
+                 evas_gl_common_image_free(im);
+                 return im2;
+              }
+         }
+
     }
   im2 = evas_gl_common_image_new_from_data(re->win->gl_context, 
                                            im->w, im->h, NULL, im->alpha,
@@ -1251,7 +1323,7 @@ eng_image_native_set(void *data, void *image, void *native)
               int config_attrs[20];
               int num_config, i = 0;
               
-              eina_hash_add(re->win->gl_context->shared->native_hash, &pmid, im);
+              eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
               
               config_attrs[i++] = EGL_RED_SIZE;
               config_attrs[i++] = 8;
@@ -1317,7 +1389,7 @@ eng_image_native_set(void *data, void *image, void *native)
               unsigned int target = 0;
               unsigned int i = 0;
               
-              eina_hash_add(re->win->gl_context->shared->native_hash, &pmid, im);
+              eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
               if ((re->win->depth_cfg[depth].tex_target &
                    GLX_TEXTURE_2D_BIT_EXT) 
                   //                 && (1) // we assume npo2 for now
@@ -1416,7 +1488,41 @@ eng_image_native_set(void *data, void *image, void *native)
     }
   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
     {
-      // FIXME: implement
+      if (native)
+        {
+          n = calloc(1, sizeof(Native));
+          if (n)
+            {
+              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+
+              eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
+
+              n->pixmap = 0;
+              n->visual = 0;
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+              n->egl_surface = 0;
+#else
+              n->fbc = 0;
+              n->glx_pixmap = 0;
+#endif
+
+              im->native.yinvert     = 0;
+              im->native.loose       = 0;
+              im->native.data        = n;
+              im->native.func.data   = re;
+              im->native.func.bind   = _native_bind_cb;
+              im->native.func.unbind = _native_unbind_cb;
+              im->native.func.free   = _native_free_cb;
+              im->native.target      = GL_TEXTURE_2D; 
+              im->native.mipmap      = 0;
+              
+              // FIXME: need to implement mapping sub texture regions
+              // x, y, w, h for possible texture atlasing
+
+              evas_gl_common_image_native_enable(im);
+            }
+        }
+
     }
    return im;
 }
@@ -1914,6 +2020,492 @@ eng_canvas_alpha_get(void *data __UNUSED__, void *info __UNUSED__)
 }
 
 static int
+_set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
+{
+   // Also initialize pixel format here as well...
+   switch(cfg->color_format)
+     {   
+      case EVAS_GL_RGB_8:
+         sfc->rt_fmt          = GL_RGB;
+         sfc->rt_internal_fmt = GL_RGB;
+         break;
+      case EVAS_GL_RGBA_8:
+         sfc->rt_fmt          = GL_RGBA;
+         sfc->rt_internal_fmt = GL_RGBA;
+         break;
+      case EVAS_GL_RGB_32:
+         // Only supported on some hw 
+         // Fill it in later...
+      case EVAS_GL_RGBA_32:
+         // Only supported on some hw
+         // Fill it in later...
+      default:
+         ERR("Invalid Color Format!");
+         return 0;
+     }
+
+   switch(cfg->depth_bits)
+     {   
+      case EVAS_GL_DEPTH_NONE:
+         break;
+      case EVAS_GL_DEPTH_BIT_8:
+      case EVAS_GL_DEPTH_BIT_16:
+      case EVAS_GL_DEPTH_BIT_24:
+         sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
+         break;
+      case EVAS_GL_DEPTH_BIT_32:
+      default:
+         ERR("Unsupported Depth Bits Format!");
+         return 0;
+     }
+
+   switch(cfg->stencil_bits)
+     {   
+      case EVAS_GL_STENCIL_NONE:
+         break;
+      case EVAS_GL_STENCIL_BIT_1:
+      case EVAS_GL_STENCIL_BIT_2:
+      case EVAS_GL_STENCIL_BIT_4:
+      case EVAS_GL_STENCIL_BIT_8:
+         sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
+         break;
+      case EVAS_GL_STENCIL_BIT_16:
+      default:
+         ERR("Unsupported Stencil Bits Format!");
+         return 0;
+     }
+
+   // Do Packed Depth24_Stencil8 Later... 
+
+   return 1;
+}
+
+static int
+_create_rt_buffers(Render_Engine *data __UNUSED__, 
+                   Render_Engine_GL_Surface *sfc)
+{
+   // Render Target texture
+   glGenTextures(1, &sfc->rt_tex );
+   glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0, 
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+   glBindTexture(GL_TEXTURE_2D, 0);
+
+   // Depth RenderBuffer - Create storage here...
+   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
+     {
+        glGenRenderbuffers(1, &sfc->rb_depth);
+        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
+        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
+                              sfc->w, sfc->h);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+
+   // Stencil RenderBuffer - Create Storage here...
+   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
+     {
+        glGenRenderbuffers(1, &sfc->rb_stencil);
+        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
+        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
+                              sfc->w, sfc->h);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+
+   return 1;
+}
+
+static int
+_create_fbo_surface(Render_Engine *data __UNUSED__, 
+                    Render_Engine_GL_Surface *sfc, 
+                    Render_Engine_GL_Context *ctx)
+{
+   int fb_status;
+
+   // FBO
+   glGenFramebuffers(1, &ctx->fbo);
+   glBindFramebuffer(GL_FRAMEBUFFER, ctx->fbo);
+   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                          GL_TEXTURE_2D, sfc->rt_tex, 0);
+   
+   // Depth RenderBuffer - Attach it to FBO
+   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
+     {
+        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                  GL_RENDERBUFFER, sfc->rb_depth);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+
+   // Stencil RenderBuffer - Attach it to FBO
+   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
+     {
+        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                  GL_RENDERBUFFER, sfc->rb_stencil);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+
+   // Check FBO for completeness
+   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+   if (fb_status != GL_FRAMEBUFFER_COMPLETE) 
+     {
+        ERR("FBO not complete!");
+        return 0;
+     }
+
+   return 1;
+}
+
+/*
+static void
+eng_gl_options_set(void *data, int options __UNUSED__)
+{
+   Render_Engine *re;
+
+   re  = (Render_Engine *)data;
+}
+*/
+
+static void *
+eng_gl_surface_create(void *data, void *config, int w, int h)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Surface *sfc;
+   Evas_GL_Config *cfg; 
+
+   sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
+
+   if (!sfc) return NULL;
+
+   re  = (Render_Engine *)data;
+   cfg = (Evas_GL_Config *)config;
+
+   sfc->initialized  = 0;
+   sfc->w            = w;
+   sfc->h            = h;
+   sfc->depth_bits   = cfg->depth_bits;
+   sfc->stencil_bits = cfg->stencil_bits;
+   sfc->rt_tex       = 0;
+   sfc->rb_depth     = 0;
+   sfc->rb_stencil   = 0;
+
+   // Set the internal format based on the config
+   if (!_set_internal_config(sfc, cfg))
+     {
+        ERR("Unsupported Format!");
+        free(sfc);
+        return NULL;
+     }
+
+   return sfc;
+}
+
+
+static int
+eng_gl_surface_destroy(void *data, void *surface)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Surface *sfc;
+   int ret;
+
+   re  = (Render_Engine *)data;
+   sfc = (Render_Engine_GL_Surface*)surface;
+
+   // I'm using evas's original context to delete the created fbo and texture
+   // This is because the fbo/texture was created in the user created context
+   // but the context can be destroyed already...
+   // I don't think this is the best way but at least for now this is A WAY. 
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]);
+#else
+   ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
+#endif
+   if (!ret) 
+     {
+        ERR("xxxMakeCurrent() failed!");
+        return 0;
+     }
+
+   // Delete FBO/RBO and Texture here
+   if (glIsTexture(sfc->rt_tex))
+     glDeleteTextures(1, &sfc->rt_tex);
+
+   if (glIsBuffer(sfc->rb_depth))
+     glDeleteRenderbuffers(1, &sfc->rb_depth);
+
+   if (glIsBuffer(sfc->rb_stencil))
+     glDeleteRenderbuffers(1, &sfc->rb_stencil);
+
+
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+#else
+   ret = glXMakeCurrent(re->info->info.display, None, NULL);
+#endif
+   if (!ret) 
+     {
+        ERR("xxxMakeCurrent() failed!");
+        return 0;
+     }
+
+   free(sfc);
+   surface = NULL;
+
+   return 1;
+}
+
+
+
+static void *
+eng_gl_context_create(void *data, void *share_context)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Context *ctx;
+   Render_Engine_GL_Context *share_ctx;
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   int context_attrs[3];
+#endif   
+
+   ctx = calloc(1, sizeof(Render_Engine_GL_Context));
+
+   if (!ctx) return NULL;
+
+   re = (Render_Engine *)data;
+   share_ctx = (Render_Engine_GL_Context *)share_context;
+
+   // Set the share context to Evas' GL context if share_context is NULL.
+   // Otherwise set it to the given share_context.
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   // EGL
+   context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
+   context_attrs[1] = 2;
+   context_attrs[2] = EGL_NONE;
+
+   if (share_ctx)
+     {
+        ctx->context = eglCreateContext(re->win->egl_disp,
+                                        re->win->egl_config,
+                                        share_ctx->context,      // Share Context
+                                        context_attrs);
+     }
+   else 
+     {
+        ctx->context = eglCreateContext(re->win->egl_disp,
+                                        re->win->egl_config,
+                                        re->win->egl_context[0], // Evas' GL Context
+                                        context_attrs);
+     }
+
+   if (!ctx->context) 
+     {
+        ERR("eglCreateContext() fail. code=%#x", eglGetError());
+        return NULL;
+     }
+#else
+   // GLX
+   if (share_context)
+     {
+        ctx->context = glXCreateContext(re->info->info.display,
+                                        re->win->visualinfo,
+                                        share_ctx->context,    // Share Context
+                                        1);
+     }
+   else 
+     {
+        ctx->context = glXCreateContext(re->info->info.display,
+                                        re->win->visualinfo,
+                                        re->win->context,      // Evas' GL Context
+                                        1);
+     }
+
+   if (!ctx->context) 
+     {
+        ERR("glXCreateContext() fail.");
+        return NULL;
+     }
+#endif
+
+   ctx->initialized = 0;
+
+   return ctx;
+}
+
+
+static int
+eng_gl_context_destroy(void *data, void *context)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Context *ctx;
+   int ret;
+
+   re  = (Render_Engine *)data;
+   ctx = (Render_Engine_GL_Context*)context;
+
+   // 1. Do a make current with the given context
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], 
+                        re->win->egl_surface[0], ctx->context);
+#else
+   ret = glXMakeCurrent(re->info->info.display, re->win->win, 
+                        ctx->context);
+#endif
+   if (!ret) 
+     {
+        ERR("xxxMakeCurrent() failed!");
+        return 0;
+     }
+
+   // 2. Delete the FBO
+   if (glIsBuffer(ctx->fbo))
+     glDeleteBuffers(1, &ctx->fbo);
+
+   // 3. Destroy the Context
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   eglDestroyContext(re->win->egl_disp, ctx->context);
+
+   ctx->context = EGL_NO_CONTEXT;
+
+   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, 
+                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
+#else
+   glXDestroyContext(re->info->info.display, ctx->context);
+
+   ctx->context = 0;
+
+   ret = glXMakeCurrent(re->info->info.display, None, NULL);
+#endif
+   if (!ret) 
+     {
+        ERR("xxxMakeCurrent() failed!");
+        return 0;
+     }
+
+   free(ctx);
+   context = NULL;
+
+   return 1;
+}
+
+
+
+static int
+eng_gl_make_current(void *data, void *surface, void *context)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Surface *sfc;
+   Render_Engine_GL_Context *ctx;
+   int ret;
+
+   re  = (Render_Engine *)data;
+   sfc = (Render_Engine_GL_Surface*)surface;
+   ctx = (Render_Engine_GL_Context*)context;
+
+
+   if ((!sfc) || (!ctx))
+     {
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+        ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, 
+                             EGL_NO_SURFACE, EGL_NO_CONTEXT);
+#else
+        ret = glXMakeCurrent(re->info->info.display, None, NULL);
+#endif
+        if (!ret) 
+          {
+             ERR("xxxMakeCurrent() failed!");
+             return 0;
+          }
+
+        return ret;
+     }
+
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], 
+                        re->win->egl_surface[0], ctx->context);
+#else
+   ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
+#endif
+   if (!ret) 
+     {
+        ERR("xxxMakeCurrent() failed!");
+        return 0;
+     }
+
+   // Create Render Target Texture/Buffers if not initialized
+   if (!sfc->initialized) 
+     {
+        if (!_create_rt_buffers(re, sfc)) 
+          {
+             ERR("_create_rt_buffers() failed.");
+             return 0;
+          }
+        sfc->initialized = 1;
+     }
+
+   // Create FBO if not initalized already
+   if (!ctx->initialized) 
+     {
+        if (!_create_fbo_surface(re, sfc, ctx)) 
+          {
+             ERR("_create_fbo_surface() failed.");
+             return 0;
+          }
+        ctx->initialized = 1;
+     }
+
+   ctx->current_sfc = sfc;
+   sfc->current_ctx = ctx;
+
+   // Bind FBO
+   glBindFramebuffer(GL_FRAMEBUFFER, ctx->fbo);
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#else
+   glDrawBuffer(GL_COLOR_ATTACHMENT0);
+#endif
+
+   return 1;
+}
+
+static void *
+eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
+{
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
+   return dlsym(RTLD_DEFAULT, name);
+#else
+   if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
+   return dlsym(RTLD_DEFAULT, name);
+#endif
+}
+
+static int 
+eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
+{
+   Render_Engine *re;
+   Render_Engine_GL_Surface *sfc;
+   Evas_Native_Surface *ns;
+
+   re  = (Render_Engine *)data;
+   sfc = (Render_Engine_GL_Surface*)surface;
+   ns  = (Evas_Native_Surface*)native_surface;
+   
+   ns->type = EVAS_NATIVE_SURFACE_OPENGL;
+   ns->version = EVAS_NATIVE_SURFACE_VERSION;
+   ns->data.opengl.texture_id = sfc->rt_tex;
+   //ns->data.opengl.framebuffer_id = sfc->fbo;
+   //ns->data.opengl.framebuffer_id = ctx->fbo;
+   ns->data.opengl.x = 0;
+   ns->data.opengl.y = 0;
+   ns->data.opengl.w = sfc->w;
+   ns->data.opengl.h = sfc->h;
+   
+   return 1;
+}
+
+static int
 module_open(Evas_Module *em)
 {
    static Eina_Bool xrm_inited = EINA_FALSE;
@@ -2001,6 +2593,14 @@ module_open(Evas_Module *em)
    ORD(image_cache_flush);
    ORD(image_cache_set);
    ORD(image_cache_get);
+
+   ORD(gl_surface_create);
+   ORD(gl_surface_destroy);
+   ORD(gl_context_create);
+   ORD(gl_context_destroy);
+   ORD(gl_make_current);
+   ORD(gl_proc_address_get);
+   ORD(gl_native_surface_get);
    
    /* now advertise out own api */
    em->functions = (void *)(&func);
@@ -2037,3 +2637,5 @@ EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
 #ifndef EVAS_STATIC_BUILD_GL_X11
 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
 #endif
+
+/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
index 0d63f9d..42eb7dd 100644 (file)
@@ -2,9 +2,16 @@
 #define EVAS_ENGINE_H
 
 #include "config.h"
+#include "evas_common.h"
+#include "evas_private.h"
+#include "evas_gl_common.h"
+#include "Evas.h"
+#include "Evas_Engine_GL_X11.h"
+
 #ifdef HAVE_GL_GLEW_H
 # include <GL/glxew.h>
 #else
+# define GL_GLEXT_PROTOTYPES
 # if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
 #  if defined(GLES_VARIETY_S3C6410)
 #   include <EGL/egl.h>
 #  include <GL/glx.h>
 # endif
 #endif
-#include "evas_common.h"
-#include "evas_private.h"
-#include "evas_gl_common.h"
-#include "Evas.h"
-#include "Evas_Engine_GL_X11.h"
 
 extern int _evas_engine_GL_X11_log_dom ;
 #ifdef ERR
index d40e09b..e3c607b 100644 (file)
@@ -925,7 +925,6 @@ static Evas_Func func =
      eng_image_scale_hint_get,
      /* more font draw functions */
      eng_font_last_up_to_pos,
-     /* FUTURE software generic calls go here (done) */
      eng_image_map_draw,
      eng_image_map_surface_new,
      eng_image_map_surface_free,
@@ -933,8 +932,15 @@ static Evas_Func func =
      NULL, // eng_image_content_hint_get - software doesn't use it
      eng_font_pen_coords_get,
      eng_font_text_props_info_create,
-     eng_font_right_inset_get
-     /* FUTURE software generic calls go here */
+     eng_font_right_inset_get,
+     NULL, // FIXME: need software mesa for gl rendering <- gl_surface_create
+     NULL, // FIXME: need software mesa for gl rendering <- gl_surface_destroy
+     NULL, // FIXME: need software mesa for gl rendering <- gl_context_create
+     NULL, // FIXME: need software mesa for gl rendering <- gl_context_destroy
+     NULL, // FIXME: need software mesa for gl rendering <- gl_make_current
+     NULL, // FIXME: need software mesa for gl rendering <- gl_proc_address_get
+     NULL  // FIXME: need software mesa for gl rendering <- gl_native_surface_get
+    /* FUTURE software generic calls go here */
 };
 
 /*