From d5190812272ea6c0835bc4428aff9560acbea80d Mon Sep 17 00:00:00 2001 From: "Park, Sung Woo" Date: Wed, 9 May 2012 17:53:08 +0900 Subject: [PATCH] Added MSAA capability to EvasGL Surface. The surface format addes mutlisample_bits to the surface config. It has three levels: high, med, low. Currently, high does maximum number of samples, Med does max/2, and Low does med/2. EvasGL MSAA surface mode is currently only supported in EGL backend with GL_IMG_multlisampled_render_to_texture extension. --- src/lib/Evas_GL.h | 27 ++- src/modules/engines/gl_x11/evas_engine.c | 341 ++++++++++++++++++++----------- 2 files changed, 239 insertions(+), 129 deletions(-) diff --git a/src/lib/Evas_GL.h b/src/lib/Evas_GL.h index 821a042..d872350 100644 --- a/src/lib/Evas_GL.h +++ b/src/lib/Evas_GL.h @@ -49,12 +49,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 @@ -406,7 +415,7 @@ EAPI void evas_gl_free (Evas_GL *evas_gl) EINA * As long as the Evas creates a config object for the user, it takes care * of the backward compatibility issue. */ -EAPI Evas_GL_Config *evas_gl_config_new (); +EAPI Evas_GL_Config *evas_gl_config_new (void); /** * Frees a config object created from evas_gl_config_new. @@ -1124,6 +1133,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 *------------------------------------------------------------------------*/ @@ -1355,7 +1370,7 @@ struct _Evas_GL_API /* GL_OES_get_program_binary */ void (*glGetProgramBinaryOES) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); - void (*glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); + void (*glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); /* GL_OES_mapbuffer */ void* (*glMapBufferOES) (GLenum target, GLenum access); GLboolean (*glUnmapBufferOES) (GLenum target); diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index 3a1b30a..c94a31b 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/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 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); @@ -463,10 +479,6 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryARB", glsym_func_void); FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryOES", glsym_func_void); - // Check the first function to see if the extension is supported... - if (glsym_glGetProgramBinaryOES) _gl_ext_entries[0].supported = 1; - - /* GL_OES_mapbuffer */ FINDSYM(glsym_glMapBufferOES, "glMapBuffer", glsym_func_void_ptr); FINDSYM(glsym_glMapBufferOES, "glMapBufferEXT", glsym_func_void_ptr); @@ -483,8 +495,6 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervARB", glsym_func_void); FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervOES", glsym_func_void); - if (glsym_glMapBufferOES) _gl_ext_entries[1].supported = 1; - /* GL_OES_texture_3D */ FINDSYM(glsym_glTexImage3DOES, "glTexImage3D", glsym_func_void); FINDSYM(glsym_glTexImage3DOES, "glTexImage3DEXT", glsym_func_void); @@ -516,8 +526,6 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DEXT", glsym_func_void); FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DOES", glsym_func_void); - if (glsym_glTexSubImage3DOES) _gl_ext_entries[2].supported = 1; - /* AMD_performance_monitor */ FINDSYM(glsym_glGetPerfMonitorGroupsAMD, "glGetPerfMonitorGroupsAMD", glsym_func_void); FINDSYM(glsym_glGetPerfMonitorCountersAMD, "glGetPerfMonitorCountersAMD", glsym_func_void); @@ -531,15 +539,11 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glEndPerfMonitorAMD, "glEndPerfMonitorAMD", glsym_func_void); FINDSYM(glsym_glGetPerfMonitorCounterDataAMD, "glGetPerfMonitorCounterDataAMD", glsym_func_void); - if (glsym_glGetPerfMonitorGroupsAMD) _gl_ext_entries[3].supported = 1; - /* GL_EXT_discard_framebuffer */ FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebuffer", glsym_func_void); FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferARB", glsym_func_void); FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferEXT", glsym_func_void); - if (glsym_glDiscardFramebufferEXT) _gl_ext_entries[4].supported = 1; - /* GL_EXT_multi_draw_arrays */ FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArrays", glsym_func_void); FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysARB", glsym_func_void); @@ -549,8 +553,6 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsARB", glsym_func_void); FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsEXT", glsym_func_void); - if (glsym_glMultiDrawArraysEXT) _gl_ext_entries[5].supported = 1; - /* GL_NV_fence */ FINDSYM(glsym_glDeleteFencesNV, "glDeleteFencesNV", glsym_func_void); FINDSYM(glsym_glGenFencesNV, "glGenFencesNV", glsym_func_void); @@ -560,16 +562,12 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glFinishFenceNV, "glFinishFenceNV", glsym_func_void); FINDSYM(glsym_glSetFenceNV, "glSetFenceNV", glsym_func_void); - if (glsym_glDeleteFencesNV) _gl_ext_entries[6].supported = 1; - /* GL_QCOM_driver_control */ FINDSYM(glsym_glGetDriverControlsQCOM, "glGetDriverControlsQCOM", glsym_func_void); FINDSYM(glsym_glGetDriverControlStringQCOM, "glGetDriverControlStringQCOM", glsym_func_void); FINDSYM(glsym_glEnableDriverControlQCOM, "glEnableDriverControlQCOM", glsym_func_void); FINDSYM(glsym_glDisableDriverControlQCOM, "glDisableDriverControlQCOM", glsym_func_void); - if (glsym_glGetDriverControlsQCOM) _gl_ext_entries[7].supported = 1; - /* GL_QCOM_extended_get */ FINDSYM(glsym_glExtGetTexturesQCOM, "glExtGetTexturesQCOM", glsym_func_void); FINDSYM(glsym_glExtGetBuffersQCOM, "glExtGetBuffersQCOM", glsym_func_void); @@ -580,15 +578,18 @@ _gl_ext_sym_init(void) FINDSYM(glsym_glExtGetTexSubImageQCOM, "glExtGetTexSubImageQCOM", glsym_func_void); FINDSYM(glsym_glExtGetBufferPointervQCOM, "glExtGetBufferPointervQCOM", glsym_func_void); - if (glsym_glExtGetTexturesQCOM) _gl_ext_entries[8].supported = 1; - /* GL_QCOM_extended_get2 */ FINDSYM(glsym_glExtGetShadersQCOM, "glExtGetShadersQCOM", glsym_func_void); FINDSYM(glsym_glExtGetProgramsQCOM, "glExtGetProgramsQCOM", glsym_func_void); FINDSYM(glsym_glExtIsProgramBinaryQCOM, "glExtIsProgramBinaryQCOM", glsym_func_uchar); 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); + } static void @@ -626,7 +627,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 @@ -2852,7 +2853,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; @@ -2876,7 +2877,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) @@ -2884,7 +2888,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); } @@ -2903,7 +2910,7 @@ _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 return 1; @@ -2919,21 +2926,29 @@ _print_gl_surface_cap(Render_Engine *re, int error) 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("---------------------------------------------------"); + 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 } @@ -2941,8 +2956,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; @@ -2950,30 +2966,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); - 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); #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - 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; + + 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_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); + 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_OES, GL_DEPTH24_STENCIL8_OES); -#else - 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[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; - 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); + 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.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, 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); @@ -2988,14 +3044,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,35 +3064,35 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C return 0; } - switch(cfg->depth_bits) + switch((int)cfg->depth_bits) { 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,49 +3102,49 @@ _set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_C return 0; } - switch(cfg->stencil_bits) + switch((int)cfg->stencil_bits) { 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; } @@ -3110,6 +3166,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; } @@ -3160,8 +3232,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); } @@ -3183,8 +3257,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); @@ -3194,8 +3275,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); @@ -3280,6 +3368,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)) { -- 2.7.4