From 0d439b46f9922de5029e3eb3a9271c2ac585803f Mon Sep 17 00:00:00 2001 From: Seungsoo Woo Date: Tue, 25 Oct 2011 15:58:01 +0900 Subject: [PATCH] Evas GL Extensions + a bug fix by Sung W. Park from svn(64139) Change-Id: Id8cb2692f8dcb92fc9b6e6b8f61d4764b7e77470 --- src/lib/Evas_GL.h | 313 +++++- src/lib/canvas/evas_gl.c | 16 + src/lib/include/evas_private.h | 2 + src/modules/engines/gl_x11/evas_engine.c | 1044 ++++++++++++++++---- src/modules/engines/software_generic/evas_engine.c | 1 + 5 files changed, 1188 insertions(+), 188 deletions(-) diff --git a/src/lib/Evas_GL.h b/src/lib/Evas_GL.h index 1307b90..d84d7c6 100644 --- a/src/lib/Evas_GL.h +++ b/src/lib/Evas_GL.h @@ -12,8 +12,9 @@ typedef struct _Evas_GL Evas_GL; typedef struct _Evas_GL_Surface Evas_GL_Surface; typedef struct _Evas_GL_Context Evas_GL_Context; typedef struct _Evas_GL_Config Evas_GL_Config; -typedef void* Evas_GL_Func; typedef struct _Evas_GL_API Evas_GL_API; +typedef void* Evas_GL_Func; +typedef void *EvasGLImage; typedef enum _Evas_GL_Color_Format { @@ -49,6 +50,9 @@ struct _Evas_GL_Config Evas_GL_Stencil_Bits stencil_bits; }; +#define EVAS_GL_EXTENSIONS 1 + + /** * @defgroup Evas_GL Rendering GL on Evas * @@ -246,6 +250,8 @@ on_pixels(void *data, Evas_Object *obj) // Draw a Triangle gl->glEnable(GL_BLEND); + gl->glUseProgram(gld->program); + gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); gl->glEnableVertexAttribArray(0); @@ -430,6 +436,14 @@ EAPI void evas_gl_context_destroy (Evas_GL *evas_gl, Evas EAPI Eina_Bool evas_gl_make_current (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *ctx) EINA_ARG_NONNULL(1,2); /** + * Returns a pointer to a static, zero-terminated string describing some aspect of evas_gl. + * + * @param evas_gl The given Evas_GL object. + * @param name Specifies a symbolic constant, one of EVAS_GL_EXTENSIONS... + */ +EAPI const char *evas_gl_string_query (Evas_GL *evas_gl, int name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; + +/** * Returns a GL or the Glue Layer's extension function. * * @param evas_gl The given Evas_GL object. @@ -437,7 +451,6 @@ EAPI Eina_Bool evas_gl_make_current (Evas_GL *evas_gl, Evas */ EAPI Evas_GL_Func evas_gl_proc_address_get (Evas_GL *evas_gl, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1,2) EINA_PURE; - /** * Fills in the Native Surface information from the given Evas GL surface. * @@ -929,23 +942,228 @@ typedef signed long int GLsizeiptr; // Changed khronos_ssize_t //---------------------------// // GLES extension defines +/* GL_OES_compressed_ETC1_RGB8_texture */ +#define GL_ETC1_RGB8_OES 0x8D64 + +/* GL_OES_compressed_paletted_texture */ +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 + +/* GL_OES_depth24 */ +#define GL_DEPTH_COMPONENT24_OES 0x81A6 + +/* GL_OES_depth32 */ +#define GL_DEPTH_COMPONENT32_OES 0x81A7 + +/* GL_OES_get_program_binary */ +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF + +/* GL_OES_mapbuffer */ +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD + +/* GL_OES_packed_depth_stencil */ +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 + +/* GL_OES_rgb8_rgba8 */ +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 + +/* GL_OES_standard_derivatives */ +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B + +/* GL_OES_stencil1 */ +#define GL_STENCIL_INDEX1_OES 0x8D46 + +/* GL_OES_stencil4 */ +#define GL_STENCIL_INDEX4_OES 0x8D47 + +/* GL_OES_texture_3D */ +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 + +/* GL_OES_texture_float */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_half_float */ +#define GL_HALF_FLOAT_OES 0x8D61 + +/* GL_OES_texture_half_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_npot */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA + +/* GL_AMD_compressed_ATC_texture */ +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE + +/* GL_AMD_performance_monitor */ +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 + +/* GL_AMD_program_binary_Z400 */ +#define GL_Z400_BINARY_AMD 0x8740 + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 + +/* GL_EXT_discard_framebuffer */ +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 + +/* GL_EXT_multi_draw_arrays */ +/* No new tokens introduced by this extension. */ + /* GL_EXT_read_format_bgra */ -#ifndef GL_EXT_read_format_bgra #define GL_BGRA_EXT 0x80E1 #define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 -#endif /* GL_EXT_texture_filter_anisotropic */ -#ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif /* GL_EXT_texture_format_BGRA8888 */ -#ifndef GL_EXT_texture_format_BGRA8888 #define GL_BGRA_EXT 0x80E1 -#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 + +/* GL_IMG_read_format */ +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 + +/* GL_IMG_shader_binary */ +#define GL_SGX_BINARY_IMG 0x8C0A + +/* GL_IMG_texture_compression_pvrtc */ +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_fence */ +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_extended_get */ +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC + +/* GL_QCOM_extended_get2 */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 + +/* GL_QCOM_writeonly_rendering */ +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/* EvasGL_KHR_image */ +#define EVAS_GL_NATIVE_PIXMAP 0x30B0 /* evasglCreateImage target */ + +/* EvasGL_KHR_vg_parent_image */ +#define EVAS_VG_PARENT_IMAGE 0x30BA /* evasglCreateImage target */ + +/* EvasGL_KHR_gl_texture_2D_image */ +#define EVAS_GL_TEXTURE_2D 0x30B1 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_LEVEL 0x30BC /* evasglCreateImage attribute */ + +/* EvasGL_KHR_gl_texture_cubemap_image */ +#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 /* evasglCreateImage target */ + +/* EvasGL_KHR_gl_texture_3D_image */ +#define EVAS_GL_TEXTURE_3D 0x30B2 /* evasglCreateImage target */ +#define EVAS_GL_TEXTURE_ZOFFSET 0x30BD /* evasglCreateImage attribute */ + +/* EvasGL_KHR_gl_renderbuffer_image */ +#define EVAS_GL_RENDERBUFFER 0x30B9 /* evasglCreateImage target */ #else # ifndef EVAS_GL_NO_GL_H_CHECK @@ -959,6 +1177,7 @@ struct _Evas_GL_API int version; /* version 1: */ + /*------- GLES 2.0 -------*/ void (*glActiveTexture) (GLenum texture); void (*glAttachShader) (GLuint program, GLuint shader); void (*glBindAttribLocation) (GLuint program, GLuint index, const char* name); @@ -1102,6 +1321,84 @@ struct _Evas_GL_API void (*glVertexAttribPointer) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); void (*glViewport) (GLint x, GLint y, GLsizei width, GLsizei height); + /*------- GLES 2.0 Extensions -------*/ + // Notice these two names have been changed to fit Evas GL and not EGL! + /* GL_OES_EvasGL_image */ + void (*glEvasGLImageTargetTexture2DOES) (GLenum target, EvasGLImage image); + void (*glEvasGLImageTargetRenderbufferStorageOES) (GLenum target, EvasGLImage image); + + /* 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); + /* GL_OES_mapbuffer */ + void* (*glMapBufferOES) (GLenum target, GLenum access); + GLboolean (*glUnmapBufferOES) (GLenum target); + void (*glGetBufferPointervOES) (GLenum target, GLenum pname, void** params); + /* GL_OES_texture_3D */ + void (*glTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + void (*glTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + void (*glCopyTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (*glCompressedTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); + void (*glCompressedTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); + void (*glFramebufferTexture3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + + /* AMD_performance_monitor */ + void (*glGetPerfMonitorGroupsAMD) (GLint* numGroups, GLsizei groupsSize, GLuint* groups); + void (*glGetPerfMonitorCountersAMD) (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters); + void (*glGetPerfMonitorGroupStringAMD) (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString); + void (*glGetPerfMonitorCounterStringAMD) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString); + void (*glGetPerfMonitorCounterInfoAMD) (GLuint group, GLuint counter, GLenum pname, void* data); + void (*glGenPerfMonitorsAMD) (GLsizei n, GLuint* monitors); + void (*glDeletePerfMonitorsAMD) (GLsizei n, GLuint* monitors); + void (*glSelectPerfMonitorCountersAMD) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList); + void (*glBeginPerfMonitorAMD) (GLuint monitor); + void (*glEndPerfMonitorAMD) (GLuint monitor); + void (*glGetPerfMonitorCounterDataAMD) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten); + + /* GL_EXT_discard_framebuffer */ + void (*glDiscardFramebufferEXT) (GLenum target, GLsizei numAttachments, const GLenum* attachments); + + /* GL_EXT_multi_draw_arrays */ + void (*glMultiDrawArraysEXT) (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount); + void (*glMultiDrawElementsEXT) (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount); + + /* GL_NV_fence */ + void (*glDeleteFencesNV) (GLsizei n, const GLuint* fences); + void (*glGenFencesNV) (GLsizei n, GLuint* fences); + GLboolean (*glIsFenceNV) (GLuint fence); + GLboolean (*glTestFenceNV) (GLuint fence); + void (*glGetFenceivNV) (GLuint fence, GLenum pname, GLint* params); + void (*glFinishFenceNV) (GLuint fence); + void (*glSetFenceNV) (GLuint, GLenum); + + /* GL_QCOM_driver_control */ + void (*glGetDriverControlsQCOM) (GLint* num, GLsizei size, GLuint* driverControls); + void (*glGetDriverControlStringQCOM) (GLuint driverControl, GLsizei bufSize, GLsizei* length, char* driverControlString); + void (*glEnableDriverControlQCOM) (GLuint driverControl); + void (*glDisableDriverControlQCOM) (GLuint driverControl); + + /* GL_QCOM_extended_get */ + void (*glExtGetTexturesQCOM) (GLuint* textures, GLint maxTextures, GLint* numTextures); + void (*glExtGetBuffersQCOM) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers); + void (*glExtGetRenderbuffersQCOM) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers); + void (*glExtGetFramebuffersQCOM) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers); + void (*glExtGetTexLevelParameterivQCOM) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params); + void (*glExtTexObjectStateOverrideiQCOM) (GLenum target, GLenum pname, GLint param); + void (*glExtGetTexSubImageQCOM) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels); + void (*glExtGetBufferPointervQCOM) (GLenum target, void** params); + + + /* GL_QCOM_extended_get2 */ + void (*glExtGetShadersQCOM) (GLuint* shaders, GLint maxShaders, GLint* numShaders); + void (*glExtGetProgramsQCOM) (GLuint* programs, GLint maxPrograms, GLint* numPrograms); + GLboolean (*glExtIsProgramBinaryQCOM) (GLuint program); + void (*glExtGetProgramBinarySourceQCOM) (GLuint program, GLenum shadertype, char* source, GLint* length); + + //------- EGL Related Extensions -------// + /* EvasGL_KHR_image */ + EvasGLImage (*evasglCreateImage) (int target, void* buffer, int* attrib_list); + void (*evasglDestroyImage) (EvasGLImage image); + /* future calls will be added down here for expansion */ /* version 2: */ }; diff --git a/src/lib/canvas/evas_gl.c b/src/lib/canvas/evas_gl.c index 7850939..47bb583 100644 --- a/src/lib/canvas/evas_gl.c +++ b/src/lib/canvas/evas_gl.c @@ -69,6 +69,12 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int return NULL; MAGIC_CHECK_END(); + if (!config) + { + ERR("Invalid Config\n"); + return NULL; + } + surf = calloc(1, sizeof(Evas_GL_Surface)); surf->data = evas_gl->evas->engine.func->gl_surface_create(evas_gl->evas->engine.data.output, config, width, height); @@ -196,6 +202,16 @@ evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *c return ret; } +EAPI const char * +evas_gl_string_query(Evas_GL *evas_gl, int name) +{ + MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL); + return EINA_FALSE; + MAGIC_CHECK_END(); + + return (const char *)evas_gl->evas->engine.func->gl_string_query(evas_gl->evas->engine.data.output, name); +} + EAPI Evas_GL_Func evas_gl_proc_address_get(Evas_GL *evas_gl, const char *name) { diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index b1c1a49..6a56f13 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -821,9 +821,11 @@ struct _Evas_Func void *(*gl_context_create) (void *data, void *share_context); int (*gl_context_destroy) (void *data, void *context); int (*gl_make_current) (void *data, void *surface, void *context); + void *(*gl_string_query) (void *data, int name); void *(*gl_proc_address_get) (void *data, const char *name); int (*gl_native_surface_get) (void *data, void *surface, void *native_surface); void *(*gl_api_get) (void *data); + int (*image_load_error_get) (void *data, void *image); int (*font_run_end_get) (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len); diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index de297d4..6626e86 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/src/modules/engines/gl_x11/evas_engine.c @@ -17,6 +17,8 @@ typedef struct _Render_Engine Render_Engine; typedef struct _Render_Engine_GL_Surface Render_Engine_GL_Surface; typedef struct _Render_Engine_GL_Context Render_Engine_GL_Context; +typedef struct _Render_Engine_GL_Resource Render_Engine_GL_Resource; +typedef struct _Extension_Entry Extension_Entry; struct _Render_Engine { @@ -33,24 +35,25 @@ struct _Render_Engine int w, h; int vsync; + }; 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 depth_bits; + int stencil_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 rt_tex; + GLint rt_internal_fmt; + GLenum rt_fmt; + GLuint rb_depth; + GLenum rb_depth_fmt; + GLuint rb_stencil; + GLenum rb_stencil_fmt; Render_Engine_GL_Context *current_ctx; }; @@ -69,40 +72,70 @@ struct _Render_Engine_GL_Context Render_Engine_GL_Surface *current_sfc; }; +// Resources used per thread +struct _Render_Engine_GL_Resource +{ + // Resource context/surface per Thread in TLS for evasgl use +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + EGLContext context; + EGLSurface surface; +#else + GLXContext context; +#endif +}; + +// Extension Handling +struct _Extension_Entry +{ + const char *name; + const char *real_name; + int supported; +}; + static int initted = 0; static int gl_wins = 0; static Render_Engine_GL_Context *current_evgl_ctx; +static Render_Engine *current_engine; + +static char _gl_ext_string[1024]; +static char _evasgl_ext_string[1024]; + +// Resource context/surface per Thread in TLS for evasgl use +static Eina_TLS resource_key; +static Eina_List *resource_list; +LK(resource_lock); + +typedef void (*_eng_fn) (void); +typedef _eng_fn (*glsym_func_eng_fn) (); +typedef void (*glsym_func_void) (); +typedef void *(*glsym_func_void_ptr) (); +typedef int (*glsym_func_int) (); +typedef unsigned int (*glsym_func_uint) (); +typedef unsigned char (*glsym_func_uchar) (); +typedef unsigned char *(*glsym_func_uchar_ptr) (); +typedef const char *(*glsym_func_const_char_ptr) (); #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) #ifndef EGL_NATIVE_PIXMAP_KHR # define EGL_NATIVE_PIXMAP_KHR 0x30b0 #endif -typedef void (*_eng_fn) (void); - -typedef _eng_fn (*glsym_func_eng_fn) (); -typedef void (*glsym_func_void) (); -typedef void *(*glsym_func_void_ptr) (); -typedef unsigned int (*glsym_func_uint) (); - _eng_fn (*glsym_eglGetProcAddress) (const char *a) = NULL; void (*glsym_eglBindTexImage) (EGLDisplay a, EGLSurface b, int c) = NULL; void (*glsym_eglReleaseTexImage) (EGLDisplay a, EGLSurface b, int c) = NULL; void *(*glsym_eglCreateImage) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL; void (*glsym_eglDestroyImage) (EGLDisplay a, void *b) = NULL; void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL; -void *(*glsym_eglMapImageSEC) (void *a, void *b) = NULL; -unsigned int (*glsym_eglUnmapImageSEC) (void *a, void *b) = NULL; -#else -typedef void (*_eng_fn) (void); +void (*glsym_glEGLImageTargetRenderbufferStorageOES) (int a, void *b) = NULL; +void *(*glsym_eglMapImageSEC) (void *a, void *b) = NULL; +unsigned int (*glsym_eglUnmapImageSEC) (void *a, void *b) = NULL; +const char *(*glsym_eglQueryString) (EGLDisplay a, int name) = NULL; -typedef _eng_fn (*glsym_func_eng_fn) (); -typedef void (*glsym_func_void) (); -typedef int (*glsym_func_int) (); +unsigned int (*glsym_eglLockSurface) (EGLDisplay a, EGLSurface b, const int *attrib_list) = NULL; +unsigned int (*glsym_eglUnlockSurface) (EGLDisplay a, EGLSurface b) = NULL; + +#else typedef XID (*glsym_func_xid) (); -typedef unsigned int (*glsym_func_uint) (); -typedef unsigned char (*glsym_func_uchar) (); -typedef unsigned char *(*glsym_func_uchar_ptr) (); _eng_fn (*glsym_glXGetProcAddress) (const char *a) = NULL; void (*glsym_glXBindTexImage) (Display *a, GLXDrawable b, int c, int *d) = NULL; @@ -112,10 +145,172 @@ int (*glsym_glXWaitVideoSync) (int a, int b, unsigned int *c) = NULL; XID (*glsym_glXCreatePixmap) (Display *a, void *b, Pixmap c, const int *d) = NULL; void (*glsym_glXDestroyPixmap) (Display *a, XID b) = NULL; void (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d) = NULL; -int (*glsym_glxSwapIntervalSGI) (int a) = NULL; -void (*glsym_glxSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL; +int (*glsym_glXSwapIntervalSGI) (int a) = NULL; +void (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL; + +const char *(*glsym_glXQueryExtensionsString) (Display *a, int screen) = NULL; #endif +// GLES2 Extensions +void (*glsym_glGetProgramBinaryOES) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) = NULL; +void (*glsym_glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length) = NULL; +void* (*glsym_glMapBufferOES) (GLenum target, GLenum access) = NULL; +unsigned char (*glsym_glUnmapBufferOES) (GLenum target) = NULL; +void (*glsym_glGetBufferPointervOES) (GLenum target, GLenum pname, void** params) = NULL; +void (*glsym_glTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) = NULL; +void (*glsym_glTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) = NULL; +void (*glsym_glCopyTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +void (*glsym_glCompressedTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) = NULL; +void (*glsym_glCompressedTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) = NULL; +void (*glsym_glFramebufferTexture3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) = NULL; +void (*glsym_glGetPerfMonitorGroupsAMD) (GLint* numGroups, GLsizei groupsSize, GLuint* groups) = NULL; +void (*glsym_glGetPerfMonitorCountersAMD) (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters) = NULL; +void (*glsym_glGetPerfMonitorGroupStringAMD) (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString) = NULL; +void (*glsym_glGetPerfMonitorCounterStringAMD) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString) = NULL; +void (*glsym_glGetPerfMonitorCounterInfoAMD) (GLuint group, GLuint counter, GLenum pname, void* data) = NULL; +void (*glsym_glGenPerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL; +void (*glsym_glDeletePerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL; +void (*glsym_glSelectPerfMonitorCountersAMD) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList) = NULL; +void (*glsym_glBeginPerfMonitorAMD) (GLuint monitor) = NULL; +void (*glsym_glEndPerfMonitorAMD) (GLuint monitor) = NULL; +void (*glsym_glGetPerfMonitorCounterDataAMD) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten) = NULL; +void (*glsym_glDiscardFramebufferEXT) (GLenum target, GLsizei numAttachments, const GLenum* attachments) = NULL; +void (*glsym_glMultiDrawArraysEXT) (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount) = NULL; +void (*glsym_glMultiDrawElementsEXT) (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount) = NULL; +void (*glsym_glDeleteFencesNV) (GLsizei n, const GLuint* fences) = NULL; +void (*glsym_glGenFencesNV) (GLsizei n, GLuint* fences) = NULL; +unsigned char (*glsym_glIsFenceNV) (GLuint fence) = NULL; +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_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; +void (*glsym_glDisableDriverControlQCOM) (GLuint driverControl) = NULL; +void (*glsym_glExtGetTexturesQCOM) (GLuint* textures, GLint maxTextures, GLint* numTextures) = NULL; +void (*glsym_glExtGetBuffersQCOM) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers) = NULL; +void (*glsym_glExtGetRenderbuffersQCOM) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers) = NULL; +void (*glsym_glExtGetFramebuffersQCOM) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers) = NULL; +void (*glsym_glExtGetTexLevelParameterivQCOM) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params) = NULL; +void (*glsym_glExtTexObjectStateOverrideiQCOM) (GLenum target, GLenum pname, GLint param) = NULL; +void (*glsym_glExtGetTexSubImageQCOM) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels) = NULL; +void (*glsym_glExtGetBufferPointervQCOM) (GLenum target, void** params) = NULL; +void (*glsym_glExtGetShadersQCOM) (GLuint* shaders, GLint maxShaders, GLint* numShaders) = NULL; +void (*glsym_glExtGetProgramsQCOM) (GLuint* programs, GLint maxPrograms, GLint* numPrograms) = NULL; +unsigned char (*glsym_glExtIsProgramBinaryQCOM) (GLuint program) = NULL; +void (*glsym_glExtGetProgramBinarySourceQCOM) (GLuint program, GLenum shadertype, char* source, GLint* length) = NULL; + + +//------ GLES 2.0 Extensions supported in EvasGL -----// +static Extension_Entry _gl_ext_entries[] = { +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + //--- Function Extensions ---// + { "GL_OES_get_program_binary", "get_program_binary", 0 }, + { "GL_OES_mapbuffer", "mapbuffer", 0 }, + { "GL_OES_texture_3D", "texture_3D", 0 }, + { "AMD_performance_monitor", "AMD_performance_monitor", 0 }, + { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 }, + { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 }, + { "GL_NV_fence", "NV_fence", 0 }, + { "GL_QCOM_driver_control", "QCOM_driver_control", 0 }, + { "GL_QCOM_extended_get", "QCOM_extended_get", 0 }, + { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 }, + + //--- Define Extensions ---// + { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 }, + { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 }, + { "GL_OES_depth24", "depth24", 0 }, + { "GL_OES_depth32", "depth32", 0 }, + { "GL_OES_EvasGL_image", "EGL_image", 0 }, + { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 }, + { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 }, + { "GL_OES_standard_derivatives", "standard_derivatives", 0 }, + { "GL_OES_stencil1", "stencil1", 0 }, + { "GL_OES_stencil4", "stencil4", 0 }, + { "GL_OES_texture_float", "texture_float", 0 }, + { "GL_OES_texture_half_float", "texture_half_float", 0 }, + { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 }, + { "GL_OES_texture_npot", "texture_npot", 0 }, + { "GL_OES_vertex_half_float", "vertex_half_float", 0 }, + { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 }, + { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 }, + { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 }, + { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 }, + { "GL_EXT_blend_minmax", "blend_minmax", 0 }, + { "GL_EXT_read_format_bgra", "read_format_bgra", 0 }, + { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 }, + { "GL_EXT_texture_format_BGRA8888", "texture_format_BGRA8888", 0 }, + { "GL_EXT_texture_type_2_10_10_10_REV", "texture_type_2_10_10_10_rev", 0 }, + { "GL_IMG_program_binary", "IMG_program_binary", 0 }, + { "GL_IMG_read_format", "IMG_read_format", 0 }, + { "GL_IMG_shader_binary", "IMG_shader_binary", 0 }, + { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 }, + { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 }, + { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 }, +#else + //--- Function Extensions ---// + { "GL_OES_get_program_binary", "get_program_binary", 0 }, + { "GL_OES_mapbuffer", "mapbuffer", 0 }, + { "GL_OES_texture_3D", "texture_3D", 0 }, + { "AMD_performance_monitor", "AMD_performance_monitor", 0 }, + { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 }, + { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 }, + { "GL_NV_fence", "NV_fence", 0 }, + { "GL_QCOM_driver_control", "QCOM_driver_control", 0 }, + { "GL_QCOM_extended_get", "QCOM_extended_get", 0 }, + { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 }, + + //--- Define Extensions ---// + { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 }, + { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 }, + { "GL_OES_depth24", "depth24", 0 }, + { "GL_OES_depth32", "depth32", 0 }, + { "GL_OES_EvasGL_image", "EGL_image", 0 }, + { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 }, + { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 }, + { "GL_OES_standard_derivatives", "standard_derivatives", 0 }, + { "GL_OES_stencil1", "stencil1", 0 }, + { "GL_OES_stencil4", "stencil4", 0 }, + { "GL_OES_texture_float", "texture_float", 0 }, + { "GL_OES_texture_half_float", "texture_half_float", 0 }, + { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 }, + { "GL_OES_texture_npot", "texture_non_power_of_two", 0 }, // Desktop differs + { "GL_OES_vertex_half_float", "half_float_vertex", 0 }, // Desktop differs + { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 }, + { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 }, + { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 }, + { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 }, + { "GL_EXT_blend_minmax", "blend_minmax", 0 }, + { "GL_EXT_read_format_bgra", "bgra", 0 }, // Desktop differs + { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 }, + { "GL_EXT_texture_format_BGRA8888", "bgra", 0 }, // Desktop differs + { "GL_EXT_texture_type_2_10_10_10_REV", "vertex_type_2_10_10_10_rev", 0 }, // Desktop differs ??? + { "GL_IMG_program_binary", "IMG_program_binary", 0 }, + { "GL_IMG_read_format", "IMG_read_format", 0 }, + { "GL_IMG_shader_binary", "IMG_shader_binary", 0 }, + { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 }, + { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 }, + { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 }, + +#endif + { NULL, NULL, 0} +}; + +//------ Extensions supported in EvasGL -----// +static Extension_Entry _evasgl_ext_entries[] = { +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + { "EvasGL_KHR_image", "EGL_KHR_image", 0 }, + { "EvasGL_KHR_vg_parent_image", "EGL_KHR_vg_parent_image", 0 }, + { "EvasGL_KHR_gl_texture_2D_image", "EGL_KHR_gl_texture_2D_image", 0 }, + { "EvasGL_KHR_gl_texture_cubemap_image", "EGL_KHR_gl_texture_cubemap_image", 0 }, + { "EvasGL_KHR_gl_texture_3D_image", "EGL_KHR_gl_texture_3D_image", 0 }, + { "EvasGL_KHR_gl_renderbuffer_image", "EGL_KHR_gl_renderbuffer_image", 0 }, +#else +#endif + { NULL, NULL, 0 } +}; + static void _sym_init(void) { @@ -155,8 +350,23 @@ _sym_init(void) FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void); + FINDSYM(glsym_glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES", glsym_func_void); + FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr); FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint); + + FINDSYM(glsym_eglQueryString, "eglQueryString", glsym_func_const_char_ptr); + + FINDSYM(glsym_eglLockSurface, "eglLockSurface", glsym_func_uint); + FINDSYM(glsym_eglLockSurface, "eglLockSurfaceEXT", glsym_func_uint); + FINDSYM(glsym_eglLockSurface, "eglLockSurfaceARB", glsym_func_uint); + FINDSYM(glsym_eglLockSurface, "eglLockSurfaceKHR", glsym_func_uint); + + FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurface", glsym_func_uint); + FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceEXT", glsym_func_uint); + FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceARB", glsym_func_uint); + FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceKHR", glsym_func_uint); + #else #define FINDSYM(dst, sym, typ) \ if ((!dst) && (glsym_glXGetProcAddress)) dst = (typ)glsym_glXGetProcAddress(sym); \ @@ -190,11 +400,204 @@ _sym_init(void) FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void); FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void); - FINDSYM(glsym_glxSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int); - FINDSYM(glsym_glxSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int); + FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int); + FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int); + + FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void); - FINDSYM(glsym_glxSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void); + FINDSYM(glsym_glXQueryExtensionsString, "glXQueryExtensionsString", glsym_func_const_char_ptr); #endif + + //----------- 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); + FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryARB", glsym_func_void); + FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryOES", glsym_func_void); + + FINDSYM(glsym_glProgramBinaryOES, "glProgramBinary", glsym_func_void); + FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryEXT", glsym_func_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); + FINDSYM(glsym_glMapBufferOES, "glMapBufferARB", glsym_func_void_ptr); + FINDSYM(glsym_glMapBufferOES, "glMapBufferOES", glsym_func_void_ptr); + + FINDSYM(glsym_glUnmapBufferOES, "glUnmapBuffer", glsym_func_uchar); + FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferEXT", glsym_func_uchar); + FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferARB", glsym_func_uchar); + FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferOES", glsym_func_uchar); + + FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointerv", glsym_func_void); + FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervEXT", glsym_func_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); + FINDSYM(glsym_glTexImage3DOES, "glTexImage3DARB", glsym_func_void); + FINDSYM(glsym_glTexImage3DOES, "glTexImage3DOES", glsym_func_void); + + FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3D", glsym_func_void); + FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DEXT", glsym_func_void); + FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DARB", glsym_func_void); + FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DOES", glsym_func_void); + + FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3D", glsym_func_void); + FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DARB", glsym_func_void); + FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DEXT", glsym_func_void); + FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DOES", glsym_func_void); + + FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3D", glsym_func_void); + FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DARB", glsym_func_void); + FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DEXT", glsym_func_void); + FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DOES", glsym_func_void); + + FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3D", glsym_func_void); + FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DARB", glsym_func_void); + FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DEXT", glsym_func_void); + FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DOES", glsym_func_void); + + FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3D", glsym_func_void); + FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DARB", glsym_func_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); + FINDSYM(glsym_glGetPerfMonitorGroupStringAMD, "glGetPerfMonitorGroupStringAMD", glsym_func_void); + FINDSYM(glsym_glGetPerfMonitorCounterStringAMD, "glGetPerfMonitorCounterStringAMD", glsym_func_void); + FINDSYM(glsym_glGetPerfMonitorCounterInfoAMD, "glGetPerfMonitorCounterInfoAMD", glsym_func_void); + FINDSYM(glsym_glGenPerfMonitorsAMD, "glGenPerfMonitorsAMD", glsym_func_void); + FINDSYM(glsym_glDeletePerfMonitorsAMD, "glDeletePerfMonitorsAMD", glsym_func_void); + FINDSYM(glsym_glSelectPerfMonitorCountersAMD, "glSelectPerfMonitorCountersAMD", glsym_func_void); + FINDSYM(glsym_glBeginPerfMonitorAMD, "glBeginPerfMonitorAMD", glsym_func_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); + FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysEXT", glsym_func_void); + + FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElements", glsym_func_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); + FINDSYM(glsym_glIsFenceNV, "glIsFenceNV", glsym_func_uchar); + FINDSYM(glsym_glTestFenceNV, "glTestFenceNV", glsym_func_uchar); + FINDSYM(glsym_glGetFenceivNV, "glGetFenceivNV", glsym_func_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); + FINDSYM(glsym_glExtGetRenderbuffersQCOM, "glExtGetRenderbuffersQCOM", glsym_func_void); + FINDSYM(glsym_glExtGetFramebuffersQCOM, "glExtGetFramebuffersQCOM", glsym_func_void); + FINDSYM(glsym_glExtGetTexLevelParameterivQCOM, "glExtGetTexLevelParameterivQCOM", glsym_func_void); + FINDSYM(glsym_glExtTexObjectStateOverrideiQCOM, "glExtTexObjectStateOverrideiQCOM", glsym_func_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; +} + +static void +_extensions_init(Render_Engine *re) +{ + int i; + const char *glexts, *evasglexts; + + memset(_gl_ext_string, 0, 1024); + memset(_evasgl_ext_string, 0, 1024); + + // GLES 2.0 Extensions + glexts = (const char*)glGetString(GL_EXTENSIONS); + + DBG("--------GLES 2.0 Extensions--------"); + for (i = 0; _gl_ext_entries[i].name != NULL; i++) + { + if ( (strstr(glexts, _gl_ext_entries[i].name) != NULL) || + (strstr(glexts, _gl_ext_entries[i].real_name) != NULL) ) + { + _gl_ext_entries[i].supported = 1; + strcat(_gl_ext_string, _gl_ext_entries[i].name); + strcat(_gl_ext_string, " "); + DBG("\t%s", _gl_ext_entries[i].name); + } + + } + DBG(" "); + +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + // EGL Extensions + evasglexts = glsym_eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); +#else + evasglexts = glXQueryExtensionsString(re->info->info.display, + re->info->info.screen); +#endif + + DBG("--------EvasGL Extensions----------"); + for (i = 0; _evasgl_ext_entries[i].name != NULL; i++) + { + if ( (strstr(evasglexts, _evasgl_ext_entries[i].name) != NULL) || + (strstr(evasglexts, _evasgl_ext_entries[i].real_name) != NULL) ) + { + _evasgl_ext_entries[i].supported = 1; + strcat(_evasgl_ext_string, _evasgl_ext_entries[i].name); + strcat(_evasgl_ext_string, " "); + DBG("\t%s", _evasgl_ext_entries[i].name); + } + } + DBG(" "); } int _evas_engine_GL_X11_log_dom = -1; @@ -293,6 +696,138 @@ _re_winfree(Render_Engine *re) eng_window_unsurf(re->win); } +static Render_Engine_GL_Resource * +_create_internal_glue_resources(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + Render_Engine_GL_Resource *rsc; + + rsc = calloc(1, sizeof(Render_Engine_GL_Resource)); + + if (!rsc) return NULL; + +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + // EGL + int context_attrs[3]; + context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; + 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) + { + ERR("Creating internal resource surface failed."); + free(rsc); + return NULL; + } + + // Create a resource context for EGL + rsc->context = eglCreateContext(re->win->egl_disp, + re->win->egl_config, + re->win->egl_context[0], // Evas' GL Context + context_attrs); + if (!rsc->context) + { + ERR("Internal Resource Context Creations Failed."); + free(rsc); + return NULL; + } + + // Add to the resource resource list for cleanup + LKL(resource_lock); + resource_list = eina_list_prepend(resource_list, rsc); + LKU(resource_lock); + + // Set the resource in TLS + if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE) + { + ERR("Failed setting TLS Resource"); + free(rsc); + return NULL; + } + +#else + // GLX + rsc->context = glXCreateContext(re->info->info.display, + re->win->visualinfo, + re->win->context, // Evas' GL Context + 1); + if (!rsc->context) + { + ERR("Internal Resource Context Creations Failed."); + free(rsc); + return NULL; + } + + // Add to the resource resource list for cleanup + LKL(resource_lock); + resource_list = eina_list_prepend(resource_list, rsc); + LKU(resource_lock); + + // Set the resource in TLS + if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE) + { + ERR("Failed setting TLS Resource"); + free(rsc); + return NULL; + } + +#endif + + + return rsc; +} + +static int +_destroy_internal_glue_resources(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + Eina_List *l; + Render_Engine_GL_Resource *rsc; + +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + // EGL + // Delete the Resources + 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); + free(rsc); + } + eina_list_free(resource_list); + LKU(resource_lock); + + // Destroy TLS + eina_tls_free(resource_key); +#else + // GLX + // Delete the Resources + LKL(resource_lock); + EINA_LIST_FOREACH(resource_list, l, rsc) + { + if (rsc) + { + glXDestroyContext(re->info->info.display, rsc->context); + free(rsc); + } + } + eina_list_free(resource_list); + LKU(resource_lock); + + // Destroy TLS + eina_tls_free(resource_key); +#endif + + return 1; +} + + + static int eng_setup(Evas *e, void *in) { @@ -306,32 +841,33 @@ eng_setup(Evas *e, void *in) #else int eb, evb; - if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0; + if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0; #endif - re = calloc(1, sizeof(Render_Engine)); - if (!re) return 0; + re = calloc(1, sizeof(Render_Engine)); + if (!re) return 0; re->info = info; re->evas = e; - e->engine.data.output = re; + e->engine.data.output = re; re->w = e->output.w; re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, - re->info->info.drawable, + re->win = eng_window_new(re->info->info.display, + re->info->info.drawable, re->info->info.screen, - re->info->info.visual, - re->info->info.colormap, - re->info->info.depth, + re->info->info.visual, + re->info->info.colormap, + re->info->info.depth, re->w, re->h, re->info->indirect, re->info->info.destination_alpha, re->info->info.rotation); - if (!re->win) - { - free(re); - e->engine.data.output = NULL; - return 0; - } + if (!re->win) + { + free(re); + e->engine.data.output = NULL; + return 0; + } + gl_wins++; { @@ -341,14 +877,14 @@ eng_setup(Evas *e, void *in) re->xr.dpi = 75000; // dpy * 1000 - status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val); - if ((!status) || (!type)) - { - if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display); - if (re->xrdb) - status = XrmGetResource(re->xrdb, - "Xft.dpi", "Xft.Dpi", &type, &val); - } + status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val); + if ((!status) || (!type)) + { + if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display); + if (re->xrdb) + status = XrmGetResource(re->xrdb, + "Xft.dpi", "Xft.Dpi", &type, &val); + } if ((status) && (type)) { @@ -402,6 +938,12 @@ eng_setup(Evas *e, void *in) evas_common_font_init(); evas_common_draw_init(); evas_common_tilebuf_init(); + + // Initialize TLS + if (eina_tls_new(&resource_key) == EINA_FALSE) + ERR("Error creating tls key"); + DBG("TLS KEY create... %d", resource_key); + initted = 1; } } @@ -494,6 +1036,10 @@ eng_setup(Evas *e, void *in) re->vsync = 0; _sym_init(); + _extensions_init(re); + + // This is used in extensions. Not pretty but can't get display otherwise. + current_engine = re; return 1; } @@ -510,8 +1056,21 @@ eng_output_free(void *data) // NOTE: XrmGetDatabase() result is shared per connection, do not free it. // if (re->xrdb) XrmDestroyDatabase(re->xrdb); +#if 0 +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + // Destroy the resource surface + // Only required for EGL case + if (re->surface) + eglDestroySurface(re->win->egl_disp, re->surface); +#endif + + // Destroy the resource context + _destroy_internal_context(re, context); +#endif if (re->win) { + if ((initted == 1) && (gl_wins == 1)) + _destroy_internal_glue_resources(re); eng_window_free(re->win); gl_wins--; } @@ -788,21 +1347,21 @@ eng_output_flush(void *data) #ifdef VSYNC_TO_SCREEN if ((re->info->vsync)/* || (1)*/) { - if (glsym_glxSwapIntervalEXT) + if (glsym_glXSwapIntervalEXT) { if (!re->vsync) { - if (re->info->vsync) glsym_glxSwapIntervalEXT(re->win->disp, re->win->win, 1); - else glsym_glxSwapIntervalEXT(re->win->disp, re->win->win, 0); + if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1); + else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0); re->vsync = 1; } } - if (glsym_glxSwapIntervalSGI) + if (glsym_glXSwapIntervalSGI) { if (!re->vsync) { - if (re->info->vsync) glsym_glxSwapIntervalSGI(1); - else glsym_glxSwapIntervalSGI(0); + if (re->info->vsync) glsym_glXSwapIntervalSGI(1); + else glsym_glXSwapIntervalSGI(0); re->vsync = 1; } } @@ -2278,34 +2837,14 @@ _create_rt_buffers(Render_Engine *data __UNUSED__, { // Render Target texture glGenTextures(1, &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); // Depth RenderBuffer - Create storage here... if (sfc->depth_bits != EVAS_GL_DEPTH_NONE) - { - glGenRenderbuffers(1, &sfc->rb_depth); - glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth); - glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt, - sfc->w, sfc->h); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - } + glGenRenderbuffers(1, &sfc->rb_depth); // Stencil RenderBuffer - Create Storage here... if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE) - { - glGenRenderbuffers(1, &sfc->rb_stencil); - glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil); - glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt, - sfc->w, sfc->h); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - } + glGenRenderbuffers(1, &sfc->rb_stencil); return 1; } @@ -2317,7 +2856,18 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__, { int fb_status; - // FBO + // 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); + + + // Attach texture to FBO glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sfc->rt_tex, 0); @@ -2326,6 +2876,8 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__, if (sfc->depth_bits != EVAS_GL_DEPTH_NONE) { glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth); + 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); @@ -2335,6 +2887,8 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__, if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE) { glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil); + 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); @@ -2351,16 +2905,17 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__, return 1; } + static void * eng_gl_surface_create(void *data, void *config, int w, int h) { Render_Engine *re; 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; re = (Render_Engine *)data; @@ -2384,47 +2939,52 @@ eng_gl_surface_create(void *data, void *config, int w, int h) return NULL; } - // Create Render Target Texture/Buffers if not initialized - if (!sfc->initialized) + // Create internal resource context if it hasn't been created already + if ((rsc = eina_tls_get(resource_key)) == NULL) { - // 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. -#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]); -#else - ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context); -#endif - if (!ret) + if ((rsc = _create_internal_glue_resources(re)) == NULL) { - ERR("xxxMakeCurrent() failed!"); + ERR("Error creating internal resources."); free(sfc); return NULL; } + } - // Create Render texture - if (!_create_rt_buffers(re, sfc)) - { - ERR("_create_rt_buffers() failed."); - free(sfc); - return NULL; - } + // 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. +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); +#else + ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); +#endif + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + free(sfc); + return NULL; + } + + // Create Render texture + if (!_create_rt_buffers(re, sfc)) + { + ERR("_create_rt_buffers() failed."); + free(sfc); + return NULL; + } #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); + ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); #else - ret = glXMakeCurrent(re->info->info.display, None, NULL); + ret = glXMakeCurrent(re->info->info.display, None, NULL); #endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - free(sfc); - return 0; - } - sfc->initialized = 1; + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + free(sfc); + return NULL; } return sfc; @@ -2435,19 +2995,20 @@ eng_gl_surface_destroy(void *data, void *surface) { Render_Engine *re; Render_Engine_GL_Surface *sfc; + Render_Engine_GL_Resource *rsc; int ret; re = (Render_Engine *)data; sfc = (Render_Engine_GL_Surface*)surface; - // I'm using evas's original context to delete the created fbo and texture - // This is because the fbo/texture was created in the user created context - // but the context can be destroyed already... - // I don't think this is the best way but at least for now this is A WAY. + if (!sfc) return 0; + + if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; + #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]); + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); #else - ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context); + ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); #endif if (!ret) { @@ -2456,15 +3017,14 @@ eng_gl_surface_destroy(void *data, void *surface) } // Delete FBO/RBO and Texture here - if (glIsTexture(sfc->rt_tex)) - glDeleteTextures(1, &sfc->rt_tex); - - if (glIsBuffer(sfc->rb_depth)) - glDeleteRenderbuffers(1, &sfc->rb_depth); + if (sfc->rt_tex) + glDeleteTextures(1, &sfc->rt_tex); - if (glIsBuffer(sfc->rb_stencil)) - glDeleteRenderbuffers(1, &sfc->rb_stencil); + if (sfc->rb_depth) + glDeleteRenderbuffers(1, &sfc->rb_depth); + if (sfc->rb_stencil) + glDeleteRenderbuffers(1, &sfc->rb_stencil); #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -2474,6 +3034,7 @@ eng_gl_surface_destroy(void *data, void *surface) if (!ret) { ERR("xxxMakeCurrent() failed!"); + free(sfc); return 0; } @@ -2564,15 +3125,20 @@ eng_gl_context_destroy(void *data, void *context) { Render_Engine *re; Render_Engine_GL_Context *ctx; + Render_Engine_GL_Resource *rsc; int ret; re = (Render_Engine *)data; ctx = (Render_Engine_GL_Context*)context; + if (!ctx) return 0; + + if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; + // 1. Do a make current with the given context #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], - re->win->egl_surface[0], ctx->context); + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, + rsc->surface, ctx->context); #else ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); @@ -2584,8 +3150,8 @@ eng_gl_context_destroy(void *data, void *context) } // 2. Delete the FBO - if (glIsBuffer(ctx->context_fbo)) - glDeleteBuffers(1, &ctx->context_fbo); + if (ctx->context_fbo) + glDeleteFramebuffers(1, &ctx->context_fbo); // 3. Destroy the Context #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) @@ -2620,6 +3186,7 @@ eng_gl_make_current(void *data, void *surface, void *context) Render_Engine *re; Render_Engine_GL_Surface *sfc; Render_Engine_GL_Context *ctx; + Render_Engine_GL_Resource *rsc; int ret = 0; re = (Render_Engine *)data; @@ -2641,52 +3208,46 @@ eng_gl_make_current(void *data, void *surface, void *context) return 0; } - ctx->current_sfc = NULL; - sfc->current_ctx = NULL; + if (ctx) ctx->current_sfc = NULL; + if (sfc) sfc->current_ctx = NULL; current_evgl_ctx = NULL; - return ret; + return 1; } - // Don't do a make current if it's already current + // Do a make current only if it's not already current #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - if ((eglGetCurrentContext() == ctx->context) && - (eglGetCurrentSurface(EGL_READ) == re->win->egl_surface[0]) && - (eglGetCurrentSurface(EGL_DRAW) == re->win->egl_surface[0]) ) - { + if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; - DBG("Context same\n"); - return 1; - } -#else - if ((glXGetCurrentContext() == ctx->context) && - (glXGetCurrentDrawable() == re->win->win) ) + if ((eglGetCurrentContext() != ctx->context) || + (eglGetCurrentSurface(EGL_READ) != rsc->surface) || + (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) ) { - DBG("Context same\n"); - return 1; - } -#endif - - - // Flush remainder of what's in Evas' pipeline - if (re->win) - eng_window_use(NULL); - + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); - // Set the context current -#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], - re->win->egl_surface[0], ctx->context); - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; + // Do a make current + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, + rsc->surface, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } } #else - ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); - if (!ret) + if ((glXGetCurrentContext() != ctx->context) || + (glXGetCurrentDrawable() != re->win->win) ) { - ERR("xxxMakeCurrent() failed!"); - return 0; + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); + + // Do a make current + ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } } #endif @@ -2719,12 +3280,24 @@ eng_gl_make_current(void *data, void *surface, void *context) // Set the current surface/context ctx->current_sfc = sfc; sfc->current_ctx = ctx; - current_evgl_ctx = ctx; + current_evgl_ctx = ctx; return 1; } static void * +eng_gl_string_query(void *data, int name) +{ + switch(name) + { + case EVAS_GL_EXTENSIONS: + return (void*)_evasgl_ext_string; + default: + return NULL; + }; +} + +static void * eng_gl_proc_address_get(void *data __UNUSED__, const char *name) { #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) @@ -2750,8 +3323,6 @@ eng_gl_native_surface_get(void *data, void *surface, void *native_surface) ns->type = EVAS_NATIVE_SURFACE_OPENGL; ns->version = EVAS_NATIVE_SURFACE_VERSION; ns->data.opengl.texture_id = sfc->rt_tex; - //ns->data.opengl.framebuffer_id = sfc->fbo; - //ns->data.opengl.framebuffer_id = ctx->context_fbo; ns->data.opengl.x = 0; ns->data.opengl.y = 0; ns->data.opengl.w = sfc->w; @@ -2760,7 +3331,16 @@ eng_gl_native_surface_get(void *data, void *surface, void *native_surface) return 1; } -#if 1 + +static const GLubyte * +evgl_glGetString(GLenum name) +{ + if (name == GL_EXTENSIONS) + return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); + else + return glGetString(name); +} + static void evgl_glBindFramebuffer(GLenum target, GLuint framebuffer) { @@ -2855,8 +3435,50 @@ evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const #endif } +//--------------------------------// +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +// EGL Extensions +static void * +evgl_evasglCreateImage(int target, void* buffer, int *attrib_list) +{ + if (current_engine) + { + return glsym_eglCreateImage(current_engine->win->egl_disp, + EGL_NO_CONTEXT, + target, + buffer, + attrib_list); + } + else + ERR("Invalid Engine... (Can't acccess EGL Display)\n"); +} + +static void +evgl_evasglDestroyImage(EvasGLImage image) +{ + if (current_engine) + glsym_eglDestroyImage(current_engine->win->egl_disp, image); + else + ERR("Invalid Engine... (Can't acccess EGL Display)\n"); +} + +static void +evgl_glEvasGLImageTargetTexture2DOES(GLenum target, EvasGLImage image) +{ + glsym_glEGLImageTargetTexture2DOES(target, image); +} + +static void +evgl_glEvasGLImageTargetRenderbufferStorageOES(GLenum target, EvasGLImage image) +{ + glsym_glEGLImageTargetTexture2DOES(target, image); +} +#else #endif +//--------------------------------// + + static void * eng_gl_api_get(void *data) { @@ -2865,8 +3487,9 @@ eng_gl_api_get(void *data) re = (Render_Engine *)data; gl_funcs.version = EVAS_GL_API_VERSION; -#if 1 + #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, ) + // GLES 2.0 ORD(glActiveTexture); ORD(glAttachShader); ORD(glBindAttribLocation); @@ -2936,7 +3559,7 @@ eng_gl_api_get(void *data) ORD(glGetShaderInfoLog); // ORD(glGetShaderPrecisionFormat); ORD(glGetShaderSource); - ORD(glGetString); +// ORD(glGetString); ORD(glGetTexParameterfv); ORD(glGetTexParameteriv); ORD(glGetUniformfv); @@ -3009,21 +3632,82 @@ eng_gl_api_get(void *data) ORD(glViewport); #undef ORD +#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_) + // Extensions + ORD(glGetProgramBinaryOES); + ORD(glProgramBinaryOES); + ORD(glMapBufferOES); + ORD(glUnmapBufferOES); + ORD(glGetBufferPointervOES); + ORD(glTexImage3DOES); + ORD(glTexSubImage3DOES); + ORD(glCopyTexSubImage3DOES); + ORD(glCompressedTexImage3DOES); + ORD(glCompressedTexSubImage3DOES); + ORD(glFramebufferTexture3DOES); + ORD(glGetPerfMonitorGroupsAMD); + ORD(glGetPerfMonitorCountersAMD); + ORD(glGetPerfMonitorGroupStringAMD); + ORD(glGetPerfMonitorCounterStringAMD); + ORD(glGetPerfMonitorCounterInfoAMD); + ORD(glGenPerfMonitorsAMD); + ORD(glDeletePerfMonitorsAMD); + ORD(glSelectPerfMonitorCountersAMD); + ORD(glBeginPerfMonitorAMD); + ORD(glEndPerfMonitorAMD); + ORD(glGetPerfMonitorCounterDataAMD); + ORD(glDiscardFramebufferEXT); + ORD(glMultiDrawArraysEXT); + ORD(glMultiDrawElementsEXT); + ORD(glDeleteFencesNV); + ORD(glGenFencesNV); + ORD(glIsFenceNV); + ORD(glTestFenceNV); + ORD(glGetFenceivNV); + ORD(glFinishFenceNV); + ORD(glSetFenceNV); + ORD(glGetDriverControlsQCOM); + ORD(glGetDriverControlStringQCOM); + ORD(glEnableDriverControlQCOM); + ORD(glDisableDriverControlQCOM); + ORD(glExtGetTexturesQCOM); + ORD(glExtGetBuffersQCOM); + ORD(glExtGetRenderbuffersQCOM); + ORD(glExtGetFramebuffersQCOM); + ORD(glExtGetTexLevelParameterivQCOM); + ORD(glExtTexObjectStateOverrideiQCOM); + ORD(glExtGetTexSubImageQCOM); + ORD(glExtGetBufferPointervQCOM); + ORD(glExtGetShadersQCOM); + ORD(glExtGetProgramsQCOM); + ORD(glExtIsProgramBinaryQCOM); + ORD(glExtGetProgramBinarySourceQCOM); +#undef ORD + // Override functions wrapped by Evas_GL #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_) ORD(glBindFramebuffer); ORD(glBindRenderbuffer); -// GLES2.0 API compat on top of desktop gl + // GLES2.0 API compat on top of desktop gl ORD(glClearDepthf); ORD(glDepthRangef); ORD(glGetShaderPrecisionFormat); ORD(glReleaseShaderCompiler); ORD(glShaderBinary); -#undef ORD + ORD(glGetString); + +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + // GLES 2.0 Extensions that needs wrapping + ORD(evasglCreateImage); + ORD(evasglDestroyImage); + ORD(glEvasGLImageTargetTexture2DOES); + ORD(glEvasGLImageTargetRenderbufferStorageOES); #endif +#undef ORD + return &gl_funcs; } @@ -3224,9 +3908,9 @@ module_open(Evas_Module *em) ORD(gl_context_create); ORD(gl_context_destroy); ORD(gl_make_current); + ORD(gl_string_query); ORD(gl_proc_address_get); ORD(gl_native_surface_get); - ORD(gl_api_get); ORD(image_load_error_get); diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c index ceed58a..4666798 100644 --- a/src/modules/engines/software_generic/evas_engine.c +++ b/src/modules/engines/software_generic/evas_engine.c @@ -1166,6 +1166,7 @@ static Evas_Func func = NULL, // FIXME: need software mesa for gl rendering <- gl_context_create NULL, // FIXME: need software mesa for gl rendering <- gl_context_destroy NULL, // FIXME: need software mesa for gl rendering <- gl_make_current + NULL, // FIXME: need software mesa for gl rendering <- gl_string_query NULL, // FIXME: need software mesa for gl rendering <- gl_proc_address_get NULL, // FIXME: need software mesa for gl rendering <- gl_native_surface_get NULL, // FIXME: need software mesa for gl rendering <- gl_api_get -- 2.7.4