Cleaned up some evas_gl code and added surface cap feature.
authorSung Park <sungwoo@gmail.com>
Wed, 2 May 2012 08:31:15 +0000 (08:31 +0000)
committerSung Park <sungwoo@gmail.com>
Wed, 2 May 2012 08:31:15 +0000 (08:31 +0000)
Previously, evas_gl_surface_create() didn't actually do
the render buffer attach to the the FBO. It was performed when
the make_current was called for the first time.  The issue
was that even though the surface was successfully created with
the given configuration, there was a possibility of make_current
failing with the error message "FBO not complete" because of
the surface configuration.

So, I've added a piece of code that checks the FBO
capabilities beforehand to set up a available surface configurations
so that it doesn't have to fail during make_current for unsupported
surface format.

Also, I've changed the surface config in a way that once the
user calls evas_gl_surface_create(), evas gl sets the config
parameter with configuration that evas_gl is actually using.

SVN revision: 70617

legacy/evas/src/lib/Evas_GL.h
legacy/evas/src/lib/canvas/evas_gl.c
legacy/evas/src/modules/engines/gl_x11/evas_engine.c

index 9a7113c..17b3aab 100644 (file)
@@ -2,7 +2,6 @@
 #define _EVAS_GL_H
 
 #include <Evas.h>
-//#include <GL/gl.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -422,6 +421,11 @@ EAPI void                     evas_gl_config_free        (Evas_GL_Config *cfg) E
  * @param w The width of the surface.
  * @param h The height of the surface.
  * @return The created GL surface object, or NULL on failure.
+ *
+ * The surface_create function internally finds the closest surface
+ * configureation that matches the input config. The function then internally 
+ * sets the input config parameters to the configuratoin that was actually
+ * used to create the surface.
  */
 EAPI Evas_GL_Surface         *evas_gl_surface_create     (Evas_GL *evas_gl, Evas_GL_Config *cfg, int w, int h) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1,2);
 
index 85ed851..bccab2d 100644 (file)
@@ -39,7 +39,7 @@ evas_gl_new(Evas *e)
 
    if (!evas_gl->evas->engine.func->gl_context_create)
      {
-        ERR("GL engine not available\n");
+        ERR("Evas GL engine not available.");
         free(evas_gl);
         return NULL;
      }
@@ -96,7 +96,7 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int
 
    if (!config)
      {
-        ERR("Invalid Config\n");
+        ERR("Invalid Config Pointer!");
         return NULL;
      }
 
@@ -108,7 +108,7 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int
 
    if (!surf->data)
      {
-        ERR("Failed creating a surface from the engine\n");
+        ERR("Failed creating a surface from the engine.");
         free(surf);
         return NULL;
      }
@@ -129,7 +129,7 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
 
    if (!surf)
      {
-        ERR("Trying to destroy a NULL surface pointer!\n");
+        ERR("Trying to destroy a NULL surface pointer!");
         return;
      }
 
@@ -158,7 +158,7 @@ evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
    ctx = calloc(1, sizeof(Evas_GL_Context));
    if (!ctx)
      {
-        ERR("Unable to create a Evas_GL_Context object\n");
+        ERR("Unable to create a Evas_GL_Context object");
         return NULL;
      }
 
@@ -175,7 +175,7 @@ evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
    // Set a few variables
    if (!ctx->data)
      {
-        ERR("Failed creating a context from the engine\n");
+        ERR("Failed creating a context from the engine.");
         free(ctx);
         return NULL;
      }
@@ -197,7 +197,7 @@ evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx)
 
    if (!ctx)
      {
-        ERR("Trying to destroy a NULL context pointer!\n");
+        ERR("Trying to destroy a NULL context pointer!");
         return;
      }
 
@@ -256,6 +256,12 @@ evas_gl_native_surface_get(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_
    return EINA_FALSE;
    MAGIC_CHECK_END();
 
+   if ((!surf) || (!ns))
+     {
+        ERR("Invalid input parameters!");
+        return EINA_FALSE;
+     }
+
    return (Eina_Bool)evas_gl->evas->engine.func->gl_native_surface_get(evas_gl->evas->engine.data.output, surf->data, ns);
 }
 
index 957f266..ef7b7f7 100644 (file)
@@ -41,17 +41,26 @@ struct _Render_Engine
    int w, h;
    int vsync;
 
-   // Shader used for Evas_GL_Direct Optimization
-   GLuint   df_program;
-   GLuint   df_vtx_shader;
-   GLuint   df_fgmt_shader;   
-   GLuint   df_col_attrib;
-   GLuint   df_pos_attrib;
-
-   GLfloat  df_clear_color[4];
-   GLfloat  df_depth_value;
-
-   int      df_initialized;
+   // GL Surface Capability
+   struct {
+        int rgb_fmt;
+        int rgba_fmt;
+
+        int depth_8;
+        int depth_16;
+        int depth_24;
+        int depth_32;
+
+        int stencil_1;
+        int stencil_2;
+        int stencil_4;
+        int stencil_8;
+        int stencil_16;
+
+        int depth_24_stencil_8;
+   } gl_cap;
+
+   int gl_cap_initted;
 };
 
 struct _Render_Engine_GL_Surface
@@ -64,7 +73,7 @@ struct _Render_Engine_GL_Surface
 
    int      direct_fb_opt;
 
-   // Render target texture/buffers
+   // Render target Texture/Buffers
    GLuint   rt_tex;
    GLint    rt_internal_fmt;
    GLenum   rt_fmt;
@@ -72,6 +81,8 @@ struct _Render_Engine_GL_Surface
    GLenum   rb_depth_fmt;
    GLuint   rb_stencil;
    GLenum   rb_stencil_fmt;
+   GLuint   rb_depth_stencil;
+   GLenum   rb_depth_stencil_fmt;
 
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
    EGLSurface  direct_sfc;
@@ -93,9 +104,9 @@ struct _Render_Engine_GL_Context
    GLuint      context_fbo;
    GLuint      current_fbo;
 
-
    int         scissor_enabled;
    int         scissor_upated;
+   GLfloat     df_clear_color[4];
 
    Render_Engine_GL_Surface   *current_sfc;
 };
@@ -343,7 +354,7 @@ static Extension_Entry _evasgl_ext_entries[] = {
 };
 
 static void
-_sym_init(void)
+_gl_ext_sym_init(void)
 {
    static int done = 0;
 
@@ -582,7 +593,7 @@ _sym_init(void)
 }
 
 static void
-_extensions_init(Render_Engine *re)
+_gl_ext_init(Render_Engine *re)
 {
    int i;
    const char *glexts, *evasglexts;
@@ -620,7 +631,7 @@ _extensions_init(Render_Engine *re)
                                               re->info->info.screen);
 #endif
 
-        DBG("--------EvasGL Extensions----------");
+        DBG("--------EvasGL Supported Extensions----------");
         for (i = 0; _evasgl_ext_entries[i].name != NULL; i++)
           {
              if ( (strstr(evasglexts, _evasgl_ext_entries[i].name) != NULL) ||
@@ -632,8 +643,8 @@ _extensions_init(Render_Engine *re)
                   DBG("\t%s", _evasgl_ext_entries[i].name);
                }
           }
-        DBG(" ");
      }
+   DBG(" ");
 }
 
 int _evas_engine_GL_X11_log_dom = -1;
@@ -750,16 +761,26 @@ _create_internal_glue_resources(void *data)
    context_attrs[1] = 2;
    context_attrs[2] = EGL_NONE;
 
-   // Create resource surface for EGL
-   rsc->surface = eglCreateWindowSurface(re->win->egl_disp,
-                                         re->win->egl_config,
-                                         (EGLNativeWindowType)DefaultRootWindow(re->info->info.display),
-                                         NULL);
-   if (!rsc->surface)
+
+
+
+   if (eina_main_loop_is())
      {
-        ERR("Creating internal resource surface failed.");
-        free(rsc);
-        return NULL;
+        rsc->surface = re->win->egl_surface[0];
+     }
+   else
+     {
+        // Create resource surface for EGL
+        rsc->surface = eglCreateWindowSurface(re->win->egl_disp,
+                                              re->win->egl_config,
+                                              (EGLNativeWindowType)DefaultRootWindow(re->info->info.display),
+                                              NULL);
+        if (!rsc->surface)
+          {
+             ERR("Creating internal resource surface failed.");
+             free(rsc);
+             return NULL;
+          }
      }
 
    // Create a resource context for EGL
@@ -832,8 +853,10 @@ _destroy_internal_glue_resources(void *data)
    LKL(resource_lock);
    EINA_LIST_FOREACH(resource_list, l, rsc)
      {
-        if (rsc->surface) eglDestroySurface(re->win->egl_disp, rsc->surface);
-        if (rsc->context) eglDestroyContext(re->win->egl_disp, rsc->context);
+        if ((rsc->surface) && (rsc->surface != re->win->egl_surface[0]))
+           eglDestroySurface(re->win->egl_disp, rsc->surface);
+        if (rsc->context)
+           eglDestroyContext(re->win->egl_disp, rsc->context);
         free(rsc);
      }
    eina_list_free(resource_list);
@@ -1072,11 +1095,8 @@ eng_setup(Evas *e, void *in)
    eng_window_use(re->win);
 
    re->vsync = 0;
-   _sym_init();
-   _extensions_init(re);
-
-   // This is used in extensions.  Not pretty but can't get display otherwise.
-   current_engine = re;
+   _gl_ext_sym_init();
+   _gl_ext_init(re);
 
    return 1;
 }
@@ -2812,7 +2832,8 @@ eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int
                                               evas_gl_font_texture_new,
                                               evas_gl_font_texture_free,
                                               evas_gl_font_texture_draw);
-        evas_common_font_draw(im, context, x, y, intl_props);
+        evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
+                              intl_props);
         evas_common_draw_context_font_ext_set(context,
                                               NULL,
                                               NULL,
@@ -2828,22 +2849,164 @@ eng_canvas_alpha_get(void *data, void *info __UNUSED__)
    return re->win->alpha;
 }
 
+
+// Unfortunately, there is no query function to figure out which surface formats work.
+// So, this is one way to test for surface config capability.
 static int
-_set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
+_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt)
+{
+   GLuint fbo, tex, rb;
+   int w, h, fb_status;
+
+   // Width/Heith for test purposes
+   w = h = 2;
+
+   // Gen FBO
+   glGenFramebuffers(1, &fbo);
+   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+   // Render Target Texture
+   if (int_fmt)
+     {
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, 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, int_fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE, NULL);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+     }
+
+   // Render Target Attachment (Stencil or Depth)
+   if (attachment)
+     {
+        glGenRenderbuffers(1, &rb);
+        glBindRenderbuffer(GL_RENDERBUFFER, rb);
+        glRenderbufferStorage(GL_RENDERBUFFER, attach_fmt, w, h);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+
+   // Check FBO for completeness
+   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+
+   // Delete Created Resources
+   glBindFramebuffer(GL_FRAMEBUFFER, 0);
+   glDeleteFramebuffers(1, &fbo);
+   if (tex) glDeleteTextures(1, &tex);
+   if (rb) glDeleteBuffers(1, &rb);
+
+   if (fb_status != GL_FRAMEBUFFER_COMPLETE)
+      return 0;
+   else
+     {
+        if (attachment) 
+           return attach_fmt;
+        else 
+           return 1;
+     }
+}
+
+static void
+_print_gl_surface_cap(Render_Engine *re, int error)
 {
-   // Also initialize pixel format here as well...
+#define PRINT_LOG(...) \
+   if (error) \
+      ERR(__VA_ARGS__); \
+   else \
+      DBG(__VA_ARGS__); 
+
+   PRINT_LOG("---------------------------------------------------");
+   PRINT_LOG("           EvasGL Supported Surface Format         ");
+   PRINT_LOG(" [RGB  Fromat]            : %x", re->gl_cap.rgb_fmt);
+   PRINT_LOG(" [RGBA Fromat]            : %x", re->gl_cap.rgba_fmt);
+   PRINT_LOG(" [Depth  8 Bits]          : %x", re->gl_cap.depth_8);
+   PRINT_LOG(" [Depth 16 Bits]          : %x", re->gl_cap.depth_16);
+   PRINT_LOG(" [Depth 24 Bits]          : %x", re->gl_cap.depth_24);
+   PRINT_LOG(" [Depth 32 Bits]          : %x", re->gl_cap.depth_32);
+   PRINT_LOG(" [Stencil  1 Bits]        : %x", re->gl_cap.stencil_1);
+   PRINT_LOG(" [Stencil  2 Bits]        : %x", re->gl_cap.stencil_2);
+   PRINT_LOG(" [Stencil  4 Bits]        : %x", re->gl_cap.stencil_4);
+   PRINT_LOG(" [Stencil  8 Bits]        : %x", re->gl_cap.stencil_8);
+   PRINT_LOG(" [Stencil 16 Bits]        : %x", re->gl_cap.stencil_16);
+   PRINT_LOG(" [Depth 24 Stencil 8 Bits]: %x", re->gl_cap.depth_24_stencil_8);
+   PRINT_LOG("---------------------------------------------------");
+#undef PRINT_LOG
+}
+
+static void
+_set_gl_surface_cap(Render_Engine *re)
+{
+   GLuint fbo, tex, depth, stencil;
+   int w, h;
+   int ret;
+
+   if (!re) return;
+   if (re->gl_cap_initted) return;
+
+   // Width/Heith for test purposes
+   w = h = 2;
+
+   re->gl_cap.rgb_fmt  = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0);
+   re->gl_cap.rgba_fmt = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0);
+
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   re->gl_cap.depth_8   = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT);
+   re->gl_cap.depth_16  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
+   re->gl_cap.depth_24  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24_OES);
+   re->gl_cap.depth_32  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32_OES);
+
+   re->gl_cap.stencil_1 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1_OES);
+   re->gl_cap.stencil_4 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4_OES);
+   re->gl_cap.stencil_8 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
+#else
+   re->gl_cap.depth_8   = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT);
+   re->gl_cap.depth_16  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
+   re->gl_cap.depth_24  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
+   re->gl_cap.depth_32  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32);
+
+   re->gl_cap.stencil_1 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1);
+   re->gl_cap.stencil_4 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4);
+   re->gl_cap.stencil_8 = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
+
+   re->gl_cap.depth_24_stencil_8  = _check_gl_surface_format(0, 0, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
+#endif
+
+   _print_gl_surface_cap(re, 0);
+
+   re->gl_cap_initted = 1;
+}
+
+static int
+_set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
+{
+   int ret = 0;
+
+   // Check if color formats are supported
    switch((int)cfg->color_format)
      {
       case EVAS_GL_RGB_888:
-         sfc->rt_fmt          = GL_RGB;
-         sfc->rt_internal_fmt = GL_RGB;
-         break;
+         if (re->gl_cap.rgb_fmt)
+           {
+              sfc->rt_fmt          = GL_RGB;
+              sfc->rt_internal_fmt = GL_RGB;
+              break;
+           }
       case EVAS_GL_RGBA_8888:
-         sfc->rt_fmt          = GL_RGBA;
-         sfc->rt_internal_fmt = GL_RGBA;
-         break;
+         if (re->gl_cap.rgba_fmt)
+           {
+              sfc->rt_fmt          = GL_RGBA;
+              sfc->rt_internal_fmt = GL_RGBA;
+              cfg->color_format    = EVAS_GL_RGBA_8888;
+              break;
+           }
       default:
-         ERR("Invalid Color Format!");
+         ERR("Color Format Not Supported!");
+         _print_gl_surface_cap(re, 1);
          return 0;
      }
 
@@ -2852,18 +3015,36 @@ _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
       case EVAS_GL_DEPTH_NONE:
          break;
       case EVAS_GL_DEPTH_BIT_8:
+         if (re->gl_cap.depth_8)
+           {
+              sfc->rb_depth_fmt = re->gl_cap.depth_8;
+              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_8;
+              break;
+           }
       case EVAS_GL_DEPTH_BIT_16:
+         if (re->gl_cap.depth_16)
+           {
+              sfc->rb_depth_fmt = re->gl_cap.depth_16;
+              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_16;
+              break;
+           }
       case EVAS_GL_DEPTH_BIT_24:
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-         // 24 bit doesn't work... just cover it with 16 for now..
-         sfc->rb_depth_fmt = GL_DEPTH_COMPONENT16;
-#else
-         sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
-#endif
-         break;
+         if (re->gl_cap.depth_24)
+           {
+              sfc->rb_depth_fmt = re->gl_cap.depth_24;
+              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_24;
+              break;
+           }
       case EVAS_GL_DEPTH_BIT_32:
+         if (re->gl_cap.depth_32)
+           {
+              sfc->rb_depth_fmt = re->gl_cap.depth_32;
+              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_32;
+              break;
+           }
       default:
          ERR("Unsupported Depth Bits Format!");
+         _print_gl_surface_cap(re, 1);
          return 0;
      }
 
@@ -2872,47 +3053,92 @@ _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
       case EVAS_GL_STENCIL_NONE:
          break;
       case EVAS_GL_STENCIL_BIT_1:
+         if (re->gl_cap.stencil_1)
+           {
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_1;
+              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_1;
+              break;
+           }
       case EVAS_GL_STENCIL_BIT_2:
+         if (re->gl_cap.stencil_2)
+           {
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_2;
+              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_2;
+              break;
+           }
       case EVAS_GL_STENCIL_BIT_4:
+         if (re->gl_cap.stencil_4)
+           {
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_4;
+              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_4;
+              break;
+           }
       case EVAS_GL_STENCIL_BIT_8:
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-         sfc->rb_stencil_fmt = GL_STENCIL_INDEX8;
-#else
-         sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
-#endif
-         break;
+         if (re->gl_cap.stencil_8)
+           {
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_8;
+              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_8;
+              break;
+           }
+         else if (re->gl_cap.depth_24_stencil_8)
+           {
+              sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8;
+              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_24;
+              cfg->stencil_bits = EVAS_GL_STENCIL_BIT_8;
+              break;
+           }
       case EVAS_GL_STENCIL_BIT_16:
+         if (re->gl_cap.stencil_16)
+           {
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_16;
+              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_16;
+              break;
+           }
       default:
          ERR("Unsupported Stencil Bits Format!");
+         _print_gl_surface_cap(re, 1);
          return 0;
      }
 
    if (cfg->options_bits)
      {
         if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
-           sfc->direct_fb_opt       = 1;
+          {
+             sfc->direct_fb_opt       = 1;
+             DBG("########################################################");
+             DBG("######### [Evas] Direct option bit is enabled ##########");
+             DBG("########################################################");
+          }
         // Add other options here...
      }
 
    return 1;
 }
 
-static int
+static void
 _create_rt_buffers(Render_Engine *data __UNUSED__,
                    Render_Engine_GL_Surface *sfc)
 {
    // Render Target texture
-   glGenTextures(1, &sfc->rt_tex );
+   if (sfc->rt_fmt)
+     {
+        glGenTextures(1, &sfc->rt_tex);
+     }
+
+   // First check if packed buffer is to be used.
+   if (sfc->rb_depth_stencil_fmt)
+     {
+        glGenRenderbuffers(1, &sfc->rb_depth_stencil);
+        return;
+     }
 
    // Depth RenderBuffer - Create storage here...
-   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
+   if (sfc->rb_depth_fmt)
       glGenRenderbuffers(1, &sfc->rb_depth);
 
    // Stencil RenderBuffer - Create Storage here...
-   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
+   if (sfc->rb_stencil_fmt)
       glGenRenderbuffers(1, &sfc->rb_stencil);
-
-   return 1;
 }
 
 static int
@@ -2922,24 +3148,41 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__,
 {
    int fb_status;
 
-   // Initialize Texture
-   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);
+   glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
 
+   // Render Target Texture
+   if (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);
+
+        // Attach texture to FBO
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_2D, sfc->rt_tex, 0);
+     }
 
-   // Attach texture to FBO
-   glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                          GL_TEXTURE_2D, sfc->rt_tex, 0);
+#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#else
+   // Depth Stencil RenderBuffer - Attach it to FBO
+   if (sfc->rb_depth_stencil)
+     {
+        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth_stencil);
+        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_stencil_fmt,
+                              sfc->w, sfc->h);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                  GL_RENDERBUFFER, sfc->rb_depth_stencil);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+     }
+#endif
 
    // Depth RenderBuffer - Attach it to FBO
-   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
+   if (sfc->rb_depth)
      {
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
@@ -2950,7 +3193,7 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__,
      }
 
    // Stencil RenderBuffer - Attach it to FBO
-   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
+   if (sfc->rb_stencil)
      {
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
@@ -2979,38 +3222,32 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
    Render_Engine_GL_Surface *sfc;
    Render_Engine_GL_Resource *rsc;
    Evas_GL_Config *cfg;
-   int ret;
-
-   sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
-   if (!sfc) return NULL;
+   void *ret = NULL;
+   int res;
 
    re  = (Render_Engine *)data;
    cfg = (Evas_GL_Config *)config;
 
-   sfc->initialized  = 0;
-   sfc->fbo_attached = 0;
+   // Allocate surface and fill in values
+   sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
+   if (!sfc) 
+     {
+        ERR("Surface allocation failed.");
+        goto finish;
+     }
+
    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;
 
-   /* Allow alpha for evas gl direct rendering */
-   // FIXME!!!: A little out of place for for now...
+   // Allow alpha for evas gl direct rendering override
+   // FIXME!!!: A little out of place but for now...
    if (!gl_direct_override)
       if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
 
    // Set the internal format based on the config
-   if (!_set_internal_config(sfc, cfg))
-     {
-        ERR("Unsupported Format!");
-        free(sfc);
-        return NULL;
-     }
-
-   if (sfc->direct_fb_opt)
+   if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
      {
         DBG("Enabling Direct rendering to the Evas' window."); 
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
@@ -3026,49 +3263,55 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
         if ((rsc = _create_internal_glue_resources(re)) == NULL)
           {
              ERR("Error creating internal resources.");
-             free(sfc);
-             return NULL;
+             goto finish;
           }
      }
 
-   // I'm using evas's original context to create the render target texture
-   // This is to prevent awkwardness in using native_surface_get() function
-   // If the rt texture creation is deferred till the context is created and
-   // make_current called, the user can't call native_surface_get() right
-   // after the surface is created. hence this is done here using evas' context.
+   // Use resource surface/context to create surface resrouces
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
+   res = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
 #else
-   ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context);
+   res = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context);
 #endif
-   if (!ret)
+   if (!res)
      {
-        ERR("xxxMakeCurrent() failed!");
-        free(sfc);
-        return NULL;
+        ERR("xxxMakeCurrent() finish!");
+        goto finish;
      }
 
-   // Create Render texture
-   if (!_create_rt_buffers(re, sfc))
+   // Set the engine surface capability first if it hasn't been set
+   if (!re->gl_cap_initted) _set_gl_surface_cap(re);
+
+   // Set the internal config value
+   if (!_set_internal_config(re, sfc, cfg))
      {
-        ERR("_create_rt_buffers() failed.");
-        free(sfc);
-        return NULL;
+        ERR("Unsupported Format!");
+        goto finish;
      }
 
+   // Create Render texture
+   _create_rt_buffers(re, sfc);
+
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+   res = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 #else
-   ret = glXMakeCurrent(re->info->info.display, None, NULL);
+   res = glXMakeCurrent(re->info->info.display, None, NULL);
 #endif
-   if (!ret)
+   if (!res)
      {
-        ERR("xxxMakeCurrent() failed!");
-        free(sfc);
-        return NULL;
+        ERR("xxxMakeCurrent() finish!");
+        goto finish;
      }
 
-   return sfc;
+   ret = sfc;
+
+finish:
+
+   if (!ret)
+     {
+        if (!sfc) free(sfc);
+     }
+   return ret;
 }
 
 static int
@@ -3104,7 +3347,7 @@ eng_gl_surface_destroy(void *data, void *surface)
         current_evgl_ctx->current_fbo = 0;
         current_evgl_ctx->current_sfc = NULL;
      }
-   
+
    // Clear direct rendering flag
    gl_direct_enabled = 0;
 
@@ -3118,6 +3361,8 @@ eng_gl_surface_destroy(void *data, void *surface)
    if (sfc->rb_stencil)
       glDeleteRenderbuffers(1, &sfc->rb_stencil);
 
+   if (sfc->rb_depth_stencil)
+      glDeleteRenderbuffers(1, &sfc->rb_depth_stencil);
 
 
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
@@ -3245,7 +3490,7 @@ eng_gl_context_destroy(void *data, void *context)
 
    // Delete the FBO
    if (ctx->context_fbo)
-        glDeleteFramebuffers(1, &ctx->context_fbo);
+      glDeleteFramebuffers(1, &ctx->context_fbo);
 
    // Destroy the Context
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
@@ -3289,6 +3534,8 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
    sfc = (Render_Engine_GL_Surface*)surface;
    ctx = (Render_Engine_GL_Context*)context;
 
+   current_engine = re;
+
    // Unset surface/context
    if ((!sfc) || (!ctx))
      {
@@ -3311,9 +3558,9 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
      }
 
    // Check if direct rendering is possible:
-   //    It's possible when direct_fb_opt is on and either current image 
-   //    object is valid or gl_direct_override is on.  Override allows 
-   //    rendering outside of pixel getter but it doesn't guarantee 
+   //    It's possible when direct_fb_opt is on and either current image
+   //    object is valid or gl_direct_override is on.  Override allows
+   //    rendering outside of pixel getter but it doesn't guarantee
    //    correct rendering.
    if ((sfc->direct_fb_opt) && (gl_direct_img_obj || gl_direct_override))
       gl_direct_enabled = 1;
@@ -3322,17 +3569,18 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
 
    if (gl_direct_enabled)
      {
+        int curr_fbo = 0;
+
         // Do a make current only if it's not already current
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if ((eglGetCurrentContext() != ctx->context) || 
+        if ((eglGetCurrentContext() != ctx->context) ||
             (eglGetCurrentSurface(EGL_READ) != sfc->direct_sfc) ||
-            (eglGetCurrentSurface(EGL_DRAW) != sfc->direct_sfc) ) 
+            (eglGetCurrentSurface(EGL_DRAW) != sfc->direct_sfc) )
           {
-             int curr_fbo = 0;
              DBG("Rendering Directly to the window\n");
 
              // Flush remainder of what's in Evas' pipeline
-             if (re->win) eng_window_use(NULL);
+             eng_window_use(NULL);
 
              // Do a make current
              ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc,
@@ -3343,50 +3591,73 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
                   //ERR("xxxMakeCurrent() failed!");
                   return 0;
                }
-
-             glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
-             if (ctx->context_fbo == curr_fbo)
-               {
-                  ctx->current_fbo = 0;
-                  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-               }
           }
 #else
         if ((glXGetCurrentContext() != ctx->context))
           {
              // Flush remainder of what's in Evas' pipeline
-             if (re->win) eng_window_use(NULL);
+             eng_window_use(NULL);
 
              // Do a make current
              ret = glXMakeCurrent(re->info->info.display, sfc->direct_sfc, ctx->context);
-             if (!ret) 
+             if (!ret)
                {
                   ERR("xxxMakeCurrent() failed!");
                   return 0;
                }
           }
 #endif
+        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
+        if (ctx->context_fbo == curr_fbo)
+          {
+             ctx->current_fbo = 0;
+             glBindFramebuffer(GL_FRAMEBUFFER, 0);
+          }
+
      }
    else
      {
         // Do a make current only if it's not already current
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
+        if (eina_main_loop_is())
+          {
+             if ((eglGetCurrentContext() != ctx->context) ||
+                 (eglGetCurrentSurface(EGL_READ) != re->win->egl_surface[0]) ||
+                 (eglGetCurrentSurface(EGL_DRAW) != re->win->egl_surface[0]) )
+               {
 
-        if ((eglGetCurrentContext() != ctx->context) || 
-            (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
-            (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) ) 
+                  // Flush remainder of what's in Evas' pipeline
+                  eng_window_use(NULL);
+
+                  // Do a make current
+                  ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0],
+                                             re->win->egl_surface[0], ctx->context);
+                  if (!ret)
+                    {
+                       ERR("xxxMakeCurrent() failed! code=%#x", eglGetError());
+                       return 0;
+                    }
+               }
+          }
+        else
           {
-             // Flush remainder of what's in Evas' pipeline
-             if (re->win) eng_window_use(NULL);
+             if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
 
-             // Do a make current
-             ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
-                                  rsc->surface, ctx->context);
-             if (!ret)
+             if ((eglGetCurrentContext() != ctx->context) ||
+                 (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
+                 (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
                {
-                  ERR("xxxMakeCurrent() failed!");
-                  return 0;
+                  // Flush remainder of what's in Evas' pipeline
+                  eng_window_use(NULL);
+
+                  // Do a make current
+                  ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
+                                             rsc->surface, ctx->context);
+                  if (!ret)
+                    {
+                       ERR("xxxMakeCurrent() failed!");
+                       return 0;
+                    }
                }
           }
 #else
@@ -3394,7 +3665,7 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
             (glXGetCurrentDrawable() != re->win->win) )
           {
              // Flush remainder of what's in Evas' pipeline
-             if (re->win) eng_window_use(NULL);
+             eng_window_use(NULL);
 
              // Do a make current
              ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
@@ -3437,6 +3708,7 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
    ctx->current_sfc = sfc;
    sfc->current_ctx = ctx;
    current_evgl_ctx = ctx;
+   current_engine = re;
 
    return 1;
 }
@@ -3466,13 +3738,11 @@ eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
 }
 
 static int
-eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
+eng_gl_native_surface_get(void *data __UNUSED__, 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;
 
@@ -3507,7 +3777,7 @@ static const GLubyte *
 evgl_glGetString(GLenum name)
 {
    if (name == GL_EXTENSIONS)
-      return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); 
+      return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS);
    else
       return glGetString(name);
 }
@@ -3553,14 +3823,14 @@ evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
 // returns: oc[4] original image object dimension in gl coord
 // returns: nc[4] tranformed  (x, y, width, heigth) in gl coord
 static void
-compute_gl_coordinates(Evas_Object *obj, int rot, int clip, 
-                       int x, int y, int width, int height, 
+compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
+                       int x, int y, int width, int height,
                        int imgc[4], int objc[4])
 {
    if (rot == 0)
      {
         // oringinal image object coordinate in gl coordinate
-        imgc[0] = obj->cur.geometry.x; 
+        imgc[0] = obj->cur.geometry.x;
         imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
         imgc[2] = imgc[0] + obj->cur.geometry.w;
         imgc[3] = imgc[1] + obj->cur.geometry.h;
@@ -3668,16 +3938,18 @@ evgl_glClear(GLbitfield mask)
 static void
 evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 {
-   current_engine->df_clear_color[0] = red;
-   current_engine->df_clear_color[1] = green;
-   current_engine->df_clear_color[2] = blue;
-   current_engine->df_clear_color[3] = alpha;
+   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+
+   current_evgl_ctx->df_clear_color[0] = red;
+   current_evgl_ctx->df_clear_color[1] = green;
+   current_evgl_ctx->df_clear_color[2] = blue;
+   current_evgl_ctx->df_clear_color[3] = alpha;
 
    glClearColor(red, green, blue, alpha);
 
 }
 
-static void 
+static void
 evgl_glEnable(GLenum cap)
 {
    Render_Engine_GL_Context *ctx = current_evgl_ctx;
@@ -3804,7 +4076,6 @@ evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint*
         precision[0] = 24; // floor(-log2((1.0/16777218.0)));
      }
    return;
-   shadertype = precisiontype = 0;
 #endif
 }
 
@@ -4125,14 +4396,14 @@ eng_gl_img_obj_set(void *data, void *image, int has_alpha)
    gl_direct_img_obj = NULL;
 
    // Normally direct rendering isn't allowed if alpha is on and
-   // rotation is not 0.  BUT, if override is on, allow it. 
-   if ((has_alpha) || (re->win->gl_context->rot!=0)) 
+   // rotation is not 0.  BUT, if override is on, allow it.
+   if ((has_alpha) || (re->win->gl_context->rot!=0))
      {
         if (gl_direct_override)
            gl_direct_img_obj = image;
      }
-   else 
-      gl_direct_img_obj = image;   
+   else
+      gl_direct_img_obj = image;
 }
 
 static int
@@ -4274,7 +4545,13 @@ module_open(Evas_Module *em)
         return 0;
      }
    /* Allow alpha for evas gl direct rendering */
-   if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
+   if (getenv("EVAS_GL_DIRECT_OVERRIDE"))
+     {
+        gl_direct_override = 1;
+        DBG("########################################################");
+        DBG("######### [Evas] Direct overriding is enabled ##########");
+        DBG("########################################################");
+     }
 
    /* store it for later use */
    func = pfunc;
@@ -4383,7 +4660,7 @@ static void
 module_close(Evas_Module *em __UNUSED__)
 {
     eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
-/*   
+/*
     if (xrdb_user.db)
       {
         XrmDestroyDatabase(xrdb_user.db);