diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 5d7d8b4266..ec41bbbd7a 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -1049,3 +1049,11 @@ * Fix native surface crash when setting to null in some situations. + +2012-09-24 Sung W. Park (sung_) + + * Refactored Evas GL engine code so wayland_egl and gl_x11 and other + engines can share the same code. The common codes are in gl_common/ + directory and evas_engine just has to implement a few engine functions. + + diff --git a/legacy/evas/src/modules/engines/gl_common/Makefile.am b/legacy/evas/src/modules/engines/gl_common/Makefile.am index 0265316160..803ec8f560 100644 --- a/legacy/evas/src/modules/engines/gl_common/Makefile.am +++ b/legacy/evas/src/modules/engines/gl_common/Makefile.am @@ -26,6 +26,9 @@ evas_gl_font.c \ evas_gl_polygon.c \ evas_gl_line.c \ evas_gl_filter.c \ +evas_gl_core.c \ +evas_gl_api.c \ +evas_gl_api_ext.c \ shader/rect_frag.h \ shader/rect_vert.h \ shader/font_frag.h \ diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_api.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_api.c new file mode 100644 index 0000000000..d705b8a0c7 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_api.c @@ -0,0 +1,2696 @@ +#include "evas_gl_core_private.h" +#include "evas_gl_api_ext.h" + +#define EVGL_FUNC_BEGIN() +#define EVGL_FUNC_END() +#define _EVGL_INT_INIT_VALUE -3 + +void +evgl_glActiveTexture(GLenum texture) +{ + EVGL_FUNC_BEGIN(); + glActiveTexture(texture); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glAttachShader(GLuint program, GLuint shader) +{ + EVGL_FUNC_BEGIN(); + glAttachShader(program, shader); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBindAttribLocation(GLuint program, GLuint index, const char* name) +{ + EVGL_FUNC_BEGIN(); + glBindAttribLocation(program, index, name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBindBuffer(GLenum target, GLuint buffer) +{ + EVGL_FUNC_BEGIN(); + glBindBuffer(target, buffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBindFramebuffer(GLenum target, GLuint framebuffer) +{ + EVGL_Context *ctx = NULL; + + EVGL_FUNC_BEGIN(); + + ctx = _evgl_current_context_get(); + + if (!ctx) + { + ERR("No current context set."); + return; + } + + // Take care of BindFramebuffer 0 issue + if (framebuffer==0) + { + if (evgl_direct_enabled(evgl_engine)) + glBindFramebuffer(target, 0); + else + glBindFramebuffer(target, ctx->surface_fbo); + ctx->current_fbo = 0; + } + else + { + glBindFramebuffer(target, framebuffer); + + // Save this for restore when doing make current + ctx->current_fbo = framebuffer; + } + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ + EVGL_FUNC_BEGIN(); + glBindRenderbuffer(target, renderbuffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBindTexture(GLenum target, GLuint texture) +{ + EVGL_FUNC_BEGIN(); + glBindTexture(target, texture); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ + EVGL_FUNC_BEGIN(); + glBlendColor(red, green, blue, alpha); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBlendEquation(GLenum mode) +{ + EVGL_FUNC_BEGIN(); + glBlendEquation(mode); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + EVGL_FUNC_BEGIN(); + glBlendEquationSeparate(modeRGB, modeAlpha); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBlendFunc(GLenum sfactor, GLenum dfactor) +{ + EVGL_FUNC_BEGIN(); + glBlendFunc(sfactor, dfactor); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +{ + EVGL_FUNC_BEGIN(); + glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) +{ + EVGL_FUNC_BEGIN(); + glBufferData(target, size, data, usage); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) +{ + EVGL_FUNC_BEGIN(); + glBufferSubData(target, offset, size, data); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +GLenum +evgl_glCheckFramebufferStatus(GLenum target) +{ + GLenum ret = GL_NONE; + + EVGL_FUNC_BEGIN(); + ret = glCheckFramebufferStatus(target); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glClear(GLbitfield mask) +{ + EVGL_FUNC_BEGIN(); + glClear(mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +void +evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ + EVGL_FUNC_BEGIN(); + glClearColor(red, green, blue, alpha); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glClearDepthf(GLclampf depth) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glClearDepthf(depth); +#else + glClearDepth(depth); +#endif + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glClearStencil(GLint s) +{ + EVGL_FUNC_BEGIN(); + glClearStencil(s); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + EVGL_FUNC_BEGIN(); + glColorMask(red, green, blue, alpha); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glCompileShader(GLuint shader) +{ + EVGL_FUNC_BEGIN(); + glCompileShader(shader); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) +{ + EVGL_FUNC_BEGIN(); + glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) +{ + EVGL_FUNC_BEGIN(); + glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + EVGL_FUNC_BEGIN(); + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVGL_FUNC_BEGIN(); + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +GLuint +evgl_glCreateProgram(void) +{ + GLuint ret = _EVGL_INT_INIT_VALUE; + + EVGL_FUNC_BEGIN(); + ret = glCreateProgram(); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLuint +evgl_glCreateShader(GLenum type) +{ + GLuint ret = _EVGL_INT_INIT_VALUE; + EVGL_FUNC_BEGIN(); + ret = glCreateShader(type); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +void +evgl_glCullFace(GLenum mode) +{ + EVGL_FUNC_BEGIN(); + glCullFace(mode); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteBuffers(GLsizei n, const GLuint* buffers) +{ + EVGL_FUNC_BEGIN(); + glDeleteBuffers(n, buffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) +{ + EVGL_FUNC_BEGIN(); + glDeleteFramebuffers(n, framebuffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteProgram(GLuint program) +{ + EVGL_FUNC_BEGIN(); + glDeleteProgram(program); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) +{ + EVGL_FUNC_BEGIN(); + glDeleteRenderbuffers(n, renderbuffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteShader(GLuint shader) +{ + EVGL_FUNC_BEGIN(); + glDeleteShader(shader); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDeleteTextures(GLsizei n, const GLuint* textures) +{ + EVGL_FUNC_BEGIN(); + glDeleteTextures(n, textures); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDepthFunc(GLenum func) +{ + EVGL_FUNC_BEGIN(); + glDepthFunc(func); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDepthMask(GLboolean flag) +{ + EVGL_FUNC_BEGIN(); + glDepthMask(flag); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDepthRangef(GLclampf zNear, GLclampf zFar) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glDepthRangef(zNear, zFar); +#else + glDepthRange(zNear, zFar); +#endif + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDetachShader(GLuint program, GLuint shader) +{ + EVGL_FUNC_BEGIN(); + glDetachShader(program, shader); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glDisable(GLenum cap) +{ + EVGL_FUNC_BEGIN(); + glDisable(cap); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +void +evgl_glDisableVertexAttribArray(GLuint index) +{ + EVGL_FUNC_BEGIN(); + glDisableVertexAttribArray(index); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDrawArrays(GLenum mode, GLint first, GLsizei count) +{ + EVGL_FUNC_BEGIN(); + glDrawArrays(mode, first, count); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) +{ + EVGL_FUNC_BEGIN(); + glDrawElements(mode, count, type, indices); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glEnable(GLenum cap) +{ + EVGL_FUNC_BEGIN(); + glEnable(cap); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +void +evgl_glEnableVertexAttribArray(GLuint index) +{ + EVGL_FUNC_BEGIN(); + glEnableVertexAttribArray(index); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glFinish(void) +{ + EVGL_FUNC_BEGIN(); + glFinish(); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glFlush(void) +{ + EVGL_FUNC_BEGIN(); + glFlush(); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ + EVGL_FUNC_BEGIN(); + glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ + EVGL_FUNC_BEGIN(); + glFramebufferTexture2D(target, attachment, textarget, texture, level); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glFrontFace(GLenum mode) +{ + EVGL_FUNC_BEGIN(); + glFrontFace(mode); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) +{ + EVGL_FUNC_BEGIN(); + glGetVertexAttribfv(index, pname, params); + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetVertexAttribiv(index, pname, params); + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) +{ + EVGL_FUNC_BEGIN(); + glGetVertexAttribPointerv(index, pname, pointer); + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glHint(GLenum target, GLenum mode) +{ + EVGL_FUNC_BEGIN(); + glHint(target, mode); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGenBuffers(GLsizei n, GLuint* buffers) +{ + EVGL_FUNC_BEGIN(); + glGenBuffers(n, buffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGenerateMipmap(GLenum target) +{ + EVGL_FUNC_BEGIN(); + glGenerateMipmap(target); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGenFramebuffers(GLsizei n, GLuint* framebuffers) +{ + EVGL_FUNC_BEGIN(); + glGenFramebuffers(n, framebuffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +{ + EVGL_FUNC_BEGIN(); + glGenRenderbuffers(n, renderbuffers); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGenTextures(GLsizei n, GLuint* textures) +{ + EVGL_FUNC_BEGIN(); + glGenTextures(n, textures); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +{ + EVGL_FUNC_BEGIN(); + glGetActiveAttrib(program, index, bufsize, length, size, type, name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) +{ + EVGL_FUNC_BEGIN(); + glGetActiveUniform(program, index, bufsize, length, size, type, name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +{ + EVGL_FUNC_BEGIN(); + glGetAttachedShaders(program, maxcount, count, shaders); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +int +evgl_glGetAttribLocation(GLuint program, const char* name) +{ + int ret = _EVGL_INT_INIT_VALUE; + EVGL_FUNC_BEGIN(); + ret = glGetAttribLocation(program, name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +void +evgl_glGetBooleanv(GLenum pname, GLboolean* params) +{ + EVGL_FUNC_BEGIN(); + glGetBooleanv(pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetBufferParameteriv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +GLenum +evgl_glGetError(void) +{ + GLenum ret = GL_NONE; + + EVGL_FUNC_BEGIN(); + ret = glGetError(); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +void +evgl_glGetFloatv(GLenum pname, GLfloat* params) +{ + EVGL_FUNC_BEGIN(); + glGetFloatv(pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetIntegerv(GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetIntegerv(pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetProgramiv(GLuint program, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetProgramiv(program, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) +{ + EVGL_FUNC_BEGIN(); + glGetProgramInfoLog(program, bufsize, length, infolog); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetRenderbufferParameteriv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetShaderiv(GLuint shader, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetShaderiv(shader, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) +{ + EVGL_FUNC_BEGIN(); + glGetShaderInfoLog(shader, bufsize, length, infolog); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); +#else + if (range) + { + range[0] = -126; // floor(log2(FLT_MIN)) + range[1] = 127; // floor(log2(FLT_MAX)) + } + if (precision) + { + precision[0] = 24; // floor(-log2((1.0/16777218.0))); + } + return; + shadertype = precisiontype = 0; +#endif + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) +{ + EVGL_FUNC_BEGIN(); + glGetShaderSource(shader, bufsize, length, source); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +const GLubyte * +evgl_glGetString(GLenum name) +{ + const GLubyte *ret = NULL; + + EVGL_FUNC_BEGIN(); +#if 0 + if (name == GL_EXTENSIONS) + return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); + else + return glGetString(name); +#endif + ret = glGetString(name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +void +evgl_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) +{ + EVGL_FUNC_BEGIN(); + glGetTexParameterfv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetTexParameteriv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetUniformfv(GLuint program, GLint location, GLfloat* params) +{ + EVGL_FUNC_BEGIN(); + glGetUniformfv(program, location, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glGetUniformiv(GLuint program, GLint location, GLint* params) +{ + EVGL_FUNC_BEGIN(); + glGetUniformiv(program, location, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +int +evgl_glGetUniformLocation(GLuint program, const char* name) +{ + int ret = _EVGL_INT_INIT_VALUE; + + EVGL_FUNC_BEGIN(); + ret = glGetUniformLocation(program, name); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsBuffer(GLuint buffer) +{ + GLboolean ret = GL_FALSE; + + EVGL_FUNC_BEGIN(); + ret = glIsBuffer(buffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsEnabled(GLenum cap) +{ + GLboolean ret = GL_FALSE; + + EVGL_FUNC_BEGIN(); + ret = glIsEnabled(cap); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsFramebuffer(GLuint framebuffer) +{ + GLboolean ret = GL_FALSE; + + EVGL_FUNC_BEGIN(); + ret = glIsFramebuffer(framebuffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsProgram(GLuint program) +{ + GLboolean ret; + EVGL_FUNC_BEGIN(); + ret = glIsProgram(program); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsRenderbuffer(GLuint renderbuffer) +{ + GLboolean ret; + EVGL_FUNC_BEGIN(); + ret = glIsRenderbuffer(renderbuffer); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsShader(GLuint shader) +{ + GLboolean ret; + EVGL_FUNC_BEGIN(); + ret = glIsShader(shader); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +GLboolean +evgl_glIsTexture(GLuint texture) +{ + GLboolean ret; + EVGL_FUNC_BEGIN(); + ret = glIsTexture(texture); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); + return ret; +} + +void +evgl_glLineWidth(GLfloat width) +{ + EVGL_FUNC_BEGIN(); + glLineWidth(width); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glLinkProgram(GLuint program) +{ + EVGL_FUNC_BEGIN(); + glLinkProgram(program); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glPixelStorei(GLenum pname, GLint param) +{ + EVGL_FUNC_BEGIN(); + glPixelStorei(pname, param); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glPolygonOffset(GLfloat factor, GLfloat units) +{ + EVGL_FUNC_BEGIN(); + glPolygonOffset(factor, units); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) +{ + EVGL_FUNC_BEGIN(); + glReadPixels(x, y, width, height, format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +void +evgl_glReleaseShaderCompiler(void) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glReleaseShaderCompiler(); +#else +#endif + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +{ + EVGL_FUNC_BEGIN(); + glRenderbufferStorage(target, internalformat, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glSampleCoverage(GLclampf value, GLboolean invert) +{ + EVGL_FUNC_BEGIN(); + glSampleCoverage(value, invert); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVGL_FUNC_BEGIN(); + glScissor(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +void +evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glShaderBinary(n, shaders, binaryformat, binary, length); +#else + // FIXME: need to dlsym/getprocaddress for this + ERR("Binary Shader is not supported here yet."); + return; + n = binaryformat = length = 0; + shaders = binary = 0; +#endif + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) +{ + EVGL_FUNC_BEGIN(); + glShaderSource(shader, count, string, length); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilFunc(GLenum func, GLint ref, GLuint mask) +{ + EVGL_FUNC_BEGIN(); + glStencilFunc(func, ref, mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + EVGL_FUNC_BEGIN(); + glStencilFuncSeparate(face, func, ref, mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilMask(GLuint mask) +{ + EVGL_FUNC_BEGIN(); + glStencilMask(mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilMaskSeparate(GLenum face, GLuint mask) +{ + EVGL_FUNC_BEGIN(); + glStencilMaskSeparate(face, mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + EVGL_FUNC_BEGIN(); + glStencilOp(fail, zfail, zpass); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ + EVGL_FUNC_BEGIN(); + glStencilOpSeparate(face, fail, zfail, zpass); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) +{ + EVGL_FUNC_BEGIN(); + glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + EVGL_FUNC_BEGIN(); + glTexParameterf(target, pname, param); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +{ + EVGL_FUNC_BEGIN(); + glTexParameterfv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexParameteri(GLenum target, GLenum pname, GLint param) +{ + EVGL_FUNC_BEGIN(); + glTexParameteri(target, pname, param); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +{ + EVGL_FUNC_BEGIN(); + glTexParameteriv(target, pname, params); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) +{ + EVGL_FUNC_BEGIN(); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform1f(GLint location, GLfloat x) +{ + EVGL_FUNC_BEGIN(); + glUniform1f(location, x); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVGL_FUNC_BEGIN(); + glUniform1fv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform1i(GLint location, GLint x) +{ + EVGL_FUNC_BEGIN(); + glUniform1i(location, x); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform1iv(GLint location, GLsizei count, const GLint* v) +{ + EVGL_FUNC_BEGIN(); + glUniform1iv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform2f(GLint location, GLfloat x, GLfloat y) +{ + EVGL_FUNC_BEGIN(); + glUniform2f(location, x, y); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVGL_FUNC_BEGIN(); + glUniform2fv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform2i(GLint location, GLint x, GLint y) +{ + EVGL_FUNC_BEGIN(); + glUniform2i(location, x, y); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform2iv(GLint location, GLsizei count, const GLint* v) +{ + EVGL_FUNC_BEGIN(); + glUniform2iv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + EVGL_FUNC_BEGIN(); + glUniform3f(location, x, y, z); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVGL_FUNC_BEGIN(); + glUniform3fv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform3i(GLint location, GLint x, GLint y, GLint z) +{ + EVGL_FUNC_BEGIN(); + glUniform3i(location, x, y, z); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform3iv(GLint location, GLsizei count, const GLint* v) +{ + EVGL_FUNC_BEGIN(); + glUniform3iv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + EVGL_FUNC_BEGIN(); + glUniform4f(location, x, y, z, w); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +{ + EVGL_FUNC_BEGIN(); + glUniform4fv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +{ + EVGL_FUNC_BEGIN(); + glUniform4i(location, x, y, z, w); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniform4iv(GLint location, GLsizei count, const GLint* v) +{ + EVGL_FUNC_BEGIN(); + glUniform4iv(location, count, v); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVGL_FUNC_BEGIN(); + glUniformMatrix2fv(location, count, transpose, value); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVGL_FUNC_BEGIN(); + glUniformMatrix3fv(location, count, transpose, value); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + EVGL_FUNC_BEGIN(); + glUniformMatrix4fv(location, count, transpose, value); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glUseProgram(GLuint program) +{ + EVGL_FUNC_BEGIN(); + glUseProgram(program); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glValidateProgram(GLuint program) +{ + EVGL_FUNC_BEGIN(); + glValidateProgram(program); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib1f(GLuint indx, GLfloat x) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib1f(indx, x); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib1fv(GLuint indx, const GLfloat* values) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib1fv(indx, values); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib2f(indx, x, y); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib2fv(GLuint indx, const GLfloat* values) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib2fv(indx, values); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib3f(indx, x, y, z); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib3fv(GLuint indx, const GLfloat* values) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib3fv(indx, values); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib4f(indx, x, y, z, w); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttrib4fv(GLuint indx, const GLfloat* values) +{ + EVGL_FUNC_BEGIN(); + glVertexAttrib4fv(indx, values); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +void +evgl_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) +{ + EVGL_FUNC_BEGIN(); + glVertexAttribPointer(indx, size, type, normalized, stride, ptr); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +#ifdef NO_DIRECT_RENDERING +void +evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVGL_FUNC_BEGIN(); + glViewport(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} +#endif + +//-------------------------------------------------------------// +// Calls for stripping precision string in the shader +#if 0 + +static const char * +opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) +{ + char *start; + char *ret; + char *p; + int retlen; + static const char *delim = " \t\n\r/"; + + if (prevbuf) + free(prevbuf); + + if (s) + { + *saveptr = s; + } + else + { + if (!(*saveptr) || !(*n)) + return NULL; + s = *saveptr; + } + + for (; *n && strchr(delim, *s); s++, (*n)--) + { + if (*s == '/' && *n > 1) + { + if (s[1] == '/') + { + do { + s++, (*n)--; + } while (*n > 1 && s[1] != '\n' && s[1] != '\r'); + } + else if (s[1] == '*') + { + do { + s++, (*n)--; + } while (*n > 2 && (s[1] != '*' || s[2] != '/')); + s++, (*n)--; + s++, (*n)--; + if (*n == 0) + { + break; + } + } + else + { + break; + } + } + } + + start = s; + for (; *n && *s && !strchr(delim, *s); s++, (*n)--); + if (*n > 0) + s++, (*n)--; + + *saveptr = s; + + retlen = s - start; + ret = malloc(retlen + 1); + p = ret; + + if (retlen == 0) + { + *p = 0; + return; + } + + while (retlen > 0) + { + if (*start == '/' && retlen > 1) + { + if (start[1] == '/') + { + do { + start++, retlen--; + } while (retlen > 1 && start[1] != '\n' && start[1] != '\r'); + start++, retlen--; + continue; + } else if (start[1] == '*') + { + do { + start++, retlen--; + } while (retlen > 2 && (start[1] != '*' || start[2] != '/')); + start += 3, retlen -= 3; + continue; + } + } + *(p++) = *(start++), retlen--; + } + + *p = 0; + return ret; +} + +static char * +do_eglShaderPatch(const char *source, int length, int *patched_len) +{ + char *saveptr = NULL; + char *sp; + char *p = NULL; + + if (!length) length = strlen(source); + + *patched_len = 0; + int patched_size = length; + char *patched = malloc(patched_size + 1); + + if (!patched) return NULL; + + p = opengl_strtok(source, &length, &saveptr, NULL); + + for (; p; p = opengl_strtok(0, &length, &saveptr, p)) + { + if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) + { + continue; + } + else if (!strncmp(p, "precision", 9)) + { + while ((p = opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')); + } + else + { + if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) + { + p = "(gl_MaxVertexUniformComponents / 4)"; + } + else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) + { + p = "(gl_MaxFragmentUniformComponents / 4)"; + } + else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) + { + p = "(gl_MaxVaryingFloats / 4)"; + } + + int new_len = strlen(p); + if (*patched_len + new_len > patched_size) + { + patched_size *= 2; + patched = realloc(patched, patched_size + 1); + + if (!patched) return NULL; + } + + memcpy(patched + *patched_len, p, new_len); + *patched_len += new_len; + } + } + + patched[*patched_len] = 0; + /* check that we don't leave dummy preprocessor lines */ + for (sp = patched; *sp;) + { + for (; *sp == ' ' || *sp == '\t'; sp++); + if (!strncmp(sp, "#define", 7)) + { + for (p = sp + 7; *p == ' ' || *p == '\t'; p++); + if (*p == '\n' || *p == '\r' || *p == '/') + { + memset(sp, 0x20, 7); + } + } + for (; *sp && *sp != '\n' && *sp != '\r'; sp++); + for (; *sp == '\n' || *sp == '\r'; sp++); + } + return patched; +} + +static int +shadersrc_gles_to_gl(GLsizei count, const char** string, char **s, const GLint* length, GLint *l) +{ + int i; + + for(i = 0; i < count; ++i) { + GLint len; + if(length) { + len = length[i]; + if (len < 0) + len = string[i] ? strlen(string[i]) : 0; + } else + len = string[i] ? strlen(string[i]) : 0; + + if(string[i]) { + s[i] = do_eglShaderPatch(string[i], len, &l[i]); + if(!s[i]) { + while(i) + free(s[--i]); + + free(l); + free(s); + return -1; + } + } else { + s[i] = NULL; + l[i] = 0; + } + } + + return 0; +} + + +void +evgl_glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) +{ + EVGL_FUNC_BEGIN(); + +#ifdef GL_GLES + glShaderSource(shader, count, string, length); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; +#else + //GET_EXT_PTR(void, glShaderSource, (int, int, char **, void *)); + int size = count; + int i; + int acc_length = 0; + GLchar **tab_prog = malloc(size * sizeof(GLchar *)); + int *tab_length = (int *) length; + + char **tab_prog_new; + GLint *tab_length_new; + + tab_prog_new = malloc(count* sizeof(char*)); + tab_length_new = malloc(count* sizeof(GLint)); + + memset(tab_prog_new, 0, count * sizeof(char*)); + memset(tab_length_new, 0, count * sizeof(GLint)); + + for (i = 0; i < size; i++) { + tab_prog[i] = ((GLchar *) string) + acc_length; + acc_length += tab_length[i]; + } + + shadersrc_gles_to_gl(count, tab_prog, tab_prog_new, tab_length, tab_length_new); + + if (!tab_prog_new || !tab_length_new) + ERR("Error allocating memory for shader string manipulation."); + + glShaderSource(shader, count, tab_prog_new, tab_length_new); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + for (i = 0; i < count; i++) + free(tab_prog_new[i]); + free(tab_prog_new); + free(tab_length_new); + + free(tab_prog); +#endif + +finish: + EVGL_FUNC_END(); +} +#endif + +//-------------------------------------------------------------// + + +//-------------------------------------------------------------// +// Calls related to Evas GL Direct Rendering +//-------------------------------------------------------------// + +// Transform from Evas Coordinat to GL Coordinate +// returns: oc[4] original image object dimension in gl coord +// returns: nc[4] tranformed (x, y, width, heigth) in gl coord +static void +compute_gl_coordinates(Evas_Object *obj, int rot, int clip, + int x, int y, int width, int height, + int imgc[4], int objc[4]) +{ + if (rot == 0) + { + // oringinal image object coordinate in gl coordinate + imgc[0] = obj->cur.geometry.x; + imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h; + imgc[2] = imgc[0] + obj->cur.geometry.w; + imgc[3] = imgc[1] + obj->cur.geometry.h; + + // transformed (x,y,width,height) in gl coordinate + objc[0] = imgc[0] + x; + objc[1] = imgc[1] + y; + objc[2] = objc[0] + width; + objc[3] = objc[1] + height; + } + else if (rot == 180) + { + // oringinal image object coordinate in gl coordinate + imgc[0] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w; + imgc[1] = obj->cur.geometry.y; + imgc[2] = imgc[0] + obj->cur.geometry.w; + imgc[3] = imgc[1] + obj->cur.geometry.h; + + // transformed (x,y,width,height) in gl coordinate + objc[0] = imgc[0] + obj->cur.geometry.w - x - width; + objc[1] = imgc[1] + obj->cur.geometry.h - y - height; + objc[2] = objc[0] + width; + objc[3] = objc[1] + height; + + } + else if (rot == 90) + { + // oringinal image object coordinate in gl coordinate + imgc[0] = obj->cur.geometry.y; + imgc[1] = obj->cur.geometry.x; + imgc[2] = imgc[0] + obj->cur.geometry.h; + imgc[3] = imgc[1] + obj->cur.geometry.w; + + // transformed (x,y,width,height) in gl coordinate + objc[0] = imgc[0] + obj->cur.geometry.h - y - height; + objc[1] = imgc[1] + x; + objc[2] = objc[0] + height; + objc[3] = objc[1] + width; + } + else if (rot == 270) + { + // oringinal image object coordinate in gl coordinate + imgc[0] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h; + imgc[1] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w; + imgc[2] = imgc[0] + obj->cur.geometry.h; + imgc[3] = imgc[1] + obj->cur.geometry.w; + + // transformed (x,y,width,height) in gl coordinate + objc[0] = imgc[0] + y; + objc[1] = imgc[1] + obj->cur.geometry.w - x - width; + objc[2] = objc[0] + height; + objc[3] = objc[1] + width; + } + else + { + ERR("Invalid rotation angle %d.", rot); + return; + } + + if (clip) + { + // Clip against original image object + if (objc[0] < imgc[0]) objc[0] = imgc[0]; + if (objc[0] > imgc[2]) objc[0] = 0; + + if (objc[1] < imgc[1]) objc[1] = imgc[1]; + if (objc[1] > imgc[3]) objc[1] = 0; + + if (objc[2] < imgc[0]) objc[0] = 0; + if (objc[2] > imgc[2]) objc[2] = imgc[2]; + + if (objc[3] < imgc[1]) objc[1] = 0; + if (objc[3] > imgc[3]) objc[3] = imgc[3]; + } + + imgc[2] = imgc[2]-imgc[0]; // width + imgc[3] = imgc[3]-imgc[1]; // height + + objc[2] = objc[2]-objc[0]; // width + objc[3] = objc[3]-objc[1]; // height +} + +static void +evgl_glClear(GLbitfield mask) +{ + EVGL_Engine *ee = evgl_engine; + EVGL_Resource *rsc; + EVGL_Context *ctx; + Evas_Object *img; + int rot = 0; + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}; + + EVGL_FUNC_BEGIN(); + + if (!(rsc=_evgl_tls_resource_get(ee))) + { + ERR("Unable to execute GL command. Error retrieving tls"); + return; + } + + ctx = rsc->current_ctx; + if (!ctx) + { + ERR("Unable to retrive Current Context"); + return; + } + + if (evgl_direct_enabled(evgl_engine)) + { + if (!(rsc->current_ctx->current_fbo)) + { + if ((!ctx->direct_scissor)) + { + glEnable(GL_SCISSOR_TEST); + ctx->direct_scissor = 1; + } + + img = rsc->direct_img_obj; + rot = ee->funcs->rotation_angle_get(ee->engine_data); + + compute_gl_coordinates(img, rot, 0, 0, 0, 0, 0, oc, nc); + + + if ((ctx->scissor_upated) && (ctx->scissor_enabled)) + { + glScissor(ctx->scissor_coord[0], ctx->scissor_coord[1], + ctx->scissor_coord[2], ctx->scissor_coord[3]); + ctx->direct_scissor = 0; + } + else + glScissor(oc[0], oc[1], oc[2], oc[3]); + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + glClear(mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glClear(mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glClear(mask); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + goto finish; + +finish: + EVGL_FUNC_END(); +} + +static void +evgl_glEnable(GLenum cap) +{ + EVGL_Context *ctx; + + EVGL_FUNC_BEGIN(); + + ctx = _evgl_current_context_get(); + + if (cap == GL_SCISSOR_TEST) + if (ctx) ctx->scissor_enabled = 1; + glEnable(cap); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + +static void +evgl_glDisable(GLenum cap) +{ + EVGL_Context *ctx; + + EVGL_FUNC_BEGIN(); + + ctx = _evgl_current_context_get(); + + if (cap == GL_SCISSOR_TEST) + if (ctx) ctx->scissor_enabled = 0; + glDisable(cap); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + goto finish; + +finish: + EVGL_FUNC_END(); +} + + +static void +evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) +{ + EVGL_Engine *ee = evgl_engine; + EVGL_Resource *rsc; + EVGL_Context *ctx; + Evas_Object *img; + int rot = 0; + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}; + + EVGL_FUNC_BEGIN(); + + if (!(rsc=_evgl_tls_resource_get(ee))) + { + ERR("Unable to execute GL command. Error retrieving tls"); + return; + } + + ctx = rsc->current_ctx; + if (!ctx) + { + ERR("Unable to retrive Current Context"); + return; + } + + if (evgl_direct_enabled(evgl_engine)) + { + + if (!(rsc->current_ctx->current_fbo)) + { + img = rsc->direct_img_obj; + rot = ee->funcs->rotation_angle_get(ee->engine_data); + + compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc); + glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + else + { + glReadPixels(x, y, width, height, format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + } + else + { + glReadPixels(x, y, width, height, format, type, pixels); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + goto finish; + +finish: + EVGL_FUNC_END(); +} + +static void +evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVGL_Engine *ee = evgl_engine; + EVGL_Resource *rsc; + EVGL_Context *ctx; + Evas_Object *img; + int rot = 0; + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}; + + EVGL_FUNC_BEGIN(); + + if (!(rsc=_evgl_tls_resource_get(ee))) + { + ERR("Unable to execute GL command. Error retrieving tls"); + return; + } + + ctx = rsc->current_ctx; + if (!ctx) + { + ERR("Unable to retrive Current Context"); + return; + } + + if (evgl_direct_enabled(evgl_engine)) + { + if (!(rsc->current_ctx->current_fbo)) + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + } + + img = rsc->direct_img_obj; + rot = ee->funcs->rotation_angle_get(ee->engine_data); + + compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc); + glScissor(nc[0], nc[1], nc[2], nc[3]); + + // Update coordinates + ctx->scissor_coord[0] = nc[0]; + ctx->scissor_coord[1] = nc[1]; + ctx->scissor_coord[2] = nc[2]; + ctx->scissor_coord[3] = nc[3]; + + ctx->direct_scissor = 0; + + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + // Check....!!!! + ctx->scissor_upated = 1; + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glScissor(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + + ctx->scissor_upated = 0; + } + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glScissor(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + goto finish; + +finish: + EVGL_FUNC_END(); +} + +static void +evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVGL_Engine *ee = evgl_engine; + EVGL_Resource *rsc; + EVGL_Context *ctx; + Evas_Object *img; + int rot = 0; + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}; + + if (!(rsc=_evgl_tls_resource_get(ee))) + { + ERR("Unable to execute GL command. Error retrieving tls"); + return; + } + + ctx = rsc->current_ctx; + if (!ctx) + { + ERR("Unable to retrive Current Context"); + return; + } + + if (evgl_direct_enabled(evgl_engine)) + { + if (!(rsc->current_ctx->current_fbo)) + { + if ((!ctx->direct_scissor)) + { + glEnable(GL_SCISSOR_TEST); + ctx->direct_scissor = 1; + } + + img = rsc->direct_img_obj; + rot = ee->funcs->rotation_angle_get(ee->engine_data); + + compute_gl_coordinates(img, rot, 0, x, y, width, height, oc, nc); + + if ((ctx->scissor_upated) && (ctx->scissor_enabled)) + { + glScissor(ctx->scissor_coord[0], ctx->scissor_coord[1], + ctx->scissor_coord[2], ctx->scissor_coord[3]); + ctx->direct_scissor = 0; + } + else + glScissor(oc[0], oc[1], oc[2], oc[3]); + + glViewport(nc[0], nc[1], nc[2], nc[3]); + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glViewport(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + } + else + { + if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) + { + glDisable(GL_SCISSOR_TEST); + ctx->direct_scissor = 0; + } + + glViewport(x, y, width, height); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } + goto finish; + +finish: + EVGL_FUNC_END(); +} +//-------------------------------------------------------------// + + + +void +_evgl_api_get(Evas_GL_API *funcs) +{ + funcs->version = EVAS_GL_API_VERSION; + +#define ORD(f) EVAS_API_OVERRIDE(f, funcs, evgl_) + // GLES 2.0 + ORD(glActiveTexture); + ORD(glAttachShader); + ORD(glBindAttribLocation); + ORD(glBindBuffer); + ORD(glBindTexture); + ORD(glBlendColor); + ORD(glBlendEquation); + ORD(glBlendEquationSeparate); + ORD(glBlendFunc); + ORD(glBlendFuncSeparate); + ORD(glBufferData); + ORD(glBufferSubData); + ORD(glCheckFramebufferStatus); + ORD(glClear); + ORD(glClearColor); + ORD(glClearDepthf); + ORD(glClearStencil); + ORD(glColorMask); + ORD(glCompileShader); + ORD(glCompressedTexImage2D); + ORD(glCompressedTexSubImage2D); + ORD(glCopyTexImage2D); + ORD(glCopyTexSubImage2D); + ORD(glCreateProgram); + ORD(glCreateShader); + ORD(glCullFace); + ORD(glDeleteBuffers); + ORD(glDeleteFramebuffers); + ORD(glDeleteProgram); + ORD(glDeleteRenderbuffers); + ORD(glDeleteShader); + ORD(glDeleteTextures); + ORD(glDepthFunc); + ORD(glDepthMask); + ORD(glDepthRangef); + ORD(glDetachShader); + ORD(glDisable); + ORD(glDisableVertexAttribArray); + ORD(glDrawArrays); + ORD(glDrawElements); + ORD(glEnable); + ORD(glEnableVertexAttribArray); + ORD(glFinish); + ORD(glFlush); + ORD(glFramebufferRenderbuffer); + ORD(glFramebufferTexture2D); + ORD(glFrontFace); + ORD(glGenBuffers); + ORD(glGenerateMipmap); + ORD(glGenFramebuffers); + ORD(glGenRenderbuffers); + ORD(glGenTextures); + ORD(glGetActiveAttrib); + ORD(glGetActiveUniform); + ORD(glGetAttachedShaders); + ORD(glGetAttribLocation); + ORD(glGetBooleanv); + ORD(glGetBufferParameteriv); + ORD(glGetError); + ORD(glGetFloatv); + ORD(glGetFramebufferAttachmentParameteriv); + ORD(glGetIntegerv); + ORD(glGetProgramiv); + ORD(glGetProgramInfoLog); + ORD(glGetRenderbufferParameteriv); + ORD(glGetShaderiv); + ORD(glGetShaderInfoLog); + ORD(glGetShaderPrecisionFormat); + ORD(glGetShaderSource); + ORD(glGetString); + ORD(glGetTexParameterfv); + ORD(glGetTexParameteriv); + ORD(glGetUniformfv); + ORD(glGetUniformiv); + ORD(glGetUniformLocation); + ORD(glGetVertexAttribfv); + ORD(glGetVertexAttribiv); + ORD(glGetVertexAttribPointerv); + ORD(glHint); + ORD(glIsBuffer); + ORD(glIsEnabled); + ORD(glIsFramebuffer); + ORD(glIsProgram); + ORD(glIsRenderbuffer); + ORD(glIsShader); + ORD(glIsTexture); + ORD(glLineWidth); + ORD(glLinkProgram); + ORD(glPixelStorei); + ORD(glPolygonOffset); + ORD(glReadPixels); + ORD(glReleaseShaderCompiler); + ORD(glRenderbufferStorage); + ORD(glSampleCoverage); + ORD(glScissor); + ORD(glShaderBinary); + ORD(glShaderSource); + ORD(glStencilFunc); + ORD(glStencilFuncSeparate); + ORD(glStencilMask); + ORD(glStencilMaskSeparate); + ORD(glStencilOp); + ORD(glStencilOpSeparate); + ORD(glTexImage2D); + ORD(glTexParameterf); + ORD(glTexParameterfv); + ORD(glTexParameteri); + ORD(glTexParameteriv); + ORD(glTexSubImage2D); + ORD(glUniform1f); + ORD(glUniform1fv); + ORD(glUniform1i); + ORD(glUniform1iv); + ORD(glUniform2f); + ORD(glUniform2fv); + ORD(glUniform2i); + ORD(glUniform2iv); + ORD(glUniform3f); + ORD(glUniform3fv); + ORD(glUniform3i); + ORD(glUniform3iv); + ORD(glUniform4f); + ORD(glUniform4fv); + ORD(glUniform4i); + ORD(glUniform4iv); + ORD(glUniformMatrix2fv); + ORD(glUniformMatrix3fv); + ORD(glUniformMatrix4fv); + ORD(glUseProgram); + ORD(glValidateProgram); + ORD(glVertexAttrib1f); + ORD(glVertexAttrib1fv); + ORD(glVertexAttrib2f); + ORD(glVertexAttrib2fv); + ORD(glVertexAttrib3f); + ORD(glVertexAttrib3fv); + ORD(glVertexAttrib4f); + ORD(glVertexAttrib4fv); + ORD(glVertexAttribPointer); + ORD(glViewport); + + ORD(glBindFramebuffer); + ORD(glBindRenderbuffer); +#undef ORD + + evgl_api_ext_get(funcs); +} + diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.c new file mode 100644 index 0000000000..4f81ccf4dc --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.c @@ -0,0 +1,286 @@ + +#include "evas_gl_api_ext.h" + +#include + + +#define MAX_EXTENSION_STRING_BUFFER 10240 + +char _gl_ext_string[10240] = { 0 }; + +#ifndef EGL_NATIVE_PIXMAP_KHR +# define EGL_NATIVE_PIXMAP_KHR 0x30b0 +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// Extension HEADER +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_BEGIN(name) +#define _EVASGL_EXT_END() +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) ret (*glextsym_##name) param = NULL; +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC +///////////////////////////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// Extension HEADER +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_BEGIN(name) int _gl_ext_support_##name = 0; +#define _EVASGL_EXT_END() +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC +///////////////////////////////////////////////////////////////////////////////////////////////////// + + +// Evas extensions from EGL extensions +#ifdef GL_GLES +static void * +evgl_evasglCreateImage(int target, void* buffer, int *attrib_list) +{ + EVGL_Engine *ee = evgl_engine; + EGLDisplay dpy = EGL_NO_DISPLAY; + + if ((ee) && (ee->funcs->display_get)) + { + dpy = (EGLDisplay)ee->funcs->display_get(ee->engine_data); + return EXT_FUNC(eglCreateImage)(dpy, EGL_NO_CONTEXT, target, buffer, attrib_list); + } + else + { + ERR("Invalid Engine... (Can't acccess EGL Display)\n"); + return NULL; + } +} + +static void +evgl_evasglDestroyImage(EvasGLImage image) +{ + EVGL_Engine *ee = evgl_engine; + EGLDisplay dpy = EGL_NO_DISPLAY; + + if ((ee) && (ee->funcs->display_get)) + { + dpy = (EGLDisplay)ee->funcs->display_get(ee->engine_data); + EXT_FUNC(eglDestroyImage)(dpy, image); + } + else + ERR("Invalid Engine... (Can't acccess EGL Display)\n"); +} + +static void +evgl_glEvasGLImageTargetTexture2D(GLenum target, EvasGLImage image) +{ + EXT_FUNC(glEGLImageTargetTexture2DOES)(target, image); +} + +static void +evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target, EvasGLImage image) +{ + EXT_FUNC(glEGLImageTargetTexture2DOES)(target, image); +} + +#else +#endif + +static int _evgl_api_ext_status = 0; + +void +evgl_api_ext_init(void *getproc, const char *glueexts) +{ + const char *glexts; + typedef void (*_getproc_fn) (void); + typedef _getproc_fn (*fp_getproc)(const char *); + + fp_getproc gp = (fp_getproc)getproc; + + memset(_gl_ext_string, 0x00, MAX_EXTENSION_STRING_BUFFER); + + +#define FINDSYM(getproc, dst, sym) \ + if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \ + if (!dst) dst = (__typeof__(dst))dlsym(RTLD_DEFAULT, sym); + + // GLES Extensions + glexts = (const char*)glGetString(GL_EXTENSIONS); + /* + // GLUE Extensions +#ifdef GL_GLES +getproc = &eglGetProcAddress; +glueexts = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); +#else +getproc = &glXGetProcAddress; +glueexts = glXQueryExtensionsString(re->info->info.display, +re->info->info.screen); +#endif + */ + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Extension HEADER + ///////////////////////////////////////////////////////////////////////////////////////////////////// +#define GETPROCADDR(sym) \ + (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym)) + +#define _EVASGL_EXT_BEGIN(name) \ + { \ + int *ext_support = &_gl_ext_support_##name; + +#define _EVASGL_EXT_END() \ + } + +#define _EVASGL_EXT_CHECK_SUPPORT(name) \ + (strstr(glexts, #name) != NULL || strstr(glueexts, #name) != NULL) + +#define _EVASGL_EXT_DISCARD_SUPPORT() \ + ext_support = 0; + +#define _EVASGL_EXT_DRVNAME(name) \ + if (_EVASGL_EXT_CHECK_SUPPORT(name)) *ext_support = 1; + +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \ + { \ + ret (**drvfunc)param = &glextsym_##name; + +#define _EVASGL_EXT_FUNCTION_END() \ + if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \ + } + +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \ + *drvfunc = name; + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC + +#undef GETPROCADDR + ///////////////////////////////////////////////////////////////////////////////////////////////////// + + + + _gl_ext_string[0] = 0x00; //NULL; + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Extension HEADER + ///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_BEGIN(name) \ + if (_gl_ext_support_##name != 0) strcat(_gl_ext_string, #name" "); + +#define _EVASGL_EXT_END() +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC + ///////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + _evgl_api_ext_status = 1; +} + +void +evgl_api_ext_get(Evas_GL_API *gl_funcs) +{ + if (_evgl_api_ext_status != 1) + { + ERR("EVGL extension is not yet initialized."); + return; + } + +#define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, glextsym_) + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Extension HEADER + ///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_BEGIN(name) \ + if (_gl_ext_support_##name != 0) \ + { +#define _EVASGL_EXT_END() \ + } +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \ + ORD(name); +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param) +#define _EVASGL_EXT_FUNCTION_PRIVATE_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN +#undef _EVASGL_EXT_FUNCTION_PRIVATE_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC + ///////////////////////////////////////////////////////////////////////////////////////////////////// +#undef ORD + +} + +const char * +evgl_api_ext_string_get() +{ + if (_evgl_api_ext_status != 1) + { + ERR("EVGL extension is not yet initialized."); + return NULL; + } + + return _gl_ext_string; +} + diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.h new file mode 100644 index 0000000000..3ab49ce132 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext.h @@ -0,0 +1,72 @@ +#ifndef _EVAS_GL_API_EXT_H +#define _EVAS_GL_API_EXT_H + +typedef char GLchar; + +#include "evas_gl_core_private.h" + +#ifdef GL_GLES +#include +#include +#else +# include +# include +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// Extension HEADER +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_BEGIN(name) +#define _EVASGL_EXT_END() +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) extern ret (*glextsym_##name) param; +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define EXT_FUNC(fname) glextsym_##fname + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// Extension HEADER +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() +#define _EVASGL_EXT_BEGIN(name) extern int _gl_ext_support_##name; +#define _EVASGL_EXT_END() +#define _EVASGL_EXT_DRVNAME(name) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) +#define _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#include "evas_gl_api_ext_def.h" + +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define EXTENSION_SUPPORT(name) (_gl_ext_support_##name == 1) + +extern void evgl_api_ext_init(void *getproc, const char *glueexts); +extern void evgl_api_ext_get(Evas_GL_API *gl_funcs); +extern const char *evgl_api_ext_string_get(); + +#endif //_EVAS_GL_API_EXT_H + diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext_def.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext_def.h new file mode 100644 index 0000000000..d5d1fa3b2b --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_api_ext_def.h @@ -0,0 +1,632 @@ + +////////////////////////////////////////////////////////////////////////////////////////////////// +#ifndef _EVASGL_EXT_BEGIN + +#define _EVASGL_EXT_USE_DEFAULT_DEFINE + +#define _EVASGL_EXT_CHECK_SUPPORT(name) +#define _EVASGL_EXT_DISCARD_SUPPORT() + +// Begin of the extension block (name : EVAS extension name) +#define _EVASGL_EXT_BEGIN(name) +// End of the extension block +#define _EVASGL_EXT_END() + +// Driver extensions to wrap (name : SPEC extension name) +#define _EVASGL_EXT_DRVNAME(name) + +// These functions will be exported to 'EVAS extension function'. +// The functions of this block must correspond with the functions list in Evas_GL.h. +// Begin of the extension function block (ret : return value, name : function name, param : parameters with bracket) +#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) ret (*name) param; +// End of the extension function block +#define _EVASGL_EXT_FUNCTION_END() + +// These functions will not be exported. Only be used in engines privately. +// Begin of the extension function block (ret : return value, name : function name, param : parameters with bracket) +#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param) +// End of the extension function block +#define _EVASGL_EXT_FUNCTION_PRIVATE_END() + +// Driver extension functions to wrap (name : SPEC extension function name) +#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) + +#endif +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN +#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param) _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) +#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED +#endif + +#ifndef _EVASGL_EXT_FUNCTION_PRIVATE_END +#define _EVASGL_EXT_FUNCTION_PRIVATE_END() _EVASGL_EXT_FUNCTION_END() +#define _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// GL/GLES EXTENSIONS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +_EVASGL_EXT_BEGIN(get_program_binary) + _EVASGL_EXT_DRVNAME(GL_OES_get_program_binary) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetProgramBinary")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const void *binary, GLint length)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glProgramBinary")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(mapbuffer) + _EVASGL_EXT_DRVNAME(GL_OES_mapbuffer) + + _EVASGL_EXT_FUNCTION_BEGIN(void *, glMapBufferOES, (GLenum target, GLenum access)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glMapBuffer")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glUnmapBufferOES, (GLenum target)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glUnmapBuffer")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetBufferPointervOES, (GLenum target, GLenum pname, void** params)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetBufferPointerv")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_3D) + _EVASGL_EXT_DRVNAME(GL_OES_texture_3D) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glTexImage3D")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(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)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glTexSubImage3D")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glCopyTexSubImage3D")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glCompressedTexImage3D")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(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)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glCompressedTexSubImage3D")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glFramebufferTexture3D")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(AMD_performance_monitor) + _EVASGL_EXT_DRVNAME(AMD_performance_monitor) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorGroupsAMD, (GLint* numGroups, GLsizei groupsSize, GLuint* groups)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorGroupsAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCountersAMD, (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorCountersAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorGroupStringAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorCounterStringAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, void* data)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorCounterInfoAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGenPerfMonitorsAMD, (GLsizei n, GLuint* monitors)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGenPerfMonitorsAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glDeletePerfMonitorsAMD, (GLsizei n, GLuint* monitors)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glDeletePerfMonitorsAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glSelectPerfMonitorCountersAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glBeginPerfMonitorAMD, (GLuint monitor)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glBeginPerfMonitorAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glEndPerfMonitorAMD, (GLuint monitor)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glEndPerfMonitorAMD")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetPerfMonitorCounterDataAMD")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(discard_framebuffer) + _EVASGL_EXT_DRVNAME(GL_EXT_discard_framebuffer) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum* attachments)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glDiscardFramebuffer")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(multi_draw_arrays) + _EVASGL_EXT_DRVNAME(GL_EXT_multi_draw_arrays) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glMultiDrawArraysEXT, (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glMultiDrawArrays")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glMultiDrawElementsEXT, (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glMultiDrawElementsARB")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(NV_fence) + _EVASGL_EXT_DRVNAME(GL_NV_fence) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteFencesNV, (GLsizei n, const GLuint* fences)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glDeleteFencesNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGenFencesNV, (GLsizei n, GLuint* fences)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGenFencesNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glIsFenceNV, (GLuint fence)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glIsFenceNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glTestFenceNV, (GLuint fence)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glTestFenceNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetFenceivNV, (GLuint fence, GLenum pname, GLint* params)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetFenceivNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glFinishFenceNV, (GLuint fence)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glFinishFenceNV")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glSetFenceNV, (GLuint, GLenum)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glSetFenceNV")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(QCOM_driver_control) + _EVASGL_EXT_DRVNAME(GL_QCOM_driver_control) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetDriverControlsQCOM, (GLint* num, GLsizei size, GLuint* driverControls)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetDriverControlsQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glGetDriverControlStringQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glEnableDriverControlQCOM, (GLuint driverControl)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glEnableDriverControlQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glDisableDriverControlQCOM, (GLuint driverControl)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glDisableDriverControlQCOM")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(QCOM_extended_get) + _EVASGL_EXT_DRVNAME(GL_QCOM_extended_get) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexturesQCOM, (GLuint* textures, GLint maxTextures, GLint* numTextures)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetTexturesQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetBuffersQCOM, (GLuint* buffers, GLint maxBuffers, GLint* numBuffers)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetBuffersQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetRenderbuffersQCOM, (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetRenderbuffersQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetFramebuffersQCOM, (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetFramebuffersQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetTexLevelParameterivQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtTexObjectStateOverrideiQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetTexSubImageQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetBufferPointervQCOM, (GLenum target, void** params)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetBufferPointervQCOM")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(QCOM_extended_get2) + _EVASGL_EXT_DRVNAME(GL_QCOM_extended_get2) + + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetShadersQCOM, (GLuint* shaders, GLint maxShaders, GLint* numShaders)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetShadersQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetProgramsQCOM, (GLuint* programs, GLint maxPrograms, GLint* numPrograms)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetProgramsQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glExtIsProgramBinaryQCOM, (GLuint program)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtIsProgramBinaryQCOM")) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, char* source, GLint* length)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glExtGetProgramBinarySourceQCOM")) + _EVASGL_EXT_FUNCTION_END() +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(multisampled_render_to_texture) + _EVASGL_EXT_DRVNAME(GL_IMG_multisampled_render_to_texture) + _EVASGL_EXT_DRVNAME(GL_EXT_multisampled_render_to_texture) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glRenderbufferStorageMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glRenderbufferStorageMultisampleIMG")) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glRenderbufferStorageMultisampleEXT")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glFramebufferTexture2DMultisample, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glFramebufferTexture2DMultisampleIMG")) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glFramebufferTexture2DMultisampleEXT")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(compressed_ETC1_RGB8_texture) + _EVASGL_EXT_DRVNAME(GL_OES_compressed_ETC1_RGB8_texture) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(compressed_paletted_texture) + _EVASGL_EXT_DRVNAME(GL_OES_compressed_paletted_texture) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(depth24) + _EVASGL_EXT_DRVNAME(GL_OES_depth24) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(depth32) + _EVASGL_EXT_DRVNAME(GL_OES_depth32) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(EGL_image) + _EVASGL_EXT_DRVNAME(GL_OES_EvasGL_image) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(packed_depth_stencil) + _EVASGL_EXT_DRVNAME(GL_OES_packed_depth_stencil) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(rgb8_rgba8) + _EVASGL_EXT_DRVNAME(GL_OES_rgb8_rgba8) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(standard_derivatives) + _EVASGL_EXT_DRVNAME(GL_OES_standard_derivatives) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(stencil1) + _EVASGL_EXT_DRVNAME(GL_OES_stencil1) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(stencil4) + _EVASGL_EXT_DRVNAME(GL_OES_stencil4) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_float) + _EVASGL_EXT_DRVNAME(GL_OES_texture_float) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_half_float) + _EVASGL_EXT_DRVNAME(GL_OES_texture_half_float) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_half_float_linear) + _EVASGL_EXT_DRVNAME(GL_OES_texture_half_float_linear) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_npot) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_OES_texture_npot) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_npot_DESKTOP) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_OES_texture_npot) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(vertex_half_float) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_OES_vertex_half_float) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(vertex_half_float_DESKTOP) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_OES_vertex_half_float) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(vertex_type_10_10_10_2) + _EVASGL_EXT_DRVNAME(GL_OES_vertex_type_10_10_10_2) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(compressed_3DC_texture) + _EVASGL_EXT_DRVNAME(GL_AMD_compressed_3DC_texture) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(compressed_ATC_texture) + _EVASGL_EXT_DRVNAME(GL_AMD_compressed_ATC_texture) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(program_binary_Z400) + _EVASGL_EXT_DRVNAME(GL_AMD_program_binary_Z400) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(blend_minmax) + _EVASGL_EXT_DRVNAME(GL_EXT_blend_minmax) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(read_format_bgra) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_read_format_bgra) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(read_format_bgra_DESKTOP) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_read_format_bgra) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_filter_anisotrophic) + _EVASGL_EXT_DRVNAME(GL_EXT_texture_filter_anisotropic) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_format_BGRA8888) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_texture_format_BGRA8888) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_format_BGRA8888_DESKTOP) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_texture_format_BGRA8888) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_type_2_10_10_10_rev) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_texture_type_2_10_10_10_REV) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(texture_type_2_10_10_10_rev_DESKTOP) // Desktop differs + _EVASGL_EXT_DRVNAME(GL_EXT_texture_type_2_10_10_10_REV) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(IMG_program_binary) + _EVASGL_EXT_DRVNAME(GL_IMG_program_binary) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(IMG_read_format) + _EVASGL_EXT_DRVNAME(GL_IMG_read_format) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(IMG_shader_binary) + _EVASGL_EXT_DRVNAME(GL_IMG_shader_binary) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(IMG_texture_compression_pvrtc) + _EVASGL_EXT_DRVNAME(GL_IMG_texture_compression_pvrtc) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(QCOM_perfmon_global_mode) + _EVASGL_EXT_DRVNAME(GL_QCOM_perfmon_global_mode) +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(QCOM_writeonly_rendering) + _EVASGL_EXT_DRVNAME(GL_QCOM_writeonly_rendering) +_EVASGL_EXT_END() +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EGL EXTENSIONS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef GL_GLES + +_EVASGL_EXT_BEGIN(EGL_KHR_image_base) + + _EVASGL_EXT_DRVNAME(EGL_KHR_image_base) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglCreateImage, (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglCreateImageKHR")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, eglDestroyImage, (EGLDisplay a, void *b)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglDestroyImageKHR")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + + _EVASGL_EXT_FUNCTION_BEGIN(EvasGLImage, evasglCreateImage, (int target, void* buffer, int *attrib_list)) + _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglCreateImage) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, evasglDestroyImage, (EvasGLImage image)) + _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglDestroyImage) + _EVASGL_EXT_FUNCTION_END() + + #ifdef _EVASGL_EXT_VERIFY + { + // Add special function pointers + evgl_evasglCreateImage_ptr = GETPROCADDR("eglCreateImageKHR"); + evgl_evasglDestroyImage_ptr = GETPROCADDR("eglDestroyImageKHR"); + } + #endif + +_EVASGL_EXT_END() + + + +_EVASGL_EXT_BEGIN(GL_OES_EGL_image) + + _EVASGL_EXT_DRVNAME(GL_OES_EGL_image) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glEGLImageTargetTexture2DOES")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glEGLImageTargetRenderbufferStorageOES")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + + _EVASGL_EXT_FUNCTION_BEGIN(void, glEvasGLImageTargetTexture2DOES, (GLenum target, EvasGLImage image)) + _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_glEvasGLImageTargetTexture2D) + _EVASGL_EXT_FUNCTION_END() + _EVASGL_EXT_FUNCTION_BEGIN(void, glEvasGLImageTargetRenderbufferStorageOES, (GLenum target, EvasGLImage image)) + _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_glEvasGLImageTargetRenderbufferStorage) + _EVASGL_EXT_FUNCTION_END() + + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif + +_EVASGL_EXT_END() + + + +_EVASGL_EXT_BEGIN(EGL_KHR_image_pixmap) + _EVASGL_EXT_DRVNAME(EGL_KHR_image_pixmap) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_image) + _EVASGL_EXT_DRVNAME(EGL_KHR_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_vg_parent_image) + _EVASGL_EXT_DRVNAME(EvasGL_KHR_vg_parent_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_2D_image) + _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_2D_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_cubemap_image) + _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_cubemap_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_3D_image) + _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_3D_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + + +_EVASGL_EXT_BEGIN(EGL_KHR_gl_renderbuffer_image) + _EVASGL_EXT_DRVNAME(EGL_KHR_gl_renderbuffer_image) + #ifdef _EVASGL_EXT_VERIFY + { + if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT(); + } + #endif +_EVASGL_EXT_END() + +#if 0 +_EVASGL_EXT_BEGIN(EGL_SEC_map_image) + _EVASGL_EXT_DRVNAME(EGL_SEC_map_image) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglMapImageSEC, void *a, void *b)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglMapImageSEC")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(unsigned int, eglUnmapImageSEC, void *a, void *b)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglUnmapImageSEC")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() +_EVASGL_EXT_END() +#endif + +#endif +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// GLX EXTENSIONS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if 0 +#ifdef GL_GLES +#else + +_EVASGL_EXT_BEGIN(GLX_EXT_swap_control) + _EVASGL_EXT_DRVNAME(GLX_EXT_swap_control) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXSwapIntervalEXT, (Display *dpy, GLXDrawable drawable, int interval)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXSwapIntervalEXT")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(GLX_SGI_swap_control) + _EVASGL_EXT_DRVNAME(GLX_SGI_swap_control) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXSwapIntervalSGI, (int interval)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXSwapIntervalSGI")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(GLX_SGI_video_sync) + _EVASGL_EXT_DRVNAME(GLX_SGI_video_sync) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXGetVideoSyncSGI, (uint *count)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXGetVideoSyncSGI")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXWaitVideoSyncSGI, (int divisor, int remainder, unsigned int *count)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXWaitVideoSyncSGI")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + +_EVASGL_EXT_END() + +_EVASGL_EXT_BEGIN(GLX_EXT_texture_from_pixmap) + _EVASGL_EXT_DRVNAME(GLX_EXT_texture_from_pixmap) + + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXBindTexImageEXT, (Display *display, GLXDrawable drawable, int buffer, const int *attrib_list)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXBindTexImageEXT")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXReleaseTexImageEXT, (Display *display, GLXDrawable drawable, int buffer)) + _EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("glXReleaseTexImageEXT")) + _EVASGL_EXT_FUNCTION_PRIVATE_END() + +_EVASGL_EXT_END() + +#endif +#endif +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#ifdef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED +#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN +#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED +#endif + +#ifdef _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED +#undef _EVASGL_EXT_FUNCTION_PRIVATE_END +#undef _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED +#endif + +#ifdef _EVASGL_EXT_USE_DEFAULT_DEFINE +#undef _EVASGL_EXT_CHECK_SUPPORT +#undef _EVASGL_EXT_DISCARD_SUPPORT +#undef _EVASGL_EXT_BEGIN +#undef _EVASGL_EXT_END +#undef _EVASGL_EXT_DRVNAME +#undef _EVASGL_EXT_FUNCTION_BEGIN +#undef _EVASGL_EXT_FUNCTION_END +#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN +#undef _EVASGL_EXT_FUNCTION_PRIVATE_END +#undef _EVASGL_EXT_FUNCTION_DRVFUNC +#endif + + diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_core.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_core.c new file mode 100755 index 0000000000..f6b27f1b68 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_core.c @@ -0,0 +1,1509 @@ +#include "evas_gl_core_private.h" +#include + +// EVGL GL Format Pair +typedef struct _GL_Format +{ + int bit; + GLenum fmt; +} GL_Format; + +// Globals +static Evas_GL_API gl_funcs; +EVGL_Engine *evgl_engine = NULL; + +static void _surface_cap_print(EVGL_Engine *ee, int error); + +//---------------------------------------------------------------// +// Internal Resources: +// - Surface and Context used for internal buffer creation +//---------------------------------------------------------------// +static int +_native_surface_pool_create(EVGL_Engine *ee) +{ + int i = 0; + int pool_num = 0; + char *s = NULL; + void *sfc = NULL, *win = NULL; + + // Check if engine is valid + if (!ee) + { + ERR("EVGL Engine not initialized!"); + return 0; + } + + // Check for evn var. Otherwise default max is 8 + s = getenv("EVAS_GL_CONTEXT_POOL_COUNT"); + if (s) pool_num = atoi(s); + if (pool_num <= 0) pool_num = 8; + ee->pool_num = pool_num; + + // Allocate surface pool + ee->surface_pool = calloc(1, sizeof(Native_Surface)*pool_num); + + if (!ee->surface_pool) + { + ERR("Error allocating native surface pool."); + goto error; + } + + for (i = 0; i < pool_num; ++i) + { + sfc = win = NULL; + + win = ee->funcs->native_window_create(ee->engine_data); + if (!win) + { + ERR("Error creating native window"); + goto error; + } + + sfc = ee->funcs->surface_create(ee->engine_data, win); + if (!sfc) + { + ERR("Error creating native surface"); + goto error; + } + + ee->surface_pool[i].window = win; + ee->surface_pool[i].surface = sfc; + } + + return 1; + +error: + for (i = 0; i < ee->pool_num; ++i) + { + win = ee->surface_pool[i].window; + sfc = ee->surface_pool[i].surface; + + if (win) + ee->funcs->native_window_destroy(ee->engine_data, win); + if (sfc) + ee->funcs->surface_destroy(ee->engine_data, sfc); + } + if (!ee->surface_pool) free(ee->surface_pool); + + return 0; +} + +static int +_native_surface_pool_destroy(EVGL_Engine *ee) +{ + int i = 0; + void *sfc = NULL, *win = NULL; + + // Check if engine is valid + if (!ee) + { + ERR("EVGL Engine not initialized!"); + return 0; + } + + for (i = 0; i < ee->pool_num; ++i) + { + win = ee->surface_pool[i].window; + sfc = ee->surface_pool[i].surface; + + if (win) + ee->funcs->native_window_destroy(ee->engine_data, win); + if (sfc) + ee->funcs->surface_destroy(ee->engine_data, sfc); + } + + if (!ee->surface_pool) free(ee->surface_pool); + + return 1; +} + +static void * +_internal_resources_create(EVGL_Engine *ee) +{ + EVGL_Resource *rsc = NULL; + + // Check if engine is valid + if (!ee) + { + ERR("EVGL Engine not initialized!"); + return NULL; + } + + // Allocate resource + rsc = calloc(1, sizeof(EVGL_Resource)); + if (!rsc) + { + ERR("Error allocating EVGL_Resource"); + return NULL; + } + + // Add to the resource resource list for cleanup + LKL(ee->resource_lock); + rsc->id = ee->resource_count++; + ee->resource_list = eina_list_prepend(ee->resource_list, rsc); + LKU(ee->resource_lock); + + // Create resource surface + // Use Evas' surface if it's in the same thread + if (rsc->id == ee->main_tid) + rsc->surface = ee->funcs->evas_surface_get(ee->engine_data); + else + if (rsc->id <= ee->pool_num) + { + rsc->surface = ee->surface_pool[rsc->id-1].surface; + ERR("Surface Pool[%d]: %p", (rsc->id-1), rsc->surface); + } + else + { + ERR("Too many threads using EvasGL."); + goto error; + } + + + //rsc->surface = ee->funcs->surface_create(ee->engine_data); + if (!rsc->surface) + { + ERR("Internal resource surface failed."); + goto error; + } + + // Create a resource context + rsc->context = ee->funcs->context_create(ee->engine_data, NULL); + if (!rsc->context) + { + ERR("Internal resource context creations failed."); + goto error; + } + + // Set the resource in TLS + if (eina_tls_set(ee->resource_key, (void*)rsc) == EINA_FALSE) + { + ERR("Failed setting TLS Resource"); + goto error; + } + + return rsc; + +error: + if (rsc->context) + ee->funcs->context_destroy(ee->engine_data, rsc->context); + if (rsc->surface) + if (rsc->id != ee->main_tid) // 0 is the main thread + ee->funcs->surface_destroy(ee->engine_data, rsc->surface); + + if (rsc) free(rsc); + + return NULL; +} + +static int +_internal_resources_destroy(EVGL_Engine *ee) +{ + EVGL_Resource *rsc = NULL; + Eina_List *l = NULL; + + // Check if engine is valid + if (!ee) + { + ERR("EVGL Engine not initialized!"); + return 0; + } + + LKL(ee->resource_lock); + EINA_LIST_FOREACH(ee->resource_list, l, rsc) + { + // Surfaces are taken care by destroying the surface pool + // Only delete contexts here. + if (rsc->context) + ee->funcs->context_destroy(ee->engine_data, rsc->context); + free(rsc); + } + eina_list_free(ee->resource_list); + LKU(ee->resource_lock); + + return 1; +} + +static int +_internal_resource_make_current(EVGL_Engine *ee, EVGL_Context *ctx) +{ + EVGL_Resource *rsc = NULL; + void *surface = NULL; + void *context = NULL; + int ret = 0; + + // Retrieve the resource object + if (!(rsc = _evgl_tls_resource_get(ee))) + { + ERR("Error retrieving resource from TLS"); + return 0; + } + + // Set context from input or from resource + if (ctx) + context = ctx->context; + else + context = (void*)rsc->context; + + // Update in case they've changed + if (rsc->id == ee->main_tid) + rsc->surface = ee->funcs->evas_surface_get(ee->engine_data); + + surface = (void*)rsc->surface; + + // Do the make current + ret = ee->funcs->make_current(ee->engine_data, surface, context, 1); + if (!ret) + { + ERR("Engine make_current with internal resources failed."); + return 0; + } + + return 1; +} + +//---------------------------------------------------------------// +// Surface Related Functions +// - Texture/ Renderbuffer Creation/ Attachment to FBO +// - Surface capability check +// - Internal config choose function +//---------------------------------------------------------------// +// Create and allocate 2D texture +void +_texture_2d_create(GLuint *tex, GLint ifmt, GLenum fmt, GLenum type, int w, int h) +{ + glGenTextures(1, tex); + glBindTexture(GL_TEXTURE_2D, *tex ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, ifmt, w, h, 0, fmt, type, NULL); + glBindTexture(GL_TEXTURE_2D, 0); +} + +// Destroy Texture +void +_texture_destroy(GLuint *tex) +{ + if (*tex) + { + glDeleteTextures(1, tex); + *tex = 0; + } +} + +// Attach 2D texture with the given format to already bound FBO +// *NOTE: attach2 here is used for depth_stencil attachment in GLES env. +void +_texture_2d_attach(GLuint tex, GLenum attach, GLenum attach2, int samples) +{ + if (samples) + { +#ifdef GL_GLES + //<<< TODO : CHECK EXTENSION SUPPORT>>> + EXT_FUNC(glFramebufferTexture2DMultisample)(GL_FRAMEBUFFER, + attach, + GL_TEXTURE_2D, tex, + 0, samples); + + if (attach2) + EXT_FUNC(glFramebufferTexture2DMultisample)(GL_FRAMEBUFFER, + attach2, + GL_TEXTURE_2D, tex, + 0, samples); +#else + ERR("MSAA not supported. Should not have come in here...!"); +#endif + } + else + { + glFramebufferTexture2D(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0); + + if (attach2) + glFramebufferTexture2D(GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0); + + } +} + +// Attach a renderbuffer with the given format to already bound FBO +void +_renderbuffer_create(GLuint *buf, GLenum fmt, int w, int h, int samples) +{ + glGenRenderbuffers(1, buf); + glBindRenderbuffer(GL_RENDERBUFFER, *buf); + if (samples) +#ifdef GL_GLES + EXT_FUNC(glRenderbufferStorageMultisample)(GL_RENDERBUFFER, samples, fmt, w, h); +#else + ERR("MSAA not supported. Should not have come in here...!"); +#endif + else + glRenderbufferStorage(GL_RENDERBUFFER, fmt, w, h); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + return; + samples = 0; +} + +void +_renderbuffer_destroy(GLuint *buf) +{ + if (*buf) + { + glDeleteRenderbuffers(1, buf); + *buf = 0; + } +} + +// Attach a renderbuffer with the given format to already bound FBO +void +_renderbuffer_attach(GLuint buf, GLenum attach) +{ + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf); +} + +// Check whether the given FBO surface config is supported by the driver +static int +_fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt, + GLenum depth_fmt, GLenum stencil_fmt, int mult_samples) +{ + GLuint fbo = 0; + GLuint color_buf = 0; + GLuint depth_buf = 0; + GLuint stencil_buf = 0; + GLuint depth_stencil_buf = 0; + int depth_stencil = 0; + int fb_status = 0; + int w = 2, h = 2; // Test it with a simple (2,2) surface. Should I test it with NPOT? + + // Gen FBO + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + // Color Buffer Texture + if ((color_ifmt) && (color_fmt)) + { + _texture_2d_create(&color_buf, color_ifmt, color_fmt, GL_UNSIGNED_BYTE, w, h); + _texture_2d_attach(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples); + } + + // Check Depth_Stencil Format First +#ifdef GL_GLES + if (depth_fmt == GL_DEPTH_STENCIL_OES) + { + _texture_2d_create(&depth_stencil_buf, depth_fmt, + depth_fmt, GL_UNSIGNED_INT_24_8_OES, w, h); + _texture_2d_attach(depth_stencil_buf, GL_DEPTH_ATTACHMENT, + GL_STENCIL_ATTACHMENT, mult_samples); + depth_stencil = 1; + } +#else + if (depth_fmt == GL_DEPTH24_STENCIL8) + { + _renderbuffer_create(&depth_stencil_buf, depth_fmt, w, h, mult_samples); + _renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT); + depth_stencil = 1; + } +#endif + + // Depth Attachment + if ((!depth_stencil) && (depth_fmt)) + { + _renderbuffer_create(&depth_buf, depth_fmt, w, h, mult_samples); + _renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT); + } + + // Stencil Attachment + if ((!depth_stencil) && (stencil_fmt)) + { + _renderbuffer_create(&stencil_buf, stencil_fmt, w, h, mult_samples); + _renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT); + } + + // Check FBO for completeness + fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + // Delete Created Resources + _texture_destroy(&color_buf); + _renderbuffer_destroy(&depth_buf); + _renderbuffer_destroy(&stencil_buf); +#ifdef GL_GLES + _texture_destroy(&depth_stencil_buf); +#else + _renderbuffer_destroy(&depth_stencil_buf); +#endif + + // Delete FBO + glBindFramebuffer(GL_FRAMEBUFFER, 0); + if (fbo) glDeleteFramebuffers(1, &fbo); + + // Return the result + if (fb_status != GL_FRAMEBUFFER_COMPLETE) + { + // Put Error Log... + return 0; + } + else + return 1; +} + +int +_surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color, + GL_Format *depth, GL_Format *stencil, int samples) +{ + int ret = 0; + + if ( (depth->bit == DEPTH_STENCIL) && (stencil->bit != STENCIL_BIT_8)) + return 0; + + ret = _fbo_surface_cap_test((GLint)color->fmt, + color->fmt, + depth->fmt, + stencil->fmt, samples); + if (ret) + { + fmt->color_bit = color->bit; + fmt->color_ifmt = (GLint)color->fmt; + fmt->color_fmt = color->fmt; + fmt->samples = samples; + + if (depth->bit == DEPTH_STENCIL) + { + // Depth Stencil Case + fmt->depth_stencil_fmt = depth->fmt; + fmt->depth_bit = DEPTH_BIT_24; + fmt->depth_fmt = 0; + fmt->stencil_bit = STENCIL_BIT_8; + fmt->stencil_fmt = 0; + } + else + { + fmt->depth_stencil_fmt = 0; + fmt->depth_bit = depth->bit; + fmt->depth_fmt = depth->fmt; + fmt->stencil_bit = stencil->bit; + fmt->stencil_fmt = stencil->fmt; + } + } + + return ret; +} + + +int +_surface_cap_check(EVGL_Engine *ee) +{ + int num_fmts = 0; + int i, j, k, m; + + GL_Format color[] = { + { COLOR_RGB_888, GL_RGB }, + { COLOR_RGBA_8888, GL_RGBA }, + { -1, -1 }, + }; + +#ifdef GL_GLES + GL_Format depth[] = { + { DEPTH_NONE, 0 }, + { DEPTH_STENCIL, GL_DEPTH_STENCIL_OES }, + { DEPTH_BIT_8, GL_DEPTH_COMPONENT }, + { DEPTH_BIT_16, GL_DEPTH_COMPONENT16 }, + { DEPTH_BIT_24, GL_DEPTH_COMPONENT24_OES }, + { DEPTH_BIT_32, GL_DEPTH_COMPONENT32_OES }, + { -1, -1 }, + }; + GL_Format stencil[] = { + { STENCIL_NONE, 0 }, + { STENCIL_BIT_1, GL_STENCIL_INDEX1_OES }, + { STENCIL_BIT_4, GL_STENCIL_INDEX4_OES }, + { STENCIL_BIT_8, GL_STENCIL_INDEX8 }, + { -1, -1 }, + }; +#else + GL_Format depth[] = { + { DEPTH_NONE, 0 }, + { DEPTH_STENCIL, GL_DEPTH24_STENCIL8 }, + { DEPTH_BIT_8, GL_DEPTH_COMPONENT }, + { DEPTH_BIT_16, GL_DEPTH_COMPONENT16 }, + { DEPTH_BIT_24, GL_DEPTH_COMPONENT24 }, + { DEPTH_BIT_32, GL_DEPTH_COMPONENT32 }, + { -1, -1 }, + }; + GL_Format stencil[] = { + { STENCIL_NONE, 0 }, + { STENCIL_BIT_1, GL_STENCIL_INDEX1 }, + { STENCIL_BIT_4, GL_STENCIL_INDEX4 }, + { STENCIL_BIT_8, GL_STENCIL_INDEX8 }, + { -1, -1 }, + }; +#endif + + int msaa_samples[4] = {0, -1, -1, -1}; // { NO_MSAA, LOW, MED, HIGH } + + EVGL_Surface_Format *fmt = NULL; + + // Check Surface Cap for MSAA + if (ee->caps.msaa_supported) + { + if ((ee->caps.msaa_samples[2] != ee->caps.msaa_samples[1]) && + (ee->caps.msaa_samples[2] != ee->caps.msaa_samples[0])) + msaa_samples[3] = ee->caps.msaa_samples[2]; // HIGH + if ((ee->caps.msaa_samples[1] != ee->caps.msaa_samples[0])) + msaa_samples[2] = ee->caps.msaa_samples[1]; // MED + if (ee->caps.msaa_samples[0]) + msaa_samples[1] = ee->caps.msaa_samples[0]; // LOW + } + + + // MSAA + for ( m = 0; m < 4; m++) + { + if (msaa_samples[m] < 0) continue; + + // Color Formats + i = 0; + while ( color[i].bit >= 0 ) + { + j = 0; + // Depth Formats + while ( depth[j].bit >= 0 ) + { + k = 0; + // Stencil Formats + while ( stencil[k].bit >= 0) + { + fmt = &ee->caps.fbo_fmts[num_fmts]; + if (_surface_cap_test(fmt, &color[i], &depth[j], &stencil[k], msaa_samples[m])) + num_fmts++; + k++; + } + j++; + } + i++; + } + } + + return num_fmts; +} + +static int +_surface_cap_init(EVGL_Engine *ee) +{ + int max_size = 0; + + // Do internal make current + if (!_internal_resource_make_current(ee, NULL)) + { + ERR("Error doing an internal resource make current"); + return 0; + } + + // Query the max width and height of the surface + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_size); + + ee->caps.max_w = max_size; + ee->caps.max_h = max_size; + DBG("Max Surface Width: %d Height: %d", ee->caps.max_w, ee->caps.max_h); + + // Check for MSAA support +#ifdef GL_GLES + int max_samples = 0; + + if (EXTENSION_SUPPORT(multisampled_render_to_texture)) + { + glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples); + + if (max_samples >= 2) + { + ee->caps.msaa_samples[0] = 2; + ee->caps.msaa_samples[1] = (max_samples>>1) < 2 ? 2 : (max_samples>>1); + ee->caps.msaa_samples[2] = max_samples; + ee->caps.msaa_supported = 1; + } + } +#endif + + int num_fmts = 0; + + // Check Surface Cap + num_fmts = _surface_cap_check(ee); + + if (num_fmts) + { + ee->caps.num_fbo_fmts = num_fmts; + _surface_cap_print(ee, 0); + DBG("Number of supported surface formats: %d", num_fmts); + return 1; + } + else + { + ERR("There are no available surface formats. Error!"); + return 0; + } +} + +static const char * +_glenum_string_get(GLenum e) +{ + switch (e) + { + case 0: + return "0"; + case GL_RGB: + return "GL_RGB"; + case GL_RGBA: + return "GL_RGBA"; + +#ifdef GL_GLES + // Depth + case GL_DEPTH_COMPONENT: + return "GL_DEPTH_COMPONENT"; + case GL_DEPTH_COMPONENT16: + return "GL_DEPTH_COMPONENT16"; + case GL_DEPTH_COMPONENT24_OES: + return "GL_DEPTH_COMPONENT24_OES"; + + // Stencil + case GL_STENCIL_INDEX: + return "GL_STENCIL_INDEX"; + case GL_STENCIL_INDEX1_OES: + return "GL_STENCIL_INDEX1_OES"; + case GL_STENCIL_INDEX4_OES: + return "GL_STENCIL_INDEX4_OES"; + case GL_STENCIL_INDEX8: + return "GL_STENCIL_INDEX8"; + + // Depth_Stencil + case GL_DEPTH_STENCIL_OES: + return "GL_DEPTH_STENCIL_OES"; +#else + // Depth + case GL_DEPTH_COMPONENT: + return "GL_DEPTH_COMPONENT"; + case GL_DEPTH_COMPONENT16: + return "GL_DEPTH_COMPONENT16"; + case GL_DEPTH_COMPONENT24: + return "GL_DEPTH_COMPONENT24"; + case GL_DEPTH_COMPONENT32: + return "GL_DEPTH_COMPONENT32"; + + // Stencil + case GL_STENCIL_INDEX: + return "GL_STENCIL_INDEX"; + case GL_STENCIL_INDEX1: + return "GL_STENCIL_INDEX1"; + case GL_STENCIL_INDEX4: + return "GL_STENCIL_INDEX4"; + case GL_STENCIL_INDEX8: + return "GL_STENCIL_INDEX8"; + + // Depth_Stencil + case GL_DEPTH24_STENCIL8: + return "GL_DEPTH24_STENCIL8"; +#endif + default: + return "ERR"; + } +} + +static void +_surface_cap_print(EVGL_Engine *ee, int error) +{ + int i = 0; +#define PRINT_LOG(...) \ + if (error) \ + ERR(__VA_ARGS__); \ + else \ + DBG(__VA_ARGS__); + + PRINT_LOG("----------------------------------------------------------------------------------------------------------------"); + PRINT_LOG(" Evas GL Supported Surface Format "); + PRINT_LOG("----------------------------------------------------------------------------------------------------------------\n"); + PRINT_LOG(" Max Surface Width: %d Height: %d", ee->caps.max_w, ee->caps.max_h); + PRINT_LOG(" Multisample Support: %d", ee->caps.msaa_supported); + //if (ee->caps.msaa_supported) + { + PRINT_LOG(" Low Samples: %d", ee->caps.msaa_samples[0]); + PRINT_LOG(" Med Samples: %d", ee->caps.msaa_samples[1]); + PRINT_LOG(" High Samples: %d", ee->caps.msaa_samples[2]); + } + PRINT_LOG("[Index] [Color Format] [------Depth Bits------] [----Stencil Bits---] [---Depth_Stencil---] [Samples]"); + +#define PRINT_SURFACE_CAP(IDX, COLOR, DEPTH, STENCIL, DS, SAMPLE) \ + { \ + PRINT_LOG(" %3d %10s %25s %25s %25s %5d", IDX, _glenum_string_get(COLOR), _glenum_string_get(DEPTH), _glenum_string_get(STENCIL), _glenum_string_get(DS), SAMPLE ); \ + } + + for (i = 0; i < ee->caps.num_fbo_fmts; ++i) + { + EVGL_Surface_Format *fmt = &ee->caps.fbo_fmts[i]; + PRINT_SURFACE_CAP(i, fmt->color_fmt, fmt->depth_fmt, fmt->stencil_fmt, fmt->depth_stencil_fmt, fmt->samples); + } + +#undef PRINT_SURFACE_CAP +#undef PRINT_LOG +} + + +//--------------------------------------------------------// +// Start from here..... +//--------------------------------------------------------// +static int +_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo) +{ + int status; + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + // Detach any previously attached buffers + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); +#ifdef GL_GLES + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); +#else + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); +#endif + + + // Render Target Texture + if (sfc->color_buf) + _texture_2d_attach(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples); + + + // Depth Stencil RenderBuffer - Attach it to FBO + if (sfc->depth_stencil_buf) + { +#ifdef GL_GLES + _texture_2d_attach(sfc->depth_stencil_buf, GL_DEPTH_ATTACHMENT, + GL_STENCIL_ATTACHMENT, sfc->msaa_samples); +#else + _renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT); +#endif + } + + // Depth RenderBuffer - Attach it to FBO + if (sfc->depth_buf) + _renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT); + + // Stencil RenderBuffer - Attach it to FBO + if (sfc->stencil_buf) + _renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT); + + // Check FBO for completeness + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + { + ERR("FBO not complete. Error Code: %x!", status); + return 0; + } + + return 1; +} + +static int +_surface_buffers_create(EVGL_Engine *ee, EVGL_Surface *sfc) +{ + GLuint fbo = 0; + int ret = 0; + + // Set the context current with resource context/surface + if (!_internal_resource_make_current(ee, NULL)) + { + ERR("Error doing an internal resource make current"); + return 0; + } + + // Create buffers + if (sfc->color_fmt) + { + _texture_2d_create(&sfc->color_buf, sfc->color_ifmt, sfc->color_fmt, + GL_UNSIGNED_BYTE, sfc->w, sfc->h); + } + + + // Depth_stencil buffers or separate buffers + if (sfc->depth_stencil_fmt) + { +#ifdef GL_GLES + _texture_2d_create(&sfc->depth_stencil_buf, sfc->depth_stencil_fmt, + sfc->depth_stencil_fmt, GL_UNSIGNED_INT_24_8_OES, + sfc->w, sfc->h); +#else + _renderbuffer_create(&sfc->depth_stencil_buf, sfc->depth_stencil_fmt, + sfc->w, sfc->h, sfc->msaa_samples); +#endif + } + else + { + if (sfc->depth_fmt) + { + _renderbuffer_create(&sfc->depth_buf, sfc->depth_fmt, sfc->w, sfc->h, + sfc->msaa_samples); + } + if (sfc->stencil_fmt) + { + _renderbuffer_create(&sfc->stencil_buf, sfc->stencil_fmt, sfc->w, + sfc->h, sfc->msaa_samples); + } + } + + // Set surface buffers with an fbo + if (!(ret = _surface_buffers_fbo_set(sfc, fbo))) + { + ERR("Attaching the surface buffers to an FBO failed."); + if (sfc->color_buf) + glDeleteTextures(1, &sfc->color_buf); + if (sfc->depth_buf) + glDeleteRenderbuffers(1, &sfc->depth_buf); + if (sfc->stencil_buf) + glDeleteRenderbuffers(1, &sfc->stencil_buf); +#ifdef GL_GLES + if (sfc->depth_stencil_buf) + glDeleteTextures(1, &sfc->depth_stencil_buf); +#else + if (sfc->depth_stencil_buf) + glDeleteRenderbuffers(1, &sfc->depth_stencil_buf); +#endif + } + + if (!ee->funcs->make_current(ee->engine_data, NULL, NULL, 0)) + { + ERR("Error doing make_current(NULL, NULL)."); + return 0; + } + return ret; +} + + +static int +_internal_config_set(EVGL_Engine *ee, EVGL_Surface *sfc, Evas_GL_Config *cfg) +{ + int i = 0, cfg_index = -1; + int color_bit = 0, depth_bit = 0, stencil_bit = 0, msaa_samples = 0; + + // Convert Config Format to bitmask friendly format + color_bit = (1 << cfg->color_format); + if (cfg->depth_bits) depth_bit = (1 << (cfg->depth_bits-1)); + if (cfg->stencil_bits) stencil_bit = (1 << (cfg->stencil_bits-1)); + if (cfg->multisample_bits) + msaa_samples = ee->caps.msaa_samples[cfg->multisample_bits-1]; + + // Run through all the available formats and choose the first match + for (i = 0; i < ee->caps.num_fbo_fmts; ++i) + { + // Check if the MSAA is supported. Fallback if not. + if ((msaa_samples) && (ee->caps.msaa_supported)) + { + if (msaa_samples > ee->caps.fbo_fmts[i].samples) + continue; + } + + if (color_bit & ee->caps.fbo_fmts[i].color_bit) + { + if (depth_bit) + { + if (!(depth_bit & ee->caps.fbo_fmts[i].depth_bit)) + continue; + } + + if (stencil_bit) + { + if (!(stencil_bit & ee->caps.fbo_fmts[i].stencil_bit)) + continue; + } + + // Set the surface format + sfc->color_ifmt = ee->caps.fbo_fmts[i].color_ifmt; + sfc->color_fmt = ee->caps.fbo_fmts[i].color_fmt; + sfc->depth_fmt = ee->caps.fbo_fmts[i].depth_fmt; + sfc->stencil_fmt = ee->caps.fbo_fmts[i].stencil_fmt; + sfc->depth_stencil_fmt = ee->caps.fbo_fmts[i].depth_stencil_fmt; + sfc->msaa_samples = ee->caps.fbo_fmts[i].samples; + + // Direct Rendering Option + if (!stencil_bit) + sfc->direct_fb_opt = cfg->options_bits & EVAS_GL_OPTIONS_DIRECT; + + cfg_index = i; + break; + } + } + + if (cfg_index < 0) + { + ERR("Unable to find the matching config format."); + return 0; + } + else + { + DBG("-------------Surface Config---------------"); + DBG("Selected Config Index: %d", cfg_index); + DBG(" Color Format : %s", _glenum_string_get(sfc->color_fmt)); + DBG(" Depth Format : %s", _glenum_string_get(sfc->depth_fmt)); + DBG(" Stencil Format : %s", _glenum_string_get(sfc->stencil_fmt)); + DBG(" D-Stencil Format : %s", _glenum_string_get(sfc->depth_stencil_fmt)); + DBG(" MSAA Samples : %d", sfc->msaa_samples); + DBG(" Direct Option : %d", sfc->direct_fb_opt); + sfc->cfg_index = cfg_index; + return 1; + } +} + +//---------------------------------------------------------------// +// Retrieve the internal resource object from TLS +//---------------------------------------------------------------// +EVGL_Resource * +_evgl_tls_resource_get(EVGL_Engine *ee) +{ + EVGL_Resource *rsc = NULL; + + // Check if engine is valid + if (!ee) + { + ERR("Invalid EVGL Engine!"); + return NULL; + } + + // Create internal resources if it hasn't been created already + if (!(rsc = eina_tls_get(ee->resource_key))) + { + if (!(rsc = _internal_resources_create(ee))) + { + ERR("Error creating internal resources."); + return NULL; + } + } + return rsc; +} + + +EVGL_Context * +_evgl_current_context_get() +{ + EVGL_Resource *rsc; + + rsc = _evgl_tls_resource_get(evgl_engine); + + if (!rsc) + { + ERR("No current context set."); + return NULL; + } + else + return rsc->current_ctx; +} + +//---------------------------------------------------------------// +// Exported functions for evas_engine to use + +// Initialize engine +// - Allocate the engine struct +// - Assign engine funcs form evas_engine +// - Create internal resources: internal context, surface for resource creation +// - Initialize extensions +// - Check surface capability +// +// This code should be called during eng_setup() in evas_engine +EVGL_Engine * +evgl_engine_create(EVGL_Interface *efunc, void *engine_data) +{ + int direct_off = 0; + char *s = NULL; + + // Check the validity of the efunc + if ((!efunc) || + (!efunc->surface_create) || + (!efunc->context_create) || + (!efunc->make_current)) + { + ERR("Invalid Engine Functions for Evas GL Engine."); + return NULL; + } + + // Allocate engine + evgl_engine = calloc(1, sizeof(EVGL_Engine)); + if (!evgl_engine) + { + ERR("Error allocating EVGL Engine. GL initialization failed."); + goto error; + } + + // Assign functions + evgl_engine->funcs = efunc; + evgl_engine->engine_data = engine_data; + + // Create a surface pool + if (!_native_surface_pool_create(evgl_engine)) + { + ERR("Error createing native surface pool"); + goto error; + } + + // Initialize Resource TLS + if (eina_tls_new(&evgl_engine->resource_key) == EINA_FALSE) + { + ERR("Error creating tls key"); + goto error; + } + DBG("TLS KEY created: %d", evgl_engine->resource_key); + + // Initialize Extensions + if (efunc->proc_address_get && efunc->ext_string_get) + evgl_api_ext_init(efunc->proc_address_get, efunc->ext_string_get(engine_data)); + else + ERR("Proc address get function not available. Extension not initialized."); + + DBG("GLUE Extension String: %s", efunc->ext_string_get(engine_data)); + DBG("GL Extension String: %s", glGetString(GL_EXTENSIONS)); + + // Surface Caps + if (!_surface_cap_init(evgl_engine)) + { + ERR("Error initializing surface cap"); + goto error; + } + + // Check if Direct Rendering Override Force Off flag is on + s = getenv("EVAS_GL_DIRECT_OVERRIDE_FORCE_OFF"); + if (s) direct_off = atoi(s); + if (direct_off == 1) + evgl_engine->force_direct_off = 1; + + evgl_engine->main_tid = 0; + + // Clear Function Pointers + memset(&gl_funcs, 0, sizeof(Evas_GL_API)); + + return evgl_engine; + +error: + if (evgl_engine->resource_key) + eina_tls_free(evgl_engine->resource_key); + if (evgl_engine) + free(evgl_engine); + return NULL; +} + +// Terminate engine and all the resources +// - destroy all internal resources +// - free allocated engine struct +int evgl_engine_destroy(EVGL_Engine *ee) +{ + // Check if engine is valid + if (!ee) + { + ERR("EVGL Engine not valid!"); + return 0; + } + + // Destroy internal resources + _internal_resources_destroy(ee); + + // Destroy surface pool + _native_surface_pool_destroy(ee); + + // Destroy TLS + if (ee->resource_key) + eina_tls_free(ee->resource_key); + + // Free engine + free(ee); + evgl_engine = NULL; + + return 1; +} + +//-----------------------------------------------------// +// Exported functions for evas_engine to use +// - We just need to implement these functions and have evas_engine load them :) +void * +evgl_surface_create(EVGL_Engine *ee, Evas_GL_Config *cfg, int w, int h) +{ + EVGL_Surface *sfc = NULL; + char *s = NULL; + int direct_override = 0; + + // Check if engine is valid + if (!ee) + { + ERR("Invalid EVGL Engine!"); + return NULL; + } + + if (!cfg) + { + ERR("Invalid Config!"); + return NULL; + } + + // Check the size of the surface + if ((w > ee->caps.max_w) || (h > ee->caps.max_h)) + { + ERR("Requested surface size [%d, %d] is greater than max supported size [%d, %d]", + w, h, ee->caps.max_w, ee->caps.max_h); + return NULL; + } + + // Allocate surface structure + sfc = calloc(1, sizeof(EVGL_Surface)); + if (!sfc) + { + ERR("Surface allocation failed."); + goto error; + } + + // Set surface info + sfc->w = w; + sfc->h = h; + + // Set the internal config value + if (!_internal_config_set(ee, sfc, cfg)) + { + ERR("Unsupported Format!"); + goto error; + } + + // Create internal buffers + if (!_surface_buffers_create(ee, sfc)) + { + ERR("Unable Create Specificed Surfaces. Unsupported format!"); + goto error; + }; + + if (!ee->direct_override) + if ((s = getenv("EVAS_GL_DIRECT_OVERRIDE"))) + { + direct_override = atoi(s); + if (direct_override == 1) + ee->direct_override = 1; + } + + return sfc; + +error: + if (sfc) free(sfc); + return NULL; +} + + +int +evgl_surface_destroy(EVGL_Engine *ee, EVGL_Surface *sfc) +{ + EVGL_Resource *rsc; + + // Check input parameter + if ((!ee) || (!sfc)) + { + ERR("Invalid input data. Engine: %p Surface:%p", ee, sfc); + return 0; + } + + // Retrieve the resource object + if (!(rsc = _evgl_tls_resource_get(ee))) + { + ERR("Error retrieving resource from TLS"); + return 0; + } + + if ((rsc->current_ctx) && (rsc->current_ctx->current_sfc == sfc) ) + { + ERR("The surface is still current before it's being destroyed."); + ERR("Doing make_current(NULL, NULL)"); + evgl_make_current(ee, NULL, NULL); + } + + // Set the context current with resource context/surface + if (!_internal_resource_make_current(ee, NULL)) + { + ERR("Error doing an internal resource make current"); + return 0; + } + + // Delete buffers + if (sfc->color_buf) + glDeleteTextures(1, &sfc->color_buf); + + if (sfc->depth_buf) + glDeleteRenderbuffers(1, &sfc->depth_buf); + + if (sfc->stencil_buf) + glDeleteRenderbuffers(1, &sfc->stencil_buf); + + if (sfc->depth_stencil_buf) + { +#ifdef GL_GLES + glDeleteTextures(1, &sfc->depth_stencil_buf); +#else + glDeleteRenderbuffers(1, &sfc->depth_stencil_buf); +#endif + } + + if (!ee->funcs->make_current(ee->engine_data, NULL, NULL, 0)) + ERR("Error doing make_current(NULL, NULL). Passing over the error..."); + + free(sfc); + sfc = NULL; + + return 1; + +} + +void * +evgl_context_create(EVGL_Engine *ee, EVGL_Context *share_ctx) +{ + EVGL_Context *ctx = NULL; + + // Check the input + if (!ee) + { + ERR("Invalid EVGL Engine!"); + return NULL; + } + + // Allocate context object + ctx = calloc(1, sizeof(EVGL_Context)); + if (!ctx) + { + ERR("Error allocating context object."); + return NULL; + } + + if (share_ctx) + ctx->context = ee->funcs->context_create(ee->engine_data, share_ctx->context); + else + ctx->context = ee->funcs->context_create(ee->engine_data, NULL); + + // Call engine create context + if (!ctx) + { + ERR("Error creating context from the Engine."); + free(ctx); + return NULL; + } + + return ctx; +} + + +int +evgl_context_destroy(EVGL_Engine *ee, EVGL_Context *ctx) +{ + // Check the input + if ((!ee) || (!ctx)) + { + ERR("Invalid input data. Engine: %p Context:%p", ee, ctx); + return 0; + } + + // Set the context current with resource context/surface + if (!_internal_resource_make_current(ee, NULL)) + { + ERR("Error doing an internal resource make current"); + return 0; + } + + // Delete the FBO + if (ctx->surface_fbo) + glDeleteFramebuffers(1, &ctx->surface_fbo); + + // Unset the currrent context + if (!ee->funcs->make_current(ee->engine_data, NULL, NULL, 0)) + { + ERR("Error doing make_current(NULL, NULL)."); + return 0; + } + + // Destroy engine context + if (!ee->funcs->context_destroy(ee->engine_data, ctx->context)) + { + ERR("Error destroying the engine context."); + return 0; + } + + // Free context + free(ctx); + ctx = NULL; + + return 1; +} + + +int +evgl_make_current(EVGL_Engine *ee, EVGL_Surface *sfc, EVGL_Context *ctx) +{ + EVGL_Resource *rsc; + int curr_fbo = 0; + + // Check the input validity. If either sfc or ctx is NULL, it's also error. + if ( (!ee) || + ((!sfc) && ctx) || + (sfc && (!ctx)) ) + { + ERR("Invalid Inputs. Engine: %p Surface: %p Context: %p!", ee, sfc, ctx); + return 0; + } + + // Get TLS Resources + if (!(rsc = _evgl_tls_resource_get(ee))) return 0; + + // Unset + if ((!sfc) && (!ctx)) + { + if (!ee->funcs->make_current(ee->engine_data, NULL, NULL, 0)) + { + ERR("Error doing make_current(NULL, NULL)."); + return 0; + } + //FIXME!!! + if (rsc->current_ctx) + { + rsc->current_ctx->current_sfc = NULL; + rsc->current_ctx = NULL; + } + return 1; + } + + + // Do a make current + if (!_internal_resource_make_current(ee, ctx)) + { + ERR("Error doing a make current with internal surface. Context: %p", ctx); + return 0; + } + + // Normal FBO Rendering + // Create FBO if it hasn't been created + if (!ctx->surface_fbo) + glGenFramebuffers(1, &ctx->surface_fbo); + + // Attach fbo and the buffers + if (ctx->current_sfc != sfc) + { + if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo)) + { + ERR("Attaching buffers to context fbo failed. Engine: %p Surface: %p Context FBO: %u", ee, sfc, ctx->surface_fbo); + return 0; + } + + // Bind to the previously bound buffer + if (ctx->current_fbo) + glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo); + } + + // Direct Rendering + if (evgl_direct_enabled(ee)) + { + // This is to transition from FBO rendering to direct rendering + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo); + if (ctx->surface_fbo == (GLuint)curr_fbo) + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + ctx->current_fbo = 0; + } + } + + ctx->current_sfc = sfc; + + rsc->current_ctx = ctx; + + return 1; +} + +const char * +evgl_string_query(EVGL_Engine *ee __UNUSED__, int name) +{ + switch(name) + { + case EVAS_GL_EXTENSIONS: + return (void*)evgl_api_ext_string_get(); + default: + return ""; + }; +} + +void * +evgl_proc_address_get(const char *name __UNUSED__) +{ + // Will eventually deprecate this function + return NULL; +} + +int +evgl_native_surface_get(EVGL_Engine *ee, EVGL_Surface *sfc, Evas_Native_Surface *ns) +{ + // Check the input + if ((!ee) || (!ns)) + { + ERR("Invalid input data. Engine: %p NS:%p", ee, ns); + return 0; + } + + ns->type = EVAS_NATIVE_SURFACE_OPENGL; + ns->version = EVAS_NATIVE_SURFACE_VERSION; + ns->data.opengl.texture_id = sfc->color_buf; + ns->data.opengl.framebuffer_id = sfc->color_buf; + ns->data.opengl.x = 0; + ns->data.opengl.y = 0; + ns->data.opengl.w = sfc->w; + ns->data.opengl.h = sfc->h; + + if (sfc->direct_fb_opt) + ns->data.opengl.framebuffer_id = 0; + + return 1; +} + +int +evgl_direct_enabled(EVGL_Engine *ee) +{ + EVGL_Resource *rsc; + + if (!(rsc=_evgl_tls_resource_get(ee))) return 0; + + EVGL_Context *ctx = rsc->current_ctx; + + if (ee->force_direct_off) return 0; + + if (rsc->id != ee->main_tid) return 0; + if (!ctx) return 0; + if (!ctx->current_sfc) return 0; + if (!ctx->current_sfc->direct_fb_opt) return 0; + if (!rsc->direct_img_obj) return 0; + + return 1; +} + +void +evgl_direct_img_obj_set(EVGL_Engine *ee, Evas_Object *img) +{ + EVGL_Resource *rsc; + + if (!(rsc=_evgl_tls_resource_get(ee))) return; + + rsc->direct_img_obj = img; +} + +Evas_Object * +evgl_direct_img_obj_get(EVGL_Engine *ee) +{ + EVGL_Resource *rsc; + + if (!(rsc=_evgl_tls_resource_get(ee))) return NULL; + + return rsc->direct_img_obj; +} + +Evas_GL_API * +evgl_api_get(EVGL_Engine *ee __UNUSED__) +{ + _evgl_api_get(&gl_funcs); + + return &gl_funcs; +} + +//-----------------------------------------------------// + + diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_core.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_core.h new file mode 100755 index 0000000000..c18f6fc9dc --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_core.h @@ -0,0 +1,39 @@ +#ifndef _EVAS_GL_CORE_H +#define _EVAS_GL_CORE_H +#define EVAS_GL_NO_GL_H_CHECK 1 +#include "Evas_GL.h" + +typedef void *EVGLNative_Display; +typedef void *EVGLNative_Surface; +typedef void *EVGLNative_Context; +typedef struct _EVGL_Engine EVGL_Engine; +typedef struct _EVGL_Interface EVGL_Interface; +typedef struct _EVGL_Surface EVGL_Surface; +typedef struct _EVGL_Native_Surface EVGL_Native_Surface; +typedef struct _EVGL_Context EVGL_Context; +typedef struct _EVGL_Resource EVGL_Resource; +typedef struct _EVGL_Cap EVGL_Cap; +typedef struct _EVGL_Surface_Cap EVGL_Surface_Cap; +typedef struct _EVGL_Surface_Format EVGL_Surface_Format; +typedef struct _Native_Surface Native_Surface; + + +extern EVGL_Engine *evgl_engine_create(EVGL_Interface *efunc, void *engine_data); +extern int evgl_engine_destroy(EVGL_Engine *ee); + +extern void *evgl_surface_create(EVGL_Engine *ee, Evas_GL_Config *cfg, int w, int h); +extern int evgl_surface_destroy(EVGL_Engine *ee, EVGL_Surface *sfc); +extern void *evgl_context_create(EVGL_Engine *ee, EVGL_Context *share_ctx); +extern int evgl_context_destroy(EVGL_Engine *ee, EVGL_Context *ctx); +extern int evgl_make_current(EVGL_Engine *ee, EVGL_Surface *sfc, EVGL_Context *ctx); +extern const char *evgl_string_query(EVGL_Engine *ee, int name); +extern void *evgl_proc_address_get(const char *name); +extern int evgl_native_surface_get(EVGL_Engine *ee, EVGL_Surface *sfc, Evas_Native_Surface *ns); +extern Evas_GL_API *evgl_api_get(EVGL_Engine *ee); + +extern int evgl_direct_enabled(EVGL_Engine *ee); +extern void evgl_direct_img_obj_set(EVGL_Engine *ee, Evas_Object *img); +extern Evas_Object *evgl_direct_img_obj_get(EVGL_Engine *ee); + + +#endif //_EVAS_GL_CORE_H diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_core_private.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_core_private.h new file mode 100755 index 0000000000..46c3f48ab3 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_core_private.h @@ -0,0 +1,224 @@ +#ifndef _EVAS_GL_CORE_PRIVATE_H +#define _EVAS_GL_CORE_PRIVATE_H +#include "evas_gl_private.h" +#include "evas_gl_core.h" +#include "evas_gl_api_ext.h" +#define EVAS_GL_NO_GL_H_CHECK 1 +#include "Evas_GL.h" + +//#include "evas_gl_ext.h" + +struct _EVGL_Interface +{ + // Returns the native display of evas engine. + void *(*display_get)(void *data); + + // Returns the Window surface that evas uses for direct rendering opt. + void *(*evas_surface_get)(void *data); + void *(*native_window_create)(void *data); + int *(*native_window_destroy)(void *data, void *window); + + // Creates/Destroys the native surface from evas engine. + void *(*surface_create)(void *data, void *native_window); + int (*surface_destroy)(void *data, void *surface); + + // Creates/Destroys the native surface from evas engine. + void *(*context_create)(void *data, void *share_ctx); + int (*context_destroy)(void *data, void *context); + + // Calls the make_current from evas_engine. + int (*make_current)(void *data, void *surface, void *context, int flush); + + // Returns the get proc_address function + void *(*proc_address_get)(const char *name); + + // Returns the string of supported extensions + const char *(*ext_string_get)(void *data); + + // Returns the current rotation angle of evas + int (*rotation_angle_get)(void *data); +}; + +struct _EVGL_Surface +{ + int w, h; + + //-------------------------// + // Related to FBO Surface + + // MSAA + GLint msaa_samples; + + // Color Buffer Target + GLuint color_buf; + GLint color_ifmt; + GLenum color_fmt; + + // Depth Buffer Target + GLuint depth_buf; + GLenum depth_fmt; + + // Stencil Buffer Target + GLuint stencil_buf; + GLenum stencil_fmt; + + // Depth_Stencil Target + GLuint depth_stencil_buf; + GLenum depth_stencil_fmt; + + // Direct Rendering Option + int direct_fb_opt; + //int direct_override; + + int cfg_index; + + // Attached Context + int fbo_attached; + //-------------------------// + + int direct_enabled; + Evas_Object *direct_img_obj; + + EVGL_Context *current_ctx; +}; + + + +struct _EVGL_Context +{ + EVGLNative_Context context; + + // Context FBO + GLuint surface_fbo; + + // Current FBO + GLuint current_fbo; + + // Direct Rendering Related + int scissor_enabled; + int scissor_upated; + int scissor_coord[4]; + + int direct_scissor; + + EVGL_Surface *current_sfc; +}; + +typedef enum _EVGL_Color_Bit +{ + COLOR_NONE = 0, + COLOR_RGB_888 = 0x1, + COLOR_RGBA_8888 = 0x3, +} EVGL_Color_Bit; + + +typedef enum _EVGL_Depth_Bit +{ + DEPTH_NONE = 0, + DEPTH_BIT_8 = 0x1, + DEPTH_BIT_16 = 0x3, + DEPTH_BIT_24 = 0x7, + DEPTH_BIT_32 = 0xF, + DEPTH_STENCIL = 0xFF, +} EVGL_Depth_Bit; + +typedef enum _EVGL_Stencil_Bit +{ + STENCIL_NONE = 0, + STENCIL_BIT_1 = 0x1, + STENCIL_BIT_2 = 0x3, + STENCIL_BIT_4 = 0x7, + STENCIL_BIT_8 = 0xF, + STENCIL_BIT_16 = 0x1F, +} EVGL_Stencil_Bit; + + +struct _EVGL_Surface_Format +{ + int index; + + EVGL_Color_Bit color_bit; + GLint color_ifmt; + GLenum color_fmt; + + EVGL_Depth_Bit depth_bit; + GLenum depth_fmt; + + EVGL_Stencil_Bit stencil_bit; + GLenum stencil_fmt; + + GLenum depth_stencil_fmt; + + int samples; +}; + +struct _EVGL_Cap +{ + EVGL_Surface_Format fbo_fmts[100]; + int num_fbo_fmts; + + int max_w; + int max_h; + + int msaa_supported; + int msaa_samples[3]; // High, Med, Low +}; + +struct _EVGL_Resource +{ + int id; + + EVGLNative_Display display; + EVGLNative_Context context; + EVGLNative_Surface surface; + + EVGL_Context *current_ctx; + //EVGL_Surface *current_sfc; + + Evas_Object *direct_img_obj; +}; + +struct _Native_Surface +{ + void *surface; + void *window; +}; + +struct _EVGL_Engine +{ + int initted; + + EVGL_Interface *funcs; + + EVGL_Cap caps; + + const char *gl_ext; + const char *evgl_ext; + + // Resource context/surface per Thread in TLS for evasgl use + LK(resource_lock); + Eina_TLS resource_key; + Eina_List *resource_list; + int resource_count; + int main_tid; + int pool_num; + Native_Surface *surface_pool; + + + int direct_override; + + // Force Off fo Debug purposes + int force_direct_off; + + void *engine_data; +}; + +// Evas GL Engine +extern EVGL_Engine *evgl_engine; + +// Internally used functions +extern void _evgl_api_get(Evas_GL_API *api); +extern EVGL_Resource *_evgl_tls_resource_get(); +extern EVGL_Context *_evgl_current_context_get(); + +#endif //_EVAS_GL_CORE_PRIVATE_H diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index 633ba43579..304d522aa3 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -1,5 +1,6 @@ #include "evas_common.h" /* Also includes international specific stuff */ #include "evas_engine.h" +#include "evas_gl_core_private.h" #ifdef HAVE_DLSYM # include /* dlopen,dlclose,etc */ @@ -11,10 +12,6 @@ #include "Evas_GL.h" 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 { @@ -26,119 +23,12 @@ struct _Render_Engine int w, h; int vsync; - // GL Surface Capability - struct { - 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; -}; - -struct _Render_Engine_GL_Surface -{ - int initialized; - int fbo_attached; - int w, h; - int depth_bits; - int stencil_bits; - - int direct_fb_opt; - int multisample_bits; - - // Render target Texture/Buffers - GLint rt_msaa_samples; - - 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; - -#ifdef GL_GLES - EGLSurface direct_sfc; -#else - Window direct_sfc; -#endif - - Render_Engine_GL_Context *current_ctx; -}; - -struct _Render_Engine_GL_Context -{ - int initialized; -#ifdef GL_GLES - EGLContext context; -#else - GLXContext context; -#endif - GLuint context_fbo; - GLuint current_fbo; - - int scissor_enabled; - int scissor_upated; - - 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 -#ifdef GL_GLES - EGLContext context; - EGLSurface surface; -#else - GLXContext context; -#endif -}; - -// Extension Handling -struct _Extension_Entry -{ - const char *name; - const char *real_name; - int supported; + EVGL_Engine *evgl_engine; }; static int initted = 0; static int gl_wins = 0; -static int gl_direct_override = 0; -static int gl_direct_enabled = 0; -static Render_Engine_GL_Context *current_evgl_ctx = NULL; -static Render_Engine *current_engine = NULL; -static Evas_Object *gl_direct_img_obj = NULL; - static int _ext_initted = 0; -static char *_gl_ext_string = NULL; -static char *_evasgl_ext_string = NULL; - -// 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) (); @@ -146,8 +36,6 @@ 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) (); #ifdef GL_GLES @@ -156,19 +44,13 @@ typedef const char *(*glsym_func_const_char_ptr) (); # define EGL_NATIVE_PIXMAP_KHR 0x30b0 #endif _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_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; -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) (); @@ -183,175 +65,443 @@ void (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d) 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_glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = NULL; -void (*glsym_glFramebufferTexture2DMultisample) (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; -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; +//----------------------------------------------------------// +// NEW_EVAS_GL Engine Functions +static void * +evgl_eng_display_get(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } -//------ GLES 2.0 Extensions supported in EvasGL -----// -static Extension_Entry _gl_ext_entries[] = { #ifdef GL_GLES - //--- 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 }, - { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 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 }, + if (re->win) + return (void*)re->win->egl_disp; #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 }, - { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 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 }, - + if (re->info) + return (void*)re->info->info.display; #endif - { NULL, NULL, 0} + else + return NULL; +} + +static void * +evgl_eng_evas_surface_get(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } + +#ifdef GL_GLES + if (re->win) + return (void*)re->win->egl_surface[0]; +#else + if (re->win) + return (void*)re->win->win; +#endif + else + return NULL; +} + +static int +evgl_eng_make_current(void *data, void *surface, void *context, int flush) +{ + Render_Engine *re = (Render_Engine *)data; + int ret = 0; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } + + +#ifdef GL_GLES + EGLContext ctx = (EGLContext)context; + EGLSurface sfc = (EGLSurface)surface; + EGLDisplay dpy = re->win->egl_disp; //eglGetCurrentDisplay(); + + if ((context==NULL) && (surface==NULL)) + { + ret = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!ret) + { + ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError()); + return 0; + } + return 1; + } + + if ((eglGetCurrentContext() != ctx) || + (eglGetCurrentSurface(EGL_READ) != sfc) || + (eglGetCurrentSurface(EGL_DRAW) != sfc) ) + { + + //!!!! Does it need to be flushed with it's set to NULL above?? + // Flush remainder of what's in Evas' pipeline + if (flush) eng_window_use(NULL); + + // Do a make current + ret = eglMakeCurrent(dpy, sfc, sfc, ctx); + + if (!ret) + { + ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError()); + return 0; + } + } + + return 1; +#else + GLXContext ctx = (GLXContext)context; + Window sfc = (Window)surface; + + if ((context==NULL) && (surface==NULL)) + { + ret = glXMakeCurrent(re->info->info.display, None, NULL); + if (!ret) + { + ERR("glXMakeCurrent() failed!"); + return 0; + } + return 1; + } + + + if ((glXGetCurrentContext() != ctx)) + { + //!!!! Does it need to be flushed with it's set to NULL above?? + // Flush remainder of what's in Evas' pipeline + if (flush) eng_window_use(NULL); + + // Do a make current + ret = glXMakeCurrent(re->info->info.display, sfc, ctx); + + if (!ret) + { + ERR("glXMakeCurrent() failed. Ret: %d! Context: %p Surface: %p", ret, (void*)ctx, (void*)sfc); + return 0; + } + } + return 1; +#endif +} + + + +static void * +evgl_eng_native_window_create(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return NULL; + } + + XSetWindowAttributes attr; + Window win; + + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.bit_gravity = NorthWestGravity; + attr.win_gravity = NorthWestGravity; + attr.save_under = False; + attr.do_not_propagate_mask = NoEventMask; + attr.event_mask = 0; + + win = XCreateWindow(re->info->info.display, + DefaultRootWindow(re->info->info.display), + 0, 0, 2, 2, 0, + CopyFromParent, InputOutput, CopyFromParent, + CWBackingStore | CWOverrideRedirect | + CWBorderPixel | CWBackPixmap | + CWSaveUnder | CWDontPropagate | + CWEventMask | CWBitGravity | + CWWinGravity, &attr); + if (!win) + { + ERR("Creating native X window failed."); + return NULL; + } + + return (void*)win; +} + +static int +evgl_eng_native_window_destroy(void *data, void *native_window) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } + + if (!native_window) + { + ERR("Inavlid native surface."); + return 0; + } + + XDestroyWindow(re->info->info.display, (Window)native_window); + + native_window = NULL; + + return 1; +} + + +// Theoretically, we wouldn't need this functoin if the surfaceless context +// is supported. But, until then... +static void * +evgl_eng_window_surface_create(void *data, void *native_window) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return NULL; + } + +#ifdef GL_GLES + EGLSurface surface = EGL_NO_SURFACE; + + // Create resource surface for EGL + surface = eglCreateWindowSurface(re->win->egl_disp, + re->win->egl_config, + (EGLNativeWindowType)native_window, + NULL); + if (!surface) + { + ERR("Creating window surface failed. Error: %#x.", eglGetError()); + return NULL; + } + + return (void*)surface; +#else + /* + // We don't need to create new one for GLX + Window surface; + + surface = re->win->win; + + return (void *)surface; + */ + return (void*)native_window; +#endif + +} + +static int +evgl_eng_window_surface_destroy(void *data, void *surface) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } + +#ifdef GL_GLES + if (!surface) + { + ERR("Invalid surface."); + return 0; + } + + eglDestroySurface(re->win->egl_disp, (EGLSurface)surface); +#endif + + surface = NULL; + + return 1; +} + +static void * +evgl_eng_context_create(void *data, void *share_ctx) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return NULL; + } + +#ifdef GL_GLES + EGLContext context = EGL_NO_CONTEXT; + int context_attrs[3]; + + context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; + context_attrs[1] = 2; + context_attrs[2] = EGL_NONE; + + // Share context already assumes that it's sharing with evas' context + if (share_ctx) + { + context = eglCreateContext(re->win->egl_disp, + re->win->egl_config, + (EGLContext)share_ctx, + context_attrs); + } + else + { + context = eglCreateContext(re->win->egl_disp, + re->win->egl_config, + re->win->egl_context[0], // Evas' GL Context + context_attrs); + } + + if (!context) + { + ERR("Engine Context Creations Failed. Error: %#x.", eglGetError()); + return NULL; + } + + return (void*)context; +#else + GLXContext context = NULL; + + // Share context already assumes that it's sharing with evas' context + if (share_ctx) + { + context = glXCreateContext(re->info->info.display, + re->win->visualinfo, + (GLXContext)share_ctx, + 1); + } + else + { + context = glXCreateContext(re->info->info.display, + re->win->visualinfo, + re->win->context, // Evas' GL Context + 1); + } + + if (!context) + { + ERR("Internal Resource Context Creations Failed."); + return NULL; + } + + return (void*)context; +#endif + +} + +static int +evgl_eng_context_destroy(void *data, void *context) +{ + Render_Engine *re = (Render_Engine *)data; + + if ((!re) || (!context)) + { + ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context); + return 0; + } + +#ifdef GL_GLES + eglDestroyContext(re->win->egl_disp, (EGLContext)context); +#else + glXDestroyContext(re->info->info.display, (GLXContext)context); +#endif + + return 1; +} + +static const char * +evgl_eng_string_get(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return NULL; + } + +#ifdef GL_GLES + // EGL Extensions + if (glsym_eglQueryString) + return glsym_eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); + else + return ""; +#else + return glXQueryExtensionsString(re->info->info.display, + re->info->info.screen); +#endif +} + +static void * +evgl_eng_proc_address_get(const char *name) +{ +#ifdef GL_GLES + if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name); + return dlsym(RTLD_DEFAULT, name); +#else + if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name); + return dlsym(RTLD_DEFAULT, name); +#endif +} + +static int +evgl_eng_rotation_angle_get(void *data) +{ + Render_Engine *re = (Render_Engine *)data; + + if (!re) + { + ERR("Invalid Render Engine Data!"); + return 0; + } + + if ((re->win) && (re->win->gl_context)) + return re->win->gl_context->rot; + else + { + ERR("Unable to retrieve rotation angle."); + return 0; + } +} + +static EVGL_Interface evgl_funcs = +{ + evgl_eng_display_get, + evgl_eng_evas_surface_get, + evgl_eng_native_window_create, + evgl_eng_native_window_destroy, + evgl_eng_window_surface_create, + evgl_eng_window_surface_destroy, + evgl_eng_context_create, + evgl_eng_context_destroy, + evgl_eng_make_current, + evgl_eng_proc_address_get, + evgl_eng_string_get, + evgl_eng_rotation_angle_get }; -//------ Extensions supported in EvasGL -----// -static Extension_Entry _evasgl_ext_entries[] = { -#ifdef GL_GLES - { "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 -_gl_ext_sym_init(void) +_ext_sym_init(void) { static int done = 0; @@ -367,16 +517,6 @@ _gl_ext_sym_init(void) FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn); FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn); - FINDSYM(glsym_eglBindTexImage, "eglBindTexImage", glsym_func_void); - FINDSYM(glsym_eglBindTexImage, "eglBindTexImageEXT", glsym_func_void); - FINDSYM(glsym_eglBindTexImage, "eglBindTexImageARB", glsym_func_void); - FINDSYM(glsym_eglBindTexImage, "eglBindTexImageKHR", glsym_func_void); - - FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImage", glsym_func_void); - FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageEXT", glsym_func_void); - FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageARB", glsym_func_void); - FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageKHR", glsym_func_void); - FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr); FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr); FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr); @@ -389,23 +529,10 @@ _gl_ext_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); \ @@ -444,245 +571,13 @@ _gl_ext_sym_init(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; - - /* GL_IMG_multisampled_render_to_texture */ - FINDSYM(glsym_glRenderbufferStorageMultisample, "glRenderbufferStorageMultisampleIMG", glsym_func_void); - FINDSYM(glsym_glRenderbufferStorageMultisample, "glRenderbufferStorageMultisampleEXT", glsym_func_void); - FINDSYM(glsym_glFramebufferTexture2DMultisample, "glFramebufferTexture2DMultisampleIMG", glsym_func_void); - FINDSYM(glsym_glFramebufferTexture2DMultisample, "glFramebufferTexture2DMultisampleEXT", glsym_func_void); - -} - -static void -_gl_ext_init(Render_Engine *re) -{ - int i, ext_len = 0; - const char *glexts, *evasglexts; - - // GLES 2.0 Extensions - glexts = (const char*)glGetString(GL_EXTENSIONS); - - ext_len = strlen(glexts); - if (!ext_len) - { - DBG("GL Get Extension string NULL: No extensions supported"); - return; - } - - _gl_ext_string = calloc(1, sizeof(char) * ext_len * 2); - if (!_gl_ext_string) - { - ERR("Error allocating _gl_ext_string."); - return; - } - - 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(" "); - -#ifdef GL_GLES - // EGL Extensions - if (glsym_eglQueryString) - { - evasglexts = glsym_eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); -#else - if (glsym_glXQueryExtensionsString) - { - evasglexts = glXQueryExtensionsString(re->info->info.display, - re->info->info.screen); -#endif - ext_len = strlen(evasglexts); - - if (!ext_len) - { - DBG("GL Get Extension string NULL: No extensions supported"); - return; - } - - _evasgl_ext_string = calloc(1, sizeof(char) * ext_len * 2); - if (!_evasgl_ext_string) - { - ERR("Error allocating _evasgl_ext_string."); - return; - } - - DBG("--------EvasGL Supported 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; /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; -/* Function table for GL APIs */ -static Evas_GL_API gl_funcs; - static void * eng_info(Evas *e) { @@ -727,194 +622,6 @@ _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; - -#ifdef GL_GLES - // EGL - int context_attrs[3]; - context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; - context_attrs[1] = 2; - context_attrs[2] = EGL_NONE; - - if (eina_main_loop_is()) - { - rsc->surface = re->win->egl_surface[0]; - } - else - { - // Create resource surface for EGL - rsc->surface = eglCreateWindowSurface(re->win->egl_disp, - re->win->egl_config, - (EGLNativeWindowType)DefaultRootWindow(re->info->info.display), - NULL); - if (!rsc->surface) - { - ERR("Creating internal resource surface failed."); - free(rsc); - return NULL; - } - } - - // Create a resource context for EGL - 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; - - LKL(resource_lock); -#ifdef GL_GLES - // EGL - // Delete the Resources - EINA_LIST_FOREACH(resource_list, l, rsc) - { - if ((rsc->surface) && (rsc->surface != re->win->egl_surface[0])) - eglDestroySurface(re->win->egl_disp, rsc->surface); - if (rsc->context) - eglDestroyContext(re->win->egl_disp, rsc->context); - free(rsc); - } - #else - // GLX - // Delete the Resources - EINA_LIST_FOREACH(resource_list, l, rsc) - { - if (rsc) - { - glXDestroyContext(re->info->info.display, rsc->context); - free(rsc); - } - } -#endif - eina_list_free(resource_list); - resource_list = NULL; - LKU(resource_lock); - - // Destroy TLS - eina_tls_free(resource_key); - - // Free the extension strings - if (_ext_initted) - { - if (_gl_ext_string) - free(_gl_ext_string); - if (_evasgl_ext_string) - free(_evasgl_ext_string); - - _gl_ext_string = NULL; - _evasgl_ext_string = NULL; - _ext_initted = 0; - } - - return 1; -} - - -static int -_internal_resources_make_current(void *data) -{ - Render_Engine *re = (Render_Engine *)data; - Render_Engine_GL_Resource *rsc; - int ret = 0; - - // Create internal resource context if it hasn't been created already - if ((rsc = eina_tls_get(resource_key)) == NULL) - { - if ((rsc = _create_internal_glue_resources(re)) == NULL) - { - ERR("Error creating internal resources."); - return 0; - } - } - - // Use resource surface/context to create surface resrouces -#ifdef GL_GLES - // Update the evas' window surface - if (eina_main_loop_is()) rsc->surface = re->win->egl_surface[0]; - - ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); - - if (!ret) - { - ERR("eglMakeCurrent() failed. Error Code: %#x", eglGetError()); - return 0; - } -#else - ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); - if (!ret) - { - ERR("glXMakeCurrent()!"); - return 0; - } -#endif - return 1; -} - static int eng_setup(Evas *e, void *in) { @@ -954,7 +661,7 @@ eng_setup(Evas *e, void *in) } e->engine.data.output = re; gl_wins++; - + if (!initted) { evas_common_cpu_init(); @@ -970,10 +677,12 @@ eng_setup(Evas *e, void *in) 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); + re->evgl_engine = evgl_engine_create(&evgl_funcs, (void*)re); + + if (!re->evgl_engine) + { + ERR("Error Creating Evas_GL Engine. Evas GL will not be supported!"); + } initted = 1; } @@ -1069,8 +778,7 @@ eng_setup(Evas *e, void *in) if (!_ext_initted) { - _gl_ext_sym_init(); - _gl_ext_init(re); + _ext_sym_init(); _ext_initted = 1 ; } @@ -1099,10 +807,12 @@ eng_output_free(void *data) #endif if (re->win) { - if ((initted == 1) && (gl_wins == 1)) - _destroy_internal_glue_resources(re); eng_window_free(re->win); gl_wins--; + + // NEW_EVAS_GL + if (gl_wins==0) + evgl_engine_destroy(re->evgl_engine); } evas_common_tilebuf_free(re->tb); free(re); @@ -2622,10 +2332,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, re = (Render_Engine *)data; if (!image) return; - if ((gl_direct_img_obj) && (gl_direct_enabled)) + if (evgl_direct_enabled(re->evgl_engine)) { DBG("Rendering Directly to the window"); - evas_object_image_pixels_dirty_set(gl_direct_img_obj, EINA_TRUE); + //evas_object_image_pixels_dirty_set(evgl_direct_img_obj_get(re->evgl_engine), EINA_TRUE); } else { @@ -2821,1787 +2531,85 @@ eng_canvas_alpha_get(void *data, void *info __UNUSED__) return re->win->alpha; } - -// Unfortunately, there is no query function to figure out which surface formats work. -// So, this is one way to test for surface config capability. -static int -_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt, int mult_samples) -{ - GLuint fbo, tex, rb, ds_tex; - int w, h, fb_status; - - // Initialize Variables - fbo = tex = rb = ds_tex = 0; - - // Width/Heith for test purposes - w = h = 2; - - // Gen FBO - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - // Render Target Texture - if (int_fmt) - { - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, 0); - - if (mult_samples) - glsym_glFramebufferTexture2DMultisample(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) - if (attachment) - { -#ifdef GL_GLES - // This is a little hacky but this is how we'll have to do for now. - if (attach_fmt == GL_DEPTH_STENCIL_OES) - { - glGenTextures(1, &ds_tex); - glBindTexture(GL_TEXTURE_2D, ds_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_DEPTH_STENCIL_OES, w, h, - 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL); - if (mult_samples) - { - glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, ds_tex, 0, mult_samples); - glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, ds_tex, 0, mult_samples); - } - else - { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, ds_tex, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, ds_tex, 0); - } - glBindTexture(GL_TEXTURE_2D, 0); - } - else -#endif - { - glGenRenderbuffers(1, &rb); - glBindRenderbuffer(GL_RENDERBUFFER, rb); - if (mult_samples) - glsym_glRenderbufferStorageMultisample(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); - } - - } - - // Check FBO for completeness - fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - - // Delete Created Resources - glBindFramebuffer(GL_FRAMEBUFFER, 0); - if (fbo) glDeleteFramebuffers(1, &fbo); - if (tex) glDeleteTextures(1, &tex); - if (ds_tex) glDeleteTextures(1, &ds_tex); - if (rb) glDeleteRenderbuffers(1, &rb); - - if (fb_status != GL_FRAMEBUFFER_COMPLETE) - return 0; - else - { - if ((attachment) && (!mult_samples)) - return attach_fmt; - else - return 1; - } -} - -static void -_print_gl_surface_info(Render_Engine_GL_Surface *sfc, int error) -{ -#define PRINT_LOG(...) \ - if (error) \ - ERR(__VA_ARGS__); \ - else \ - DBG(__VA_ARGS__); - - PRINT_LOG("----------Surface Info------------"); - PRINT_LOG(" [Surface] %x", (unsigned int)sfc); - PRINT_LOG(" Width: %d", sfc->w); - PRINT_LOG(" Height: %d", sfc->h); - PRINT_LOG(" Direct Surface: %x", (unsigned int)sfc->direct_sfc); - PRINT_LOG(" Current Context: %x", (unsigned int)sfc->current_ctx); - PRINT_LOG(" [-------Config-------]"); - PRINT_LOG(" Depth Bits : %d", sfc->depth_bits); - PRINT_LOG(" Stencil Bits : %d", sfc->stencil_bits); - PRINT_LOG(" Direct FB Opt : %d", sfc->direct_fb_opt); - PRINT_LOG(" Multisample Bits: %d", sfc->multisample_bits); - PRINT_LOG(" MSAA Samples : %d", sfc->rt_msaa_samples); - PRINT_LOG(" [-------Internal-----]"); - PRINT_LOG(" RenderTarget Texture : %d", sfc->rt_tex); - PRINT_LOG(" RenderTarget Internal Format : %x", sfc->rt_internal_fmt); - PRINT_LOG(" RenderTaret Format : %x", sfc->rt_fmt); - PRINT_LOG(" RenderBuffer Depth : %x", sfc->rb_depth); - PRINT_LOG(" RenderBuffer Depth Format : %x", sfc->rb_depth_fmt); - PRINT_LOG(" RenderBuffer Stencil : %d", sfc->rb_stencil); - PRINT_LOG(" RenderBuffer Stencil Format : %x", sfc->rb_stencil_fmt); - PRINT_LOG(" RenderBuffer Depth Stencil : %x", sfc->rb_depth_stencil); - PRINT_LOG(" RenderBuffer Depth Stencil Format: %x", sfc->rb_depth_stencil_fmt); - PRINT_LOG("--------------------------------------"); - -#undef PRINT_LOG -} - -static void -_print_gl_surface_cap(Render_Engine *re, int error) -{ -#define PRINT_LOG(...) \ - if (error) \ - ERR(__VA_ARGS__); \ - else \ - DBG(__VA_ARGS__); - - PRINT_LOG("----------------------------------------------------"); - PRINT_LOG(" EvasGL Supported Surface Format "); - PRINT_LOG(" "); - PRINT_LOG(" [Max Renderbuffer Size] : %d", re->gl_cap.max_rb_size); - PRINT_LOG(" [Multisample Support ] : %d", re->gl_cap.msaa_support); - PRINT_LOG(" [Low Samples] : %d", re->gl_cap.msaa_samples[1]); - PRINT_LOG(" [Med Samples] : %d", re->gl_cap.msaa_samples[2]); - PRINT_LOG(" [High Samples] : %d", re->gl_cap.msaa_samples[3]); - PRINT_LOG(" [--Multisamples--] "); - PRINT_LOG(" [Norm] [Low] [Med] [High]"); - PRINT_LOG(" [RGB Format] : %4x %d %d %d", re->gl_cap.rgb_888[0], re->gl_cap.rgb_888[1], re->gl_cap.rgb_888[2], re->gl_cap.rgb_888[3]); - PRINT_LOG(" [RGBA Format] : %4x %d %d %d", re->gl_cap.rgba_8888[0], re->gl_cap.rgba_8888[1], re->gl_cap.rgba_8888[2], re->gl_cap.rgba_8888[3]); - PRINT_LOG(" [Depth 8 Bits] : %4x %d %d %d", re->gl_cap.depth_8[0], re->gl_cap.depth_8[1], re->gl_cap.depth_8[2], re->gl_cap.depth_8[3]); - PRINT_LOG(" [Depth 16 Bits] : %4x %d %d %d", re->gl_cap.depth_16[0], re->gl_cap.depth_16[1], re->gl_cap.depth_16[2], re->gl_cap.depth_16[3]); - PRINT_LOG(" [Depth 24 Bits] : %4x %d %d %d", re->gl_cap.depth_24[0], re->gl_cap.depth_24[1], re->gl_cap.depth_24[2], re->gl_cap.depth_24[3]); - PRINT_LOG(" [Depth 32 Bits] : %4x %d %d %d", re->gl_cap.depth_32[0], re->gl_cap.depth_32[1], re->gl_cap.depth_32[2], re->gl_cap.depth_32[3]); - PRINT_LOG(" [Stencil 1 Bits] : %4x %d %d %d", re->gl_cap.stencil_1[0], re->gl_cap.stencil_1[1], re->gl_cap.stencil_1[2], re->gl_cap.stencil_1[3]); - PRINT_LOG(" [Stencil 2 Bits] : %4x %d %d %d", re->gl_cap.stencil_2[0], re->gl_cap.stencil_2[1], re->gl_cap.stencil_2[2], re->gl_cap.stencil_2[3]); - PRINT_LOG(" [Stencil 4 Bits] : %4x %d %d %d", re->gl_cap.stencil_4[0], re->gl_cap.stencil_4[1], re->gl_cap.stencil_4[2], re->gl_cap.stencil_4[3]); - PRINT_LOG(" [Stencil 8 Bits] : %4x %d %d %d", re->gl_cap.stencil_8[0], re->gl_cap.stencil_8[1], re->gl_cap.stencil_8[2], re->gl_cap.stencil_8[3]); - PRINT_LOG(" [Stencil 16 Bits] : %4x %d %d %d", re->gl_cap.stencil_16[0], re->gl_cap.stencil_16[1], re->gl_cap.stencil_16[2], re->gl_cap.stencil_16[3]); - PRINT_LOG(" [Depth 24 Stencil 8 Bits]: %4x %d %d %d", re->gl_cap.depth_24_stencil_8[0], re->gl_cap.depth_24_stencil_8[1], re->gl_cap.depth_24_stencil_8[2], re->gl_cap.depth_24_stencil_8[3]); - PRINT_LOG("----------------------------------------------------"); -#undef PRINT_LOG -} - -static void -_set_gl_surface_cap(Render_Engine *re) -{ - int i, count; - - if (!re) return; - if (re->gl_cap_initted) return; - -#ifdef GL_GLES - int max_samples = 0; - - glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples); - - // Check if msaa_support is supported - if ((max_samples) && - (glsym_glFramebufferTexture2DMultisample) && - (glsym_glRenderbufferStorageMultisample)) - { - 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[2] = re->gl_cap.msaa_samples[3]; - if (!re->gl_cap.msaa_samples[1]) - 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); - -#ifdef GL_GLES - count = (re->gl_cap.msaa_support) ? 4 : 1; - - for (i = 0; i < count; i++) - { - re->gl_cap.rgb_888[i] = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]); - re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]); - - re->gl_cap.depth_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_16[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_24[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24_OES, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_32[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32_OES, re->gl_cap.msaa_samples[i]); - - re->gl_cap.stencil_1[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1_OES, re->gl_cap.msaa_samples[i]); - re->gl_cap.stencil_4[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4_OES, re->gl_cap.msaa_samples[i]); - re->gl_cap.stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]); - - re->gl_cap.depth_24_stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_STENCIL_OES, GL_DEPTH_STENCIL_OES, re->gl_cap.msaa_samples[i]); - } - -#else - count = (re->gl_cap.msaa_support) ? 4 : 1; - - for (i = 0; i < count; i++) - { - re->gl_cap.rgb_888[i] = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]); - re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]); - - re->gl_cap.depth_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_16[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_24[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24, re->gl_cap.msaa_samples[i]); - re->gl_cap.depth_32[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32, re->gl_cap.msaa_samples[i]); - - re->gl_cap.stencil_1[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1, re->gl_cap.msaa_samples[i]); - re->gl_cap.stencil_4[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4, re->gl_cap.msaa_samples[i]); - re->gl_cap.stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]); - - re->gl_cap.depth_24_stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8, re->gl_cap.msaa_samples[i]); - } -#endif - - _print_gl_surface_cap(re, 0); - - re->gl_cap_initted = 1; -} - -static int -_set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg) -{ - // Check if color formats are supported - switch((int)cfg->color_format) - { - case EVAS_GL_RGB_888: - 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_8888[0]) - { - sfc->rt_fmt = GL_RGBA; - sfc->rt_internal_fmt = GL_RGBA; - cfg->color_format = EVAS_GL_RGBA_8888; - break; - } - default: - ERR("Color Format Not Supported: %d", cfg->color_format); - _print_gl_surface_cap(re, 1); - return 0; - } - - switch((int)cfg->depth_bits) - { - case EVAS_GL_DEPTH_NONE: - break; - case EVAS_GL_DEPTH_BIT_8: - if (re->gl_cap.depth_8[0]) - { - 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[0]) - { - 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[0]) - { - sfc->rb_depth_fmt = re->gl_cap.depth_24[0]; - cfg->depth_bits = EVAS_GL_DEPTH_BIT_24; - break; - } - else if (re->gl_cap.depth_24_stencil_8[0]) - { - sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8[0]; - sfc->rb_depth_fmt = re->gl_cap.depth_24_stencil_8[0]; - cfg->depth_bits = EVAS_GL_DEPTH_BIT_24; - break; - } - case EVAS_GL_DEPTH_BIT_32: - if (re->gl_cap.depth_32[0]) - { - sfc->rb_depth_fmt = re->gl_cap.depth_32[0]; - cfg->depth_bits = EVAS_GL_DEPTH_BIT_32; - break; - } - default: - ERR("Unsupported Depth Bits Format: %d", cfg->depth_bits); - _print_gl_surface_cap(re, 1); - return 0; - } - - switch((int)cfg->stencil_bits) - { - case EVAS_GL_STENCIL_NONE: - break; - case EVAS_GL_STENCIL_BIT_1: - if (re->gl_cap.stencil_1[0]) - { - 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[0]) - { - 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[0]) - { - 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 == (GLenum)re->gl_cap.depth_24_stencil_8[0]) || - (sfc->rb_depth_fmt == (GLenum)re->gl_cap.depth_24[0]) || - (!(re->gl_cap.stencil_8[0]) && (re->gl_cap.depth_24_stencil_8[0]))) - { - sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8[0]; - sfc->rb_stencil_fmt = re->gl_cap.depth_24_stencil_8[0]; - cfg->stencil_bits = EVAS_GL_STENCIL_BIT_8; - break; - } - else if (re->gl_cap.stencil_8[0]) - { - 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[0]) - { - sfc->rb_stencil_fmt = re->gl_cap.stencil_16[0]; - cfg->stencil_bits = EVAS_GL_STENCIL_BIT_16; - break; - } - default: - ERR("Unsupported Stencil Bits Format: %d", cfg->stencil_bits); - _print_gl_surface_cap(re, 1); - return 0; - } - - if (cfg->options_bits) - { - if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT) - { - sfc->direct_fb_opt = 1; - DBG("########################################################"); - DBG("######### [Evas] Direct option bit is enabled ##########"); - DBG("########################################################"); - } - // 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; -} - -static int -_attach_fbo_surface(Render_Engine *data __UNUSED__, - Render_Engine_GL_Surface *sfc, - int fbo) -{ - int fb_status, curr_tex, curr_rb; - - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - // Detach any previously attached buffers - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); -#ifdef GL_GLES - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); -#else - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); -#endif - - - // Render Target Texture - if (sfc->rt_tex) - { - curr_tex = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_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, curr_tex); - - // Attach texture to FBO - if (sfc->rt_msaa_samples) - glsym_glFramebufferTexture2DMultisample(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); - } - - - // Depth Stencil RenderBuffer - Attach it to FBO - if (sfc->rb_depth_stencil) - { -#ifdef GL_GLES - curr_tex = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_tex); - glBindTexture(GL_TEXTURE_2D, sfc->rb_depth_stencil); - 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_DEPTH_STENCIL_OES, sfc->w, sfc->h, - 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL); - if (sfc->rt_msaa_samples) - { - glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, - sfc->rb_depth_stencil, - 0, sfc->rt_msaa_samples); - glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, - sfc->rb_depth_stencil, - 0, sfc->rt_msaa_samples); - } - else - { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, sfc->rb_depth_stencil, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, sfc->rb_depth_stencil, 0); - } - glBindTexture(GL_TEXTURE_2D, curr_tex); - -#else - curr_rb = 0; - glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb); - glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth_stencil); - glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_stencil_fmt, - sfc->w, sfc->h); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, sfc->rb_depth_stencil); - glBindRenderbuffer(GL_RENDERBUFFER, curr_rb); -#endif - } - - // Depth RenderBuffer - Attach it to FBO - if (sfc->rb_depth) - { - curr_rb = 0; - glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb); - - glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth); - - if (sfc->rt_msaa_samples) - glsym_glRenderbufferStorageMultisample(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, curr_rb); - } - - // Stencil RenderBuffer - Attach it to FBO - if (sfc->rb_stencil) - { - curr_rb = 0; - glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb); - - glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil); - - if (sfc->rt_msaa_samples) - glsym_glRenderbufferStorageMultisample(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, curr_rb); - } - - // Check FBO for completeness - fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (fb_status != GL_FRAMEBUFFER_COMPLETE) - { - ERR("FBO not complete. Error Code: %x!", fb_status); - _print_gl_surface_info(sfc, 1); - return 0; - } - - return 1; -} - -static int -_create_rt_buffers(Render_Engine *data __UNUSED__, - Render_Engine_GL_Surface *sfc) -{ - int ret = 0; - GLuint fbo = 0; - GLint curr_fbo = 0; - - //------------------------------------// - // Render Target texture - if (sfc->rt_fmt) - { - glGenTextures(1, &sfc->rt_tex); - } - - // First check if packed buffer is to be used. - if (sfc->rb_depth_stencil_fmt) - { -#ifdef GL_GLES - glGenTextures(1, &sfc->rb_depth_stencil); -#else - glGenRenderbuffers(1, &sfc->rb_depth_stencil); -#endif - } - else - { - // Depth RenderBuffer - Create storage here... - if (sfc->rb_depth_fmt) - glGenRenderbuffers(1, &sfc->rb_depth); - - // Stencil RenderBuffer - Create Storage here... - if (sfc->rb_stencil_fmt) - glGenRenderbuffers(1, &sfc->rb_stencil); - } - //------------------------------------// - // Try attaching the given configuration - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo); - glGenFramebuffers(1 ,&fbo); - - ret = _attach_fbo_surface(NULL, sfc, fbo); - - if (fbo) glDeleteFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)curr_fbo); - - if (!ret) - { - if (sfc->rt_tex) glDeleteTextures(1, &sfc->rt_tex); - if (sfc->rb_depth) glDeleteRenderbuffers(1, &sfc->rb_depth); - if (sfc->rb_stencil) glDeleteRenderbuffers(1, &sfc->rb_stencil); -#ifdef GL_GLES - if (sfc->rb_depth_stencil) glDeleteTextures(1, &sfc->rb_depth_stencil); -#else - if (sfc->rb_depth_stencil) glDeleteRenderbuffers(1, &sfc->rb_depth_stencil); -#endif - ERR("_attach_fbo_surface() failed."); - return 0; - } - else - return 1; -} - - +//--------------------------------// +// Evas GL Related Code static void * eng_gl_surface_create(void *data, void *config, int w, int h) { - Render_Engine *re; - Render_Engine_GL_Surface *sfc; - Evas_GL_Config *cfg; - void *ret = NULL; - int res; + Render_Engine *re = (Render_Engine *)data; + Evas_GL_Config *cfg = (Evas_GL_Config *)config; - re = (Render_Engine *)data; - cfg = (Evas_GL_Config *)config; - - // Allocate surface and fill in values - sfc = calloc(1, sizeof(Render_Engine_GL_Surface)); - if (!sfc) - { - ERR("Surface allocation failed."); - goto finish; - } - - sfc->w = w; - sfc->h = h; - sfc->depth_bits = cfg->depth_bits; - sfc->stencil_bits = cfg->stencil_bits; - - // Allow alpha for evas gl direct rendering override - // FIXME!!!: A little out of place but for now... - if (!gl_direct_override) - if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1; - - // Set the internal format based on the config - if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT) - { - DBG("Enabling Direct rendering to the Evas' window."); -#ifdef GL_GLES - sfc->direct_sfc = re->win->egl_surface[0]; -#else - sfc->direct_sfc = re->win->win; -#endif - } - - // Use resource surface/context to do a make current - if (!_internal_resources_make_current(re)) - { - ERR("Error doing a make current with the internal resources."); - goto finish; - } - - // 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)) - { - ERR("Unsupported Format!"); - goto finish; - } - - // Create Render texture - if (!_create_rt_buffers(re, sfc)) - { - ERR("Unable Create Specificed Surfaces. Unsupported format!"); - goto finish; - }; - - ret = sfc; - -finish: - -#ifdef GL_GLES - res = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -#else - res = glXMakeCurrent(re->info->info.display, None, NULL); -#endif - if (!res) - { - ERR("xxxMakeCurrent() (NULL, NULL) Error!"); - } - - if (!ret) - { - if (sfc) free(sfc); - } - return ret; + return evgl_surface_create(re->evgl_engine, cfg, w, h); } static int eng_gl_surface_destroy(void *data, void *surface) { - Render_Engine *re; - Render_Engine_GL_Surface *sfc; - int ret; + Render_Engine *re = (Render_Engine *)data; + EVGL_Surface *sfc = (EVGL_Surface *)surface; - re = (Render_Engine *)data; - sfc = (Render_Engine_GL_Surface*)surface; - - if (!sfc) return 0; - - // Use resource surface/context to create surface resrouces - if (!_internal_resources_make_current(re)) - { - ERR("Error doing a make current with the internal resources."); - return 0; - } - - // Reset the Framebuffer binding point - if ((current_evgl_ctx) && (current_evgl_ctx->current_fbo == current_evgl_ctx->context_fbo)) - { - //glBindFramebuffer(GL_FRAMEBUFFER, 0); - current_evgl_ctx->current_fbo = 0; - current_evgl_ctx->current_sfc = NULL; - } - - // Clear direct rendering flag - gl_direct_enabled = 0; - - // Delete FBO/RBO and Texture here - if (sfc->rt_tex) - glDeleteTextures(1, &sfc->rt_tex); - - if (sfc->rb_depth) - glDeleteRenderbuffers(1, &sfc->rb_depth); - - if (sfc->rb_stencil) - glDeleteRenderbuffers(1, &sfc->rb_stencil); - - if (sfc->rb_depth_stencil) - { -#ifdef GL_GLES - glDeleteTextures(1, &sfc->rb_depth_stencil); -#else - glDeleteRenderbuffers(1, &sfc->rb_depth_stencil); -#endif - } - - -#ifdef GL_GLES - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -#else - ret = glXMakeCurrent(re->info->info.display, None, NULL); -#endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - free(sfc); - return 0; - } - - free(sfc); - surface = NULL; - - return 1; + return evgl_surface_destroy(re->evgl_engine, sfc); } static void * eng_gl_context_create(void *data, void *share_context) { - Render_Engine *re; - Render_Engine_GL_Context *ctx; - Render_Engine_GL_Context *share_ctx; -#ifdef GL_GLES - int context_attrs[3]; -#endif + Render_Engine *re = (Render_Engine *)data; + EVGL_Context *sctx = (EVGL_Context *)share_context; - ctx = calloc(1, sizeof(Render_Engine_GL_Context)); - - if (!ctx) return NULL; - - re = (Render_Engine *)data; - share_ctx = (Render_Engine_GL_Context *)share_context; - - // Set the share context to Evas' GL context if share_context is NULL. - // Otherwise set it to the given share_context. -#ifdef GL_GLES - // EGL - context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; - context_attrs[1] = 2; - context_attrs[2] = EGL_NONE; - - if (share_ctx) - { - ctx->context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, - share_ctx->context, // Share Context - context_attrs); - } - else - { - ctx->context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, - re->win->egl_context[0], // Evas' GL Context - context_attrs); - } - - if (!ctx->context) - { - ERR("eglCreateContext() fail. code=%#x", eglGetError()); - return NULL; - } -#else - // GLX - if (share_context) - { - ctx->context = glXCreateContext(re->info->info.display, - re->win->visualinfo, - share_ctx->context, // Share Context - 1); - } - else - { - ctx->context = glXCreateContext(re->info->info.display, - re->win->visualinfo, - re->win->context, // Evas' GL Context - 1); - } - - if (!ctx->context) - { - ERR("glXCreateContext() fail."); - return NULL; - } -#endif - - ctx->initialized = 0; - ctx->context_fbo = 0; - ctx->current_sfc = NULL; - - return ctx; + return evgl_context_create(re->evgl_engine, sctx); } static int eng_gl_context_destroy(void *data, void *context) { - Render_Engine *re; - Render_Engine_GL_Context *ctx; - int ret; + Render_Engine *re = (Render_Engine *)data; + EVGL_Context *ctx = (EVGL_Context *)context; - re = (Render_Engine *)data; - ctx = (Render_Engine_GL_Context*)context; - - if (!ctx) return 0; - - // Use resource surface/context to create surface resrouces - if (!_internal_resources_make_current(re)) - { - ERR("Error doing a make current with the internal resources."); - return 0; - } - - // Delete the FBO - if (ctx->context_fbo) - glDeleteFramebuffers(1, &ctx->context_fbo); - - // Destroy the Context -#ifdef GL_GLES - eglDestroyContext(re->win->egl_disp, ctx->context); - - ctx->context = EGL_NO_CONTEXT; - - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); -#else - glXDestroyContext(re->info->info.display, ctx->context); - - ctx->context = 0; - - ret = glXMakeCurrent(re->info->info.display, None, NULL); -#endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; - } - - if (current_evgl_ctx == ctx) - current_evgl_ctx = NULL; - - free(ctx); - context = NULL; - - return 1; + return evgl_context_destroy(re->evgl_engine, ctx); } static int eng_gl_make_current(void *data __UNUSED__, void *surface, void *context) { - Render_Engine *re; - Render_Engine_GL_Surface *sfc; - Render_Engine_GL_Context *ctx; - int ret = 0; -#ifdef GL_GLES - Render_Engine_GL_Resource *rsc; -#endif + Render_Engine *re = (Render_Engine *)data; + EVGL_Surface *sfc = (EVGL_Surface *)surface; + EVGL_Context *ctx = (EVGL_Context *)context; - re = (Render_Engine *)data; - sfc = (Render_Engine_GL_Surface*)surface; - ctx = (Render_Engine_GL_Context*)context; - - current_engine = re; - - // Unset surface/context - if ((!sfc) || (!ctx)) - { -#ifdef GL_GLES - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); -#else - ret = glXMakeCurrent(re->info->info.display, None, NULL); -#endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; - } - - if (ctx) ctx->current_sfc = NULL; - if (sfc) sfc->current_ctx = NULL; - current_evgl_ctx = NULL; - return 1; - } - - // Check if direct rendering is possible: - // It's possible when direct_fb_opt is on and either current image - // object is valid or gl_direct_override is on. Override allows - // rendering outside of pixel getter but it doesn't guarantee - // correct rendering. - if ((sfc->direct_fb_opt) && (gl_direct_img_obj || gl_direct_override)) - { -#ifdef GL_GLES - sfc->direct_sfc = re->win->egl_surface[0]; -#else - sfc->direct_sfc = re->win->win; -#endif - gl_direct_enabled = 1; - } - else - gl_direct_enabled = 0; - - if (gl_direct_enabled) - { - GLint curr_fbo = 0; - - // Do a make current only if it's not already current -#ifdef GL_GLES - if ((eglGetCurrentContext() != ctx->context) || - (eglGetCurrentSurface(EGL_READ) != sfc->direct_sfc) || - (eglGetCurrentSurface(EGL_DRAW) != sfc->direct_sfc) ) - { - DBG("Rendering Directly to the window\n"); - - // Flush remainder of what's in Evas' pipeline - eng_window_use(NULL); - - // Do a make current - ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc, - sfc->direct_sfc, ctx->context); - if (!ret) - { - ERR("xxxMakeCurrent() failed! code=%#x", eglGetError()); - //ERR("xxxMakeCurrent() failed!"); - return 0; - } - } -#else - if ((glXGetCurrentContext() != ctx->context)) - { - // Flush remainder of what's in Evas' pipeline - eng_window_use(NULL); - - // Do a make current - ret = glXMakeCurrent(re->info->info.display, sfc->direct_sfc, ctx->context); - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; - } - } -#endif - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo); - if (ctx->context_fbo == (GLuint)curr_fbo) - { - ctx->current_fbo = 0; - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - } - else - { - // Do a make current only if it's not already current -#ifdef GL_GLES - if (eina_main_loop_is()) - { - if ((eglGetCurrentContext() != ctx->context) || - (eglGetCurrentSurface(EGL_READ) != re->win->egl_surface[0]) || - (eglGetCurrentSurface(EGL_DRAW) != re->win->egl_surface[0]) ) - { - - // Flush remainder of what's in Evas' pipeline - eng_window_use(NULL); - - // Do a make current - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], - re->win->egl_surface[0], ctx->context); - if (!ret) - { - ERR("xxxMakeCurrent() failed! code=%#x", eglGetError()); - return 0; - } - } - } - else - { - if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; - - if ((eglGetCurrentContext() != ctx->context) || - (eglGetCurrentSurface(EGL_READ) != rsc->surface) || - (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) ) - { - // Flush remainder of what's in Evas' pipeline - eng_window_use(NULL); - - // Do a make current - ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, - rsc->surface, ctx->context); - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; - } - } - } -#else - if ((glXGetCurrentContext() != ctx->context) || - (glXGetCurrentDrawable() != re->win->win) ) - { - // Flush remainder of what's in Evas' pipeline - 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 - - // Create FBO if not already created - if (!ctx->initialized) - { - glGenFramebuffers(1, &ctx->context_fbo); - ctx->initialized = 1; - } - - // Attach FBO if it hasn't been attached or if surface changed - if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc)) - { - if (!_attach_fbo_surface(re, sfc, ctx->context_fbo)) - { - ERR("_attach_fbo_surface() failed."); - _print_gl_surface_info(sfc, 1); - return 0; - } - - if (ctx->current_fbo) - // Bind to the previously bound buffer - glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo); - else - // Bind FBO - glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); - - sfc->fbo_attached = 1; - } - } - - // Set the current surface/context - ctx->current_sfc = sfc; - sfc->current_ctx = ctx; - current_evgl_ctx = ctx; - current_engine = re; - - return 1; + return evgl_make_current(re->evgl_engine, sfc, ctx); } static void * eng_gl_string_query(void *data __UNUSED__, int name) { - switch(name) - { - case EVAS_GL_EXTENSIONS: - return (void*)_evasgl_ext_string; - default: - return NULL; - }; + Render_Engine *re = (Render_Engine *)data; + + return (void *)evgl_string_query(re->evgl_engine, name); } +// Need to deprecate this function.. static void * -eng_gl_proc_address_get(void *data __UNUSED__, const char *name) +eng_gl_proc_address_get(void *data __UNUSED__, const char *name __UNUSED__) { -#ifdef GL_GLES - if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name); - return dlsym(RTLD_DEFAULT, name); -#else - if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name); - return dlsym(RTLD_DEFAULT, name); -#endif + return NULL; } static int eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_surface) { - Render_Engine_GL_Surface *sfc; - Evas_Native_Surface *ns; + Render_Engine *re = (Render_Engine *)data; + EVGL_Surface *sfc = (EVGL_Surface *)surface; + Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface; - sfc = (Render_Engine_GL_Surface*)surface; - ns = (Evas_Native_Surface*)native_surface; - - if (sfc->direct_fb_opt) - { - 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 = 0; - ns->data.opengl.x = 0; - ns->data.opengl.y = 0; - ns->data.opengl.w = sfc->w; - ns->data.opengl.h = sfc->h; - } - else - { - 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->rt_tex; - ns->data.opengl.x = 0; - ns->data.opengl.y = 0; - ns->data.opengl.w = sfc->w; - ns->data.opengl.h = sfc->h; - } - - return 1; + return evgl_native_surface_get(re->evgl_engine, sfc, ns); } - -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) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - - if (!ctx) - { - ERR("No current context set."); - return; - } - - // Take care of BindFramebuffer 0 issue - if (framebuffer==0) - { - if (gl_direct_enabled) - glBindFramebuffer(target, 0); - else - glBindFramebuffer(target, ctx->context_fbo); - ctx->current_fbo = 0; - } - else - { - glBindFramebuffer(target, framebuffer); - - // Save this for restore when doing make current - ctx->current_fbo = framebuffer; - } -} - -static void -evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer) -{ - // Add logic to take care when renderbuffer=0 - // On a second thought we don't need this - glBindRenderbuffer(target, renderbuffer); -} - -// Transform from Evas Coordinat to GL Coordinate -// returns: oc[4] original image object dimension in gl coord -// returns: nc[4] tranformed (x, y, width, heigth) in gl coord -static void -compute_gl_coordinates(Evas_Object *obj, int rot, int clip, - int x, int y, int width, int height, - int imgc[4], int objc[4]) -{ - if (rot == 0) - { - // oringinal image object coordinate in gl coordinate - imgc[0] = obj->cur.geometry.x; - imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h; - imgc[2] = imgc[0] + obj->cur.geometry.w; - imgc[3] = imgc[1] + obj->cur.geometry.h; - - // transformed (x,y,width,height) in gl coordinate - objc[0] = imgc[0] + x; - objc[1] = imgc[1] + y; - objc[2] = objc[0] + width; - objc[3] = objc[1] + height; - } - else if (rot == 180) - { - // oringinal image object coordinate in gl coordinate - imgc[0] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w; - imgc[1] = obj->cur.geometry.y; - imgc[2] = imgc[0] + obj->cur.geometry.w; - imgc[3] = imgc[1] + obj->cur.geometry.h; - - // transformed (x,y,width,height) in gl coordinate - objc[0] = imgc[0] + obj->cur.geometry.w - x - width; - objc[1] = imgc[1] + obj->cur.geometry.h - y - height; - objc[2] = objc[0] + width; - objc[3] = objc[1] + height; - - } - else if (rot == 90) - { - // oringinal image object coordinate in gl coordinate - imgc[0] = obj->cur.geometry.y; - imgc[1] = obj->cur.geometry.x; - imgc[2] = imgc[0] + obj->cur.geometry.h; - imgc[3] = imgc[1] + obj->cur.geometry.w; - - // transformed (x,y,width,height) in gl coordinate - objc[0] = imgc[0] + obj->cur.geometry.h - y - height; - objc[1] = imgc[1] + x; - objc[2] = objc[0] + height; - objc[3] = objc[1] + width; - } - else if (rot == 270) - { - // oringinal image object coordinate in gl coordinate - imgc[0] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h; - imgc[1] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w; - imgc[2] = imgc[0] + obj->cur.geometry.h; - imgc[3] = imgc[1] + obj->cur.geometry.w; - - // transformed (x,y,width,height) in gl coordinate - objc[0] = imgc[0] + y; - objc[1] = imgc[1] + obj->cur.geometry.w - x - width; - objc[2] = objc[0] + height; - objc[3] = objc[1] + width; - } - else - { - ERR("Invalid rotation angle %d.", rot); - return; - } - - if (clip) - { - // Clip against original image object - if (objc[0] < imgc[0]) objc[0] = imgc[0]; - if (objc[0] > imgc[2]) objc[0] = 0; - - if (objc[1] < imgc[1]) objc[1] = imgc[1]; - if (objc[1] > imgc[3]) objc[1] = 0; - - if (objc[2] < imgc[0]) objc[0] = 0; - if (objc[2] > imgc[2]) objc[2] = imgc[2]; - - if (objc[3] < imgc[1]) objc[1] = 0; - if (objc[3] > imgc[3]) objc[3] = imgc[3]; - } - - imgc[2] = imgc[2]-imgc[0]; // width - imgc[3] = imgc[3]-imgc[1]; // height - - objc[2] = objc[2]-objc[0]; // width - objc[3] = objc[3]-objc[1]; // height -} - -static void -evgl_glClear(GLbitfield mask) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - int rot = 0; - int oc[4], nc[4]; - - if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo)) - { - if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context)) - rot = current_engine->win->gl_context->rot; - else - ERR("Unable to retrieve rotation angle: %d", rot); - - compute_gl_coordinates(gl_direct_img_obj, rot, 0, 0, 0, 0, 0, oc, nc); - glScissor(oc[0], oc[1], oc[2], oc[3]); - glClear(mask); - } - else - glClear(mask); -} - -static void -evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - glClearColor(red, green, blue, alpha); -} - -static void -evgl_glEnable(GLenum cap) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - - if (cap == GL_SCISSOR_TEST) - if (ctx) ctx->scissor_enabled = 1; - glEnable(cap); -} - -static void -evgl_glDisable(GLenum cap) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - - if (cap == GL_SCISSOR_TEST) - if (ctx) ctx->scissor_enabled = 0; - glDisable(cap); -} - - -static void -evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - int rot = 0; - int oc[4], nc[4]; - - if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo)) - { - if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context)) - rot = current_engine->win->gl_context->rot; - else - ERR("Unable to retrieve rotation angle: %d", rot); - - compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc); - glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels); - } - else - glReadPixels(x, y, width, height, format, type, pixels); -} - -static void -evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - int rot = 0; - int oc[4], nc[4]; - - if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo)) - { - if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context)) - rot = current_engine->win->gl_context->rot; - else - ERR("Unable to retrieve rotation angle: %d", rot); - - compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc); - glScissor(nc[0], nc[1], nc[2], nc[3]); - ctx->scissor_upated = 1; - } - else - glScissor(x, y, width, height); -} - -static void -evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) -{ - Render_Engine_GL_Context *ctx = current_evgl_ctx; - int rot = 0; - int oc[4], nc[4]; - - if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo)) - { - if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context)) - rot = current_engine->win->gl_context->rot; - else - ERR("Unable to retrieve rotation angle: %d", rot); - - compute_gl_coordinates(gl_direct_img_obj, rot, 0, x, y, width, height, oc, nc); - glEnable(GL_SCISSOR_TEST); - glScissor(oc[0], oc[1], oc[2], oc[3]); - glViewport(nc[0], nc[1], nc[2], nc[3]); - } - else - glViewport(x, y, width, height); - -} - - -//----------------------------------------------// - -static void -evgl_glClearDepthf(GLclampf depth) -{ -#ifdef GL_GLES - glClearDepthf(depth); -#else - glClearDepth(depth); -#endif -} - -static void -evgl_glDepthRangef(GLclampf zNear, GLclampf zFar) -{ -#ifdef GL_GLES - glDepthRangef(zNear, zFar); -#else - glDepthRange(zNear, zFar); -#endif -} - -static void -evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) -{ -#ifdef GL_GLES - glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); -#else - if (range) - { - range[0] = -126; // floor(log2(FLT_MIN)) - range[1] = 127; // floor(log2(FLT_MAX)) - } - if (precision) - { - precision[0] = 24; // floor(-log2((1.0/16777218.0))); - } - return; -#endif -} - -static void -evgl_glReleaseShaderCompiler(void) -{ -#ifdef GL_GLES - glReleaseShaderCompiler(); -#else -#endif -} - -static void -evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) -{ -#ifdef GL_GLES - glShaderBinary(n, shaders, binaryformat, binary, length); -#else -// FIXME: need to dlsym/getprocaddress for this - return; - n = binaryformat = length = 0; - shaders = binary = 0; -#endif -} - -//--------------------------------// -#ifdef GL_GLES -// 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"); - return NULL; - } -} - -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 __UNUSED__) { - gl_funcs.version = EVAS_GL_API_VERSION; + Render_Engine *re = (Render_Engine *)data; -#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, ) - // GLES 2.0 - ORD(glActiveTexture); - ORD(glAttachShader); - ORD(glBindAttribLocation); - ORD(glBindBuffer); - ORD(glBindTexture); - ORD(glBlendColor); - ORD(glBlendEquation); - ORD(glBlendEquationSeparate); - ORD(glBlendFunc); - ORD(glBlendFuncSeparate); - ORD(glBufferData); - ORD(glBufferSubData); - ORD(glCheckFramebufferStatus); -// ORD(glClear); -// ORD(glClearColor); -// ORD(glClearDepthf); - ORD(glClearStencil); - ORD(glColorMask); - ORD(glCompileShader); - ORD(glCompressedTexImage2D); - ORD(glCompressedTexSubImage2D); - ORD(glCopyTexImage2D); - ORD(glCopyTexSubImage2D); - ORD(glCreateProgram); - ORD(glCreateShader); - ORD(glCullFace); - ORD(glDeleteBuffers); - ORD(glDeleteFramebuffers); - ORD(glDeleteProgram); - ORD(glDeleteRenderbuffers); - ORD(glDeleteShader); - ORD(glDeleteTextures); - ORD(glDepthFunc); - ORD(glDepthMask); -// ORD(glDepthRangef); - ORD(glDetachShader); -// ORD(glDisable); - ORD(glDisableVertexAttribArray); - ORD(glDrawArrays); - ORD(glDrawElements); -// ORD(glEnable); - ORD(glEnableVertexAttribArray); - ORD(glFinish); - ORD(glFlush); - ORD(glFramebufferRenderbuffer); - ORD(glFramebufferTexture2D); - ORD(glFrontFace); - ORD(glGenBuffers); - ORD(glGenerateMipmap); - ORD(glGenFramebuffers); - ORD(glGenRenderbuffers); - ORD(glGenTextures); - ORD(glGetActiveAttrib); - ORD(glGetActiveUniform); - ORD(glGetAttachedShaders); - ORD(glGetAttribLocation); - ORD(glGetBooleanv); - ORD(glGetBufferParameteriv); - ORD(glGetError); - ORD(glGetFloatv); - ORD(glGetFramebufferAttachmentParameteriv); - ORD(glGetIntegerv); - ORD(glGetProgramiv); - ORD(glGetProgramInfoLog); - ORD(glGetRenderbufferParameteriv); - ORD(glGetShaderiv); - ORD(glGetShaderInfoLog); -// ORD(glGetShaderPrecisionFormat); - ORD(glGetShaderSource); -// ORD(glGetString); - ORD(glGetTexParameterfv); - ORD(glGetTexParameteriv); - ORD(glGetUniformfv); - ORD(glGetUniformiv); - ORD(glGetUniformLocation); - ORD(glGetVertexAttribfv); - ORD(glGetVertexAttribiv); - ORD(glGetVertexAttribPointerv); - ORD(glHint); - ORD(glIsBuffer); - ORD(glIsEnabled); - ORD(glIsFramebuffer); - ORD(glIsProgram); - ORD(glIsRenderbuffer); - ORD(glIsShader); - ORD(glIsTexture); - ORD(glLineWidth); - ORD(glLinkProgram); - ORD(glPixelStorei); - ORD(glPolygonOffset); - ORD(glReadPixels); -// ORD(glReleaseShaderCompiler); - ORD(glRenderbufferStorage); - ORD(glSampleCoverage); -// ORD(glScissor); -// ORD(glShaderBinary); - ORD(glShaderSource); - ORD(glStencilFunc); - ORD(glStencilFuncSeparate); - ORD(glStencilMask); - ORD(glStencilMaskSeparate); - ORD(glStencilOp); - ORD(glStencilOpSeparate); - ORD(glTexImage2D); - ORD(glTexParameterf); - ORD(glTexParameterfv); - ORD(glTexParameteri); - ORD(glTexParameteriv); - ORD(glTexSubImage2D); - ORD(glUniform1f); - ORD(glUniform1fv); - ORD(glUniform1i); - ORD(glUniform1iv); - ORD(glUniform2f); - ORD(glUniform2fv); - ORD(glUniform2i); - ORD(glUniform2iv); - ORD(glUniform3f); - ORD(glUniform3fv); - ORD(glUniform3i); - ORD(glUniform3iv); - ORD(glUniform4f); - ORD(glUniform4fv); - ORD(glUniform4i); - ORD(glUniform4iv); - ORD(glUniformMatrix2fv); - ORD(glUniformMatrix3fv); - ORD(glUniformMatrix4fv); - ORD(glUseProgram); - ORD(glValidateProgram); - ORD(glVertexAttrib1f); - ORD(glVertexAttrib1fv); - ORD(glVertexAttrib2f); - ORD(glVertexAttrib2fv); - ORD(glVertexAttrib3f); - ORD(glVertexAttrib3fv); - ORD(glVertexAttrib4f); - ORD(glVertexAttrib4fv); - ORD(glVertexAttribPointer); -// 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); - - ORD(glClear); - ORD(glClearColor); - ORD(glEnable); - ORD(glDisable); - ORD(glReadPixels); - ORD(glScissor); - ORD(glViewport); - - // GLES2.0 API compat on top of desktop gl - ORD(glClearDepthf); - ORD(glDepthRangef); - ORD(glGetShaderPrecisionFormat); - ORD(glReleaseShaderCompiler); - ORD(glShaderBinary); - - ORD(glGetString); - -#ifdef GL_GLES - // GLES 2.0 Extensions that needs wrapping - ORD(evasglCreateImage); - ORD(evasglDestroyImage); - ORD(glEvasGLImageTargetTexture2DOES); - ORD(glEvasGLImageTargetRenderbufferStorageOES); -#endif - -#undef ORD - - return &gl_funcs; + return evgl_api_get(re->evgl_engine); } static void @@ -4609,18 +2617,19 @@ eng_gl_img_obj_set(void *data, void *image, int has_alpha) { Render_Engine *re = (Render_Engine *)data; - gl_direct_img_obj = NULL; - // Normally direct rendering isn't allowed if alpha is on and // rotation is not 0. BUT, if override is on, allow it. if ((has_alpha) || (re->win->gl_context->rot!=0)) { - if (gl_direct_override) - gl_direct_img_obj = image; + if (re->evgl_engine->direct_override) + evgl_direct_img_obj_set(re->evgl_engine, image); + else + evgl_direct_img_obj_set(re->evgl_engine, NULL); } else - gl_direct_img_obj = image; + evgl_direct_img_obj_set(re->evgl_engine, image); } +//--------------------------------// static int eng_image_load_error_get(void *data __UNUSED__, void *image) @@ -4761,16 +2770,6 @@ module_open(Evas_Module *em) return 0; } - - /* Allow alpha for evas gl direct rendering */ - if (getenv("EVAS_GL_DIRECT_OVERRIDE")) - { - gl_direct_override = 1; - DBG("########################################################"); - DBG("######### [Evas] Direct overriding is enabled ##########"); - DBG("########################################################"); - } - /* store it for later use */ func = pfunc; /* now to override methods */