diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 13e14914ae..14680bbeb6 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -617,3 +617,9 @@ 2012-01-03 Cedric Bail * Use Eina_File for PSD file to. + +2012-01-06 Sung W. Park (sung_) + + * Add EvasGL support to software backend using OSMesa. Requires OSMesa + library. Due to caveats in OSMesa, surface config stays with a + context diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index d868d4be3a..cd3fb333d9 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -1,6 +1,269 @@ #include "evas_common.h" /* Also includes international specific stuff */ #include "evas_private.h" + +#define EVAS_GL_NO_GL_H_CHECK 1 +#include "Evas_GL.h" + +#ifdef HAVE_DLSYM +# include /* dlopen,dlclose,etc */ +#else +# error software_generic should not get compiled if dlsym is not found on the system! +#endif + +//----------------------------------// +// OSMesa... + +#define OSMESA_MAJOR_VERSION 6 +#define OSMESA_MINOR_VERSION 5 +#define OSMESA_PATCH_VERSION 0 + +/* + * Values for the format parameter of OSMesaCreateContext() + * New in version 2.0. + */ +#define OSMESA_COLOR_INDEX GL_COLOR_INDEX +#define OSMESA_RGBA GL_RGBA +#define OSMESA_BGRA 0x1 +#define OSMESA_ARGB 0x2 +#define OSMESA_RGB GL_RGB +#define OSMESA_BGR 0x4 +#define OSMESA_RGB_565 0x5 + + +/* + * OSMesaPixelStore() parameters: + * New in version 2.0. + */ +#define OSMESA_ROW_LENGTH 0x10 +#define OSMESA_Y_UP 0x11 + + +/* + * Accepted by OSMesaGetIntegerv: + */ +#define OSMESA_WIDTH 0x20 +#define OSMESA_HEIGHT 0x21 +#define OSMESA_FORMAT 0x22 +#define OSMESA_TYPE 0x23 +#define OSMESA_MAX_WIDTH 0x24 /* new in 4.0 */ +#define OSMESA_MAX_HEIGHT 0x25 /* new in 4.0 */ + + +typedef void (*OSMESAproc)(); +typedef struct osmesa_context *OSMesaContext; + +typedef struct _Render_Engine_GL_Surface Render_Engine_GL_Surface; +typedef struct _Render_Engine_GL_Context Render_Engine_GL_Context; + +struct _Render_Engine_GL_Surface +{ + int initialized; + int w, h; + + GLenum internal_fmt; + int internal_cpp; // Component per pixel. ie. RGB = 3 + + int depth_bits; + int stencil_bits; + + // Data + void *buffer; + + Render_Engine_GL_Context *current_ctx; +}; + +struct _Render_Engine_GL_Context +{ + int initialized; + + OSMesaContext context; + + Render_Engine_GL_Context *share_ctx; + + Render_Engine_GL_Surface *current_sfc; +}; + + +//------------------------------------------------------// +typedef void (*_eng_fn) (void ); +typedef _eng_fn (*glsym_func_eng_fn) (); +typedef void (*glsym_func_void) (); +typedef unsigned int (*glsym_func_uint) (); +typedef int (*glsym_func_int) (); +typedef unsigned char (*glsym_func_uchar) (); +typedef unsigned char *(*glsym_func_uchar_ptr) (); +typedef const unsigned char *(*glsym_func_const_uchar_ptr) (); +typedef char const *(*glsym_func_char_const_ptr) (); +typedef GLboolean (*glsym_func_bool) (); +typedef OSMesaContext (*glsym_func_osm_ctx) (); +//------------------------------------------------------// + +/* Function table for GL APIs */ +static Evas_GL_API gl_funcs; +static void *gl_lib_handle; +static int gl_lib_is_gles = 0; +static Evas_GL_API gl_funcs; + +//------------------------------------------------------// +// OSMesa APIS... +static OSMesaContext (*_sym_OSMesaCreateContextExt) (GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist) = NULL; +static void (*_sym_OSMesaDestroyContext) (OSMesaContext ctx) = NULL; +static GLboolean (*_sym_OSMesaMakeCurrent) (OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height) = NULL; +static void (*_sym_OSMesaPixelStore) (GLint pname, GLint value) = NULL; +static OSMESAproc (*_sym_OSMesaGetProcAddress) (const char *funcName); + + +//------------------------------------------------------// +// GLES 2.0 APIs... +static void (*_sym_glActiveTexture) (GLenum texture) = NULL; +static void (*_sym_glAttachShader) (GLuint program, GLuint shader) = NULL; +static void (*_sym_glBindAttribLocation) (GLuint program, GLuint index, const char* name) = NULL; +static void (*_sym_glBindBuffer) (GLenum target, GLuint buffer) = NULL; +static void (*_sym_glBindFramebuffer) (GLenum target, GLuint framebuffer) = NULL; +static void (*_sym_glBindRenderbuffer) (GLenum target, GLuint renderbuffer) = NULL; +static void (*_sym_glBindTexture) (GLenum target, GLuint texture) = NULL; +static void (*_sym_glBlendColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL; +static void (*_sym_glBlendEquation) (GLenum mode) = NULL; +static void (*_sym_glBlendEquationSeparate) (GLenum modeRGB, GLenum modeAlpha) = NULL; +static void (*_sym_glBlendFunc) (GLenum sfactor, GLenum dfactor) = NULL; +static void (*_sym_glBlendFuncSeparate) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = NULL; +static void (*_sym_glBufferData) (GLenum target, GLsizeiptr size, const void* data, GLenum usage) = NULL; +static void (*_sym_glBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data) = NULL; +static GLenum (*_sym_glCheckFramebufferStatus) (GLenum target) = NULL; +static void (*_sym_glClear) (GLbitfield mask) = NULL; +static void (*_sym_glClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL; +static void (*_sym_glClearDepthf) (GLclampf depth) = NULL; +static void (*_sym_glClearStencil) (GLint s) = NULL; +static void (*_sym_glColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = NULL; +static void (*_sym_glCompileShader) (GLuint shader) = NULL; +static void (*_sym_glCompressedTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) = NULL; +static void (*_sym_glCompressedTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) = NULL; +static void (*_sym_glCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) = NULL; +static void (*_sym_glCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +static GLuint (*_sym_glCreateProgram) (void) = NULL; +static GLuint (*_sym_glCreateShader) (GLenum type) = NULL; +static void (*_sym_glCullFace) (GLenum mode) = NULL; +static void (*_sym_glDeleteBuffers) (GLsizei n, const GLuint* buffers) = NULL; +static void (*_sym_glDeleteFramebuffers) (GLsizei n, const GLuint* framebuffers) = NULL; +static void (*_sym_glDeleteProgram) (GLuint program) = NULL; +static void (*_sym_glDeleteRenderbuffers) (GLsizei n, const GLuint* renderbuffers) = NULL; +static void (*_sym_glDeleteShader) (GLuint shader) = NULL; +static void (*_sym_glDeleteTextures) (GLsizei n, const GLuint* textures) = NULL; +static void (*_sym_glDepthFunc) (GLenum func) = NULL; +static void (*_sym_glDepthMask) (GLboolean flag) = NULL; +static void (*_sym_glDepthRangef) (GLclampf zNear, GLclampf zFar) = NULL; +static void (*_sym_glDetachShader) (GLuint program, GLuint shader) = NULL; +static void (*_sym_glDisable) (GLenum cap) = NULL; +static void (*_sym_glDisableVertexAttribArray) (GLuint index) = NULL; +static void (*_sym_glDrawArrays) (GLenum mode, GLint first, GLsizei count) = NULL; +static void (*_sym_glDrawElements) (GLenum mode, GLsizei count, GLenum type, const void* indices) = NULL; +static void (*_sym_glEnable) (GLenum cap) = NULL; +static void (*_sym_glEnableVertexAttribArray) (GLuint index) = NULL; +static void (*_sym_glFinish) (void) = NULL; +static void (*_sym_glFlush) (void) = NULL; +static void (*_sym_glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) = NULL; +static void (*_sym_glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) = NULL; +static void (*_sym_glFrontFace) (GLenum mode) = NULL; +static void (*_sym_glGenBuffers) (GLsizei n, GLuint* buffers) = NULL; +static void (*_sym_glGenerateMipmap) (GLenum target) = NULL; +static void (*_sym_glGenFramebuffers) (GLsizei n, GLuint* framebuffers) = NULL; +static void (*_sym_glGenRenderbuffers) (GLsizei n, GLuint* renderbuffers) = NULL; +static void (*_sym_glGenTextures) (GLsizei n, GLuint* textures) = NULL; +static void (*_sym_glGetActiveAttrib) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL; +static void (*_sym_glGetActiveUniform) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL; +static void (*_sym_glGetAttachedShaders) (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) = NULL; +static int (*_sym_glGetAttribLocation) (GLuint program, const char* name) = NULL; +static void (*_sym_glGetBooleanv) (GLenum pname, GLboolean* params) = NULL; +static void (*_sym_glGetBufferParameteriv) (GLenum target, GLenum pname, GLint* params) = NULL; +static GLenum (*_sym_glGetError) (void) = NULL; +static void (*_sym_glGetFloatv) (GLenum pname, GLfloat* params) = NULL; +static void (*_sym_glGetFramebufferAttachmentParameteriv) (GLenum target, GLenum attachment, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetIntegerv) (GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetProgramiv) (GLuint program, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetProgramInfoLog) (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = NULL; +static void (*_sym_glGetRenderbufferParameteriv) (GLenum target, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetShaderiv) (GLuint shader, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetShaderInfoLog) (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = NULL; +static void (*_sym_glGetShaderPrecisionFormat) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) = NULL; +static void (*_sym_glGetShaderSource) (GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = NULL; +static const GLubyte *(*_sym_glGetString) (GLenum name) = NULL; +static void (*_sym_glGetTexParameterfv) (GLenum target, GLenum pname, GLfloat* params) = NULL; +static void (*_sym_glGetTexParameteriv) (GLenum target, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetUniformfv) (GLuint program, GLint location, GLfloat* params) = NULL; +static void (*_sym_glGetUniformiv) (GLuint program, GLint location, GLint* params) = NULL; +static int (*_sym_glGetUniformLocation) (GLuint program, const char* name) = NULL; +static void (*_sym_glGetVertexAttribfv) (GLuint index, GLenum pname, GLfloat* params) = NULL; +static void (*_sym_glGetVertexAttribiv) (GLuint index, GLenum pname, GLint* params) = NULL; +static void (*_sym_glGetVertexAttribPointerv) (GLuint index, GLenum pname, void** pointer) = NULL; +static void (*_sym_glHint) (GLenum target, GLenum mode) = NULL; +static GLboolean (*_sym_glIsBuffer) (GLuint buffer) = NULL; +static GLboolean (*_sym_glIsEnabled) (GLenum cap) = NULL; +static GLboolean (*_sym_glIsFramebuffer) (GLuint framebuffer) = NULL; +static GLboolean (*_sym_glIsProgram) (GLuint program) = NULL; +static GLboolean (*_sym_glIsRenderbuffer) (GLuint renderbuffer) = NULL; +static GLboolean (*_sym_glIsShader) (GLuint shader) = NULL; +static GLboolean (*_sym_glIsTexture) (GLuint texture) = NULL; +static void (*_sym_glLineWidth) (GLfloat width) = NULL; +static void (*_sym_glLinkProgram) (GLuint program) = NULL; +static void (*_sym_glPixelStorei) (GLenum pname, GLint param) = NULL; +static void (*_sym_glPolygonOffset) (GLfloat factor, GLfloat units) = NULL; +static void (*_sym_glReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) = NULL; +static void (*_sym_glReleaseShaderCompiler) (void) = NULL; +static void (*_sym_glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = NULL; +static void (*_sym_glSampleCoverage) (GLclampf value, GLboolean invert) = NULL; +static void (*_sym_glScissor) (GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +static void (*_sym_glShaderBinary) (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) = NULL; +static void (*_sym_glShaderSource) (GLuint shader, GLsizei count, const char** string, const GLint* length) = NULL; +static void (*_sym_glStencilFunc) (GLenum func, GLint ref, GLuint mask) = NULL; +static void (*_sym_glStencilFuncSeparate) (GLenum face, GLenum func, GLint ref, GLuint mask) = NULL; +static void (*_sym_glStencilMask) (GLuint mask) = NULL; +static void (*_sym_glStencilMaskSeparate) (GLenum face, GLuint mask) = NULL; +static void (*_sym_glStencilOp) (GLenum fail, GLenum zfail, GLenum zpass) = NULL; +static void (*_sym_glStencilOpSeparate) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) = NULL; +static void (*_sym_glTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) = NULL; +static void (*_sym_glTexParameterf) (GLenum target, GLenum pname, GLfloat param) = NULL; +static void (*_sym_glTexParameterfv) (GLenum target, GLenum pname, const GLfloat* params) = NULL; +static void (*_sym_glTexParameteri) (GLenum target, GLenum pname, GLint param) = NULL; +static void (*_sym_glTexParameteriv) (GLenum target, GLenum pname, const GLint* params) = NULL; +static void (*_sym_glTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) = NULL; +static void (*_sym_glUniform1f) (GLint location, GLfloat x) = NULL; +static void (*_sym_glUniform1fv) (GLint location, GLsizei count, const GLfloat* v) = NULL; +static void (*_sym_glUniform1i) (GLint location, GLint x) = NULL; +static void (*_sym_glUniform1iv) (GLint location, GLsizei count, const GLint* v) = NULL; +static void (*_sym_glUniform2f) (GLint location, GLfloat x, GLfloat y) = NULL; +static void (*_sym_glUniform2fv) (GLint location, GLsizei count, const GLfloat* v) = NULL; +static void (*_sym_glUniform2i) (GLint location, GLint x, GLint y) = NULL; +static void (*_sym_glUniform2iv) (GLint location, GLsizei count, const GLint* v) = NULL; +static void (*_sym_glUniform3f) (GLint location, GLfloat x, GLfloat y, GLfloat z) = NULL; +static void (*_sym_glUniform3fv) (GLint location, GLsizei count, const GLfloat* v) = NULL; +static void (*_sym_glUniform3i) (GLint location, GLint x, GLint y, GLint z) = NULL; +static void (*_sym_glUniform3iv) (GLint location, GLsizei count, const GLint* v) = NULL; +static void (*_sym_glUniform4f) (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL; +static void (*_sym_glUniform4fv) (GLint location, GLsizei count, const GLfloat* v) = NULL; +static void (*_sym_glUniform4i) (GLint location, GLint x, GLint y, GLint z, GLint w) = NULL; +static void (*_sym_glUniform4iv) (GLint location, GLsizei count, const GLint* v) = NULL; +static void (*_sym_glUniformMatrix2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL; +static void (*_sym_glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL; +static void (*_sym_glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL; +static void (*_sym_glUseProgram) (GLuint program) = NULL; +static void (*_sym_glValidateProgram) (GLuint program) = NULL; +static void (*_sym_glVertexAttrib1f) (GLuint indx, GLfloat x) = NULL; +static void (*_sym_glVertexAttrib1fv) (GLuint indx, const GLfloat* values) = NULL; +static void (*_sym_glVertexAttrib2f) (GLuint indx, GLfloat x, GLfloat y) = NULL; +static void (*_sym_glVertexAttrib2fv) (GLuint indx, const GLfloat* values) = NULL; +static void (*_sym_glVertexAttrib3f) (GLuint indx, GLfloat x, GLfloat y, GLfloat z) = NULL; +static void (*_sym_glVertexAttrib3fv) (GLuint indx, const GLfloat* values) = NULL; +static void (*_sym_glVertexAttrib4f) (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL; +static void (*_sym_glVertexAttrib4fv) (GLuint indx, const GLfloat* values) = NULL; +static void (*_sym_glVertexAttribPointer) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) = NULL; +static void (*_sym_glViewport) (GLint x, GLint y, GLsizei width, GLsizei height) = NULL; + +// GLES Extensions... +static void (*_sym_glGetProgramBinary) (GLuint a, GLsizei b, GLsizei* c, GLenum* d, void* e) = NULL; +static void (*_sym_glProgramBinary) (GLuint a, GLenum b, const void* c, GLint d) = NULL; +static void (*_sym_glProgramParameteri) (GLuint a, GLuint b, GLint d) = NULL; + /* ***** ** @@ -358,7 +621,37 @@ eng_image_colorspace_set(void *data __UNUSED__, void *image, int cspace) static void * eng_image_native_set(void *data __UNUSED__, void *image, void *native __UNUSED__) { - return image; + //return image; + Evas_Native_Surface *ns = native; + Image_Entry *im = image, *im2 = NULL; + + if (!im) + { + if ((!ns) && (ns->data.x11.visual)) + { + im = evas_cache_image_data(evas_common_image_cache_get(), + im->w, im->h, + ns->data.x11.visual, 1, + EVAS_COLORSPACE_ARGB8888); + return im; + } + else + return NULL; + } + + if ((!ns) && (!im)) return im; + + if (!ns) return im; + + im2 = evas_cache_image_data(evas_common_image_cache_get(), + im->w, im->h, + ns->data.x11.visual, 1, + EVAS_COLORSPACE_ARGB8888); + evas_cache_image_drop(im); + im = im2; + + return im; + } static void * @@ -1044,6 +1337,268 @@ eng_image_load_error_get(void *data __UNUSED__, void *image) return im->cache_entry.load_error; } +//------------ Evas GL engine code ---------------// +static void * +eng_gl_surface_create(void *data __UNUSED__, void *config, int w, int h) +{ + Render_Engine_GL_Surface *sfc; + Evas_GL_Config *cfg; + + sfc = calloc(1, sizeof(Render_Engine_GL_Surface)); + if (!sfc) return NULL; + + cfg = (Evas_GL_Config *)config; + + sfc->initialized = 0; + sfc->w = w; + sfc->h = h; + + // Color Format + switch (cfg->color_format) + { + + case EVAS_GL_RGB_888: + sfc->internal_fmt = OSMESA_RGB; + sfc->internal_cpp = 3; + break; + case EVAS_GL_RGBA_8888: + sfc->internal_fmt = OSMESA_BGRA; + sfc->internal_cpp = 4; + break; + default: + sfc->internal_fmt = OSMESA_RGBA; + sfc->internal_cpp = 4; + break; + } + + // Depth Bits + switch (cfg->depth_bits) + { + case EVAS_GL_DEPTH_BIT_8: + sfc->depth_bits = 8; + break; + case EVAS_GL_DEPTH_BIT_16: + sfc->depth_bits = 16; + break; + case EVAS_GL_DEPTH_BIT_24: + sfc->depth_bits = 24; + break; + case EVAS_GL_DEPTH_BIT_32: + sfc->depth_bits = 32; + break; + case EVAS_GL_DEPTH_NONE: + default: + sfc->depth_bits = 0; + break; + } + + // Stencil Bits + switch (cfg->stencil_bits) + { + case EVAS_GL_STENCIL_BIT_1: + sfc->stencil_bits = 1; + break; + case EVAS_GL_STENCIL_BIT_2: + sfc->stencil_bits = 2; + break; + case EVAS_GL_STENCIL_BIT_4: + sfc->stencil_bits = 4; + break; + case EVAS_GL_STENCIL_BIT_8: + sfc->stencil_bits = 8; + break; + case EVAS_GL_STENCIL_BIT_16: + sfc->stencil_bits = 16; + break; + case EVAS_GL_STENCIL_NONE: + default: + sfc->stencil_bits = 0; + break; + } + + sfc->buffer = malloc(sizeof(unsigned char)*sfc->internal_cpp*w*h); + + if (!sfc->buffer) + { + free(sfc); + return NULL; + } + + return sfc; +} + +static int +eng_gl_surface_destroy(void *data __UNUSED__, void *surface) +{ + Render_Engine_GL_Surface *sfc; + + sfc = (Render_Engine_GL_Surface*)surface; + + if (!sfc) return 0; + + if (sfc->buffer) free(sfc->buffer); + + free(sfc); + + surface = NULL; + + return 1; +} + +static void * +eng_gl_context_create(void *data __UNUSED__, void *share_context) +{ + Render_Engine_GL_Context *ctx; + Render_Engine_GL_Context *share_ctx; + + ctx = calloc(1, sizeof(Render_Engine_GL_Context)); + + if (!ctx) return NULL; + + share_ctx = (Render_Engine_GL_Context *)share_context; + + ctx->share_ctx = share_ctx; + + /* + if (share_ctx) + ctx->context = OSMesaCreateContextExt( OSMESA_RGBA, 8, 0, 0, share_ctx->context ); + else + ctx->context = OSMesaCreateContextExt( OSMESA_RGBA, 8, 0, 0, NULL ); + + + if (!ctx->context) + { + ERR("Error creating OSMesa Context."); + free(ctx); + return NULL; + } + */ + + ctx->initialized = 0; + + return ctx; +} + +static int +eng_gl_context_destroy(void *data __UNUSED__, void *context) +{ + Render_Engine_GL_Context *ctx; + + ctx = (Render_Engine_GL_Context*)context; + + if (!ctx) return 0; + + _sym_OSMesaDestroyContext(ctx->context); + + free(ctx); + context = NULL; + + return 1; +} + +static int +eng_gl_make_current(void *data __UNUSED__, void *surface, void *context) +{ + Render_Engine_GL_Surface *sfc; + Render_Engine_GL_Context *ctx; + OSMesaContext share_ctx; + GLboolean ret; + + sfc = (Render_Engine_GL_Surface*)surface; + ctx = (Render_Engine_GL_Context*)context; + + // Unset surface/context + if ((!sfc) || (!ctx)) + { + if (ctx) ctx->current_sfc = NULL; + if (sfc) sfc->current_ctx = NULL; + return 1; + } + + // Initialize Context if it hasn't been. + if (!ctx->initialized) + { + if (ctx->share_ctx) + share_ctx = ctx->share_ctx->context; + else + share_ctx = NULL; + + ctx->context = _sym_OSMesaCreateContextExt(sfc->internal_fmt, + sfc->depth_bits, + sfc->stencil_bits, + 0, + share_ctx); + if (!ctx->context) + { + ERR("Error initializing context."); + return 0; + } + + ctx->initialized = 1; + } + + + // Call MakeCurrent + ret = _sym_OSMesaMakeCurrent(ctx->context, sfc->buffer, GL_UNSIGNED_BYTE, + sfc->w, sfc->h); + + if (ret == GL_FALSE) + { + ERR("Error doing MakeCurrent."); + return 0; + } + + _sym_OSMesaPixelStore(OSMESA_Y_UP, 0); + + // Set the current surface/context + ctx->current_sfc = sfc; + sfc->current_ctx = ctx; + + return 1; +} + +// FIXME!!! Implement later +static void * +eng_gl_string_query(void *data, int name) +{ + return NULL; +} + +static void * +eng_gl_proc_address_get(void *data __UNUSED__, const char *name) +{ + if (_sym_OSMesaGetProcAddress) return _sym_OSMesaGetProcAddress(name); + return dlsym(RTLD_DEFAULT, name); +} + +static int +eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_surface) +{ + Render_Engine_GL_Surface *sfc; + Evas_Native_Surface *ns; + + sfc = (Render_Engine_GL_Surface*)surface; + ns = (Evas_Native_Surface*)native_surface; + + if (!sfc) return 0; + + ns->type = EVAS_NATIVE_SURFACE_OPENGL; + ns->version = EVAS_NATIVE_SURFACE_VERSION; + ns->data.x11.visual = sfc->buffer; + + return 1; +} + + +static void * +eng_gl_api_get(void *data __UNUSED__) +{ + return &gl_funcs; +} + +//------------------------------------------------// + + /* ***** ** @@ -1171,15 +1726,15 @@ static Evas_Func func = eng_image_filtered_save, eng_image_filtered_free, #endif - NULL, // FIXME: need software mesa for gl rendering <- gl_surface_create - NULL, // FIXME: need software mesa for gl rendering <- gl_surface_destroy - NULL, // FIXME: need software mesa for gl rendering <- gl_context_create - NULL, // FIXME: need software mesa for gl rendering <- gl_context_destroy - NULL, // FIXME: need software mesa for gl rendering <- gl_make_current - NULL, // FIXME: need software mesa for gl rendering <- gl_string_query - NULL, // FIXME: need software mesa for gl rendering <- gl_proc_address_get - NULL, // FIXME: need software mesa for gl rendering <- gl_native_surface_get - NULL, // FIXME: need software mesa for gl rendering <- gl_api_get + NULL, // need software mesa for gl rendering <- gl_surface_create + NULL, // need software mesa for gl rendering <- gl_surface_destroy + NULL, // need software mesa for gl rendering <- gl_context_create + NULL, // need software mesa for gl rendering <- gl_context_destroy + NULL, // need software mesa for gl rendering <- gl_make_current + NULL, // need software mesa for gl rendering <- gl_string_query + NULL, // need software mesa for gl rendering <- gl_proc_address_get + NULL, // need software mesa for gl rendering <- gl_native_surface_get + NULL, // need software mesa for gl rendering <- gl_api_get eng_image_load_error_get, eng_font_run_font_end_get, eng_image_animated_get, @@ -1192,6 +1747,980 @@ static Evas_Func func = /* FUTURE software generic calls go here */ }; + +//----------------------------------------------------------------// +// // +// Load Symbols // +// // +//----------------------------------------------------------------// +static void +sym_missing(void) +{ + ERR("GL symbols missing!\n"); +} + + +static int +glue_sym_init(void) +{ + //------------------------------------------------// + // Use eglGetProcAddress +#define FINDSYM(dst, sym, typ) \ + if (!dst) dst = (typeof(dst))dlsym(gl_lib_handle, sym); \ + if (!dst) \ + { \ + ERR("Symbol not found %s\n", sym); \ + return 0; \ + } +#define FALLBAK(dst, typ) if (!dst) dst = (typeof(dst))sym_missing; + + //------------------------------------------------------// + // OSMesa APIs... + FINDSYM(_sym_OSMesaCreateContextExt, "OSMesaCreateContextExt", glsym_func_osm_ctx); + FALLBAK(_sym_OSMesaCreateContextExt, glsym_func_void); + + FINDSYM(_sym_OSMesaDestroyContext, "OSMesaDestroyContext", glsym_func_void); + FALLBAK(_sym_OSMesaDestroyContext, glsym_func_void); + + FINDSYM(_sym_OSMesaMakeCurrent, "OSMesaMakeCurrent", glsym_func_bool); + FALLBAK(_sym_OSMesaMakeCurrent, glsym_func_void); + + FINDSYM(_sym_OSMesaPixelStore, "OSMesaPixelStore", glsym_func_void); + FALLBAK(_sym_OSMesaPixelStore, glsym_func_void); + + FINDSYM(_sym_OSMesaGetProcAddress, "OSMesaGetProcAddress", glsym_func_eng_fn); + FALLBAK(_sym_OSMesaGetProcAddress, glsym_func_void); + +#undef FINDSYM +#undef FALLBAK + + return 1; +} + +static int +gl_sym_init(void) +{ + //------------------------------------------------// +#define FINDSYM(dst, sym, typ) \ + if (!dst) dst = (typeof(dst))dlsym(gl_lib_handle, sym); \ + if (!dst) DBG("Symbol not found %s\n", sym); +#define FALLBAK(dst, typ) if (!dst) dst = (typeof(dst))sym_missing; + + + //------------------------------------------------------// + // GLES 2.0 APIs... + FINDSYM(_sym_glActiveTexture, "glActiveTexture", glsym_func_void); + FALLBAK(_sym_glActiveTexture, glsym_func_void); + + FINDSYM(_sym_glAttachShader, "glAttachShader", glsym_func_void); + FALLBAK(_sym_glAttachShader, glsym_func_void); + + FINDSYM(_sym_glBindAttribLocation, "glBindAttribLocation", glsym_func_void); + FALLBAK(_sym_glBindAttribLocation, glsym_func_void); + + FINDSYM(_sym_glBindBuffer, "glBindBuffer", glsym_func_void); + FALLBAK(_sym_glBindBuffer, glsym_func_void); + + FINDSYM(_sym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void); + FALLBAK(_sym_glBindFramebuffer, glsym_func_void); + + FINDSYM(_sym_glBindRenderbuffer, "glBindRenderbuffer", glsym_func_void); + FALLBAK(_sym_glBindRenderbuffer, glsym_func_void); + + FINDSYM(_sym_glBindTexture, "glBindTexture", glsym_func_void); + FALLBAK(_sym_glBindTexture, glsym_func_void); + + FINDSYM(_sym_glBlendColor, "glBlendColor", glsym_func_void); + FALLBAK(_sym_glBlendColor, glsym_func_void); + + FINDSYM(_sym_glBlendEquation, "glBlendEquation", glsym_func_void); + FALLBAK(_sym_glBlendEquation, glsym_func_void); + + FINDSYM(_sym_glBlendEquationSeparate, "glBlendEquationSeparate", glsym_func_void); + FALLBAK(_sym_glBlendEquationSeparate, glsym_func_void); + + FINDSYM(_sym_glBlendFunc, "glBlendFunc", glsym_func_void); + FALLBAK(_sym_glBlendFunc, glsym_func_void); + + FINDSYM(_sym_glBlendFuncSeparate, "glBlendFuncSeparate", glsym_func_void); + FALLBAK(_sym_glBlendFuncSeparate, glsym_func_void); + + FINDSYM(_sym_glBufferData, "glBufferData", glsym_func_void); + FALLBAK(_sym_glBufferData, glsym_func_void); + + FINDSYM(_sym_glBufferSubData, "glBufferSubData", glsym_func_void); + FALLBAK(_sym_glBufferSubData, glsym_func_void); + + FINDSYM(_sym_glCheckFramebufferStatus, "glCheckFramebufferStatus", glsym_func_uint); + FALLBAK(_sym_glCheckFramebufferStatus, glsym_func_uint); + + FINDSYM(_sym_glClear, "glClear", glsym_func_void); + FALLBAK(_sym_glClear, glsym_func_void); + + FINDSYM(_sym_glClearColor, "glClearColor", glsym_func_void); + FALLBAK(_sym_glClearColor, glsym_func_void); + + FINDSYM(_sym_glClearDepthf, "glClearDepthf", glsym_func_void); + FINDSYM(_sym_glClearDepthf, "glClearDepth", glsym_func_void); + FALLBAK(_sym_glClearDepthf, glsym_func_void); + + FINDSYM(_sym_glClearStencil, "glClearStencil", glsym_func_void); + FALLBAK(_sym_glClearStencil, glsym_func_void); + + FINDSYM(_sym_glColorMask, "glColorMask", glsym_func_void); + FALLBAK(_sym_glColorMask, glsym_func_void); + + FINDSYM(_sym_glCompileShader, "glCompileShader", glsym_func_void); + FALLBAK(_sym_glCompileShader, glsym_func_void); + + FINDSYM(_sym_glCompressedTexImage2D, "glCompressedTexImage2D", glsym_func_void); + FALLBAK(_sym_glCompressedTexImage2D, glsym_func_void); + + FINDSYM(_sym_glCompressedTexSubImage2D, "glCompressedTexSubImage2D", glsym_func_void); + FALLBAK(_sym_glCompressedTexSubImage2D, glsym_func_void); + + FINDSYM(_sym_glCopyTexImage2D, "glCopyTexImage2D", glsym_func_void); + FALLBAK(_sym_glCopyTexImage2D, glsym_func_void); + + FINDSYM(_sym_glCopyTexSubImage2D, "glCopyTexSubImage2D", glsym_func_void); + FALLBAK(_sym_glCopyTexSubImage2D, glsym_func_void); + + FINDSYM(_sym_glCreateProgram, "glCreateProgram", glsym_func_uint); + FALLBAK(_sym_glCreateProgram, glsym_func_uint); + + FINDSYM(_sym_glCreateShader, "glCreateShader", glsym_func_uint); + FALLBAK(_sym_glCreateShader, glsym_func_uint); + + FINDSYM(_sym_glCullFace, "glCullFace", glsym_func_void); + FALLBAK(_sym_glCullFace, glsym_func_void); + + FINDSYM(_sym_glDeleteBuffers, "glDeleteBuffers", glsym_func_void); + FALLBAK(_sym_glDeleteBuffers, glsym_func_void); + + FINDSYM(_sym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void); + FALLBAK(_sym_glDeleteFramebuffers, glsym_func_void); + + FINDSYM(_sym_glDeleteProgram, "glDeleteProgram", glsym_func_void); + FALLBAK(_sym_glDeleteProgram, glsym_func_void); + + FINDSYM(_sym_glDeleteRenderbuffers, "glDeleteRenderbuffers", glsym_func_void); + FALLBAK(_sym_glDeleteRenderbuffers, glsym_func_void); + + FINDSYM(_sym_glDeleteShader, "glDeleteShader", glsym_func_void); + FALLBAK(_sym_glDeleteShader, glsym_func_void); + + FINDSYM(_sym_glDeleteTextures, "glDeleteTextures", glsym_func_void); + FALLBAK(_sym_glDeleteTextures, glsym_func_void); + + FINDSYM(_sym_glDepthFunc, "glDepthFunc", glsym_func_void); + FALLBAK(_sym_glDepthFunc, glsym_func_void); + + FINDSYM(_sym_glDepthMask, "glDepthMask", glsym_func_void); + FALLBAK(_sym_glDepthMask, glsym_func_void); + + FINDSYM(_sym_glDepthRangef, "glDepthRangef", glsym_func_void); + FINDSYM(_sym_glDepthRangef, "glDepthRange", glsym_func_void); + FALLBAK(_sym_glDepthRangef, glsym_func_void); + + FINDSYM(_sym_glDetachShader, "glDetachShader", glsym_func_void); + FALLBAK(_sym_glDetachShader, glsym_func_void); + + FINDSYM(_sym_glDisable, "glDisable", glsym_func_void); + FALLBAK(_sym_glDisable, glsym_func_void); + + FINDSYM(_sym_glDisableVertexAttribArray, "glDisableVertexAttribArray", glsym_func_void); + FALLBAK(_sym_glDisableVertexAttribArray, glsym_func_void); + + FINDSYM(_sym_glDrawArrays, "glDrawArrays", glsym_func_void); + FALLBAK(_sym_glDrawArrays, glsym_func_void); + + FINDSYM(_sym_glDrawElements, "glDrawElements", glsym_func_void); + FALLBAK(_sym_glDrawElements, glsym_func_void); + + FINDSYM(_sym_glEnable, "glEnable", glsym_func_void); + FALLBAK(_sym_glEnable, glsym_func_void); + + FINDSYM(_sym_glEnableVertexAttribArray, "glEnableVertexAttribArray", glsym_func_void); + FALLBAK(_sym_glEnableVertexAttribArray, glsym_func_void); + + FINDSYM(_sym_glFinish, "glFinish", glsym_func_void); + FALLBAK(_sym_glFinish, glsym_func_void); + + FINDSYM(_sym_glFlush, "glFlush", glsym_func_void); + FALLBAK(_sym_glFlush, glsym_func_void); + + FINDSYM(_sym_glFramebufferRenderbuffer, "glFramebufferRenderbuffer", glsym_func_void); + FALLBAK(_sym_glFramebufferRenderbuffer, glsym_func_void); + + FINDSYM(_sym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void); + FALLBAK(_sym_glFramebufferTexture2D, glsym_func_void); + + FINDSYM(_sym_glFrontFace, "glFrontFace", glsym_func_void); + FALLBAK(_sym_glFrontFace, glsym_func_void); + + FINDSYM(_sym_glGenBuffers, "glGenBuffers", glsym_func_void); + FALLBAK(_sym_glGenBuffers, glsym_func_void); + + FINDSYM(_sym_glGenerateMipmap, "glGenerateMipmap", glsym_func_void); + FALLBAK(_sym_glGenerateMipmap, glsym_func_void); + + FINDSYM(_sym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void); + FALLBAK(_sym_glGenFramebuffers, glsym_func_void); + + FINDSYM(_sym_glGenRenderbuffers, "glGenRenderbuffers", glsym_func_void); + FALLBAK(_sym_glGenRenderbuffers, glsym_func_void); + + FINDSYM(_sym_glGenTextures, "glGenTextures", glsym_func_void); + FALLBAK(_sym_glGenTextures, glsym_func_void); + + FINDSYM(_sym_glGetActiveAttrib, "glGetActiveAttrib", glsym_func_void); + FALLBAK(_sym_glGetActiveAttrib, glsym_func_void); + + FINDSYM(_sym_glGetActiveUniform, "glGetActiveUniform", glsym_func_void); + FALLBAK(_sym_glGetActiveUniform, glsym_func_void); + + FINDSYM(_sym_glGetAttachedShaders, "glGetAttachedShaders", glsym_func_void); + FALLBAK(_sym_glGetAttachedShaders, glsym_func_void); + + FINDSYM(_sym_glGetAttribLocation, "glGetAttribLocation", glsym_func_int); + FALLBAK(_sym_glGetAttribLocation, glsym_func_int); + + FINDSYM(_sym_glGetBooleanv, "glGetBooleanv", glsym_func_void); + FALLBAK(_sym_glGetBooleanv, glsym_func_void); + + FINDSYM(_sym_glGetBufferParameteriv, "glGetBufferParameteriv", glsym_func_void); + FALLBAK(_sym_glGetBufferParameteriv, glsym_func_void); + + FINDSYM(_sym_glGetError, "glGetError", glsym_func_uint); + FALLBAK(_sym_glGetError, glsym_func_uint); + + FINDSYM(_sym_glGetFloatv, "glGetFloatv", glsym_func_void); + FALLBAK(_sym_glGetFloatv, glsym_func_void); + + FINDSYM(_sym_glGetFramebufferAttachmentParameteriv, "glGetFramebufferAttachmentParameteriv", glsym_func_void); + FALLBAK(_sym_glGetFramebufferAttachmentParameteriv, glsym_func_void); + + FINDSYM(_sym_glGetIntegerv, "glGetIntegerv", glsym_func_void); + FALLBAK(_sym_glGetIntegerv, glsym_func_void); + + FINDSYM(_sym_glGetProgramiv, "glGetProgramiv", glsym_func_void); + FALLBAK(_sym_glGetProgramiv, glsym_func_void); + + FINDSYM(_sym_glGetProgramInfoLog, "glGetProgramInfoLog", glsym_func_void); + FALLBAK(_sym_glGetProgramInfoLog, glsym_func_void); + + FINDSYM(_sym_glGetRenderbufferParameteriv, "glGetRenderbufferParameteriv", glsym_func_void); + FALLBAK(_sym_glGetRenderbufferParameteriv, glsym_func_void); + + FINDSYM(_sym_glGetShaderiv, "glGetShaderiv", glsym_func_void); + FALLBAK(_sym_glGetShaderiv, glsym_func_void); + + FINDSYM(_sym_glGetShaderInfoLog, "glGetShaderInfoLog", glsym_func_void); + FALLBAK(_sym_glGetShaderInfoLog, glsym_func_void); + + FINDSYM(_sym_glGetShaderPrecisionFormat, "glGetShaderPrecisionFormat", glsym_func_void); + FALLBAK(_sym_glGetShaderPrecisionFormat, glsym_func_void); + + FINDSYM(_sym_glGetShaderSource, "glGetShaderSource", glsym_func_void); + FALLBAK(_sym_glGetShaderSource, glsym_func_void); + + FINDSYM(_sym_glGetString, "glGetString", glsym_func_uchar_ptr); + FALLBAK(_sym_glGetString, glsym_func_const_uchar_ptr); + + FINDSYM(_sym_glGetTexParameterfv, "glGetTexParameterfv", glsym_func_void); + FALLBAK(_sym_glGetTexParameterfv, glsym_func_void); + + FINDSYM(_sym_glGetTexParameteriv, "glGetTexParameteriv", glsym_func_void); + FALLBAK(_sym_glGetTexParameteriv, glsym_func_void); + + FINDSYM(_sym_glGetUniformfv, "glGetUniformfv", glsym_func_void); + FALLBAK(_sym_glGetUniformfv, glsym_func_void); + + FINDSYM(_sym_glGetUniformiv, "glGetUniformiv", glsym_func_void); + FALLBAK(_sym_glGetUniformiv, glsym_func_void); + + FINDSYM(_sym_glGetUniformLocation, "glGetUniformLocation", glsym_func_int); + FALLBAK(_sym_glGetUniformLocation, glsym_func_int); + + FINDSYM(_sym_glGetVertexAttribfv, "glGetVertexAttribfv", glsym_func_void); + FALLBAK(_sym_glGetVertexAttribfv, glsym_func_void); + + FINDSYM(_sym_glGetVertexAttribiv, "glGetVertexAttribiv", glsym_func_void); + FALLBAK(_sym_glGetVertexAttribiv, glsym_func_void); + + FINDSYM(_sym_glGetVertexAttribPointerv, "glGetVertexAttribPointerv", glsym_func_void); + FALLBAK(_sym_glGetVertexAttribPointerv, glsym_func_void); + + FINDSYM(_sym_glHint, "glHint", glsym_func_void); + FALLBAK(_sym_glHint, glsym_func_void); + + FINDSYM(_sym_glIsBuffer, "glIsBuffer", glsym_func_uchar); + FALLBAK(_sym_glIsBuffer, glsym_func_uchar); + + FINDSYM(_sym_glIsEnabled, "glIsEnabled", glsym_func_uchar); + FALLBAK(_sym_glIsEnabled, glsym_func_uchar); + + FINDSYM(_sym_glIsFramebuffer, "glIsFramebuffer", glsym_func_uchar); + FALLBAK(_sym_glIsFramebuffer, glsym_func_uchar); + + FINDSYM(_sym_glIsProgram, "glIsProgram", glsym_func_uchar); + FALLBAK(_sym_glIsProgram, glsym_func_uchar); + + FINDSYM(_sym_glIsRenderbuffer, "glIsRenderbuffer", glsym_func_uchar); + FALLBAK(_sym_glIsRenderbuffer, glsym_func_uchar); + + FINDSYM(_sym_glIsShader, "glIsShader", glsym_func_uchar); + FALLBAK(_sym_glIsShader, glsym_func_uchar); + + FINDSYM(_sym_glIsTexture, "glIsTexture", glsym_func_uchar); + FALLBAK(_sym_glIsTexture, glsym_func_uchar); + + FINDSYM(_sym_glLineWidth, "glLineWidth", glsym_func_void); + FALLBAK(_sym_glLineWidth, glsym_func_void); + + FINDSYM(_sym_glLinkProgram, "glLinkProgram", glsym_func_void); + FALLBAK(_sym_glLinkProgram, glsym_func_void); + + FINDSYM(_sym_glPixelStorei, "glPixelStorei", glsym_func_void); + FALLBAK(_sym_glPixelStorei, glsym_func_void); + + FINDSYM(_sym_glPolygonOffset, "glPolygonOffset", glsym_func_void); + FALLBAK(_sym_glPolygonOffset, glsym_func_void); + + FINDSYM(_sym_glReadPixels, "glReadPixels", glsym_func_void); + FALLBAK(_sym_glReadPixels, glsym_func_void); + + FINDSYM(_sym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void); + FALLBAK(_sym_glReleaseShaderCompiler, glsym_func_void); + + FINDSYM(_sym_glRenderbufferStorage, "glRenderbufferStorage", glsym_func_void); + FALLBAK(_sym_glRenderbufferStorage, glsym_func_void); + + FINDSYM(_sym_glSampleCoverage, "glSampleCoverage", glsym_func_void); + FALLBAK(_sym_glSampleCoverage, glsym_func_void); + + FINDSYM(_sym_glScissor, "glScissor", glsym_func_void); + FALLBAK(_sym_glScissor, glsym_func_void); + + FINDSYM(_sym_glShaderBinary, "glShaderBinary", glsym_func_void); + FALLBAK(_sym_glShaderBinary, glsym_func_void); + + FINDSYM(_sym_glShaderSource, "glShaderSource", glsym_func_void); + FALLBAK(_sym_glShaderSource, glsym_func_void); + + FINDSYM(_sym_glStencilFunc, "glStencilFunc", glsym_func_void); + FALLBAK(_sym_glStencilFunc, glsym_func_void); + + FINDSYM(_sym_glStencilFuncSeparate, "glStencilFuncSeparate", glsym_func_void); + FALLBAK(_sym_glStencilFuncSeparate, glsym_func_void); + + FINDSYM(_sym_glStencilMask, "glStencilMask", glsym_func_void); + FALLBAK(_sym_glStencilMask, glsym_func_void); + + FINDSYM(_sym_glStencilMaskSeparate, "glStencilMaskSeparate", glsym_func_void); + FALLBAK(_sym_glStencilMaskSeparate, glsym_func_void); + + FINDSYM(_sym_glStencilOp, "glStencilOp", glsym_func_void); + FALLBAK(_sym_glStencilOp, glsym_func_void); + + FINDSYM(_sym_glStencilOpSeparate, "glStencilOpSeparate", glsym_func_void); + FALLBAK(_sym_glStencilOpSeparate, glsym_func_void); + + FINDSYM(_sym_glTexImage2D, "glTexImage2D", glsym_func_void); + FALLBAK(_sym_glTexImage2D, glsym_func_void); + + FINDSYM(_sym_glTexParameterf, "glTexParameterf", glsym_func_void); + FALLBAK(_sym_glTexParameterf, glsym_func_void); + + FINDSYM(_sym_glTexParameterfv, "glTexParameterfv", glsym_func_void); + FALLBAK(_sym_glTexParameterfv, glsym_func_void); + + FINDSYM(_sym_glTexParameteri, "glTexParameteri", glsym_func_void); + FALLBAK(_sym_glTexParameteri, glsym_func_void); + + FINDSYM(_sym_glTexParameteriv, "glTexParameteriv", glsym_func_void); + FALLBAK(_sym_glTexParameteriv, glsym_func_void); + + FINDSYM(_sym_glTexSubImage2D, "glTexSubImage2D", glsym_func_void); + FALLBAK(_sym_glTexSubImage2D, glsym_func_void); + + FINDSYM(_sym_glUniform1f, "glUniform1f", glsym_func_void); + FALLBAK(_sym_glUniform1f, glsym_func_void); + + FINDSYM(_sym_glUniform1fv, "glUniform1fv", glsym_func_void); + FALLBAK(_sym_glUniform1fv, glsym_func_void); + + FINDSYM(_sym_glUniform1i, "glUniform1i", glsym_func_void); + FALLBAK(_sym_glUniform1i, glsym_func_void); + + FINDSYM(_sym_glUniform1iv, "glUniform1iv", glsym_func_void); + FALLBAK(_sym_glUniform1iv, glsym_func_void); + + FINDSYM(_sym_glUniform2f, "glUniform2f", glsym_func_void); + FALLBAK(_sym_glUniform2f, glsym_func_void); + + FINDSYM(_sym_glUniform2fv, "glUniform2fv", glsym_func_void); + FALLBAK(_sym_glUniform2fv, glsym_func_void); + + FINDSYM(_sym_glUniform2i, "glUniform2i", glsym_func_void); + FALLBAK(_sym_glUniform2i, glsym_func_void); + + FINDSYM(_sym_glUniform2iv, "glUniform2iv", glsym_func_void); + FALLBAK(_sym_glUniform2iv, glsym_func_void); + + FINDSYM(_sym_glUniform3f, "glUniform3f", glsym_func_void); + FALLBAK(_sym_glUniform3f, glsym_func_void); + + FINDSYM(_sym_glUniform3fv, "glUniform3fv", glsym_func_void); + FALLBAK(_sym_glUniform3fv, glsym_func_void); + + FINDSYM(_sym_glUniform3i, "glUniform3i", glsym_func_void); + FALLBAK(_sym_glUniform3i, glsym_func_void); + + FINDSYM(_sym_glUniform3iv, "glUniform3iv", glsym_func_void); + FALLBAK(_sym_glUniform3iv, glsym_func_void); + + FINDSYM(_sym_glUniform4f, "glUniform4f", glsym_func_void); + FALLBAK(_sym_glUniform4f, glsym_func_void); + + FINDSYM(_sym_glUniform4fv, "glUniform4fv", glsym_func_void); + FALLBAK(_sym_glUniform4fv, glsym_func_void); + + FINDSYM(_sym_glUniform4i, "glUniform4i", glsym_func_void); + FALLBAK(_sym_glUniform4i, glsym_func_void); + + FINDSYM(_sym_glUniform4iv, "glUniform4iv", glsym_func_void); + FALLBAK(_sym_glUniform4iv, glsym_func_void); + + FINDSYM(_sym_glUniformMatrix2fv, "glUniformMatrix2fv", glsym_func_void); + FALLBAK(_sym_glUniformMatrix2fv, glsym_func_void); + + FINDSYM(_sym_glUniformMatrix3fv, "glUniformMatrix3fv", glsym_func_void); + FALLBAK(_sym_glUniformMatrix3fv, glsym_func_void); + + FINDSYM(_sym_glUniformMatrix4fv, "glUniformMatrix4fv", glsym_func_void); + FALLBAK(_sym_glUniformMatrix4fv, glsym_func_void); + + FINDSYM(_sym_glUseProgram, "glUseProgram", glsym_func_void); + FALLBAK(_sym_glUseProgram, glsym_func_void); + + FINDSYM(_sym_glValidateProgram, "glValidateProgram", glsym_func_void); + FALLBAK(_sym_glValidateProgram, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib1f, "glVertexAttrib1f", glsym_func_void); + FALLBAK(_sym_glVertexAttrib1f, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib1fv, "glVertexAttrib1fv", glsym_func_void); + FALLBAK(_sym_glVertexAttrib1fv, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib2f, "glVertexAttrib2f", glsym_func_void); + FALLBAK(_sym_glVertexAttrib2f, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib2fv, "glVertexAttrib2fv", glsym_func_void); + FALLBAK(_sym_glVertexAttrib2fv, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib3f, "glVertexAttrib3f", glsym_func_void); + FALLBAK(_sym_glVertexAttrib3f, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib3fv, "glVertexAttrib3fv", glsym_func_void); + FALLBAK(_sym_glVertexAttrib3fv, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib4f, "glVertexAttrib4f", glsym_func_void); + FALLBAK(_sym_glVertexAttrib4f, glsym_func_void); + + FINDSYM(_sym_glVertexAttrib4fv, "glVertexAttrib4fv", glsym_func_void); + FALLBAK(_sym_glVertexAttrib4fv, glsym_func_void); + + FINDSYM(_sym_glVertexAttribPointer, "glVertexAttribPointer", glsym_func_void); + FALLBAK(_sym_glVertexAttribPointer, glsym_func_void); + + FINDSYM(_sym_glViewport, "glViewport", glsym_func_void); + FALLBAK(_sym_glViewport, glsym_func_void); + +#undef FINDSYM +#undef FALLBAK + + // Checking to see if this function exists is a poor but reasonable way to + // check if it's gles but it works for now + if (_sym_glGetShaderPrecisionFormat != (typeof(_sym_glGetShaderPrecisionFormat))sym_missing ) + { + DBG("GL Library is GLES."); + gl_lib_is_gles = 1; + } + + return 1; +} + +//--------------------------------------------------------------// +// Wrapped GL APIs to handle desktop compatibility + +// Stripping precision code from GLES shader for desktop compatibility +// Code adopted from Meego GL code. Temporary Fix. +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 = (char *)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)--; + } + } + } + + start = (char *)s; + for (; *n && *s && !strchr(delim, *s); s++, (*n)--); + if (*n > 0) s++, (*n)--; + + *saveptr = (char *)s; + + retlen = s - start; + ret = malloc(retlen + 1); + p = ret; + + 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 * +patch_gles_shader(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 = (char *)opengl_strtok(source, &length, &saveptr, NULL); + for (; p; p = (char *)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 = (char *)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 void +evgl_glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) +{ + char *newstr; + char *srcbk; + char *token = NULL; + char *saveptr; + int i = 0; + int len = 0; + int token_len = 0; + + char **s = malloc(count * sizeof(char*)); + GLint *l = malloc(count * sizeof(GLint)); + + memset(s, 0, count * sizeof(char*)); + memset(l, 0, count * sizeof(GLint)); + + for (i = 0; i < count; ++i) + { + 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] = patch_gles_shader(string[i], len, &l[i]); + if (!s[i]) + { + while(i) + free(s[--i]); + free(l); + free(s); + + DBG("Patching Shader Failed."); + return; + } + } + else + { + s[i] = NULL; + l[i] = 0; + } + } + + _sym_glShaderSource(shader, count, (const char **)s, l); + + while(i) + free(s[--i]); + free(l); + free(s); +} + + +static void +evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +{ + 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; +} + +static void +evgl_glReleaseShaderCompiler(void) +{ + DBG("Not supported in Desktop GL"); + return; +} + +static void +evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) +{ + // FIXME: need to dlsym/getprocaddress for this + DBG("Not supported in Desktop GL"); + return; + //n = binaryformat = length = 0; + //shaders = binary = 0; +} +//--------------------------------------------------------------// + + +static void +override_gl_apis(Evas_GL_API *api) +{ + + api->version = EVAS_GL_API_VERSION; + +#define ORD(f) EVAS_API_OVERRIDE(f, api, _sym_) + // 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); // FIXME + 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, evgl_) + if (!gl_lib_is_gles) + { + // Override functions wrapped by Evas_GL + // GLES2.0 API compat on top of desktop gl + ORD(glGetShaderPrecisionFormat); + ORD(glReleaseShaderCompiler); + ORD(glShaderBinary); + } + + ORD(glShaderSource); // Do precision stripping in both cases +#undef ORD +} + +//-------------------------------------------// +static int +gl_lib_init(void) +{ + // dlopen OSMesa + gl_lib_handle = dlopen("libOSMesa.so.1", RTLD_NOW); + if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so", RTLD_NOW); + if (!gl_lib_handle) + { + DBG("Unable to open libOSMesa: %s", dlerror()); + return 0; + } + + //------------------------------------------------// + if (!glue_sym_init()) return 0; + if (!gl_sym_init()) return 0; + + override_gl_apis(&gl_funcs); + + return 1; +} + + +static void +init_gl() +{ + DBG("Initializing Software OpenGL APIs...\n"); + + if (!gl_lib_init()) + DBG("Unable to support EvasGL in this engine module. Install OSMesa to get it running"); + else + { +#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) + ORD(gl_surface_create); + ORD(gl_surface_destroy); + ORD(gl_context_create); + ORD(gl_context_destroy); + ORD(gl_make_current); + ORD(gl_string_query); // FIXME: Need to implement + ORD(gl_proc_address_get); // FIXME: Need to implement + ORD(gl_native_surface_get); + ORD(gl_api_get); +#undef ORD + } +} + + /* ***** ** @@ -1211,6 +2740,9 @@ module_open(Evas_Module *em) EINA_LOG_ERR("Can not create a module log domain."); return 0; } + + init_gl(); + em->functions = (void *)(&func); cpunum = eina_cpu_count(); return 1;