Adding MSAA (Multisample Anti-Aliased) Surface Option to Evas GL.
authorsung <sung@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 14 May 2012 08:52:56 +0000 (08:52 +0000)
committersung <sung@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 14 May 2012 08:52:56 +0000 (08:52 +0000)
Currently, this feature is only supported in EGL/GLESv2 environment
with GL_IMG_multisampled_render_to_texture extension supported.

_____________________

from:    (sanghee park) sh15.park@samsung.com

Dear all,

     I compose this mail to ask reviewal this patch about multisampling on the evasgl.
     I want to make multisampling capacity to enhance rendering quality of the evasgl.
     But if MSAA is applied always, this have possibility lowering rendering performance,
     I separated user's input level to high, mid, low, none.
     If you want to test this patch, try to examine rendering qulity on EGL circumstance with multisampling level.
     Plaese review it, and any suggestion will be appreciated.

     Best Regards,
     SangHee

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

ChangeLog
src/lib/Evas_GL.h
src/modules/engines/gl_x11/evas_engine.c

index c9ced49..1c18991 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * Add CServe2 and image cache2 that makes use of it. Several changes
        in the buffer and software engines to use the right cache if CServe2
        is requested for the application.
-        
+
 2012-05-14  Carsten Haitzler (The Rasterman)
 
         * Fix pixman rendering support if you set alpha flag AFTER
         setting image size for custom image data.
 
+2012-05-14 Sanghee Park
+
+       * Add Multisample Anti-Anliased surface format for Evas GL. 
+        The formats are divided into High, Med, Low, None, where High represent
+        max number of samples.  Currently, this feature is only supported in GLES2
+        environment with GL_IMG_multisampled_render_to_texture extension supported.
index 9a7113c..f90f227 100644 (file)
@@ -47,12 +47,21 @@ typedef enum _Evas_GL_Options_Bits
    EVAS_GL_OPTIONS_DIRECT  = (1<<0)
 } Evas_GL_Options_Bits;
 
+typedef enum _Evas_GL_Multisample_Bits
+{
+   EVAS_GL_MULTISAMPLE_NONE = 0,
+   EVAS_GL_MULTISAMPLE_LOW  = 1,
+   EVAS_GL_MULTISAMPLE_MED  = 2,
+   EVAS_GL_MULTISAMPLE_HIGH = 3 
+} Evas_GL_Multisample_Bits;
+
 struct _Evas_GL_Config
 {
-   Evas_GL_Color_Format     color_format;
-   Evas_GL_Depth_Bits       depth_bits;
-   Evas_GL_Stencil_Bits     stencil_bits;
-   Evas_GL_Options_Bits     options_bits;
+   Evas_GL_Color_Format       color_format;
+   Evas_GL_Depth_Bits         depth_bits;
+   Evas_GL_Stencil_Bits       stencil_bits;
+   Evas_GL_Options_Bits       options_bits;
+   Evas_GL_Multisample_Bits   multisample_bits;
 };
 
 #define EVAS_GL_EXTENSIONS       1
@@ -1122,6 +1131,12 @@ typedef signed long int  GLsizeiptr;   // Changed khronos_ssize_t
 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
 
+/* GL_IMG_multisampled_render_to_texture */
+#define GL_RENDERBUFFER_SAMPLES_IMG                             0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG               0x9134
+#define GL_MAX_SAMPLES_IMG                                      0x9135
+#define GL_TEXTURE_SAMPLES_IMG                                  0x9136
+
 /*------------------------------------------------------------------------*
  * NV extension tokens
  *------------------------------------------------------------------------*/
index 704e680..8e23801 100644 (file)
@@ -43,21 +43,26 @@ struct _Render_Engine
 
    // 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;
+        int max_rb_size;
+        int msaa_support;
+        int msaa_samples[4];
+
+        //---------//
+        int rgb_888[4];
+        int rgba_8888[4];
+
+        int depth_8[4];
+        int depth_16[4];
+        int depth_24[4];
+        int depth_32[4];
+
+        int stencil_1[4];
+        int stencil_2[4];
+        int stencil_4[4];
+        int stencil_8[4];
+        int stencil_16[4];
+
+        int depth_24_stencil_8[4];
    } gl_cap;
 
    int gl_cap_initted;
@@ -65,24 +70,30 @@ struct _Render_Engine
 
 struct _Render_Engine_GL_Surface
 {
-   int      initialized;
-   int      fbo_attached;
-   int      w, h;
-   int      depth_bits;
-   int      stencil_bits;
+   int         initialized;
+   int         fbo_attached;
+   int         w, h;
 
-   int      direct_fb_opt;
+   // Surface Config
+   int         depth_bits;
+   int         stencil_bits;
+   int         direct_fb_opt;
+   int         multiample_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;
-   GLuint   rb_depth_stencil;
-   GLenum   rb_depth_stencil_fmt;
+   GLint       rt_msaa_samples;
+
+   GLuint      rt_tex;
+   GLuint      rb_depth;
+   GLuint      rb_stencil;
+   GLuint      rb_depth_stencil;
+
+   GLenum      rt_fmt;
+   GLint       rt_internal_fmt;
+
+   GLenum      rb_depth_fmt;
+   GLenum      rb_stencil_fmt;
+   GLenum      rb_depth_stencil_fmt;
 
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
    EGLSurface  direct_sfc;
@@ -113,7 +124,7 @@ struct _Render_Engine_GL_Context
 // Resources used per thread
 struct _Render_Engine_GL_Resource
 {
-   // Resource context/surface per Thread in TLS for evasgl use 
+   // Resource context/surface per Thread in TLS for evasgl use
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
    EGLContext context;
    EGLSurface surface;
@@ -141,7 +152,7 @@ static Evas_Object *gl_direct_img_obj = NULL;
 static char _gl_ext_string[1024];
 static char _evasgl_ext_string[1024];
 
-// Resource context/surface per Thread in TLS for evasgl use 
+// Resource context/surface per Thread in TLS for evasgl use
 static Eina_TLS   resource_key;
 static Eina_List *resource_list;
 LK(resource_lock);
@@ -225,6 +236,8 @@ unsigned char       (*glsym_glTestFenceNV) (GLuint fence) = NULL;
 void   (*glsym_glGetFenceivNV) (GLuint fence, GLenum pname, GLint* params) = NULL;
 void   (*glsym_glFinishFenceNV) (GLuint fence) = NULL;
 void   (*glsym_glSetFenceNV) (GLuint, GLenum) = NULL;
+void    (*glsym_glRenderbufferStorageMultisampleIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = NULL;
+void    (*glsym_glFramebufferTexture2DMultisampleIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) = NULL;
 void   (*glsym_glGetDriverControlsQCOM) (GLint* num, GLsizei size, GLuint* driverControls) = NULL;
 void   (*glsym_glGetDriverControlStringQCOM) (GLuint driverControl, GLsizei bufSize, GLsizei* length, char* driverControlString) = NULL;
 void   (*glsym_glEnableDriverControlQCOM) (GLuint driverControl) = NULL;
@@ -257,6 +270,7 @@ static Extension_Entry _gl_ext_entries[] = {
        { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
        { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
        { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
+       { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 0 },
 
        //--- Define Extensions ---//
        { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
@@ -301,6 +315,7 @@ static Extension_Entry _gl_ext_entries[] = {
        { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
        { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
        { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
+       { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 0 },
 
        //--- Define Extensions ---//
        { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
@@ -452,6 +467,7 @@ _gl_ext_sym_init(void)
    //----------- GLES 2.0 Extensions ------------//
    // If the symbol's not found, they get set to NULL
    // If one of the functions in the extension exists, the extension in supported
+
    /* GL_OES_get_program_binary */
    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinary", glsym_func_void);
    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryEXT", glsym_func_void);
@@ -589,6 +605,16 @@ _gl_ext_sym_init(void)
    FINDSYM(glsym_glExtGetProgramBinarySourceQCOM, "glExtGetProgramBinarySourceQCOM", glsym_func_void);
 
    if (glsym_glExtGetShadersQCOM) _gl_ext_entries[9].supported = 1;
+
+   /* GL_IMG_multisampled_render_to_texture */
+   FINDSYM(glsym_glRenderbufferStorageMultisampleIMG, "glRenderbufferStorageMultisampleIMG", glsym_func_void);
+   FINDSYM(glsym_glRenderbufferStorageMultisampleIMG, "glRenderbufferStorageMultisampleEXT", glsym_func_void);
+   FINDSYM(glsym_glFramebufferTexture2DMultisampleIMG, "glFramebufferTexture2DMultisampleIMG", glsym_func_void);
+   FINDSYM(glsym_glFramebufferTexture2DMultisampleIMG, "glFramebufferTexture2DMultisampleEXT", glsym_func_void);
+
+   if (glsym_glRenderbufferStorageMultisampleIMG) _gl_ext_entries[10].supported = 1;
+
+
 }
 
 static void
@@ -626,7 +652,7 @@ _gl_ext_init(Render_Engine *re)
 #else
    if (glsym_glXQueryExtensionsString)
      {
-        evasglexts = glXQueryExtensionsString(re->info->info.display, 
+        evasglexts = glXQueryExtensionsString(re->info->info.display,
                                               re->info->info.screen);
 #endif
 
@@ -2848,7 +2874,7 @@ eng_canvas_alpha_get(void *data, void *info __UNUSED__)
 // 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
-_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt)
+_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt, int mult_samples)
 {
    GLuint fbo, tex, rb;
    int w, h, fb_status;
@@ -2872,7 +2898,10 @@ _check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum at
         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);
+        if (mult_samples)
+           glsym_glFramebufferTexture2DMultisampleIMG(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0, mult_samples);
+        else
+           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
      }
 
    // Render Target Attachment (Stencil or Depth)
@@ -2880,7 +2909,10 @@ _check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum at
      {
         glGenRenderbuffers(1, &rb);
         glBindRenderbuffer(GL_RENDERBUFFER, rb);
-        glRenderbufferStorage(GL_RENDERBUFFER, attach_fmt, w, h);
+        if (mult_samples)
+           glsym_glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, mult_samples, attach_fmt, w, h);
+        else
+           glRenderbufferStorage(GL_RENDERBUFFER, attach_fmt, w, h);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb);
         glBindRenderbuffer(GL_RENDERBUFFER, 0);
      }
@@ -2899,9 +2931,9 @@ _check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum at
       return 0;
    else
      {
-        if (attachment
+        if ((attachment) && (!mult_samples)
            return attach_fmt;
-        else 
+        else
            return 1;
      }
 }
@@ -2913,23 +2945,31 @@ _print_gl_surface_cap(Render_Engine *re, int error)
    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("---------------------------------------------------");
+      DBG(__VA_ARGS__);
+
+   PRINT_LOG("----------------------------------------------------");
+   PRINT_LOG("           EvasGL Supported Surface Format          ");
+   PRINT_LOG("                                                    ");
+   PRINT_LOG(" [Max Renderbuffer Size]  : %d", re->gl_cap.max_rb_size);
+   PRINT_LOG(" [Multisample Support  ]  : %d", re->gl_cap.msaa_support);
+   PRINT_LOG("          [Low  Samples]  : %d", re->gl_cap.msaa_samples[1]);
+   PRINT_LOG("          [Med  Samples]  : %d", re->gl_cap.msaa_samples[2]);
+   PRINT_LOG("          [High Samples]  : %d", re->gl_cap.msaa_samples[3]);
+   PRINT_LOG("                                  [--Multisamples--]   ");
+   PRINT_LOG("                           [Norm] [Low] [Med] [High]");
+   PRINT_LOG(" [RGB  Format]            : %4x    %d     %d     %d", re->gl_cap.rgb_888[0], re->gl_cap.rgb_888[1], re->gl_cap.rgb_888[2], re->gl_cap.rgb_888[3]);
+   PRINT_LOG(" [RGBA Format]            : %4x    %d     %d     %d", re->gl_cap.rgba_8888[0], re->gl_cap.rgba_8888[1], re->gl_cap.rgba_8888[2], re->gl_cap.rgba_8888[3]);
+   PRINT_LOG(" [Depth  8 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_8[0], re->gl_cap.depth_8[1], re->gl_cap.depth_8[2], re->gl_cap.depth_8[3]);
+   PRINT_LOG(" [Depth 16 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_16[0], re->gl_cap.depth_16[1], re->gl_cap.depth_16[2], re->gl_cap.depth_16[3]);
+   PRINT_LOG(" [Depth 24 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_24[0], re->gl_cap.depth_24[1], re->gl_cap.depth_24[2], re->gl_cap.depth_24[3]);
+   PRINT_LOG(" [Depth 32 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_32[0], re->gl_cap.depth_32[1], re->gl_cap.depth_32[2], re->gl_cap.depth_32[3]);
+   PRINT_LOG(" [Stencil  1 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_1[0], re->gl_cap.stencil_1[1], re->gl_cap.stencil_1[2], re->gl_cap.stencil_1[3]);
+   PRINT_LOG(" [Stencil  2 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_2[0], re->gl_cap.stencil_2[1], re->gl_cap.stencil_2[2], re->gl_cap.stencil_2[3]);
+   PRINT_LOG(" [Stencil  4 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_4[0], re->gl_cap.stencil_4[1], re->gl_cap.stencil_4[2], re->gl_cap.stencil_4[3]);
+   PRINT_LOG(" [Stencil  8 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_8[0], re->gl_cap.stencil_8[1], re->gl_cap.stencil_8[2], re->gl_cap.stencil_8[3]);
+   PRINT_LOG(" [Stencil 16 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_16[0], re->gl_cap.stencil_16[1], re->gl_cap.stencil_16[2], re->gl_cap.stencil_16[3]);
+   PRINT_LOG(" [Depth 24 Stencil 8 Bits]: %4x    %d     %d     %d", re->gl_cap.depth_24_stencil_8[0], re->gl_cap.depth_24_stencil_8[1], re->gl_cap.depth_24_stencil_8[2], re->gl_cap.depth_24_stencil_8[3]);
+   PRINT_LOG("----------------------------------------------------");
 #undef PRINT_LOG
 }
 
@@ -2937,8 +2977,9 @@ static void
 _set_gl_surface_cap(Render_Engine *re)
 {
    GLuint fbo, tex, depth, stencil;
-   int w, h;
-   int ret;
+   int w, h, max_samples;
+   
+   int i, ret, count;
 
    if (!re) return;
    if (re->gl_cap_initted) return;
@@ -2946,29 +2987,70 @@ _set_gl_surface_cap(Render_Engine *re)
    // 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)
+   glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples);
+
+   // Check if msaa_support is supported
+   if (max_samples &&
+       (glsym_glFramebufferTexture2DMultisampleIMG) &&
+       (glsym_glRenderbufferStorageMultisampleIMG))
+     {
+        re->gl_cap.msaa_support = 1;
+
+        re->gl_cap.msaa_samples[3] = max_samples;
+        re->gl_cap.msaa_samples[2] = max_samples/2;
+        re->gl_cap.msaa_samples[1] = max_samples/4;
+        re->gl_cap.msaa_samples[0] = 0;
+
+        if (!re->gl_cap.msaa_samples[2]) re->gl_cap.msaa_samples[3];
+        if (!re->gl_cap.msaa_samples[1]) re->gl_cap.msaa_samples[2];
+     }
+   else
+     {
+        re->gl_cap.msaa_support = 0;
+     }
+
+#endif
+   glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &re->gl_cap.max_rb_size);
+
 
 #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);
+   count = (re->gl_cap.msaa_support) ? 4 : 1;
+
+   for (i = 0; i < count; i++)
+     {
+        re->gl_cap.rgb_888[i]   = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]);
 
-   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_8[i]   = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_16[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_24[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_32[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32_OES, re->gl_cap.msaa_samples[i]);
 
-   re->gl_cap.depth_24_stencil_8  = _check_gl_surface_format(0, 0, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
+        re->gl_cap.stencil_1[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_4[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_8[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]);
+     }
+
+  #else
+   count = (re->gl_cap.msaa_support) ? 4 : 1;
+
+   for (i = 0; i < count; i++)
+     {
+        re->gl_cap.rgb_888[i]   = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.depth_8[i]   = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_16[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_24[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_32[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.stencil_1[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_4[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_8[i] = _check_gl_surface_format(0, 0, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.depth_24_stencil_8[i]  = _check_gl_surface_format(0, 0, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8, re->gl_cap.msaa_samples[i]);
+     }
 #endif
 
    _print_gl_surface_cap(re, 0);
@@ -2983,14 +3065,14 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C
    switch((int)cfg->color_format)
      {
       case EVAS_GL_RGB_888:
-         if (re->gl_cap.rgb_fmt)
+         if (re->gl_cap.rgb_888[0])
            {
               sfc->rt_fmt          = GL_RGB;
               sfc->rt_internal_fmt = GL_RGB;
               break;
            }
       case EVAS_GL_RGBA_8888:
-         if (re->gl_cap.rgba_fmt)
+         if (re->gl_cap.rgba_8888[0])
            {
               sfc->rt_fmt          = GL_RGBA;
               sfc->rt_internal_fmt = GL_RGBA;
@@ -3008,30 +3090,30 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C
       case EVAS_GL_DEPTH_NONE:
          break;
       case EVAS_GL_DEPTH_BIT_8:
-         if (re->gl_cap.depth_8)
+         if (re->gl_cap.depth_8[0])
            {
-              sfc->rb_depth_fmt = re->gl_cap.depth_8;
+              sfc->rb_depth_fmt = re->gl_cap.depth_8[0];
               cfg->depth_bits   = EVAS_GL_DEPTH_BIT_8;
               break;
            }
       case EVAS_GL_DEPTH_BIT_16:
-         if (re->gl_cap.depth_16)
+         if (re->gl_cap.depth_16[0])
            {
-              sfc->rb_depth_fmt = re->gl_cap.depth_16;
+              sfc->rb_depth_fmt = re->gl_cap.depth_16[0];
               cfg->depth_bits   = EVAS_GL_DEPTH_BIT_16;
               break;
            }
       case EVAS_GL_DEPTH_BIT_24:
-         if (re->gl_cap.depth_24)
+         if (re->gl_cap.depth_24[0])
            {
-              sfc->rb_depth_fmt = re->gl_cap.depth_24;
+              sfc->rb_depth_fmt = re->gl_cap.depth_24[0];
               cfg->depth_bits   = EVAS_GL_DEPTH_BIT_24;
               break;
            }
       case EVAS_GL_DEPTH_BIT_32:
-         if (re->gl_cap.depth_32)
+         if (re->gl_cap.depth_32[0])
            {
-              sfc->rb_depth_fmt = re->gl_cap.depth_32;
+              sfc->rb_depth_fmt = re->gl_cap.depth_32[0];
               cfg->depth_bits   = EVAS_GL_DEPTH_BIT_32;
               break;
            }
@@ -3046,44 +3128,44 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C
       case EVAS_GL_STENCIL_NONE:
          break;
       case EVAS_GL_STENCIL_BIT_1:
-         if (re->gl_cap.stencil_1)
+         if (re->gl_cap.stencil_1[0])
            {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_1;
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_1[0];
               cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_1;
               break;
            }
       case EVAS_GL_STENCIL_BIT_2:
-         if (re->gl_cap.stencil_2)
+         if (re->gl_cap.stencil_2[0])
            {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_2;
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_2[0];
               cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_2;
               break;
            }
       case EVAS_GL_STENCIL_BIT_4:
-         if (re->gl_cap.stencil_4)
+         if (re->gl_cap.stencil_4[0])
            {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_4;
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_4[0];
               cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_4;
               break;
            }
       case EVAS_GL_STENCIL_BIT_8:
-         if ((sfc->rb_depth_fmt == re->gl_cap.depth_24) && (re->gl_cap.depth_24_stencil_8))
+         if ((sfc->rb_depth_fmt == re->gl_cap.depth_24[0]) && (re->gl_cap.depth_24_stencil_8[0]))
            {
-              sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8;
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_8;
+              sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8[0];
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_8[0];
               cfg->stencil_bits = EVAS_GL_STENCIL_BIT_8;
               break;
            }
-         else if (re->gl_cap.stencil_8)
+         else if (re->gl_cap.stencil_8[0])
            {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_8;
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_8[0];
               cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_8;
               break;
            }
       case EVAS_GL_STENCIL_BIT_16:
-         if (re->gl_cap.stencil_16)
+         if (re->gl_cap.stencil_16[0])
            {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_16;
+              sfc->rb_stencil_fmt = re->gl_cap.stencil_16[0];
               cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_16;
               break;
            }
@@ -3105,6 +3187,22 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C
         // Add other options here...
      }
 
+   // Multisample bit
+   if (re->gl_cap.msaa_support)
+     {
+        if ( ((int)(cfg->multisample_bits) > (int)EVAS_GL_MULTISAMPLE_HIGH) ||
+             ((int)(cfg->multisample_bits) < 0) )
+          {
+             ERR("Unsupported Multisample Bits Format!");
+             _print_gl_surface_cap(re, 1);
+             return 0;
+          }
+        else
+          {
+             sfc->rt_msaa_samples = re->gl_cap.msaa_samples[(int)cfg->multisample_bits];
+          }
+     }
+
    return 1;
 }
 
@@ -3155,8 +3253,10 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__,
                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
         glBindTexture(GL_TEXTURE_2D, 0);
 
-        // Attach texture to FBO
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+        if (sfc->rt_msaa_samples)
+           glsym_glFramebufferTexture2DMultisampleIMG(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sfc->rt_tex, 0, sfc->rt_msaa_samples);
+        else
+           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                GL_TEXTURE_2D, sfc->rt_tex, 0);
      }
 
@@ -3178,8 +3278,15 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__,
    if (sfc->rb_depth)
      {
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
-        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
-                              sfc->w, sfc->h);
+
+        if (sfc->rt_msaa_samples)
+           glsym_glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
+                                                     sfc->rt_msaa_samples,
+                                                     sfc->rb_depth_fmt,
+                                                     sfc->w, sfc->h);
+        else
+           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
+                                 sfc->w, sfc->h);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                   GL_RENDERBUFFER, sfc->rb_depth);
         glBindRenderbuffer(GL_RENDERBUFFER, 0);
@@ -3189,8 +3296,15 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__,
    if (sfc->rb_stencil)
      {
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
-        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
-                              sfc->w, sfc->h);
+
+        if (sfc->rt_msaa_samples)
+           glsym_glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
+                                                     sfc->rt_msaa_samples,
+                                                     sfc->rb_stencil_fmt,
+                                                     sfc->w, sfc->h);
+        else
+           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
+                                 sfc->w, sfc->h);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                   GL_RENDERBUFFER, sfc->rb_stencil);
         glBindRenderbuffer(GL_RENDERBUFFER, 0);
@@ -3223,7 +3337,7 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
 
    // Allocate surface and fill in values
    sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
-   if (!sfc) 
+   if (!sfc)
      {
         ERR("Surface allocation failed.");
         goto finish;
@@ -3242,7 +3356,7 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
    // Set the internal format based on the config
    if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
      {
-        DBG("Enabling Direct rendering to the Evas' window."); 
+        DBG("Enabling Direct rendering to the Evas' window.");
 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
         sfc->direct_sfc = re->win->egl_surface[0];
 #else
@@ -3275,6 +3389,13 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
    // Set the engine surface capability first if it hasn't been set
    if (!re->gl_cap_initted) _set_gl_surface_cap(re);
 
+   // Check the size of the surface
+   if ( (w > re->gl_cap.max_rb_size) || (h > re->gl_cap.max_rb_size) )
+     {
+        ERR("Surface size greater than the supported size. Max Surface Size: %d", re->gl_cap.max_rb_size);
+        goto finish;
+     }
+
    // Set the internal config value
    if (!_set_internal_config(re, sfc, cfg))
      {
@@ -3662,7 +3783,7 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
 
              // Do a make current
              ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
-             if (!ret) 
+             if (!ret)
                {
                   ERR("xxxMakeCurrent() failed!");
                   return 0;
@@ -3780,7 +3901,7 @@ evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
 {
    Render_Engine_GL_Context *ctx = current_evgl_ctx;
 
-   if (!ctx) 
+   if (!ctx)
      {
         ERR("No current context set.");
         return;
@@ -3791,7 +3912,7 @@ evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
      {
         if (gl_direct_enabled)
            glBindFramebuffer(target, 0);
-        else 
+        else
            glBindFramebuffer(target, ctx->context_fbo);
         ctx->current_fbo = 0;
      }
@@ -4529,6 +4650,8 @@ module_open(Evas_Module *em)
         EINA_LOG_ERR("Can not create a module log domain.");
         return 0;
      }
+
+
    /* Allow alpha for evas gl direct rendering */
    if (getenv("EVAS_GL_DIRECT_OVERRIDE"))
      {