From b0f7d91c3207d56fe041a85f5849e3c1184e796b Mon Sep 17 00:00:00 2001 From: Sung Park Date: Mon, 14 May 2012 08:52:56 +0000 Subject: [PATCH] Adding MSAA (Multisample Anti-Aliased) Surface Option to Evas GL. 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 SVN revision: 70992 --- legacy/evas/ChangeLog | 8 +- legacy/evas/src/lib/Evas_GL.h | 23 +- .../src/modules/engines/gl_x11/evas_engine.c | 333 ++++++++++++------ 3 files changed, 254 insertions(+), 110 deletions(-) diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index c9ced49f10..1c18991fb6 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -731,9 +731,15 @@ * 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. diff --git a/legacy/evas/src/lib/Evas_GL.h b/legacy/evas/src/lib/Evas_GL.h index 9a7113cdb4..f90f227374 100644 --- a/legacy/evas/src/lib/Evas_GL.h +++ b/legacy/evas/src/lib/Evas_GL.h @@ -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 *------------------------------------------------------------------------*/ diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index 704e680a9e..8e23801a42 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -43,21 +43,26 @@ struct _Render_Engine // GL Surface Capability struct { - int rgb_fmt; - int rgba_fmt; + int max_rb_size; + int msaa_support; + int msaa_samples[4]; - int depth_8; - int depth_16; - int depth_24; - int depth_32; + //---------// + int rgb_888[4]; + int rgba_8888[4]; - int stencil_1; - int stencil_2; - int stencil_4; - int stencil_8; - int stencil_16; + int depth_8[4]; + int depth_16[4]; + int depth_24[4]; + int depth_32[4]; - int depth_24_stencil_8; + 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__); + 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("---------------------------------------------------"); + 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); + count = (re->gl_cap.msaa_support) ? 4 : 1; - 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); + 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")) {