jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=47ddb889ad950d806d6b22d3b3bf4e7cba82debc

commit 47ddb889ad950d806d6b22d3b3bf4e7cba82debc
Author: Jean-Philippe Andre <[email protected]>
Date:   Tue Sep 23 15:33:16 2014 +0900

    Evas GL: Add support for OpenGL-ES 1.1 (part 3)
    
    This introduces XPixmap usage for indirect rendering.
    Of course this works only for the gl_x11 engine... and for
    now only when using EGL... and only on some drivers...
    damn limitations.
    Direct rendering should work on more platforms (eg. some desktop
    nvidia cards with the EGL drivers).
---
 src/modules/evas/engines/gl_common/evas_gl_core.c  |  53 ++++++++++
 .../evas/engines/gl_common/evas_gl_core_private.h  |  16 +++
 src/modules/evas/engines/gl_drm/evas_engine.c      |   5 +-
 src/modules/evas/engines/gl_sdl/evas_engine.c      |   5 +-
 src/modules/evas/engines/gl_x11/evas_engine.c      | 110 ++++++++++++++++++++-
 5 files changed, 186 insertions(+), 3 deletions(-)

diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c 
b/src/modules/evas/engines/gl_common/evas_gl_core.c
index 45c2c89..9782b3a 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_core.c
@@ -1559,6 +1559,19 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, 
int w, int h)
         goto error;
      }
 
+   // Allocate a special surface for 1.1
+   if (cfg->gles_version == EVAS_GL_GLES_1_X)
+     {
+        if (!evgl_engine->funcs->gles1_surface_create)
+          {
+             evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
+             goto error;
+          }
+
+        INF("Creating special surface for GLES 1.x rendering");
+        evgl_engine->funcs->gles1_surface_create(eng_data, sfc, cfg, w, h);
+     }
+
    // Create internal buffers
    if (!_surface_buffers_create(sfc))
      {
@@ -1768,6 +1781,25 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
           }
      }
 
+   // Destroy surface used for 1.1
+   if (sfc->gles1_indirect)
+     {
+        int ret;
+        if (!evgl_engine->funcs->gles1_surface_destroy)
+          {
+             ERR("Error destroying GLES 1.x surface");
+             return 0;
+          }
+
+        INF("Destroying special surface used for GLES 1.x rendering");
+        ret = evgl_engine->funcs->gles1_surface_destroy(eng_data, sfc);
+
+        if (!ret) ERR("Engine failed to destroy a GLES1.x Surface.");
+        return ret;
+
+     }
+
+
    // Destroy created buffers
    if (!_surface_buffers_destroy(sfc))
      {
@@ -1857,6 +1889,9 @@ evgl_context_create(void *eng_data, EVGL_Context 
*share_ctx,
         return NULL;
      }
 
+   ctx->version = version;
+
+   // Call engine create context
    if (share_ctx)
       ctx->context = evgl_engine->funcs->context_create(eng_data, 
share_ctx->context, version);
    else
@@ -2027,6 +2062,24 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, 
EVGL_Context *ctx)
         return 0;
      }
 
+   if (ctx->version == EVAS_GL_GLES_1_X)
+     {
+        if (_evgl_direct_renderable(rsc, sfc))
+          {
+             rsc->direct.rendered = 1;
+          }
+        else
+          {
+             evgl_engine->funcs->make_current(eng_data, sfc->gles1_sfc,
+                                              ctx->context, EINA_TRUE);
+          }
+
+        ctx->current_sfc = sfc;
+        rsc->current_ctx = ctx;
+        rsc->current_eng = eng_data;
+        return 1;
+     }
+
    // Normal FBO Rendering
    // Create FBO if it hasn't been created
    if (!ctx->surface_fbo)
diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h 
b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
index f977c81..5fe0e76 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
@@ -67,6 +67,12 @@ struct _EVGL_Interface
 
    // Create a pbuffer surface
    void       *(*pbuffer_surface_create)(void *data, EVGL_Surface *evgl_sfc, 
const int *attrib_list);
+
+   // Create a surface for 1.x rendering (could be pbuffer or xpixmap for 
instance)
+   void       *(*gles1_surface_create)(void *data, EVGL_Surface *evgl_sfc, 
Evas_GL_Config *cfg, int w, int h);
+
+   // Destroy 1.x surface (could be pbuffer or xpixmap for instance)
+   int        (*gles1_surface_destroy)(void *data, EVGL_Surface *evgl_sfc);
 };
 
 struct _EVGL_Surface
@@ -101,6 +107,10 @@ struct _EVGL_Surface
    unsigned client_side_rotation : 1;
    unsigned alpha : 1;
 
+   // Flag indicating this surface is used for GLES 1 indirect rendering
+   unsigned gles1_indirect : 1;
+   unsigned xpixmap : 1;
+
    int     cfg_index;
 
    // Attached Context
@@ -114,6 +124,12 @@ struct _EVGL_Surface
    int     buffer_mem[4];
 
    //-------------------------//
+   // Used if gles1_indirect == 1
+   EVGLNative_Surface gles1_sfc;
+   void              *gles1_sfc_native;
+   void              *gles1_sfc_visual;
+
+   //-------------------------//
    // Related to PBuffer Surface
    struct {
       EVGLNative_Surface    native_surface;
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c 
b/src/modules/evas/engines/gl_drm/evas_engine.c
index f7e959b..1322bae 100644
--- a/src/modules/evas/engines/gl_drm/evas_engine.c
+++ b/src/modules/evas/engines/gl_drm/evas_engine.c
@@ -118,7 +118,10 @@ static const EVGL_Interface evgl_funcs =
    evgl_eng_make_current,
    evgl_eng_proc_address_get,
    evgl_eng_string_get,
-   evgl_eng_rotation_angle_get
+   evgl_eng_rotation_angle_get,
+   NULL, // PBuffer
+   NULL, // OpenGL-ES 1
+   NULL, // OpenGL-ES 1
 };
 
 /* local functions */
diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c 
b/src/modules/evas/engines/gl_sdl/evas_engine.c
index 801c5a5..d2bba51 100644
--- a/src/modules/evas/engines/gl_sdl/evas_engine.c
+++ b/src/modules/evas/engines/gl_sdl/evas_engine.c
@@ -254,7 +254,10 @@ static const EVGL_Interface evgl_funcs =
    evgl_eng_make_current,
    evgl_eng_proc_address_get,
    evgl_eng_string_get,
-   evgl_eng_rotation_angle_get
+   evgl_eng_rotation_angle_get,
+   NULL, // PBuffer
+   NULL, // OpenGL-ES 1
+   NULL, // OpenGL-ES 1
 };
 
 
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c 
b/src/modules/evas/engines/gl_x11/evas_engine.c
index d3df0df..94bcc02 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -519,6 +519,7 @@ evgl_eng_context_create(void *data, void *share_ctx, 
Evas_GL_Context_Version ver
                                    (GLXContext)share_ctx,
                                    1);
      }
+   /* TODO: Check this case.
    else if (version == EVAS_GL_GLES_1_X)
      {
         context = glXCreateContext(eng_get_ob(re)->info->info.display,
@@ -526,6 +527,7 @@ evgl_eng_context_create(void *data, void *share_ctx, 
Evas_GL_Context_Version ver
                                    NULL,
                                    1);
      }
+   */
    else
      {
         context = glXCreateContext(eng_get_ob(re)->info->info.display,
@@ -750,6 +752,110 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface 
*sfc,
 #endif
 }
 
+// This function should create a surface that can be used for offscreen 
rendering
+// with GLES 1.x, and still be bindable to a texture in Evas main GL context.
+// For now, this will create an X pixmap... Ideally it should be able to create
+// a bindable pbuffer surface or just an FBO if that is supported and it can
+// be shared with Evas.
+static void *
+evgl_eng_gles1_surface_create(void *data, EVGL_Surface *evgl_sfc,
+                              Evas_GL_Config *cfg, int w, int h)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   Pixmap px;
+
+   if (!re || !evgl_sfc || !cfg)
+     {
+        glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
+
+   if (cfg->gles_version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Inconsistent parameters, not creating any surface!");
+        glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
+
+   // FIXME: Check the depth of the buffer!
+   px =  XCreatePixmap(eng_get_ob(re)->disp, eng_get_ob(re)->win, w, h,
+                       XDefaultDepth(eng_get_ob(re)->disp, 
eng_get_ob(re)->screen));
+   if (!px)
+     {
+        ERR("Failed to create XPixmap!");
+        glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
+
+#ifdef GL_GLES
+   EGLSurface egl_sfc;
+
+   egl_sfc = eglCreatePixmapSurface(eng_get_ob(re)->egl_disp, 
eng_get_ob(re)->egl_config, px, NULL);
+   if (!egl_sfc)
+     {
+        int err = eglGetError();
+        ERR("eglCreatePixmapSurface failed with error: %x", err);
+        glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
+        XFreePixmap(eng_get_ob(re)->disp, px);
+        return NULL;
+     }
+
+   evgl_sfc->gles1_indirect = EINA_TRUE;
+   evgl_sfc->xpixmap = EINA_TRUE;
+   evgl_sfc->gles1_sfc = egl_sfc;
+   evgl_sfc->gles1_sfc_native = (void *)(intptr_t) px;
+   evgl_sfc->gles1_sfc_visual = eng_get_ob(re)->info->info.visual; // FIXME: 
Check this!
+   return evgl_sfc;
+
+#else
+#warning GLX support is not implemented for GLES 1.x
+   CRIT("Not implemented yet! (GLX for GLES 1)");
+   return NULL;
+#endif
+}
+
+// This function should destroy the surface used for offscreen rendering
+// with GLES 1.x.This will also destroy the X pixmap...
+static int
+evgl_eng_gles1_surface_destroy(void *data, EVGL_Surface *evgl_sfc)
+{
+   Render_Engine *re = (Render_Engine *)data;
+
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
+        return 0;
+     }
+
+#ifdef GL_GLES
+   if ((!evgl_sfc) || (!evgl_sfc->gles1_sfc))
+     {
+        ERR("Invalid surface.");
+        glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
+        return 0;
+     }
+
+   eglDestroySurface(eng_get_ob(re)->egl_disp, 
(EGLSurface)evgl_sfc->gles1_sfc);
+
+#else
+#warning GLX support is not implemented for GLES 1.x
+   CRIT("Not implemented yet! (GLX for GLES 1)");
+   return 0;
+#endif
+
+   if (!evgl_sfc->gles1_sfc_native)
+     {
+        ERR("Inconsistent parameters, not freeing XPixmap for gles1 surface!");
+        glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
+        return 0;
+     }
+
+   XFreePixmap(eng_get_ob(re)->disp, (Pixmap)evgl_sfc->gles1_sfc_native);
+
+   return 1;
+}
+
 static const EVGL_Interface evgl_funcs =
 {
    evgl_eng_display_get,
@@ -764,7 +870,9 @@ static const EVGL_Interface evgl_funcs =
    evgl_eng_proc_address_get,
    evgl_eng_string_get,
    evgl_eng_rotation_angle_get,
-   evgl_eng_pbuffer_surface_create
+   evgl_eng_pbuffer_surface_create,
+   evgl_eng_gles1_surface_create,
+   evgl_eng_gles1_surface_destroy,
 };
 
 //----------------------------------------------------------//

-- 


Reply via email to