Evas (gl_x11): Fix no return value in function that is supposed to
[framework/uifw/evas.git] / src / modules / engines / gl_x11 / evas_engine.c
1 #include "evas_common.h" /* Also includes international specific stuff */
2 #include "evas_engine.h"
3
4 #ifdef HAVE_DLSYM
5 # include <dlfcn.h>      /* dlopen,dlclose,etc */
6 #else
7 # error gl_x11 should not get compiled if dlsym is not found on the system!
8 #endif
9
10 #define EVAS_GL_NO_GL_H_CHECK 1
11 #include "Evas_GL.h"
12
13 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
14 // EGL / GLES
15 # if defined(GLES_VARIETY_S3C6410)
16 # elif defined(GLES_VARIETY_SGX)
17 # endif
18 #else
19 // GLX
20 #endif
21
22 typedef struct _Render_Engine               Render_Engine;
23 typedef struct _Render_Engine_GL_Surface    Render_Engine_GL_Surface;
24 typedef struct _Render_Engine_GL_Context    Render_Engine_GL_Context;
25 typedef struct _Render_Engine_GL_Resource   Render_Engine_GL_Resource;
26 typedef struct _Extension_Entry             Extension_Entry;
27
28 struct _Render_Engine
29 {
30    Evas_GL_X11_Window      *win;
31    Evas_Engine_Info_GL_X11 *info;
32    Evas                    *evas;
33    Tilebuf                 *tb;
34    int                      end;
35 /*
36    XrmDatabase   xrdb; // xres - dpi
37    struct { // xres - dpi
38       int        dpi; // xres - dpi
39    } xr; // xres - dpi
40  */
41    int w, h;
42    int vsync;
43
44 };
45
46 struct _Render_Engine_GL_Surface
47 {
48    int      initialized;
49    int      fbo_attached;
50    int      w, h;
51    int      depth_bits;
52    int      stencil_bits;
53
54    // Render target texture/buffers
55    GLuint   rt_tex;
56    GLint    rt_internal_fmt;
57    GLenum   rt_fmt;
58    GLuint   rb_depth;
59    GLenum   rb_depth_fmt;
60    GLuint   rb_stencil;
61    GLenum   rb_stencil_fmt;
62
63    Render_Engine_GL_Context   *current_ctx;
64 };
65
66 struct _Render_Engine_GL_Context
67 {
68    int         initialized;
69 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
70    EGLContext  context;
71 #else
72    GLXContext  context;
73 #endif
74    GLuint      context_fbo;
75    GLuint      current_fbo;
76
77    Render_Engine_GL_Surface   *current_sfc;
78 };
79
80 // Resources used per thread
81 struct _Render_Engine_GL_Resource
82 {
83    // Resource context/surface per Thread in TLS for evasgl use 
84 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
85    EGLContext context;
86    EGLSurface surface;
87 #else
88    GLXContext context;
89 #endif
90 };
91
92 // Extension Handling
93 struct _Extension_Entry
94 {
95    const char *name;
96    const char *real_name;
97    int supported;
98 };
99
100 static int initted = 0;
101 static int gl_wins = 0;
102 static Render_Engine_GL_Context *current_evgl_ctx;
103 static Render_Engine *current_engine;
104
105 static char _gl_ext_string[1024];
106 static char _evasgl_ext_string[1024];
107
108 // Resource context/surface per Thread in TLS for evasgl use 
109 static Eina_TLS   resource_key;
110 static Eina_List *resource_list;
111 LK(resource_lock);
112
113 typedef void            (*_eng_fn) (void);
114 typedef _eng_fn         (*glsym_func_eng_fn) ();
115 typedef void            (*glsym_func_void) ();
116 typedef void           *(*glsym_func_void_ptr) ();
117 typedef int             (*glsym_func_int) ();
118 typedef unsigned int    (*glsym_func_uint) ();
119 typedef unsigned char   (*glsym_func_uchar) ();
120 typedef unsigned char  *(*glsym_func_uchar_ptr) ();
121 typedef const char     *(*glsym_func_const_char_ptr) ();
122
123 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
124
125 #ifndef EGL_NATIVE_PIXMAP_KHR
126 # define EGL_NATIVE_PIXMAP_KHR 0x30b0
127 #endif
128 _eng_fn  (*glsym_eglGetProcAddress)            (const char *a) = NULL;
129 void     (*glsym_eglBindTexImage)              (EGLDisplay a, EGLSurface b, int c) = NULL;
130 void     (*glsym_eglReleaseTexImage)           (EGLDisplay a, EGLSurface b, int c) = NULL;
131 void    *(*glsym_eglCreateImage)               (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL;
132 void     (*glsym_eglDestroyImage)              (EGLDisplay a, void *b) = NULL;
133 void     (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b)  = NULL;
134 void     (*glsym_glEGLImageTargetRenderbufferStorageOES) (int a, void *b)  = NULL;
135 void          *(*glsym_eglMapImageSEC)         (void *a, void *b) = NULL;
136 unsigned int   (*glsym_eglUnmapImageSEC)       (void *a, void *b) = NULL;
137 const char    *(*glsym_eglQueryString)         (EGLDisplay a, int name) = NULL;
138
139 unsigned int   (*glsym_eglLockSurface)          (EGLDisplay a, EGLSurface b, const int *attrib_list) = NULL;
140 unsigned int   (*glsym_eglUnlockSurface)        (EGLDisplay a, EGLSurface b) = NULL;
141
142 #else
143 typedef XID     (*glsym_func_xid) ();
144
145 _eng_fn  (*glsym_glXGetProcAddress)  (const char *a) = NULL;
146 void     (*glsym_glXBindTexImage)    (Display *a, GLXDrawable b, int c, int *d) = NULL;
147 void     (*glsym_glXReleaseTexImage) (Display *a, GLXDrawable b, int c) = NULL;
148 int      (*glsym_glXGetVideoSync)    (unsigned int *a) = NULL;
149 int      (*glsym_glXWaitVideoSync)   (int a, int b, unsigned int *c) = NULL;
150 XID      (*glsym_glXCreatePixmap)    (Display *a, void *b, Pixmap c, const int *d) = NULL;
151 void     (*glsym_glXDestroyPixmap)   (Display *a, XID b) = NULL;
152 void     (*glsym_glXQueryDrawable)   (Display *a, XID b, int c, unsigned int *d) = NULL;
153 int      (*glsym_glXSwapIntervalSGI) (int a) = NULL;
154 void     (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL;
155
156 const char *(*glsym_glXQueryExtensionsString) (Display *a, int screen) = NULL;
157 #endif
158
159 // GLES2 Extensions
160 void    (*glsym_glGetProgramBinaryOES) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) = NULL;
161 void    (*glsym_glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length) = NULL;
162 void*   (*glsym_glMapBufferOES) (GLenum target, GLenum access) = NULL;
163 unsigned char   (*glsym_glUnmapBufferOES) (GLenum target) = NULL;
164 void    (*glsym_glGetBufferPointervOES) (GLenum target, GLenum pname, void** params) = NULL;
165 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;
166 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;
167 void    (*glsym_glCopyTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
168 void    (*glsym_glCompressedTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) = NULL;
169 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;
170 void    (*glsym_glFramebufferTexture3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) = NULL;
171 void    (*glsym_glGetPerfMonitorGroupsAMD) (GLint* numGroups, GLsizei groupsSize, GLuint* groups) = NULL;
172 void    (*glsym_glGetPerfMonitorCountersAMD) (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters) = NULL;
173 void    (*glsym_glGetPerfMonitorGroupStringAMD) (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString) = NULL;
174 void    (*glsym_glGetPerfMonitorCounterStringAMD) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString) = NULL;
175 void    (*glsym_glGetPerfMonitorCounterInfoAMD) (GLuint group, GLuint counter, GLenum pname, void* data) = NULL;
176 void    (*glsym_glGenPerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL;
177 void    (*glsym_glDeletePerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL;
178 void    (*glsym_glSelectPerfMonitorCountersAMD) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList) = NULL;
179 void    (*glsym_glBeginPerfMonitorAMD) (GLuint monitor) = NULL;
180 void    (*glsym_glEndPerfMonitorAMD) (GLuint monitor) = NULL;
181 void    (*glsym_glGetPerfMonitorCounterDataAMD) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten) = NULL;
182 void    (*glsym_glDiscardFramebufferEXT) (GLenum target, GLsizei numAttachments, const GLenum* attachments) = NULL;
183 void    (*glsym_glMultiDrawArraysEXT) (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount) = NULL;
184 void    (*glsym_glMultiDrawElementsEXT) (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount) = NULL;
185 void    (*glsym_glDeleteFencesNV) (GLsizei n, const GLuint* fences) = NULL;
186 void    (*glsym_glGenFencesNV) (GLsizei n, GLuint* fences) = NULL;
187 unsigned char   (*glsym_glIsFenceNV) (GLuint fence) = NULL;
188 unsigned char   (*glsym_glTestFenceNV) (GLuint fence) = NULL;
189 void    (*glsym_glGetFenceivNV) (GLuint fence, GLenum pname, GLint* params) = NULL;
190 void    (*glsym_glFinishFenceNV) (GLuint fence) = NULL;
191 void    (*glsym_glSetFenceNV) (GLuint, GLenum) = NULL;
192 void    (*glsym_glGetDriverControlsQCOM) (GLint* num, GLsizei size, GLuint* driverControls) = NULL;
193 void    (*glsym_glGetDriverControlStringQCOM) (GLuint driverControl, GLsizei bufSize, GLsizei* length, char* driverControlString) = NULL;
194 void    (*glsym_glEnableDriverControlQCOM) (GLuint driverControl) = NULL;
195 void    (*glsym_glDisableDriverControlQCOM) (GLuint driverControl) = NULL;
196 void    (*glsym_glExtGetTexturesQCOM) (GLuint* textures, GLint maxTextures, GLint* numTextures) = NULL;
197 void    (*glsym_glExtGetBuffersQCOM) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers) = NULL;
198 void    (*glsym_glExtGetRenderbuffersQCOM) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers) = NULL;
199 void    (*glsym_glExtGetFramebuffersQCOM) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers) = NULL;
200 void    (*glsym_glExtGetTexLevelParameterivQCOM) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params) = NULL;
201 void    (*glsym_glExtTexObjectStateOverrideiQCOM) (GLenum target, GLenum pname, GLint param) = NULL;
202 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;
203 void    (*glsym_glExtGetBufferPointervQCOM) (GLenum target, void** params) = NULL;
204 void    (*glsym_glExtGetShadersQCOM) (GLuint* shaders, GLint maxShaders, GLint* numShaders) = NULL;
205 void    (*glsym_glExtGetProgramsQCOM) (GLuint* programs, GLint maxPrograms, GLint* numPrograms) = NULL;
206 unsigned char   (*glsym_glExtIsProgramBinaryQCOM) (GLuint program) = NULL;
207 void    (*glsym_glExtGetProgramBinarySourceQCOM) (GLuint program, GLenum shadertype, char* source, GLint* length) = NULL;
208
209
210 //------ GLES 2.0 Extensions supported in EvasGL -----//
211 static Extension_Entry _gl_ext_entries[] = {
212 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
213        //--- Function Extensions ---//
214        { "GL_OES_get_program_binary", "get_program_binary", 0 },
215        { "GL_OES_mapbuffer", "mapbuffer", 0 },
216        { "GL_OES_texture_3D", "texture_3D", 0 },
217        { "AMD_performance_monitor", "AMD_performance_monitor", 0 },
218        { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 },
219        { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 },
220        { "GL_NV_fence", "NV_fence", 0 },
221        { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
222        { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
223        { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
224
225        //--- Define Extensions ---//
226        { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
227        { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 },
228        { "GL_OES_depth24", "depth24", 0 },
229        { "GL_OES_depth32", "depth32", 0 },
230        { "GL_OES_EvasGL_image", "EGL_image", 0 },
231        { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 },
232        { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 },
233        { "GL_OES_standard_derivatives", "standard_derivatives", 0 },
234        { "GL_OES_stencil1", "stencil1", 0 },
235        { "GL_OES_stencil4", "stencil4", 0 },
236        { "GL_OES_texture_float", "texture_float", 0 },
237        { "GL_OES_texture_half_float", "texture_half_float", 0 },
238        { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 },
239        { "GL_OES_texture_npot", "texture_npot", 0 },
240        { "GL_OES_vertex_half_float", "vertex_half_float", 0 },
241        { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 },
242        { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 },
243        { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 },
244        { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 },
245        { "GL_EXT_blend_minmax", "blend_minmax", 0 },
246        { "GL_EXT_read_format_bgra", "read_format_bgra", 0 },
247        { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 },
248        { "GL_EXT_texture_format_BGRA8888", "texture_format_BGRA8888", 0 },
249        { "GL_EXT_texture_type_2_10_10_10_REV", "texture_type_2_10_10_10_rev", 0 },
250        { "GL_IMG_program_binary", "IMG_program_binary", 0 },
251        { "GL_IMG_read_format", "IMG_read_format", 0 },
252        { "GL_IMG_shader_binary", "IMG_shader_binary", 0 },
253        { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 },
254        { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 },
255        { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 },
256 #else
257        //--- Function Extensions ---//
258        { "GL_OES_get_program_binary", "get_program_binary", 0 },
259        { "GL_OES_mapbuffer", "mapbuffer", 0 },
260        { "GL_OES_texture_3D", "texture_3D", 0 },
261        { "AMD_performance_monitor", "AMD_performance_monitor", 0 },
262        { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 },
263        { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 },
264        { "GL_NV_fence", "NV_fence", 0 },
265        { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
266        { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
267        { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
268
269        //--- Define Extensions ---//
270        { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
271        { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 },
272        { "GL_OES_depth24", "depth24", 0 },
273        { "GL_OES_depth32", "depth32", 0 },
274        { "GL_OES_EvasGL_image", "EGL_image", 0 },
275        { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 },
276        { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 },
277        { "GL_OES_standard_derivatives", "standard_derivatives", 0 },
278        { "GL_OES_stencil1", "stencil1", 0 },
279        { "GL_OES_stencil4", "stencil4", 0 },
280        { "GL_OES_texture_float", "texture_float", 0 },
281        { "GL_OES_texture_half_float", "texture_half_float", 0 },
282        { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 },
283        { "GL_OES_texture_npot", "texture_non_power_of_two", 0 },     // Desktop differs
284        { "GL_OES_vertex_half_float", "half_float_vertex", 0 }, // Desktop differs
285        { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 },
286        { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 },
287        { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 },
288        { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 },
289        { "GL_EXT_blend_minmax", "blend_minmax", 0 },
290        { "GL_EXT_read_format_bgra", "bgra", 0 }, // Desktop differs
291        { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 },
292        { "GL_EXT_texture_format_BGRA8888", "bgra", 0 }, // Desktop differs
293        { "GL_EXT_texture_type_2_10_10_10_REV", "vertex_type_2_10_10_10_rev", 0 },  // Desktop differs ???
294        { "GL_IMG_program_binary", "IMG_program_binary", 0 },
295        { "GL_IMG_read_format", "IMG_read_format", 0 },
296        { "GL_IMG_shader_binary", "IMG_shader_binary", 0 },
297        { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 },
298        { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 },
299        { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 },
300
301 #endif
302        { NULL, NULL, 0}
303 };
304
305 //------ Extensions supported in EvasGL -----//
306 static Extension_Entry _evasgl_ext_entries[] = {
307 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
308        { "EvasGL_KHR_image", "EGL_KHR_image", 0 },
309        { "EvasGL_KHR_vg_parent_image", "EGL_KHR_vg_parent_image", 0 },
310        { "EvasGL_KHR_gl_texture_2D_image", "EGL_KHR_gl_texture_2D_image", 0 },
311        { "EvasGL_KHR_gl_texture_cubemap_image", "EGL_KHR_gl_texture_cubemap_image", 0 },
312        { "EvasGL_KHR_gl_texture_3D_image", "EGL_KHR_gl_texture_3D_image", 0 },
313        { "EvasGL_KHR_gl_renderbuffer_image", "EGL_KHR_gl_renderbuffer_image", 0 },
314 #else
315 #endif
316        { NULL, NULL, 0 }
317 };
318
319 static void
320 _sym_init(void)
321 {
322    static int done = 0;
323
324    if (done) return;
325
326 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
327 #define FINDSYM(dst, sym, typ) \
328    if ((!dst) && (glsym_eglGetProcAddress)) dst = (typ)glsym_eglGetProcAddress(sym); \
329    if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
330
331    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
332    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
333    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
334    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
335
336    FINDSYM(glsym_eglBindTexImage, "eglBindTexImage", glsym_func_void);
337    FINDSYM(glsym_eglBindTexImage, "eglBindTexImageEXT", glsym_func_void);
338    FINDSYM(glsym_eglBindTexImage, "eglBindTexImageARB", glsym_func_void);
339    FINDSYM(glsym_eglBindTexImage, "eglBindTexImageKHR", glsym_func_void);
340
341    FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImage", glsym_func_void);
342    FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageEXT", glsym_func_void);
343    FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageARB", glsym_func_void);
344    FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageKHR", glsym_func_void);
345
346    FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
347    FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
348    FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
349    FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
350
351    FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
352    FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
353    FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
354    FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
355
356    FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
357
358    FINDSYM(glsym_glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES", glsym_func_void);
359
360    FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
361    FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
362
363    FINDSYM(glsym_eglQueryString, "eglQueryString", glsym_func_const_char_ptr);
364
365    FINDSYM(glsym_eglLockSurface, "eglLockSurface", glsym_func_uint);
366    FINDSYM(glsym_eglLockSurface, "eglLockSurfaceEXT", glsym_func_uint);
367    FINDSYM(glsym_eglLockSurface, "eglLockSurfaceARB", glsym_func_uint);
368    FINDSYM(glsym_eglLockSurface, "eglLockSurfaceKHR", glsym_func_uint);
369
370    FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurface", glsym_func_uint);
371    FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceEXT", glsym_func_uint);
372    FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceARB", glsym_func_uint);
373    FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceKHR", glsym_func_uint);
374
375 #else
376 #define FINDSYM(dst, sym, typ) \
377    if ((!dst) && (glsym_glXGetProcAddress)) dst = (typ)glsym_glXGetProcAddress(sym); \
378    if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
379
380    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
381    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
382    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
383
384    FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
385    FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
386    FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
387
388    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
389    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
390    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
391
392    FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
393
394    FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
395
396    FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
397    FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
398    FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
399
400    FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
401    FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
402    FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
403
404    FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
405    FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
406    FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
407
408    FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
409    FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
410
411    FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
412
413    FINDSYM(glsym_glXQueryExtensionsString, "glXQueryExtensionsString", glsym_func_const_char_ptr);
414 #endif
415
416    //----------- GLES 2.0 Extensions ------------//
417    // If the symbol's not found, they get set to NULL
418    // If one of the functions in the extension exists, the extension in supported
419    /* GL_OES_get_program_binary */
420    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinary", glsym_func_void);
421    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryEXT", glsym_func_void);
422    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryARB", glsym_func_void);
423    FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryOES", glsym_func_void);
424
425    FINDSYM(glsym_glProgramBinaryOES, "glProgramBinary", glsym_func_void);
426    FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryEXT", glsym_func_void);
427    FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryARB", glsym_func_void);
428    FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryOES", glsym_func_void);
429
430    // Check the first function to see if the extension is supported...
431    if (glsym_glGetProgramBinaryOES) _gl_ext_entries[0].supported = 1;
432
433
434    /* GL_OES_mapbuffer */
435    FINDSYM(glsym_glMapBufferOES, "glMapBuffer", glsym_func_void_ptr);
436    FINDSYM(glsym_glMapBufferOES, "glMapBufferEXT", glsym_func_void_ptr);
437    FINDSYM(glsym_glMapBufferOES, "glMapBufferARB", glsym_func_void_ptr);
438    FINDSYM(glsym_glMapBufferOES, "glMapBufferOES", glsym_func_void_ptr);
439
440    FINDSYM(glsym_glUnmapBufferOES, "glUnmapBuffer", glsym_func_uchar);
441    FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferEXT", glsym_func_uchar);
442    FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferARB", glsym_func_uchar);
443    FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferOES", glsym_func_uchar);
444
445    FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointerv", glsym_func_void);
446    FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervEXT", glsym_func_void);
447    FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervARB", glsym_func_void);
448    FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervOES", glsym_func_void);
449
450    if (glsym_glMapBufferOES) _gl_ext_entries[1].supported = 1;
451
452    /* GL_OES_texture_3D */
453    FINDSYM(glsym_glTexImage3DOES, "glTexImage3D", glsym_func_void);
454    FINDSYM(glsym_glTexImage3DOES, "glTexImage3DEXT", glsym_func_void);
455    FINDSYM(glsym_glTexImage3DOES, "glTexImage3DARB", glsym_func_void);
456    FINDSYM(glsym_glTexImage3DOES, "glTexImage3DOES", glsym_func_void);
457
458    FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3D", glsym_func_void);
459    FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DEXT", glsym_func_void);
460    FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DARB", glsym_func_void);
461    FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DOES", glsym_func_void);
462
463    FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3D", glsym_func_void);
464    FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DARB", glsym_func_void);
465    FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DEXT", glsym_func_void);
466    FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DOES", glsym_func_void);
467
468    FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3D", glsym_func_void);
469    FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DARB", glsym_func_void);
470    FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DEXT", glsym_func_void);
471    FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DOES", glsym_func_void);
472
473    FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3D", glsym_func_void);
474    FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DARB", glsym_func_void);
475    FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DEXT", glsym_func_void);
476    FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DOES", glsym_func_void);
477
478    FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3D", glsym_func_void);
479    FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DARB", glsym_func_void);
480    FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DEXT", glsym_func_void);
481    FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DOES", glsym_func_void);
482
483    if (glsym_glTexSubImage3DOES) _gl_ext_entries[2].supported = 1;
484
485    /* AMD_performance_monitor */
486    FINDSYM(glsym_glGetPerfMonitorGroupsAMD, "glGetPerfMonitorGroupsAMD", glsym_func_void);
487    FINDSYM(glsym_glGetPerfMonitorCountersAMD, "glGetPerfMonitorCountersAMD", glsym_func_void);
488    FINDSYM(glsym_glGetPerfMonitorGroupStringAMD, "glGetPerfMonitorGroupStringAMD", glsym_func_void);
489    FINDSYM(glsym_glGetPerfMonitorCounterStringAMD, "glGetPerfMonitorCounterStringAMD", glsym_func_void);
490    FINDSYM(glsym_glGetPerfMonitorCounterInfoAMD, "glGetPerfMonitorCounterInfoAMD", glsym_func_void);
491    FINDSYM(glsym_glGenPerfMonitorsAMD, "glGenPerfMonitorsAMD", glsym_func_void);
492    FINDSYM(glsym_glDeletePerfMonitorsAMD, "glDeletePerfMonitorsAMD", glsym_func_void);
493    FINDSYM(glsym_glSelectPerfMonitorCountersAMD, "glSelectPerfMonitorCountersAMD", glsym_func_void);
494    FINDSYM(glsym_glBeginPerfMonitorAMD, "glBeginPerfMonitorAMD", glsym_func_void);
495    FINDSYM(glsym_glEndPerfMonitorAMD, "glEndPerfMonitorAMD", glsym_func_void);
496    FINDSYM(glsym_glGetPerfMonitorCounterDataAMD, "glGetPerfMonitorCounterDataAMD", glsym_func_void);
497
498    if (glsym_glGetPerfMonitorGroupsAMD) _gl_ext_entries[3].supported = 1;
499
500    /* GL_EXT_discard_framebuffer */
501    FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebuffer", glsym_func_void);
502    FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferARB", glsym_func_void);
503    FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferEXT", glsym_func_void);
504
505    if (glsym_glDiscardFramebufferEXT) _gl_ext_entries[4].supported = 1;
506
507    /* GL_EXT_multi_draw_arrays */
508    FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArrays", glsym_func_void);
509    FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysARB", glsym_func_void);
510    FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysEXT", glsym_func_void);
511
512    FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElements", glsym_func_void);
513    FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsARB", glsym_func_void);
514    FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsEXT", glsym_func_void);
515
516    if (glsym_glMultiDrawArraysEXT) _gl_ext_entries[5].supported = 1;
517
518    /* GL_NV_fence */
519    FINDSYM(glsym_glDeleteFencesNV, "glDeleteFencesNV", glsym_func_void);
520    FINDSYM(glsym_glGenFencesNV, "glGenFencesNV", glsym_func_void);
521    FINDSYM(glsym_glIsFenceNV, "glIsFenceNV", glsym_func_uchar);
522    FINDSYM(glsym_glTestFenceNV, "glTestFenceNV", glsym_func_uchar);
523    FINDSYM(glsym_glGetFenceivNV, "glGetFenceivNV", glsym_func_void);
524    FINDSYM(glsym_glFinishFenceNV, "glFinishFenceNV", glsym_func_void);
525    FINDSYM(glsym_glSetFenceNV, "glSetFenceNV", glsym_func_void);
526
527    if (glsym_glDeleteFencesNV) _gl_ext_entries[6].supported = 1;
528
529    /* GL_QCOM_driver_control */
530    FINDSYM(glsym_glGetDriverControlsQCOM, "glGetDriverControlsQCOM", glsym_func_void);
531    FINDSYM(glsym_glGetDriverControlStringQCOM, "glGetDriverControlStringQCOM", glsym_func_void);
532    FINDSYM(glsym_glEnableDriverControlQCOM, "glEnableDriverControlQCOM", glsym_func_void);
533    FINDSYM(glsym_glDisableDriverControlQCOM, "glDisableDriverControlQCOM", glsym_func_void);
534
535    if (glsym_glGetDriverControlsQCOM) _gl_ext_entries[7].supported = 1;
536
537    /* GL_QCOM_extended_get */
538    FINDSYM(glsym_glExtGetTexturesQCOM, "glExtGetTexturesQCOM", glsym_func_void);
539    FINDSYM(glsym_glExtGetBuffersQCOM, "glExtGetBuffersQCOM", glsym_func_void);
540    FINDSYM(glsym_glExtGetRenderbuffersQCOM, "glExtGetRenderbuffersQCOM", glsym_func_void);
541    FINDSYM(glsym_glExtGetFramebuffersQCOM, "glExtGetFramebuffersQCOM", glsym_func_void);
542    FINDSYM(glsym_glExtGetTexLevelParameterivQCOM, "glExtGetTexLevelParameterivQCOM", glsym_func_void);
543    FINDSYM(glsym_glExtTexObjectStateOverrideiQCOM, "glExtTexObjectStateOverrideiQCOM", glsym_func_void);
544    FINDSYM(glsym_glExtGetTexSubImageQCOM, "glExtGetTexSubImageQCOM", glsym_func_void);
545    FINDSYM(glsym_glExtGetBufferPointervQCOM, "glExtGetBufferPointervQCOM", glsym_func_void);
546
547    if (glsym_glExtGetTexturesQCOM) _gl_ext_entries[8].supported = 1;
548
549    /* GL_QCOM_extended_get2 */
550    FINDSYM(glsym_glExtGetShadersQCOM, "glExtGetShadersQCOM", glsym_func_void);
551    FINDSYM(glsym_glExtGetProgramsQCOM, "glExtGetProgramsQCOM", glsym_func_void);
552    FINDSYM(glsym_glExtIsProgramBinaryQCOM, "glExtIsProgramBinaryQCOM", glsym_func_uchar);
553    FINDSYM(glsym_glExtGetProgramBinarySourceQCOM, "glExtGetProgramBinarySourceQCOM", glsym_func_void);
554
555    if (glsym_glExtGetShadersQCOM) _gl_ext_entries[9].supported = 1;
556 }
557
558 static void
559 _extensions_init(Render_Engine *re)
560 {
561    int i;
562    const char *glexts, *evasglexts;
563
564    memset(_gl_ext_string, 0, 1024);
565    memset(_evasgl_ext_string, 0, 1024);
566
567    // GLES 2.0 Extensions
568    glexts = (const char*)glGetString(GL_EXTENSIONS);
569
570    DBG("--------GLES 2.0 Extensions--------");
571    for (i = 0; _gl_ext_entries[i].name != NULL; i++)
572      {
573         if ( (strstr(glexts, _gl_ext_entries[i].name) != NULL) ||
574              (strstr(glexts, _gl_ext_entries[i].real_name) != NULL) )
575           {
576              _gl_ext_entries[i].supported = 1;
577              strcat(_gl_ext_string, _gl_ext_entries[i].name);
578              strcat(_gl_ext_string, " ");
579              DBG("\t%s", _gl_ext_entries[i].name);
580           }
581
582      }
583    DBG(" ");
584
585 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
586    // EGL Extensions
587    evasglexts = glsym_eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
588 #else
589    evasglexts = glXQueryExtensionsString(re->info->info.display, 
590                                          re->info->info.screen);
591 #endif
592
593    DBG("--------EvasGL Extensions----------");
594    for (i = 0; _evasgl_ext_entries[i].name != NULL; i++)
595      {
596         if ( (strstr(evasglexts, _evasgl_ext_entries[i].name) != NULL) ||
597              (strstr(evasglexts, _evasgl_ext_entries[i].real_name) != NULL) )
598           {
599              _evasgl_ext_entries[i].supported = 1;
600              strcat(_evasgl_ext_string, _evasgl_ext_entries[i].name);
601              strcat(_evasgl_ext_string, " ");
602              DBG("\t%s", _evasgl_ext_entries[i].name);
603           }
604      }
605    DBG(" ");
606 }
607
608 int _evas_engine_GL_X11_log_dom = -1;
609 /* function tables - filled in later (func and parent func) */
610 static Evas_Func func, pfunc;
611
612 /* Function table for GL APIs */
613 static Evas_GL_API gl_funcs;
614 /*
615 struct xrdb_user
616 {
617    time_t last_stat;
618    time_t last_mtime;
619    XrmDatabase db;
620 };
621 static struct xrdb_user xrdb_user = {0, 0, NULL};
622
623 static Eina_Bool
624 xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
625 {
626    time_t last = xrdb_user.last_stat, now = time(NULL);
627
628    xrdb_user.last_stat = now;
629    if (last != now) // don't stat() more than once every second
630      {
631         struct stat st;
632         const char *home = getenv("HOME");
633         char tmp[PATH_MAX];
634
635         if (!home) goto failed;
636         snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
637         if (stat(tmp, &st) != 0) goto failed;
638         if (xrdb_user.last_mtime != st.st_mtime)
639           {
640              if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
641              xrdb_user.db = XrmGetFileDatabase(tmp);
642              if (!xrdb_user.db) goto failed;
643              xrdb_user.last_mtime = st.st_mtime;
644           }
645      }
646
647    if (!xrdb_user.db) return EINA_FALSE;
648    return XrmGetResource(xrdb_user.db, name, cls, type, val);
649
650  failed:
651    if (xrdb_user.db)
652      {
653         XrmDestroyDatabase(xrdb_user.db);
654         xrdb_user.db = NULL;
655      }
656    xrdb_user.last_mtime = 0;
657    return EINA_FALSE;
658 }
659 */
660
661 static void *
662 eng_info(Evas *e)
663 {
664    Evas_Engine_Info_GL_X11 *info;
665
666    info = calloc(1, sizeof(Evas_Engine_Info_GL_X11));
667    info->magic.magic = rand();
668    info->func.best_visual_get = eng_best_visual_get;
669    info->func.best_colormap_get = eng_best_colormap_get;
670    info->func.best_depth_get = eng_best_depth_get;
671    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
672    return info;
673    e = NULL;
674 }
675
676 static void
677 eng_info_free(Evas *e __UNUSED__, void *info)
678 {
679    Evas_Engine_Info_GL_X11 *in;
680 // dont free! why bother? its not worth it
681 //   eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
682    in = (Evas_Engine_Info_GL_X11 *)info;
683    free(in);
684 }
685
686 static int
687 _re_wincheck(Render_Engine *re)
688 {
689    if (re->win->surf) return 1;
690    eng_window_resurf(re->win);
691    if (!re->win->surf)
692      {
693         ERR("GL engine can't re-create window surface!");
694      }
695    return 0;
696 }
697
698 static void
699 _re_winfree(Render_Engine *re)
700 {
701    if (!re->win->surf) return;
702    eng_window_unsurf(re->win);
703 }
704
705 static Render_Engine_GL_Resource *
706 _create_internal_glue_resources(void *data)
707 {
708    Render_Engine *re = (Render_Engine *)data;
709    Render_Engine_GL_Resource *rsc;
710
711    rsc = calloc(1, sizeof(Render_Engine_GL_Resource));
712
713    if (!rsc) return NULL;
714
715 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
716    // EGL
717    int context_attrs[3];
718    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
719    context_attrs[1] = 2;
720    context_attrs[2] = EGL_NONE;
721
722    // Create resource surface for EGL
723    rsc->surface = eglCreateWindowSurface(re->win->egl_disp,
724                                          re->win->egl_config,
725                                          (EGLNativeWindowType)DefaultRootWindow(re->info->info.display),
726                                          NULL);
727    if (!rsc->surface)
728      {
729         ERR("Creating internal resource surface failed.");
730         free(rsc);
731         return NULL;
732      }
733
734    // Create a resource context for EGL
735    rsc->context = eglCreateContext(re->win->egl_disp,
736                                    re->win->egl_config,
737                                    re->win->egl_context[0], // Evas' GL Context
738                                    context_attrs);
739    if (!rsc->context)
740      {
741         ERR("Internal Resource Context Creations Failed.");
742         free(rsc);
743         return NULL;
744      }
745
746    // Add to the resource resource list for cleanup
747    LKL(resource_lock);
748    resource_list = eina_list_prepend(resource_list, rsc);
749    LKU(resource_lock);
750
751    // Set the resource in TLS
752    if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE)
753      {
754         ERR("Failed setting TLS Resource");
755         free(rsc);
756         return NULL;
757      }
758
759 #else
760    // GLX
761    rsc->context = glXCreateContext(re->info->info.display,
762                                    re->win->visualinfo,
763                                    re->win->context,      // Evas' GL Context
764                                    1);
765    if (!rsc->context)
766      {
767         ERR("Internal Resource Context Creations Failed.");
768         free(rsc);
769         return NULL;
770      }
771
772    // Add to the resource resource list for cleanup
773    LKL(resource_lock);
774    resource_list = eina_list_prepend(resource_list, rsc);
775    LKU(resource_lock);
776
777    // Set the resource in TLS
778    if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE)
779      {
780         ERR("Failed setting TLS Resource");
781         free(rsc);
782         return NULL;
783      }
784
785 #endif
786
787
788    return rsc;
789 }
790
791 static int
792 _destroy_internal_glue_resources(void *data)
793 {
794    Render_Engine *re = (Render_Engine *)data;
795    Eina_List *l;
796    Render_Engine_GL_Resource *rsc;
797
798 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
799    // EGL
800    // Delete the Resources
801    LKL(resource_lock);
802    EINA_LIST_FOREACH(resource_list, l, rsc)
803      {
804         if (rsc->surface) eglDestroySurface(re->win->egl_disp, rsc->surface);
805         if (rsc->context) eglDestroyContext(re->win->egl_disp, rsc->context);
806         free(rsc);
807      }
808    eina_list_free(resource_list);
809    LKU(resource_lock);
810
811    // Destroy TLS
812    eina_tls_free(resource_key);
813 #else
814    // GLX
815    // Delete the Resources
816    LKL(resource_lock);
817    EINA_LIST_FOREACH(resource_list, l, rsc)
818      {
819         if (rsc)
820           {
821              glXDestroyContext(re->info->info.display, rsc->context);
822              free(rsc);
823           }
824      }
825    eina_list_free(resource_list);
826    LKU(resource_lock);
827
828    // Destroy TLS
829    eina_tls_free(resource_key);
830 #endif
831
832    return 1;
833 }
834
835
836
837 static int
838 eng_setup(Evas *e, void *in)
839 {
840    Render_Engine *re;
841    Evas_Engine_Info_GL_X11 *info;
842
843    info = (Evas_Engine_Info_GL_X11 *)in;
844    if (!e->engine.data.output)
845      {
846 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
847 #else
848         int eb, evb;
849
850         if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
851 #endif
852         re = calloc(1, sizeof(Render_Engine));
853         if (!re) return 0;
854         re->info = info;
855         re->evas = e;
856         e->engine.data.output = re;
857         re->w = e->output.w;
858         re->h = e->output.h;
859         re->win = eng_window_new(re->info->info.display,
860                                  re->info->info.drawable,
861                                  re->info->info.screen,
862                                  re->info->info.visual,
863                                  re->info->info.colormap,
864                                  re->info->info.depth,
865                                  re->w,
866                                  re->h,
867                                  re->info->indirect,
868                                  re->info->info.destination_alpha,
869                                  re->info->info.rotation);
870         if (!re->win)
871           {
872              free(re);
873              e->engine.data.output = NULL;
874              return 0;
875           }
876
877         gl_wins++;
878 /*
879           {
880              int status;
881              char *type = NULL;
882              XrmValue val;
883
884              re->xr.dpi = 75000; // dpy * 1000
885
886              status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
887              if ((!status) || (!type))
888                {
889                   if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display);
890                   if (re->xrdb)
891                     status = XrmGetResource(re->xrdb,
892                                             "Xft.dpi", "Xft.Dpi", &type, &val);
893                }
894
895              if ((status) && (type))
896                {
897                   if (!strcmp(type, "String"))
898                     {
899                        const char *str, *dp;
900
901                        str = val.addr;
902                        dp = strchr(str, '.');
903                        if (!dp) dp = strchr(str, ',');
904
905                        if (dp)
906                          {
907                             int subdpi, len, i;
908                             char *buf;
909
910                             buf = alloca(dp - str + 1);
911                             strncpy(buf, str, dp - str);
912                             buf[dp - str] = 0;
913                             len = strlen(dp + 1);
914                             subdpi = atoi(dp + 1);
915
916                             if (len < 3)
917                               {
918                                  for (i = len; i < 3; i++) subdpi *= 10;
919                               }
920                             else if (len > 3)
921                               {
922                                  for (i = len; i > 3; i--) subdpi /= 10;
923                               }
924                             re->xr.dpi = atoi(buf) * 1000;
925                          }
926                        else
927                          re->xr.dpi = atoi(str) * 1000;
928                        evas_common_font_dpi_set(re->xr.dpi / 1000);
929                     }
930                }
931           }
932  */
933         if (!initted)
934           {
935              evas_common_cpu_init();
936
937              evas_common_blend_init();
938              evas_common_image_init();
939              evas_common_convert_init();
940              evas_common_scale_init();
941              evas_common_rectangle_init();
942              evas_common_polygon_init();
943              evas_common_line_init();
944              evas_common_font_init();
945              evas_common_draw_init();
946              evas_common_tilebuf_init();
947
948              // Initialize TLS
949              if (eina_tls_new(&resource_key) == EINA_FALSE)
950                 ERR("Error creating tls key");
951              DBG("TLS KEY create... %d", resource_key);
952
953              initted = 1;
954           }
955      }
956    else
957      {
958         re = e->engine.data.output;
959         if (_re_wincheck(re))
960           {
961              if ((re->info->info.display != re->win->disp) ||
962                  (re->info->info.drawable != re->win->win) ||
963                  (re->info->info.screen != re->win->screen) ||
964                  (re->info->info.visual != re->win->visual) ||
965                  (re->info->info.colormap != re->win->colormap) ||
966                  (re->info->info.depth != re->win->depth) ||
967                  (re->info->info.destination_alpha != re->win->alpha) ||
968                  (re->info->info.rotation != re->win->rot))
969                {
970                   int inc = 0;
971
972                   if (re->win)
973                     {
974                        re->win->gl_context->references++;
975                        eng_window_free(re->win);
976                        inc = 1;
977                        gl_wins--;
978                     }
979                   re->w = e->output.w;
980                   re->h = e->output.h;
981                   re->win = eng_window_new(re->info->info.display,
982                                            re->info->info.drawable,
983                                            re->info->info.screen,
984                                            re->info->info.visual,
985                                            re->info->info.colormap,
986                                            re->info->info.depth,
987                                            re->w,
988                                            re->h,
989                                            re->info->indirect,
990                                            re->info->info.destination_alpha,
991                                            re->info->info.rotation);
992                   eng_window_use(re->win);
993                   if (re->win) gl_wins++;
994                   if ((re->win) && (inc))
995                      re->win->gl_context->references--;
996                }
997              else if ((re->win->w != e->output.w) ||
998                       (re->win->h != e->output.h))
999                {
1000                   re->w = e->output.w;
1001                   re->h = e->output.h;
1002                   re->win->w = e->output.w;
1003                   re->win->h = e->output.h;
1004                   eng_window_use(re->win);
1005                   evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
1006                }
1007           }
1008      }
1009    if (!re->win)
1010      {
1011         free(re);
1012         return 0;
1013      }
1014
1015    if (!e->engine.data.output)
1016      {
1017         if (re->win)
1018           {
1019              eng_window_free(re->win);
1020              gl_wins--;
1021           }
1022         free(re);
1023         return 0;
1024      }
1025    re->tb = evas_common_tilebuf_new(re->win->w, re->win->h);
1026    if (!re->tb)
1027      {
1028         if (re->win)
1029           {
1030              eng_window_free(re->win);
1031              gl_wins--;
1032           }
1033         free(re);
1034         return 0;
1035      }
1036    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
1037
1038    if (!e->engine.data.context)
1039      e->engine.data.context =
1040      e->engine.func->context_new(e->engine.data.output);
1041    eng_window_use(re->win);
1042
1043    re->vsync = 0;
1044    _sym_init();
1045    _extensions_init(re);
1046
1047    // This is used in extensions.  Not pretty but can't get display otherwise.
1048    current_engine = re;
1049
1050    return 1;
1051 }
1052
1053 static void
1054 eng_output_free(void *data)
1055 {
1056    Render_Engine *re;
1057
1058    re = (Render_Engine *)data;
1059
1060    if (re)
1061      {
1062 // NOTE: XrmGetDatabase() result is shared per connection, do not free it.
1063 //   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
1064
1065 #if 0
1066 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1067         // Destroy the resource surface
1068         // Only required for EGL case
1069         if (re->surface)
1070            eglDestroySurface(re->win->egl_disp, re->surface);
1071 #endif
1072
1073         // Destroy the resource context
1074         _destroy_internal_context(re, context);
1075 #endif
1076         if (re->win)
1077           {
1078              if ((initted == 1) && (gl_wins == 1))
1079                   _destroy_internal_glue_resources(re);
1080              eng_window_free(re->win);
1081              gl_wins--;
1082           }
1083         evas_common_tilebuf_free(re->tb);
1084         free(re);
1085      }
1086    if ((initted == 1) && (gl_wins == 0))
1087      {
1088         evas_common_image_shutdown();
1089         evas_common_font_shutdown();
1090         initted = 0;
1091      }
1092 }
1093
1094 static void
1095 eng_output_resize(void *data, int w, int h)
1096 {
1097    Render_Engine *re;
1098
1099    re = (Render_Engine *)data;
1100    re->win->w = w;
1101    re->win->h = h;
1102    eng_window_use(re->win);
1103    evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
1104    evas_common_tilebuf_free(re->tb);
1105    re->tb = evas_common_tilebuf_new(w, h);
1106    if (re->tb)
1107      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
1108 }
1109
1110 static void
1111 eng_output_tile_size_set(void *data, int w, int h)
1112 {
1113    Render_Engine *re;
1114
1115    re = (Render_Engine *)data;
1116    evas_common_tilebuf_set_tile_size(re->tb, w, h);
1117 }
1118
1119 static void
1120 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
1121 {
1122    Render_Engine *re;
1123
1124    re = (Render_Engine *)data;
1125    eng_window_use(re->win);
1126    evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
1127    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
1128
1129    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h);
1130    if ((w <= 0) || (h <= 0)) return;
1131    if (!re->win->draw.redraw)
1132      {
1133 #if 1
1134         re->win->draw.x1 = x;
1135         re->win->draw.y1 = y;
1136         re->win->draw.x2 = x + w - 1;
1137         re->win->draw.y2 = y + h - 1;
1138 #else
1139         re->win->draw.x1 = 0;
1140         re->win->draw.y1 = 0;
1141         re->win->draw.x2 = re->win->w - 1;
1142         re->win->draw.y2 = re->win->h - 1;
1143 #endif
1144      }
1145    else
1146      {
1147         if (x < re->win->draw.x1) re->win->draw.x1 = x;
1148         if (y < re->win->draw.y1) re->win->draw.y1 = y;
1149         if ((x + w - 1) > re->win->draw.x2) re->win->draw.x2 = x + w - 1;
1150         if ((y + h - 1) > re->win->draw.y2) re->win->draw.y2 = y + h - 1;
1151      }
1152    re->win->draw.redraw = 1;
1153 }
1154
1155 static void
1156 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
1157 {
1158    Render_Engine *re;
1159
1160    re = (Render_Engine *)data;
1161    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
1162 }
1163
1164 static void
1165 eng_output_redraws_clear(void *data)
1166 {
1167    Render_Engine *re;
1168
1169    re = (Render_Engine *)data;
1170    evas_common_tilebuf_clear(re->tb);
1171 /*   re->win->draw.redraw = 0;*/
1172 //   INF("GL: finish update cycle!");
1173 }
1174
1175 /* vsync games - not for now though */
1176 #define VSYNC_TO_SCREEN 1
1177
1178 static void *
1179 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
1180 {
1181    Render_Engine *re;
1182    Tilebuf_Rect *rects;
1183
1184    re = (Render_Engine *)data;
1185    /* get the upate rect surface - return engine data as dummy */
1186    rects = evas_common_tilebuf_get_render_rects(re->tb);
1187    if (rects)
1188      {
1189 /*        
1190         Tilebuf_Rect *r;
1191         
1192         printf("REAAAAACCTS\n");
1193         EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
1194           {
1195              printf("  %i %i %ix%i\n", r->x, r->y, r->w, r->h);
1196           }
1197  */
1198         evas_common_tilebuf_free_render_rects(rects);
1199         evas_common_tilebuf_clear(re->tb);
1200 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1201         // dont need to for egl - eng_window_use() can check for other ctxt's
1202 #else
1203         eng_window_use(NULL);
1204 #endif
1205         eng_window_use(re->win);
1206         if (!_re_wincheck(re)) return NULL;
1207         evas_gl_common_context_flush(re->win->gl_context);
1208         evas_gl_common_context_newframe(re->win->gl_context);
1209         if (x) *x = 0;
1210         if (y) *y = 0;
1211         if (w) *w = re->win->w;
1212         if (h) *h = re->win->h;
1213         if (cx) *cx = 0;
1214         if (cy) *cy = 0;
1215         if (cw) *cw = re->win->w;
1216         if (ch) *ch = re->win->h;
1217         return re->win->gl_context->def_surface;
1218      }
1219    return NULL;
1220 /*   
1221    if (!re->win->draw.redraw) return NULL;
1222 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1223    // dont need to for egl - eng_window_use() can check for other ctxt's
1224 #else
1225    eng_window_use(NULL);
1226 #endif
1227    eng_window_use(re->win);
1228    if (!_re_wincheck(re)) return NULL;
1229    evas_gl_common_context_flush(re->win->gl_context);
1230    evas_gl_common_context_newframe(re->win->gl_context);
1231    if (x) *x = re->win->draw.x1;
1232    if (y) *y = re->win->draw.y1;
1233    if (w) *w = re->win->draw.x2 - re->win->draw.x1 + 1;
1234    if (h) *h = re->win->draw.y2 - re->win->draw.y1 + 1;
1235    if (cx) *cx = re->win->draw.x1;
1236    if (cy) *cy = re->win->draw.y1;
1237    if (cw) *cw = re->win->draw.x2 - re->win->draw.x1 + 1;
1238    if (ch) *ch = re->win->draw.y2 - re->win->draw.y1 + 1;
1239    return re->win->gl_context->def_surface;
1240  */
1241 }
1242
1243 //#define FRAMECOUNT 1
1244
1245 #ifdef FRAMECOUNT
1246 static double
1247 get_time(void)
1248 {
1249    struct timeval timev;
1250
1251    gettimeofday(&timev, NULL);
1252    return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
1253 }
1254 #endif
1255
1256 static int safe_native = -1;
1257
1258 static void
1259 eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
1260 {
1261    Render_Engine *re;
1262 #ifdef FRAMECOUNT
1263    static double pt = 0.0;
1264    double ta, tb;
1265 #endif
1266
1267    re = (Render_Engine *)data;
1268    /* put back update surface.. in this case just unflag redraw */
1269    if (!_re_wincheck(re)) return;
1270    re->win->draw.redraw = 0;
1271    re->win->draw.drew = 1;
1272    evas_gl_common_context_flush(re->win->gl_context);
1273    if (safe_native == -1)
1274      {
1275         const char *s = getenv("EVAS_GL_SAFE_NATIVE");
1276         safe_native = 0;
1277         if (s) safe_native = atoi(s);
1278         else
1279           {
1280              s = (const char *)glGetString(GL_RENDERER);
1281              if (s)
1282                {
1283                   if (strstr(s, "PowerVR SGX 540") ||
1284                       strstr(s, "Mali-400 MP"))
1285                     safe_native = 1;
1286                }
1287           }
1288      }
1289 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1290    // this is needed to make sure all previous rendering is flushed to
1291    // buffers/surfaces
1292 #ifdef FRAMECOUNT
1293    double t0 = get_time();
1294    ta = t0 - pt;
1295    pt = t0;
1296 #endif
1297    // previous rendering should be done and swapped
1298    if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
1299 #ifdef FRAMECOUNT
1300    double t1 = get_time();
1301    tb = t1 - t0;
1302    printf("... %1.5f -> %1.5f | ", ta, tb);
1303 #endif
1304 //   if (eglGetError() != EGL_SUCCESS)
1305 //     {
1306 //        printf("Error:  eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
1307 //     }
1308 #else
1309    // previous rendering should be done and swapped
1310    if (!safe_native) glXWaitX();
1311 #endif
1312 //x//   printf("frame -> push\n");
1313 }
1314
1315 static void
1316 eng_output_flush(void *data)
1317 {
1318    Render_Engine *re;
1319
1320    re = (Render_Engine *)data;
1321    if (!_re_wincheck(re)) return;
1322    if (!re->win->draw.drew) return;
1323 //x//   printf("frame -> flush\n");
1324    re->win->draw.drew = 0;
1325    eng_window_use(re->win);
1326
1327 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1328 #ifdef FRAMECOUNT
1329    double t0 = get_time();
1330 #endif
1331    if (!re->vsync)
1332      {
1333         if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
1334         else eglSwapInterval(re->win->egl_disp, 0);
1335         re->vsync = 1;
1336      }
1337    if (re->info->callback.pre_swap)
1338      {
1339         re->info->callback.pre_swap(re->info->callback.data, re->evas);
1340      }
1341    eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
1342    if (!safe_native) eglWaitGL();
1343    if (re->info->callback.post_swap)
1344      {
1345         re->info->callback.post_swap(re->info->callback.data, re->evas);
1346      }
1347 #ifdef FRAMECOUNT
1348    double t1 = get_time();
1349    printf("%1.5f\n", t1 - t0);
1350 #endif
1351 //   if (eglGetError() != EGL_SUCCESS)
1352 //     {
1353 //        printf("Error:  eglSwapBuffers() fail.\n");
1354 //     }
1355 #else
1356 #ifdef VSYNC_TO_SCREEN
1357    if ((re->info->vsync)/* || (1)*/)
1358      {
1359         if (glsym_glXSwapIntervalEXT)
1360           {
1361              if (!re->vsync)
1362                {
1363                   if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1);
1364                   else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0);
1365                   re->vsync = 1;
1366                }
1367           }
1368         if (glsym_glXSwapIntervalSGI)
1369           {
1370              if (!re->vsync)
1371                {
1372                   if (re->info->vsync) glsym_glXSwapIntervalSGI(1);
1373                   else glsym_glXSwapIntervalSGI(0);
1374                   re->vsync = 1;
1375                }
1376           }
1377         else
1378           {
1379              if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
1380                {
1381                   unsigned int rc;
1382
1383                   glsym_glXGetVideoSync(&rc);
1384                   glsym_glXWaitVideoSync(1, 0, &rc);
1385                }
1386           }
1387      }
1388 # endif
1389    if (re->info->callback.pre_swap)
1390      {
1391         re->info->callback.pre_swap(re->info->callback.data, re->evas);
1392      }
1393 #if 1
1394    if (1)
1395 #else
1396    if ((re->win->draw.x1 == 0) && (re->win->draw.y1 == 0) && (re->win->draw.x2 == (re->win->w - 1)) && (re->win->draw.y2 == (re->win->h - 1)))
1397 #endif     
1398      {
1399 //        double t, t2 = 0.0;
1400 //        t = get_time();
1401         glXSwapBuffers(re->win->disp, re->win->win);
1402 //        t = get_time() - t;
1403 //        if (!safe_native)
1404 //          {
1405 //             t2 = get_time();
1406 //             glXWaitGL();
1407 //             t2 = get_time() - t2;
1408 //          }
1409 //        printf("swap: %3.5f (%3.5fms), x wait gl: %3.5f (%3.5fms)\n", 
1410 //               t, t * 1000.0, t2, t2 * 1000.0);
1411      }
1412    else
1413      {
1414 // FIXME: this doesn't work.. why oh why?
1415         int sx, sy, sw, sh;
1416
1417         sx = re->win->draw.x1;
1418         sy = re->win->draw.y1;
1419         sw = (re->win->draw.x2 - re->win->draw.x1) + 1;
1420         sh = (re->win->draw.y2 - re->win->draw.y1) + 1;
1421         sy = re->win->h - sy - sh;
1422         
1423         glBitmap(0, 0, 0, 0, sx, re->win->h - sy, NULL);
1424         glEnable(GL_SCISSOR_TEST);
1425         glScissor(sx, sy, sw, sh);
1426         glDrawBuffer(GL_FRONT);
1427         glCopyPixels(sx, sy, sw, sh, GL_COLOR);
1428         glDrawBuffer(GL_BACK);
1429         glDisable(GL_SCISSOR_TEST);
1430         glBitmap(0, 0, 0, 0, 0, 0, NULL);
1431         glFlush();
1432      }
1433    if (re->info->callback.post_swap)
1434      {
1435         re->info->callback.post_swap(re->info->callback.data, re->evas);
1436      }
1437 #endif
1438 }
1439
1440 static void
1441 eng_output_idle_flush(void *data)
1442 {
1443    Render_Engine *re;
1444
1445    re = (Render_Engine *)data;
1446 }
1447
1448 static void
1449 eng_output_dump(void *data)
1450 {
1451    Render_Engine *re;
1452
1453    re = (Render_Engine *)data;
1454    evas_common_image_image_all_unload();
1455    evas_common_font_font_all_unload();
1456    evas_gl_common_image_all_unload(re->win->gl_context);
1457    _re_winfree(re);
1458 }
1459
1460 static void
1461 eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
1462 {
1463 //   Render_Engine *re;
1464 //
1465 //   re = (Render_Engine *)data;
1466 //   re->win->gl_context->dc = context;
1467    evas_common_draw_context_add_cutout(context, x, y, w, h);
1468 }
1469
1470 static void
1471 eng_context_cutout_clear(void *data __UNUSED__, void *context)
1472 {
1473 //   Render_Engine *re;
1474 //
1475 //   re = (Render_Engine *)data;
1476 //   re->win->gl_context->dc = context;
1477    evas_common_draw_context_clear_cutouts(context);
1478 }
1479
1480 static void
1481 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
1482 {
1483    Render_Engine *re;
1484
1485    re = (Render_Engine *)data;
1486    eng_window_use(re->win);
1487    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1488    re->win->gl_context->dc = context;
1489    evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
1490 }
1491
1492 static void
1493 eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
1494 {
1495    Render_Engine *re;
1496
1497    re = (Render_Engine *)data;
1498    eng_window_use(re->win);
1499    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1500    re->win->gl_context->dc = context;
1501    evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2);
1502 }
1503
1504 static void *
1505 eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
1506 {
1507    Render_Engine *re;
1508
1509    re = (Render_Engine *)data;
1510    return evas_gl_common_poly_point_add(polygon, x, y);
1511 }
1512
1513 static void *
1514 eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
1515 {
1516    Render_Engine *re;
1517
1518    re = (Render_Engine *)data;
1519    return evas_gl_common_poly_points_clear(polygon);
1520 }
1521
1522 static void
1523 eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *polygon, int x, int y)
1524 {
1525    Render_Engine *re;
1526
1527    re = (Render_Engine *)data;
1528    eng_window_use(re->win);
1529    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1530    re->win->gl_context->dc = context;
1531    evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
1532 }
1533
1534 static int
1535 eng_image_alpha_get(void *data __UNUSED__, void *image)
1536 {
1537 //   Render_Engine *re;
1538    Evas_GL_Image *im;
1539
1540 //   re = (Render_Engine *)data;
1541    if (!image) return 1;
1542    im = image;
1543    return im->alpha;
1544 }
1545
1546 static int
1547 eng_image_colorspace_get(void *data __UNUSED__, void *image)
1548 {
1549 //   Render_Engine *re;
1550    Evas_GL_Image *im;
1551
1552 //   re = (Render_Engine *)data;
1553    if (!image) return EVAS_COLORSPACE_ARGB8888;
1554    im = image;
1555    return im->cs.space;
1556 }
1557
1558 static void
1559 eng_image_mask_create(void *data __UNUSED__, void *image)
1560 {
1561    Evas_GL_Image *im;
1562
1563    if (!image) return;
1564    im = image;
1565    if (!im->im->image.data)
1566       evas_cache_image_load_data(&im->im->cache_entry);
1567    if (!im->tex)
1568       im->tex = evas_gl_common_texture_new(im->gc, im->im);
1569 }
1570
1571
1572 static void *
1573 eng_image_alpha_set(void *data, void *image, int has_alpha)
1574 {
1575    Render_Engine *re;
1576    Evas_GL_Image *im;
1577
1578    re = (Render_Engine *)data;
1579    if (!image) return NULL;
1580    im = image;
1581    if (im->alpha == has_alpha) return image;
1582    if (im->native.data)
1583      {
1584         im->alpha = has_alpha;
1585         return image;
1586      }
1587    eng_window_use(re->win);
1588    if ((im->tex) && (im->tex->pt->dyn.img))
1589      {
1590         im->alpha = has_alpha;
1591         im->tex->alpha = im->alpha;
1592         return image;
1593      }
1594    /* FIXME: can move to gl_common */
1595    if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
1596    if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
1597    else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
1598    if (im->references > 1)
1599      {
1600         Evas_GL_Image *im_new;
1601
1602         im_new = evas_gl_common_image_new_from_copied_data
1603            (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
1604                im->im->image.data,
1605                eng_image_alpha_get(data, image),
1606                eng_image_colorspace_get(data, image));
1607         if (!im_new) return im;
1608         evas_gl_common_image_free(im);
1609         im = im_new;
1610      }
1611    else
1612      evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1613    return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
1614 //   im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
1615 //   return image;
1616 }
1617
1618 static void *
1619 eng_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
1620 {
1621 //   Render_Engine *re;
1622 //
1623 //   re = (Render_Engine *)data;
1624    return image;
1625 }
1626
1627 static void
1628 eng_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
1629 {
1630 //   Render_Engine *re;
1631 //
1632 //   re = (Render_Engine *)data;
1633 }
1634
1635 static char *
1636 eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
1637 {
1638 //   Render_Engine *re;
1639    Evas_GL_Image *im;
1640
1641 //   re = (Render_Engine *)data;
1642    if (!image) return NULL;
1643    im = image;
1644    if (!im->im) return NULL;
1645    return im->im->info.comment;
1646 }
1647
1648 static char *
1649 eng_image_format_get(void *data __UNUSED__, void *image)
1650 {
1651 //   Render_Engine *re;
1652    Evas_GL_Image *im;
1653
1654 //   re = (Render_Engine *)data;
1655    im = image;
1656    return NULL;
1657 }
1658
1659 static void
1660 eng_image_colorspace_set(void *data, void *image, int cspace)
1661 {
1662    Render_Engine *re;
1663    Evas_GL_Image *im;
1664
1665    re = (Render_Engine *)data;
1666    if (!image) return;
1667    im = image;
1668    if (im->native.data) return;
1669    /* FIXME: can move to gl_common */
1670    if (im->cs.space == cspace) return;
1671    eng_window_use(re->win);
1672    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
1673    switch (cspace)
1674      {
1675       case EVAS_COLORSPACE_ARGB8888:
1676          if (im->cs.data)
1677            {
1678               if (!im->cs.no_free) free(im->cs.data);
1679               im->cs.data = NULL;
1680               im->cs.no_free = 0;
1681            }
1682          break;
1683       case EVAS_COLORSPACE_YCBCR422P601_PL:
1684       case EVAS_COLORSPACE_YCBCR422P709_PL:
1685       case EVAS_COLORSPACE_YCBCR422601_PL:
1686       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1687       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1688          if (im->tex) evas_gl_common_texture_free(im->tex);
1689          im->tex = NULL;
1690          if (im->cs.data)
1691            {
1692               if (!im->cs.no_free) free(im->cs.data);
1693            }
1694          if (im->im->cache_entry.h > 0)
1695            im->cs.data =
1696               calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
1697          else
1698            im->cs.data = NULL;
1699          im->cs.no_free = 0;
1700          break;
1701       default:
1702          abort();
1703          break;
1704      }
1705    im->cs.space = cspace;
1706 }
1707
1708 /////////////////////////////////////////////////////////////////////////
1709 //
1710 //
1711 typedef struct _Native Native;
1712
1713 struct _Native
1714 {
1715    Evas_Native_Surface ns;
1716    Pixmap     pixmap;
1717    Visual    *visual;
1718
1719 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1720    void      *egl_surface;
1721 #else
1722    void  *fbc;
1723    XID    glx_pixmap;
1724 #endif
1725 };
1726
1727 // FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
1728 // (i am sure this is the reason)  not to mention seemingly superfluous. but
1729 // i need to enable it for it to work on fglrx at least. havent tried nvidia.
1730 //
1731 // why is this the case? does anyone know? has anyone tried it on other gfx
1732 // drivers?
1733 //
1734 //#define GLX_TEX_PIXMAP_RECREATE 1
1735
1736 static void
1737 _native_bind_cb(void *data, void *image)
1738 {
1739    Evas_GL_Image *im = image;
1740    Native *n = im->native.data;
1741
1742   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1743     {
1744 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1745       if (n->egl_surface)
1746         {
1747           if (glsym_glEGLImageTargetTexture2DOES)
1748             {
1749               glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
1750               if (eglGetError() != EGL_SUCCESS)
1751                 ERR("glEGLImageTargetTexture2DOES() failed.");
1752             }
1753           else
1754             ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
1755         }
1756 #else
1757 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1758       Render_Engine *re = data;
1759
1760       if (glsym_glXBindTexImage)
1761         {
1762           glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
1763                                 GLX_FRONT_LEFT_EXT, NULL);
1764           GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1765         }
1766       else
1767         ERR("Try glXBindTexImage on GLX with no support");
1768 # endif
1769 #endif
1770     }
1771   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1772     {
1773       glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
1774       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1775     }
1776    return;
1777    data = NULL;
1778 }
1779
1780 static void
1781 _native_unbind_cb(void *data, void *image)
1782 {
1783   Evas_GL_Image *im = image;
1784   Native *n = im->native.data;
1785
1786   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1787     {
1788 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1789       // nothing
1790 #else
1791 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1792       Render_Engine *re = data;
1793
1794       if (glsym_glXReleaseTexImage)
1795         {
1796           glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1797                                    GLX_FRONT_LEFT_EXT);
1798           GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1799         }
1800       else
1801         ERR("Try glXReleaseTexImage on GLX with no support");
1802 # endif
1803 #endif
1804     }
1805   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1806     {
1807       glBindTexture(GL_TEXTURE_2D, 0);
1808       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1809     }
1810    return;
1811    data = NULL;
1812 }
1813
1814 static void
1815 _native_free_cb(void *data, void *image)
1816 {
1817   Render_Engine *re = data;
1818   Evas_GL_Image *im = image;
1819   Native *n = im->native.data;
1820   uint32_t pmid, texid;
1821
1822   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1823     {
1824       pmid = n->pixmap;
1825       eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1826 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1827       if (n->egl_surface)
1828         {
1829           if (glsym_eglDestroyImage)
1830             {
1831               glsym_eglDestroyImage(re->win->egl_disp,
1832                                     n->egl_surface);
1833               if (eglGetError() != EGL_SUCCESS)
1834                 ERR("eglDestroyImage() failed.");
1835             }
1836           else
1837             ERR("Try eglDestroyImage on EGL with no support");
1838         }
1839 #else
1840 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1841       if (n->glx_pixmap)
1842         {
1843           if (im->native.loose)
1844             {
1845               if (glsym_glXReleaseTexImage)
1846                 {
1847                   glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1848                                            GLX_FRONT_LEFT_EXT);
1849                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1850                 }
1851               else
1852                 ERR("Try glXReleaseTexImage on GLX with no support");
1853             }
1854           if (glsym_glXDestroyPixmap)
1855             {
1856               glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
1857               GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1858             }
1859           else
1860             ERR("Try glXDestroyPixmap on GLX with no support");
1861           n->glx_pixmap = 0;
1862         }
1863 # endif
1864 #endif
1865     }
1866   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1867     {
1868       texid = n->ns.data.opengl.texture_id;
1869       eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
1870     }
1871   im->native.data        = NULL;
1872   im->native.func.data   = NULL;
1873   im->native.func.bind   = NULL;
1874   im->native.func.unbind = NULL;
1875   im->native.func.free   = NULL;
1876   free(n);
1877 }
1878
1879 static void *
1880 eng_image_native_set(void *data, void *image, void *native)
1881 {
1882   Render_Engine *re = (Render_Engine *)data;
1883   Evas_Native_Surface *ns = native;
1884   Evas_GL_Image *im = image, *im2 = NULL;
1885   Visual *vis = NULL;
1886   Pixmap pm = 0;
1887   Native *n = NULL;
1888   uint32_t pmid, texid;
1889   unsigned int tex = 0;
1890   unsigned int fbo = 0;
1891
1892   if (!im)
1893     {
1894        if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
1895          {
1896             im = evas_gl_common_image_new_from_data(re->win->gl_context,
1897                                                     ns->data.opengl.w,
1898                                                     ns->data.opengl.h,
1899                                                     NULL, 1,
1900                                                     EVAS_COLORSPACE_ARGB8888);
1901          }
1902        else
1903            return NULL;
1904     }
1905
1906   if (ns)
1907     {
1908       if (ns->type == EVAS_NATIVE_SURFACE_X11)
1909         {
1910           vis = ns->data.x11.visual;
1911           pm = ns->data.x11.pixmap;
1912           if (im->native.data)
1913             {
1914               Evas_Native_Surface *ens = im->native.data;
1915               if ((ens->data.x11.visual == vis) &&
1916                   (ens->data.x11.pixmap == pm))
1917                 return im;
1918             }
1919         }
1920       else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1921         {
1922           tex = ns->data.opengl.texture_id;
1923           fbo = ns->data.opengl.framebuffer_id;
1924           if (im->native.data)
1925             {
1926               Evas_Native_Surface *ens = im->native.data;
1927               if ((ens->data.opengl.texture_id == tex) &&
1928                   (ens->data.opengl.framebuffer_id == fbo))
1929                 return im;
1930             }
1931         }
1932     }
1933   if ((!ns) && (!im->native.data)) return im;
1934
1935   eng_window_use(re->win);
1936
1937   if (im->native.data)
1938     {
1939       if (im->native.func.free)
1940         im->native.func.free(im->native.func.data, im);
1941       evas_gl_common_image_native_disable(im);
1942     }
1943
1944   if (!ns) return im;
1945
1946   if (ns->type == EVAS_NATIVE_SURFACE_X11)
1947     {
1948       pmid = pm;
1949       im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
1950       if (im2 == im) return im;
1951       if (im2)
1952         {
1953            n = im2->native.data;
1954            if (n)
1955              {
1956                 evas_gl_common_image_ref(im2);
1957                 evas_gl_common_image_free(im);
1958                 return im2;
1959              }
1960         }
1961     }
1962   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1963     {
1964        texid = tex;
1965        im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
1966        if (im2 == im) return im;
1967        if (im2)
1968          {
1969             n = im2->native.data;
1970             if (n)
1971               {
1972                  evas_gl_common_image_ref(im2);
1973                  evas_gl_common_image_free(im);
1974                  return im2;
1975               }
1976          }
1977
1978     }
1979   im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
1980                                            im->w, im->h, NULL, im->alpha,
1981                                            EVAS_COLORSPACE_ARGB8888);
1982   evas_gl_common_image_free(im);
1983   im = im2;
1984   if (ns->type == EVAS_NATIVE_SURFACE_X11)
1985     {
1986 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1987       if (native)
1988         {
1989           n = calloc(1, sizeof(Native));
1990           if (n)
1991             {
1992               EGLConfig egl_config;
1993               int config_attrs[20];
1994               int num_config, i = 0;
1995
1996               eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1997
1998               config_attrs[i++] = EGL_RED_SIZE;
1999               config_attrs[i++] = 8;
2000               config_attrs[i++] = EGL_GREEN_SIZE;
2001               config_attrs[i++] = 8;
2002               config_attrs[i++] = EGL_BLUE_SIZE;
2003               config_attrs[i++] = 8;
2004               config_attrs[i++] = EGL_ALPHA_SIZE;
2005               config_attrs[i++] = 8;
2006               config_attrs[i++] = EGL_DEPTH_SIZE;
2007               config_attrs[i++] = 0;
2008               config_attrs[i++] = EGL_STENCIL_SIZE;
2009               config_attrs[i++] = 0;
2010               config_attrs[i++] = EGL_RENDERABLE_TYPE;
2011               config_attrs[i++] = EGL_OPENGL_ES2_BIT;
2012               config_attrs[i++] = EGL_SURFACE_TYPE;
2013               config_attrs[i++] = EGL_PIXMAP_BIT;
2014               config_attrs[i++] = EGL_NONE;
2015
2016               if (!eglChooseConfig(re->win->egl_disp, config_attrs,
2017                                    &egl_config, 1, &num_config))
2018                 ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
2019               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2020               n->pixmap = pm;
2021               n->visual = vis;
2022               if (glsym_eglCreateImage)
2023                 n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
2024                                                       EGL_NO_CONTEXT,
2025                                                       EGL_NATIVE_PIXMAP_KHR,
2026                                                       (void *)pm,
2027                                                       NULL);
2028               else
2029                 ERR("Try eglCreateImage on EGL with no support");
2030               if (!n->egl_surface)
2031                 ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
2032               im->native.yinvert     = 1;
2033               im->native.loose       = 0;
2034               im->native.data        = n;
2035               im->native.func.data   = re;
2036               im->native.func.bind   = _native_bind_cb;
2037               im->native.func.unbind = _native_unbind_cb;
2038               im->native.func.free   = _native_free_cb;
2039               im->native.target      = GL_TEXTURE_2D;
2040               im->native.mipmap      = 0;
2041               evas_gl_common_image_native_enable(im);
2042             }
2043         }
2044 #else
2045 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
2046       if (native)
2047         {
2048           int dummy;
2049           unsigned int w, h, depth = 32, border;
2050           Window wdummy;
2051
2052           // fixme: round trip :(
2053           XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
2054                        &w, &h, &border, &depth);
2055           n = calloc(1, sizeof(Native));
2056           if (n)
2057             {
2058               int pixmap_att[20];
2059               unsigned int target = 0;
2060               unsigned int i = 0;
2061
2062               eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
2063               if ((re->win->depth_cfg[depth].tex_target &
2064                    GLX_TEXTURE_2D_BIT_EXT)
2065                   //                 && (1) // we assume npo2 for now
2066                   // size is pow2 || mnpo2 supported
2067                  )
2068                 target = GLX_TEXTURE_2D_EXT;
2069               else if ((re->win->depth_cfg[depth].tex_target &
2070                         GLX_TEXTURE_RECTANGLE_BIT_EXT))
2071                 {
2072                   ERR("rect!!! (not handled)");
2073                   target = GLX_TEXTURE_RECTANGLE_EXT;
2074                 }
2075               if (!target)
2076                 {
2077                   ERR("broken text-from-pixmap");
2078                   if (!(re->win->depth_cfg[depth].tex_target &
2079                         GLX_TEXTURE_2D_BIT_EXT))
2080                     target = GLX_TEXTURE_RECTANGLE_EXT;
2081                   else if (!(re->win->depth_cfg[depth].tex_target &
2082                              GLX_TEXTURE_RECTANGLE_BIT_EXT))
2083                     target = GLX_TEXTURE_2D_EXT;
2084                 }
2085
2086
2087               pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
2088               pixmap_att[i++] = re->win->depth_cfg[depth].tex_format;
2089               pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
2090               pixmap_att[i++] = re->win->depth_cfg[depth].mipmap;
2091
2092               if (target)
2093                 {
2094                   pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
2095                   pixmap_att[i++] = target;
2096                 }
2097
2098               pixmap_att[i++] = 0;
2099
2100               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2101               n->pixmap = pm;
2102               n->visual = vis;
2103               n->fbc = re->win->depth_cfg[depth].fbc;
2104               if (glsym_glXCreatePixmap)
2105                 n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
2106                                                       n->fbc,
2107                                                       n->pixmap,
2108                                                       pixmap_att);
2109               else
2110                 ERR("Try glXCreatePixmap on GLX with no support");
2111               if (n->glx_pixmap)
2112                 {
2113 //                  printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
2114 //                         n, pm, w, h, depth, n->glx_pixmap);
2115                   if (!target)
2116                     {
2117                       ERR("no target :(");
2118                       if (glsym_glXQueryDrawable)
2119                         glsym_glXQueryDrawable(re->win->disp,
2120                                                n->pixmap,
2121                                                GLX_TEXTURE_TARGET_EXT,
2122                                                &target);
2123                     }
2124                   if (target == GLX_TEXTURE_2D_EXT)
2125                     {
2126                       im->native.target = GL_TEXTURE_2D;
2127                       im->native.mipmap = re->win->depth_cfg[depth].mipmap;
2128                     }
2129 #  ifdef GL_TEXTURE_RECTANGLE_ARB
2130                   else if (target == GLX_TEXTURE_RECTANGLE_EXT)
2131                     {
2132                       im->native.target = GL_TEXTURE_RECTANGLE_ARB;
2133                       im->native.mipmap = 0;
2134                     }
2135 #  endif
2136                   else
2137                     {
2138                       im->native.target = GL_TEXTURE_2D;
2139                       im->native.mipmap = 0;
2140                       ERR("still unknown target");
2141                     }
2142                 }
2143               else
2144                 ERR("GLX Pixmap create fail");
2145               im->native.yinvert     = re->win->depth_cfg[depth].yinvert;
2146               im->native.loose       = re->win->detected.loose_binding;
2147               im->native.data        = n;
2148               im->native.func.data   = re;
2149               im->native.func.bind   = _native_bind_cb;
2150               im->native.func.unbind = _native_unbind_cb;
2151               im->native.func.free   = _native_free_cb;
2152
2153               evas_gl_common_image_native_enable(im);
2154             }
2155         }
2156 # endif
2157 #endif
2158     }
2159   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
2160     {
2161       if (native)
2162         {
2163           n = calloc(1, sizeof(Native));
2164           if (n)
2165             {
2166               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2167
2168               eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
2169
2170               n->pixmap = 0;
2171               n->visual = 0;
2172 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2173               n->egl_surface = 0;
2174 #else
2175               n->fbc = 0;
2176               n->glx_pixmap = 0;
2177 #endif
2178
2179               im->native.yinvert     = 0;
2180               im->native.loose       = 0;
2181               im->native.data        = n;
2182               im->native.func.data   = re;
2183               im->native.func.bind   = _native_bind_cb;
2184               im->native.func.unbind = _native_unbind_cb;
2185               im->native.func.free   = _native_free_cb;
2186               im->native.target      = GL_TEXTURE_2D;
2187               im->native.mipmap      = 0;
2188
2189               // FIXME: need to implement mapping sub texture regions
2190               // x, y, w, h for possible texture atlasing
2191
2192               evas_gl_common_image_native_enable(im);
2193             }
2194         }
2195
2196     }
2197    return im;
2198 }
2199
2200 static void *
2201 eng_image_native_get(void *data __UNUSED__, void *image)
2202 {
2203    Evas_GL_Image *im = image;
2204    Native *n;
2205    if (!im) return NULL;
2206    n = im->native.data;
2207    if (!n) return NULL;
2208    return &(n->ns);
2209 }
2210
2211 #if 0 // filtering disabled
2212 static void
2213 eng_image_draw_filtered(void *data, void *context, void *surface,
2214                         void *image, Evas_Filter_Info *filter)
2215 {
2216    Render_Engine *re = data;
2217
2218    if (!image) return;
2219    eng_window_use(re->win);
2220    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2221    re->win->gl_context->dc = context;
2222
2223    evas_gl_common_filter_draw(re->win->gl_context, image, filter);
2224 }
2225
2226 static Filtered_Image *
2227 eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
2228 {
2229    return evas_gl_common_image_filtered_get(im, key, keylen);
2230 }
2231
2232 static Filtered_Image *
2233 eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
2234 {
2235    return evas_gl_common_image_filtered_save(im, fim, key, keylen);
2236 }
2237
2238 static void
2239 eng_image_filtered_free(void *im, Filtered_Image *fim)
2240 {
2241    evas_gl_common_image_filtered_free(im, fim);
2242 }
2243 #endif
2244
2245
2246 //
2247 //
2248 /////////////////////////////////////////////////////////////////////////
2249
2250 static void *
2251 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
2252 {
2253    Render_Engine *re;
2254
2255    re = (Render_Engine *)data;
2256    *error = EVAS_LOAD_ERROR_NONE;
2257    eng_window_use(re->win);
2258    return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
2259 }
2260
2261 static void *
2262 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
2263 {
2264    Render_Engine *re;
2265
2266    re = (Render_Engine *)data;
2267    eng_window_use(re->win);
2268    return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
2269 }
2270
2271 static void *
2272 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
2273 {
2274    Render_Engine *re;
2275
2276    re = (Render_Engine *)data;
2277    eng_window_use(re->win);
2278    return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
2279 }
2280
2281 static void
2282 eng_image_free(void *data, void *image)
2283 {
2284    Render_Engine *re;
2285
2286    re = (Render_Engine *)data;
2287    if (!image) return;
2288    eng_window_use(re->win);
2289    evas_gl_common_image_free(image);
2290 }
2291
2292 static void
2293 eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
2294 {
2295    if (!image)
2296      {
2297         *w = 0;
2298         *h = 0;
2299         return;
2300      }
2301    if (w) *w = ((Evas_GL_Image *)image)->w;
2302    if (h) *h = ((Evas_GL_Image *)image)->h;
2303 }
2304
2305 static void *
2306 eng_image_size_set(void *data, void *image, int w, int h)
2307 {
2308    Render_Engine *re;
2309    Evas_GL_Image *im = image;
2310    Evas_GL_Image *im_old;
2311
2312    re = (Render_Engine *)data;
2313    if (!im) return NULL;
2314    if (im->native.data)
2315      {
2316         im->w = w;
2317         im->h = h;
2318         return image;
2319      }
2320    eng_window_use(re->win);
2321    if ((im->tex) && (im->tex->pt->dyn.img))
2322      {
2323         evas_gl_common_texture_free(im->tex);
2324         im->tex = NULL;
2325         im->w = w;
2326         im->h = h;
2327         im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
2328         return image;
2329      }
2330    im_old = image;
2331
2332    switch (eng_image_colorspace_get(data, image))
2333      {
2334       case EVAS_COLORSPACE_YCBCR422P601_PL:
2335       case EVAS_COLORSPACE_YCBCR422P709_PL:
2336       case EVAS_COLORSPACE_YCBCR422601_PL:
2337       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
2338       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
2339          w &= ~0x1;
2340          break;
2341      }
2342
2343    if ((im_old) &&
2344        ((int)im_old->im->cache_entry.w == w) &&
2345        ((int)im_old->im->cache_entry.h == h))
2346      return image;
2347    if (im_old)
2348      {
2349         im = evas_gl_common_image_new(re->win->gl_context, w, h,
2350                                       eng_image_alpha_get(data, image),
2351                                       eng_image_colorspace_get(data, image));
2352         /*
2353         evas_common_load_image_data_from_file(im_old->im);
2354         if (im_old->im->image->data)
2355           {
2356              evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
2357              evas_common_cpu_end_opt();
2358           }
2359  */
2360         evas_gl_common_image_free(im_old);
2361      }
2362    else
2363      im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
2364    return im;
2365 }
2366
2367 static void *
2368 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
2369 {
2370    Render_Engine *re;
2371    Evas_GL_Image *im = image;
2372
2373    re = (Render_Engine *)data;
2374    if (!image) return NULL;
2375    if (im->native.data) return image;
2376    eng_window_use(re->win);
2377    evas_gl_common_image_dirty(image, x, y, w, h);
2378    return image;
2379 }
2380
2381 static void *
2382 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
2383 {
2384    Render_Engine *re;
2385    Evas_GL_Image *im;
2386    int error;
2387
2388    re = (Render_Engine *)data;
2389    if (!image)
2390      {
2391         *image_data = NULL;
2392         if (err) *err = EVAS_LOAD_ERROR_GENERIC;
2393         return NULL;
2394      }
2395    im = image;
2396    if (im->native.data)
2397      {
2398         *image_data = NULL;
2399         if (err) *err = EVAS_LOAD_ERROR_NONE;
2400         return im;
2401      }
2402
2403 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2404    eng_window_use(re->win);
2405
2406    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
2407      {
2408         if (im->tex->pt->dyn.checked_out > 0)
2409           {
2410              im->tex->pt->dyn.checked_out++;
2411              *image_data = im->tex->pt->dyn.data;
2412              if (err) *err = EVAS_LOAD_ERROR_NONE;
2413              return im;
2414           }
2415         *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
2416
2417         if (!im->tex->pt->dyn.data)
2418           {
2419              if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
2420              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2421              return im;
2422           }
2423         im->tex->pt->dyn.checked_out++;
2424
2425         if (err) *err = EVAS_LOAD_ERROR_NONE;
2426         return im;
2427      }
2428 #else
2429    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
2430      {
2431         *image_data = im->tex->pt->dyn.data;
2432         if (err) *err = EVAS_LOAD_ERROR_NONE;
2433         return im;
2434      }
2435
2436    eng_window_use(re->win);
2437 #endif
2438
2439    /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
2440         so it is need to add code which check im->im's NULL value*/
2441
2442    if (!im->im)
2443     {
2444        *image_data = NULL;
2445        if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
2446        return NULL;
2447     }
2448
2449    error = evas_cache_image_load_data(&im->im->cache_entry);
2450    switch (im->cs.space)
2451      {
2452       case EVAS_COLORSPACE_ARGB8888:
2453          if (to_write)
2454            {
2455               if (im->references > 1)
2456                 {
2457                    Evas_GL_Image *im_new;
2458
2459                    im_new = evas_gl_common_image_new_from_copied_data
2460                       (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
2461                        im->im->image.data,
2462                        eng_image_alpha_get(data, image),
2463                        eng_image_colorspace_get(data, image));
2464                    if (!im_new)
2465                      {
2466                         *image_data = NULL;
2467                         if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
2468                         return NULL;
2469                      }
2470                    evas_gl_common_image_free(im);
2471                    im = im_new;
2472                 }
2473               else
2474                 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
2475            }
2476          *image_data = im->im->image.data;
2477          break;
2478       case EVAS_COLORSPACE_YCBCR422P601_PL:
2479       case EVAS_COLORSPACE_YCBCR422P709_PL:
2480       case EVAS_COLORSPACE_YCBCR422601_PL:
2481       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
2482       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
2483          *image_data = im->cs.data;
2484          break;
2485       default:
2486          abort();
2487          break;
2488      }
2489    if (err) *err = error;
2490    return im;
2491 }
2492
2493 static void *
2494 eng_image_data_put(void *data, void *image, DATA32 *image_data)
2495 {
2496    Render_Engine *re;
2497    Evas_GL_Image *im, *im2;
2498
2499    re = (Render_Engine *)data;
2500    if (!image) return NULL;
2501    im = image;
2502    if (im->native.data) return image;
2503    eng_window_use(re->win);
2504    if ((im->tex) && (im->tex->pt)
2505        && (im->tex->pt->dyn.data)
2506        && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
2507      {
2508         int w, h;
2509
2510         if (im->tex->pt->dyn.data == image_data)
2511           {
2512              im->tex->pt->dyn.checked_out--;
2513 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2514              if (im->tex->pt->dyn.checked_out == 0)
2515                glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
2516 #endif
2517              return image;
2518           }
2519
2520         w = im->im->cache_entry.w;
2521         h = im->im->cache_entry.h;
2522         im2 = eng_image_new_from_data(data, w, h, image_data,
2523                                       eng_image_alpha_get(data, image),
2524                                       eng_image_colorspace_get(data, image));
2525         if (!im2) return im;
2526         evas_gl_common_image_free(im);
2527         im = im2;
2528         evas_gl_common_image_dirty(im, 0, 0, 0, 0);
2529         return im;
2530      }
2531    switch (im->cs.space)
2532      {
2533       case EVAS_COLORSPACE_ARGB8888:
2534          if (image_data != im->im->image.data)
2535            {
2536               int w, h;
2537
2538               w = im->im->cache_entry.w;
2539               h = im->im->cache_entry.h;
2540               im2 = eng_image_new_from_data(data, w, h, image_data,
2541                                             eng_image_alpha_get(data, image),
2542                                             eng_image_colorspace_get(data, image));
2543               if (!im2) return im;
2544               evas_gl_common_image_free(im);
2545               im = im2;
2546            }
2547          break;
2548       case EVAS_COLORSPACE_YCBCR422P601_PL:
2549       case EVAS_COLORSPACE_YCBCR422P709_PL:
2550       case EVAS_COLORSPACE_YCBCR422601_PL:
2551       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
2552       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
2553          if (image_data != im->cs.data)
2554            {
2555               if (im->cs.data)
2556                 {
2557                    if (!im->cs.no_free) free(im->cs.data);
2558                 }
2559               im->cs.data = image_data;
2560            }
2561          evas_gl_common_image_dirty(im, 0, 0, 0, 0);
2562          break;
2563       default:
2564          abort();
2565          break;
2566      }
2567    return im;
2568 }
2569
2570 static void
2571 eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
2572 {
2573    Evas_GL_Image *gim = image;
2574    RGBA_Image *im;
2575
2576    if (!gim) return;
2577    if (gim->native.data) return;
2578    im = (RGBA_Image *)gim->im;
2579    if (!im) return;
2580    evas_cache_image_preload_data(&im->cache_entry, target);
2581 }
2582
2583 static void
2584 eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
2585 {
2586    Evas_GL_Image *gim = image;
2587    RGBA_Image *im;
2588
2589    if (!gim) return;
2590    if (gim->native.data) return;
2591    im = (RGBA_Image *)gim->im;
2592    if (!im) return;
2593    evas_cache_image_preload_cancel(&im->cache_entry, target);
2594 }
2595
2596 static void
2597 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
2598 {
2599    Render_Engine *re;
2600
2601    re = (Render_Engine *)data;
2602    if (!image) return;
2603    eng_window_use(re->win);
2604    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2605    re->win->gl_context->dc = context;
2606    evas_gl_common_image_draw(re->win->gl_context, image,
2607                              src_x, src_y, src_w, src_h,
2608                              dst_x, dst_y, dst_w, dst_h,
2609                              smooth);
2610 }
2611
2612 static void
2613 eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
2614 {
2615    if (image) evas_gl_common_image_scale_hint_set(image, hint);
2616 }
2617
2618 static int
2619 eng_image_scale_hint_get(void *data __UNUSED__, void *image)
2620 {
2621    Evas_GL_Image *gim = image;
2622    if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
2623    return gim->scale_hint;
2624 }
2625
2626 static void
2627 eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
2628 {
2629    Evas_GL_Image *gim = image;
2630    Render_Engine *re;
2631
2632    re = (Render_Engine *)data;
2633    if (!image) return;
2634    eng_window_use(re->win);
2635    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2636    re->win->gl_context->dc = context;
2637    if (npoints != 4)
2638      {
2639         // FIXME: nash - you didn't fix this
2640         abort();
2641      }
2642    if ((p[0].x == p[3].x) &&
2643        (p[1].x == p[2].x) &&
2644        (p[0].y == p[1].y) &&
2645        (p[3].y == p[2].y) &&
2646        (p[0].x <= p[1].x) &&
2647        (p[0].y <= p[2].y) &&
2648        (p[0].u == 0) &&
2649        (p[0].v == 0) &&
2650        (p[1].u == (gim->w << FP)) &&
2651        (p[1].v == 0) &&
2652        (p[2].u == (gim->w << FP)) &&
2653        (p[2].v == (gim->h << FP)) &&
2654        (p[3].u == 0) &&
2655        (p[3].v == (gim->h << FP)) &&
2656        (p[0].col == 0xffffffff) &&
2657        (p[1].col == 0xffffffff) &&
2658        (p[2].col == 0xffffffff) &&
2659        (p[3].col == 0xffffffff))
2660      {
2661         int dx, dy, dw, dh;
2662
2663         dx = p[0].x >> FP;
2664         dy = p[0].y >> FP;
2665         dw = (p[2].x >> FP) - dx;
2666         dh = (p[2].y >> FP) - dy;
2667         eng_image_draw(data, context, surface, image,
2668                        0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
2669      }
2670    else
2671      {
2672         evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
2673                                       smooth, level);
2674      }
2675 }
2676
2677 static void *
2678 eng_image_map_surface_new(void *data, int w, int h, int alpha)
2679 {
2680    Render_Engine *re;
2681
2682    re = (Render_Engine *)data;
2683    return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
2684 }
2685
2686 static void
2687 eng_image_map_surface_free(void *data __UNUSED__, void *surface)
2688 {
2689    evas_gl_common_image_free(surface);
2690 }
2691
2692 static void
2693 eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
2694 {
2695    if (image) evas_gl_common_image_content_hint_set(image, hint);
2696 }
2697
2698 static int
2699 eng_image_content_hint_get(void *data __UNUSED__, void *image)
2700 {
2701    Evas_GL_Image *gim = image;
2702    if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
2703    return gim->content_hint;
2704 }
2705
2706 static void
2707 eng_image_cache_flush(void *data)
2708 {
2709    Render_Engine *re;
2710    int tmp_size;
2711
2712    re = (Render_Engine *)data;
2713
2714    tmp_size = evas_common_image_get_cache();
2715    evas_common_image_set_cache(0);
2716    evas_common_rgba_image_scalecache_flush();
2717    evas_gl_common_image_cache_flush(re->win->gl_context);
2718    evas_common_image_set_cache(tmp_size);
2719 }
2720
2721 static void
2722 eng_image_cache_set(void *data, int bytes)
2723 {
2724    Render_Engine *re;
2725
2726    re = (Render_Engine *)data;
2727    evas_common_image_set_cache(bytes);
2728    evas_common_rgba_image_scalecache_size_set(bytes);
2729    evas_gl_common_image_cache_flush(re->win->gl_context);
2730 }
2731
2732 static int
2733 eng_image_cache_get(void *data __UNUSED__)
2734 {
2735    return evas_common_image_get_cache();
2736 }
2737
2738 static void
2739 eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
2740 {
2741    Evas_GL_Image *im = image;
2742
2743    if ((im->tex) && (im->tex->pt->dyn.img))
2744      *stride = im->tex->pt->dyn.stride;
2745    else
2746      *stride = im->w * 4;
2747 }
2748
2749 static void
2750 eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
2751 {
2752    Render_Engine *re;
2753
2754    re = (Render_Engine *)data;
2755    eng_window_use(re->win);
2756    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2757    re->win->gl_context->dc = context;
2758      {
2759         // FIXME: put im into context so we can free it
2760         static RGBA_Image *im = NULL;
2761
2762         if (!im)
2763           im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
2764         im->cache_entry.w = re->win->w;
2765         im->cache_entry.h = re->win->h;
2766         evas_common_draw_context_font_ext_set(context,
2767                                               re->win->gl_context,
2768                                               evas_gl_font_texture_new,
2769                                               evas_gl_font_texture_free,
2770                                               evas_gl_font_texture_draw);
2771         evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
2772                               intl_props);
2773         evas_common_draw_context_font_ext_set(context,
2774                                               NULL,
2775                                               NULL,
2776                                               NULL,
2777                                               NULL);
2778      }
2779 }
2780
2781 static Eina_Bool
2782 eng_canvas_alpha_get(void *data, void *info __UNUSED__)
2783 {
2784    Render_Engine *re = (Render_Engine *)data;
2785    return re->win->alpha;
2786 }
2787
2788 static int
2789 _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2790 {
2791    // Also initialize pixel format here as well...
2792    switch(cfg->color_format)
2793      {
2794       case EVAS_GL_RGB_888:
2795          sfc->rt_fmt          = GL_RGB;
2796          sfc->rt_internal_fmt = GL_RGB;
2797          break;
2798       case EVAS_GL_RGBA_8888:
2799          sfc->rt_fmt          = GL_RGBA;
2800          sfc->rt_internal_fmt = GL_RGBA;
2801          break;
2802       default:
2803          ERR("Invalid Color Format!");
2804          return 0;
2805      }
2806
2807    switch(cfg->depth_bits)
2808      {
2809       case EVAS_GL_DEPTH_NONE:
2810          break;
2811       case EVAS_GL_DEPTH_BIT_8:
2812       case EVAS_GL_DEPTH_BIT_16:
2813       case EVAS_GL_DEPTH_BIT_24:
2814 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2815          // 24 bit doesn't work... just cover it with 16 for now..
2816          sfc->rb_depth_fmt = GL_DEPTH_COMPONENT16;
2817 #else
2818          sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
2819 #endif
2820          break;
2821       case EVAS_GL_DEPTH_BIT_32:
2822       default:
2823          ERR("Unsupported Depth Bits Format!");
2824          return 0;
2825      }
2826
2827    switch(cfg->stencil_bits)
2828      {
2829       case EVAS_GL_STENCIL_NONE:
2830          break;
2831       case EVAS_GL_STENCIL_BIT_1:
2832       case EVAS_GL_STENCIL_BIT_2:
2833       case EVAS_GL_STENCIL_BIT_4:
2834       case EVAS_GL_STENCIL_BIT_8:
2835 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2836          sfc->rb_stencil_fmt = GL_STENCIL_INDEX8;
2837 #else
2838          sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
2839 #endif
2840          break;
2841       case EVAS_GL_STENCIL_BIT_16:
2842       default:
2843          ERR("Unsupported Stencil Bits Format!");
2844          return 0;
2845      }
2846
2847    // Do Packed Depth24_Stencil8 Later...
2848
2849    return 1;
2850 }
2851
2852 static int
2853 _create_rt_buffers(Render_Engine *data __UNUSED__,
2854                    Render_Engine_GL_Surface *sfc)
2855 {
2856    // Render Target texture
2857    glGenTextures(1, &sfc->rt_tex );
2858
2859    // Depth RenderBuffer - Create storage here...
2860    if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2861       glGenRenderbuffers(1, &sfc->rb_depth);
2862
2863    // Stencil RenderBuffer - Create Storage here...
2864    if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2865       glGenRenderbuffers(1, &sfc->rb_stencil);
2866
2867    return 1;
2868 }
2869
2870 static int
2871 _attach_fbo_surface(Render_Engine *data __UNUSED__,
2872                     Render_Engine_GL_Surface *sfc,
2873                     Render_Engine_GL_Context *ctx)
2874 {
2875    int fb_status;
2876
2877    // Initialize Texture
2878    glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
2879    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2880    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2881    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2882    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2883    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
2884                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2885    glBindTexture(GL_TEXTURE_2D, 0);
2886
2887
2888    // Attach texture to FBO
2889    glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2890    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2891                           GL_TEXTURE_2D, sfc->rt_tex, 0);
2892
2893    // Depth RenderBuffer - Attach it to FBO
2894    if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2895      {
2896         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2897         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
2898                               sfc->w, sfc->h);
2899         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
2900                                   GL_RENDERBUFFER, sfc->rb_depth);
2901         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2902      }
2903
2904    // Stencil RenderBuffer - Attach it to FBO
2905    if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2906      {
2907         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2908         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
2909                               sfc->w, sfc->h);
2910         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
2911                                   GL_RENDERBUFFER, sfc->rb_stencil);
2912         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2913      }
2914
2915    // Check FBO for completeness
2916    fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2917    if (fb_status != GL_FRAMEBUFFER_COMPLETE)
2918      {
2919         ERR("FBO not complete!");
2920         return 0;
2921      }
2922
2923    return 1;
2924 }
2925
2926
2927 static void *
2928 eng_gl_surface_create(void *data, void *config, int w, int h)
2929 {
2930    Render_Engine *re;
2931    Render_Engine_GL_Surface *sfc;
2932    Render_Engine_GL_Resource *rsc;
2933    Evas_GL_Config *cfg;
2934    int ret;
2935
2936    sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
2937    if (!sfc) return NULL;
2938
2939    re  = (Render_Engine *)data;
2940    cfg = (Evas_GL_Config *)config;
2941
2942    sfc->initialized  = 0;
2943    sfc->fbo_attached = 0;
2944    sfc->w            = w;
2945    sfc->h            = h;
2946    sfc->depth_bits   = cfg->depth_bits;
2947    sfc->stencil_bits = cfg->stencil_bits;
2948    sfc->rt_tex       = 0;
2949    sfc->rb_depth     = 0;
2950    sfc->rb_stencil   = 0;
2951
2952    // Set the internal format based on the config
2953    if (!_set_internal_config(sfc, cfg))
2954      {
2955         ERR("Unsupported Format!");
2956         free(sfc);
2957         return NULL;
2958      }
2959
2960    // Create internal resource context if it hasn't been created already
2961    if ((rsc = eina_tls_get(resource_key)) == NULL)
2962      {
2963         if ((rsc = _create_internal_glue_resources(re)) == NULL)
2964           {
2965              ERR("Error creating internal resources.");
2966              free(sfc);
2967              return NULL;
2968           }
2969      }
2970
2971    // I'm using evas's original context to create the render target texture
2972    // This is to prevent awkwardness in using native_surface_get() function
2973    // If the rt texture creation is deferred till the context is created and
2974    // make_current called, the user can't call native_surface_get() right
2975    // after the surface is created. hence this is done here using evas' context.
2976 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2977    ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
2978 #else
2979    ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context);
2980 #endif
2981    if (!ret)
2982      {
2983         ERR("xxxMakeCurrent() failed!");
2984         free(sfc);
2985         return NULL;
2986      }
2987
2988    // Create Render texture
2989    if (!_create_rt_buffers(re, sfc))
2990      {
2991         ERR("_create_rt_buffers() failed.");
2992         free(sfc);
2993         return NULL;
2994      }
2995
2996 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2997    ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2998 #else
2999    ret = glXMakeCurrent(re->info->info.display, None, NULL);
3000 #endif
3001    if (!ret)
3002      {
3003         ERR("xxxMakeCurrent() failed!");
3004         free(sfc);
3005         return NULL;
3006      }
3007
3008    return sfc;
3009 }
3010
3011 static int
3012 eng_gl_surface_destroy(void *data, void *surface)
3013 {
3014    Render_Engine *re;
3015    Render_Engine_GL_Surface *sfc;
3016    Render_Engine_GL_Resource *rsc;
3017    int ret;
3018
3019    re  = (Render_Engine *)data;
3020    sfc = (Render_Engine_GL_Surface*)surface;
3021
3022    if (!sfc) return 0;
3023
3024    if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
3025
3026 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3027    ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
3028 #else
3029    ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context);
3030 #endif
3031    if (!ret)
3032      {
3033         ERR("xxxMakeCurrent() failed!");
3034         return 0;
3035      }
3036
3037    // Delete FBO/RBO and Texture here
3038    if (sfc->rt_tex)
3039       glDeleteTextures(1, &sfc->rt_tex);
3040
3041    if (sfc->rb_depth)
3042       glDeleteRenderbuffers(1, &sfc->rb_depth);
3043
3044    if (sfc->rb_stencil)
3045       glDeleteRenderbuffers(1, &sfc->rb_stencil);
3046
3047 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3048    ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
3049 #else
3050    ret = glXMakeCurrent(re->info->info.display, None, NULL);
3051 #endif
3052    if (!ret)
3053      {
3054         ERR("xxxMakeCurrent() failed!");
3055         free(sfc);
3056         return 0;
3057      }
3058
3059    free(sfc);
3060    surface = NULL;
3061
3062    return 1;
3063 }
3064
3065 static void *
3066 eng_gl_context_create(void *data, void *share_context)
3067 {
3068    Render_Engine *re;
3069    Render_Engine_GL_Context *ctx;
3070    Render_Engine_GL_Context *share_ctx;
3071 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3072    int context_attrs[3];
3073 #endif
3074
3075    ctx = calloc(1, sizeof(Render_Engine_GL_Context));
3076
3077    if (!ctx) return NULL;
3078
3079    re = (Render_Engine *)data;
3080    share_ctx = (Render_Engine_GL_Context *)share_context;
3081
3082    // Set the share context to Evas' GL context if share_context is NULL.
3083    // Otherwise set it to the given share_context.
3084 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3085    // EGL
3086    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
3087    context_attrs[1] = 2;
3088    context_attrs[2] = EGL_NONE;
3089
3090    if (share_ctx)
3091      {
3092         ctx->context = eglCreateContext(re->win->egl_disp,
3093                                         re->win->egl_config,
3094                                         share_ctx->context,      // Share Context
3095                                         context_attrs);
3096      }
3097    else
3098      {
3099         ctx->context = eglCreateContext(re->win->egl_disp,
3100                                         re->win->egl_config,
3101                                         re->win->egl_context[0], // Evas' GL Context
3102                                         context_attrs);
3103      }
3104
3105    if (!ctx->context)
3106      {
3107         ERR("eglCreateContext() fail. code=%#x", eglGetError());
3108         return NULL;
3109      }
3110 #else
3111    // GLX
3112    if (share_context)
3113      {
3114         ctx->context = glXCreateContext(re->info->info.display,
3115                                         re->win->visualinfo,
3116                                         share_ctx->context,    // Share Context
3117                                         1);
3118      }
3119    else
3120      {
3121         ctx->context = glXCreateContext(re->info->info.display,
3122                                         re->win->visualinfo,
3123                                         re->win->context,      // Evas' GL Context
3124                                         1);
3125      }
3126
3127    if (!ctx->context)
3128      {
3129         ERR("glXCreateContext() fail.");
3130         return NULL;
3131      }
3132 #endif
3133
3134    ctx->initialized = 0;
3135    ctx->context_fbo = 0;
3136    ctx->current_sfc = NULL;
3137
3138    return ctx;
3139 }
3140
3141 static int
3142 eng_gl_context_destroy(void *data, void *context)
3143 {
3144    Render_Engine *re;
3145    Render_Engine_GL_Context *ctx;
3146    Render_Engine_GL_Resource *rsc;
3147    int ret;
3148
3149    re  = (Render_Engine *)data;
3150    ctx = (Render_Engine_GL_Context*)context;
3151
3152    if (!ctx) return 0;
3153
3154    if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
3155
3156    // 1. Do a make current with the given context
3157 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3158    ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
3159                         rsc->surface, ctx->context);
3160 #else
3161    ret = glXMakeCurrent(re->info->info.display, re->win->win,
3162                         ctx->context);
3163 #endif
3164    if (!ret)
3165      {
3166         ERR("xxxMakeCurrent() failed!");
3167         return 0;
3168      }
3169
3170    // 2. Delete the FBO
3171    if (ctx->context_fbo)
3172         glDeleteFramebuffers(1, &ctx->context_fbo);
3173
3174    // 3. Destroy the Context
3175 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3176    eglDestroyContext(re->win->egl_disp, ctx->context);
3177
3178    ctx->context = EGL_NO_CONTEXT;
3179
3180    ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
3181                         EGL_NO_SURFACE, EGL_NO_CONTEXT);
3182 #else
3183    glXDestroyContext(re->info->info.display, ctx->context);
3184
3185    ctx->context = 0;
3186
3187    ret = glXMakeCurrent(re->info->info.display, None, NULL);
3188 #endif
3189    if (!ret)
3190      {
3191         ERR("xxxMakeCurrent() failed!");
3192         return 0;
3193      }
3194
3195    free(ctx);
3196    context = NULL;
3197
3198    return 1;
3199 }
3200
3201 static int
3202 eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
3203 {
3204    Render_Engine *re;
3205    Render_Engine_GL_Surface *sfc;
3206    Render_Engine_GL_Context *ctx;
3207    int ret = 0;
3208 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3209    Render_Engine_GL_Resource *rsc;
3210 #endif
3211
3212    re  = (Render_Engine *)data;
3213    sfc = (Render_Engine_GL_Surface*)surface;
3214    ctx = (Render_Engine_GL_Context*)context;
3215
3216    // Unset surface/context
3217    if ((!sfc) || (!ctx))
3218      {
3219 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3220         ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
3221                              EGL_NO_SURFACE, EGL_NO_CONTEXT);
3222 #else
3223         ret = glXMakeCurrent(re->info->info.display, None, NULL);
3224 #endif
3225         if (!ret)
3226           {
3227              ERR("xxxMakeCurrent() failed!");
3228              return 0;
3229           }
3230
3231         if (ctx) ctx->current_sfc = NULL;
3232         if (sfc) sfc->current_ctx = NULL;
3233         current_evgl_ctx = NULL;
3234         return 1;
3235      }
3236
3237    // Do a make current only if it's not already current
3238 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3239    if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
3240
3241    if ((eglGetCurrentContext() != ctx->context) ||
3242        (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
3243        (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
3244      {
3245         // Flush remainder of what's in Evas' pipeline
3246         if (re->win) eng_window_use(NULL);
3247
3248         // Do a make current
3249         ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
3250                              rsc->surface, ctx->context);
3251         if (!ret)
3252           {
3253              ERR("xxxMakeCurrent() failed!");
3254              return 0;
3255           }
3256      }
3257 #else
3258    if ((glXGetCurrentContext() != ctx->context) ||
3259        (glXGetCurrentDrawable() != re->win->win) )
3260      {
3261         // Flush remainder of what's in Evas' pipeline
3262         if (re->win) eng_window_use(NULL);
3263
3264         // Do a make current
3265         ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
3266         if (!ret)
3267           {
3268              ERR("xxxMakeCurrent() failed!");
3269              return 0;
3270           }
3271      }
3272 #endif
3273
3274    // Create FBO if not already created
3275    if (!ctx->initialized)
3276      {
3277         glGenFramebuffers(1, &ctx->context_fbo);
3278         ctx->initialized = 1;
3279      }
3280
3281    // Attach FBO if it hasn't been attached or if surface changed
3282    if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
3283      {
3284         if (!_attach_fbo_surface(re, sfc, ctx))
3285           {
3286              ERR("_attach_fbo_surface() failed.");
3287              return 0;
3288           }
3289
3290         if (ctx->current_fbo)
3291            // Bind to the previously bound buffer
3292            glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
3293         else
3294            // Bind FBO
3295            glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
3296
3297         sfc->fbo_attached = 1;
3298      }
3299
3300    // Set the current surface/context
3301    ctx->current_sfc = sfc;
3302    sfc->current_ctx = ctx;
3303    current_evgl_ctx = ctx;
3304
3305    return 1;
3306 }
3307
3308 static void *
3309 eng_gl_string_query(void *data __UNUSED__, int name)
3310 {
3311    switch(name)
3312      {
3313       case EVAS_GL_EXTENSIONS:
3314          return (void*)_evasgl_ext_string;
3315       default:
3316          return NULL;
3317      };
3318 }
3319
3320 static void *
3321 eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
3322 {
3323 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3324    if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
3325    return dlsym(RTLD_DEFAULT, name);
3326 #else
3327    if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
3328    return dlsym(RTLD_DEFAULT, name);
3329 #endif
3330 }
3331
3332 static int
3333 eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
3334 {
3335    Render_Engine *re;
3336    Render_Engine_GL_Surface *sfc;
3337    Evas_Native_Surface *ns;
3338
3339    re  = (Render_Engine *)data;
3340    sfc = (Render_Engine_GL_Surface*)surface;
3341    ns  = (Evas_Native_Surface*)native_surface;
3342
3343    ns->type = EVAS_NATIVE_SURFACE_OPENGL;
3344    ns->version = EVAS_NATIVE_SURFACE_VERSION;
3345    ns->data.opengl.texture_id = sfc->rt_tex;
3346    ns->data.opengl.x = 0;
3347    ns->data.opengl.y = 0;
3348    ns->data.opengl.w = sfc->w;
3349    ns->data.opengl.h = sfc->h;
3350
3351    return 1;
3352 }
3353
3354
3355 static const GLubyte *
3356 evgl_glGetString(GLenum name)
3357 {
3358    if (name == GL_EXTENSIONS)
3359       return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); 
3360    else
3361       return glGetString(name);
3362 }
3363
3364 static void
3365 evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
3366 {
3367    Render_Engine_GL_Context *ctx = current_evgl_ctx;
3368
3369    // Take care of BindFramebuffer 0 issue
3370    if (framebuffer==0)
3371      {
3372         if (ctx)
3373           {
3374              glBindFramebuffer(target, ctx->context_fbo);
3375              ctx->current_fbo = 0;
3376           }
3377      }
3378    else
3379      {
3380         glBindFramebuffer(target, framebuffer);
3381
3382         // Save this for restore when doing make current
3383         if (ctx)
3384            ctx->current_fbo = framebuffer;
3385      }
3386 }
3387
3388 static void
3389 evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
3390 {
3391    // Add logic to take care when renderbuffer=0
3392    // On a second thought we don't need this
3393    glBindRenderbuffer(target, renderbuffer);
3394 }
3395
3396 static void
3397 evgl_glClearDepthf(GLclampf depth)
3398 {
3399 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3400    glClearDepthf(depth);
3401 #else
3402    glClearDepth(depth);
3403 #endif
3404 }
3405
3406 static void
3407 evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
3408 {
3409 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3410    glDepthRangef(zNear, zFar);
3411 #else
3412    glDepthRange(zNear, zFar);
3413 #endif
3414 }
3415
3416 static void
3417 evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3418 {
3419 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3420    glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
3421 #else
3422    if (range)
3423      {
3424         range[0] = -126; // floor(log2(FLT_MIN))
3425         range[1] = 127; // floor(log2(FLT_MAX))
3426      }
3427    if (precision)
3428      {
3429         precision[0] = 24; // floor(-log2((1.0/16777218.0)));
3430      }
3431    return;
3432    shadertype = precisiontype = 0;
3433 #endif
3434 }
3435
3436 static void
3437 evgl_glReleaseShaderCompiler(void)
3438 {
3439 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3440    glReleaseShaderCompiler();
3441 #else
3442 #endif
3443 }
3444
3445 static void
3446 evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
3447 {
3448 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3449    glShaderBinary(n, shaders, binaryformat, binary, length);
3450 #else
3451 // FIXME: need to dlsym/getprocaddress for this
3452    return;
3453    n = binaryformat = length = 0;
3454    shaders = binary = 0;
3455 #endif
3456 }
3457
3458 //--------------------------------//
3459 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3460 // EGL Extensions
3461 static void *
3462 evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
3463 {
3464    if (current_engine)
3465      {
3466         return glsym_eglCreateImage(current_engine->win->egl_disp,
3467                                     EGL_NO_CONTEXT,
3468                                     target,
3469                                     buffer,
3470                                     attrib_list);
3471      }
3472    else
3473      {
3474         ERR("Invalid Engine... (Can't acccess EGL Display)\n");
3475         return NULL;
3476      }
3477 }
3478
3479 static void
3480 evgl_evasglDestroyImage(EvasGLImage image)
3481 {
3482    if (current_engine)
3483         glsym_eglDestroyImage(current_engine->win->egl_disp, image);
3484    else
3485       ERR("Invalid Engine... (Can't acccess EGL Display)\n");
3486 }
3487
3488 static void
3489 evgl_glEvasGLImageTargetTexture2DOES(GLenum target, EvasGLImage image)
3490 {
3491    glsym_glEGLImageTargetTexture2DOES(target, image);
3492 }
3493
3494 static void
3495 evgl_glEvasGLImageTargetRenderbufferStorageOES(GLenum target, EvasGLImage image)
3496 {
3497    glsym_glEGLImageTargetTexture2DOES(target, image);
3498 }
3499 #else
3500 #endif
3501
3502 //--------------------------------//
3503
3504
3505 static void *
3506 eng_gl_api_get(void *data)
3507 {
3508    Render_Engine *re;
3509
3510    re  = (Render_Engine *)data;
3511
3512    gl_funcs.version = EVAS_GL_API_VERSION;
3513
3514 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
3515    // GLES 2.0
3516    ORD(glActiveTexture);
3517    ORD(glAttachShader);
3518    ORD(glBindAttribLocation);
3519    ORD(glBindBuffer);
3520    ORD(glBindTexture);
3521    ORD(glBlendColor);
3522    ORD(glBlendEquation);
3523    ORD(glBlendEquationSeparate);
3524    ORD(glBlendFunc);
3525    ORD(glBlendFuncSeparate);
3526    ORD(glBufferData);
3527    ORD(glBufferSubData);
3528    ORD(glCheckFramebufferStatus);
3529    ORD(glClear);
3530    ORD(glClearColor);
3531 //   ORD(glClearDepthf);
3532    ORD(glClearStencil);
3533    ORD(glColorMask);
3534    ORD(glCompileShader);
3535    ORD(glCompressedTexImage2D);
3536    ORD(glCompressedTexSubImage2D);
3537    ORD(glCopyTexImage2D);
3538    ORD(glCopyTexSubImage2D);
3539    ORD(glCreateProgram);
3540    ORD(glCreateShader);
3541    ORD(glCullFace);
3542    ORD(glDeleteBuffers);
3543    ORD(glDeleteFramebuffers);
3544    ORD(glDeleteProgram);
3545    ORD(glDeleteRenderbuffers);
3546    ORD(glDeleteShader);
3547    ORD(glDeleteTextures);
3548    ORD(glDepthFunc);
3549    ORD(glDepthMask);
3550 //   ORD(glDepthRangef);
3551    ORD(glDetachShader);
3552    ORD(glDisable);
3553    ORD(glDisableVertexAttribArray);
3554    ORD(glDrawArrays);
3555    ORD(glDrawElements);
3556    ORD(glEnable);
3557    ORD(glEnableVertexAttribArray);
3558    ORD(glFinish);
3559    ORD(glFlush);
3560    ORD(glFramebufferRenderbuffer);
3561    ORD(glFramebufferTexture2D);
3562    ORD(glFrontFace);
3563    ORD(glGenBuffers);
3564    ORD(glGenerateMipmap);
3565    ORD(glGenFramebuffers);
3566    ORD(glGenRenderbuffers);
3567    ORD(glGenTextures);
3568    ORD(glGetActiveAttrib);
3569    ORD(glGetActiveUniform);
3570    ORD(glGetAttachedShaders);
3571    ORD(glGetAttribLocation);
3572    ORD(glGetBooleanv);
3573    ORD(glGetBufferParameteriv);
3574    ORD(glGetError);
3575    ORD(glGetFloatv);
3576    ORD(glGetFramebufferAttachmentParameteriv);
3577    ORD(glGetIntegerv);
3578    ORD(glGetProgramiv);
3579    ORD(glGetProgramInfoLog);
3580    ORD(glGetRenderbufferParameteriv);
3581    ORD(glGetShaderiv);
3582    ORD(glGetShaderInfoLog);
3583 //   ORD(glGetShaderPrecisionFormat);
3584    ORD(glGetShaderSource);
3585 //   ORD(glGetString);
3586    ORD(glGetTexParameterfv);
3587    ORD(glGetTexParameteriv);
3588    ORD(glGetUniformfv);
3589    ORD(glGetUniformiv);
3590    ORD(glGetUniformLocation);
3591    ORD(glGetVertexAttribfv);
3592    ORD(glGetVertexAttribiv);
3593    ORD(glGetVertexAttribPointerv);
3594    ORD(glHint);
3595    ORD(glIsBuffer);
3596    ORD(glIsEnabled);
3597    ORD(glIsFramebuffer);
3598    ORD(glIsProgram);
3599    ORD(glIsRenderbuffer);
3600    ORD(glIsShader);
3601    ORD(glIsTexture);
3602    ORD(glLineWidth);
3603    ORD(glLinkProgram);
3604    ORD(glPixelStorei);
3605    ORD(glPolygonOffset);
3606    ORD(glReadPixels);
3607 //   ORD(glReleaseShaderCompiler);
3608    ORD(glRenderbufferStorage);
3609    ORD(glSampleCoverage);
3610    ORD(glScissor);
3611 //   ORD(glShaderBinary);
3612    ORD(glShaderSource);
3613    ORD(glStencilFunc);
3614    ORD(glStencilFuncSeparate);
3615    ORD(glStencilMask);
3616    ORD(glStencilMaskSeparate);
3617    ORD(glStencilOp);
3618    ORD(glStencilOpSeparate);
3619    ORD(glTexImage2D);
3620    ORD(glTexParameterf);
3621    ORD(glTexParameterfv);
3622    ORD(glTexParameteri);
3623    ORD(glTexParameteriv);
3624    ORD(glTexSubImage2D);
3625    ORD(glUniform1f);
3626    ORD(glUniform1fv);
3627    ORD(glUniform1i);
3628    ORD(glUniform1iv);
3629    ORD(glUniform2f);
3630    ORD(glUniform2fv);
3631    ORD(glUniform2i);
3632    ORD(glUniform2iv);
3633    ORD(glUniform3f);
3634    ORD(glUniform3fv);
3635    ORD(glUniform3i);
3636    ORD(glUniform3iv);
3637    ORD(glUniform4f);
3638    ORD(glUniform4fv);
3639    ORD(glUniform4i);
3640    ORD(glUniform4iv);
3641    ORD(glUniformMatrix2fv);
3642    ORD(glUniformMatrix3fv);
3643    ORD(glUniformMatrix4fv);
3644    ORD(glUseProgram);
3645    ORD(glValidateProgram);
3646    ORD(glVertexAttrib1f);
3647    ORD(glVertexAttrib1fv);
3648    ORD(glVertexAttrib2f);
3649    ORD(glVertexAttrib2fv);
3650    ORD(glVertexAttrib3f);
3651    ORD(glVertexAttrib3fv);
3652    ORD(glVertexAttrib4f);
3653    ORD(glVertexAttrib4fv);
3654    ORD(glVertexAttribPointer);
3655    ORD(glViewport);
3656 #undef ORD
3657
3658 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_)
3659    // Extensions
3660    ORD(glGetProgramBinaryOES);
3661    ORD(glProgramBinaryOES);
3662    ORD(glMapBufferOES);
3663    ORD(glUnmapBufferOES);
3664    ORD(glGetBufferPointervOES);
3665    ORD(glTexImage3DOES);
3666    ORD(glTexSubImage3DOES);
3667    ORD(glCopyTexSubImage3DOES);
3668    ORD(glCompressedTexImage3DOES);
3669    ORD(glCompressedTexSubImage3DOES);
3670    ORD(glFramebufferTexture3DOES);
3671    ORD(glGetPerfMonitorGroupsAMD);
3672    ORD(glGetPerfMonitorCountersAMD);
3673    ORD(glGetPerfMonitorGroupStringAMD);
3674    ORD(glGetPerfMonitorCounterStringAMD);
3675    ORD(glGetPerfMonitorCounterInfoAMD);
3676    ORD(glGenPerfMonitorsAMD);
3677    ORD(glDeletePerfMonitorsAMD);
3678    ORD(glSelectPerfMonitorCountersAMD);
3679    ORD(glBeginPerfMonitorAMD);
3680    ORD(glEndPerfMonitorAMD);
3681    ORD(glGetPerfMonitorCounterDataAMD);
3682    ORD(glDiscardFramebufferEXT);
3683    ORD(glMultiDrawArraysEXT);
3684    ORD(glMultiDrawElementsEXT);
3685    ORD(glDeleteFencesNV);
3686    ORD(glGenFencesNV);
3687    ORD(glIsFenceNV);
3688    ORD(glTestFenceNV);
3689    ORD(glGetFenceivNV);
3690    ORD(glFinishFenceNV);
3691    ORD(glSetFenceNV);
3692    ORD(glGetDriverControlsQCOM);
3693    ORD(glGetDriverControlStringQCOM);
3694    ORD(glEnableDriverControlQCOM);
3695    ORD(glDisableDriverControlQCOM);
3696    ORD(glExtGetTexturesQCOM);
3697    ORD(glExtGetBuffersQCOM);
3698    ORD(glExtGetRenderbuffersQCOM);
3699    ORD(glExtGetFramebuffersQCOM);
3700    ORD(glExtGetTexLevelParameterivQCOM);
3701    ORD(glExtTexObjectStateOverrideiQCOM);
3702    ORD(glExtGetTexSubImageQCOM);
3703    ORD(glExtGetBufferPointervQCOM);
3704    ORD(glExtGetShadersQCOM);
3705    ORD(glExtGetProgramsQCOM);
3706    ORD(glExtIsProgramBinaryQCOM);
3707    ORD(glExtGetProgramBinarySourceQCOM);
3708 #undef ORD
3709
3710 // Override functions wrapped by Evas_GL
3711 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
3712    ORD(glBindFramebuffer);
3713    ORD(glBindRenderbuffer);
3714
3715    // GLES2.0 API compat on top of desktop gl
3716    ORD(glClearDepthf);
3717    ORD(glDepthRangef);
3718    ORD(glGetShaderPrecisionFormat);
3719    ORD(glReleaseShaderCompiler);
3720    ORD(glShaderBinary);
3721
3722    ORD(glGetString);
3723
3724 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3725    // GLES 2.0 Extensions that needs wrapping
3726    ORD(evasglCreateImage);
3727    ORD(evasglDestroyImage);
3728    ORD(glEvasGLImageTargetTexture2DOES);
3729    ORD(glEvasGLImageTargetRenderbufferStorageOES);
3730 #endif
3731
3732 #undef ORD
3733
3734    return &gl_funcs;
3735 }
3736
3737 static int
3738 eng_image_load_error_get(void *data __UNUSED__, void *image)
3739 {
3740    Evas_GL_Image *im;
3741
3742    if (!image) return EVAS_LOAD_ERROR_NONE;
3743    im = image;
3744    return im->im->cache_entry.load_error;
3745 }
3746
3747 static Eina_Bool
3748 eng_image_animated_get(void *data __UNUSED__, void *image)
3749 {
3750    Evas_GL_Image *gim = image;
3751    Image_Entry *im;
3752
3753    if (!gim) return EINA_FALSE;
3754    im = (Image_Entry *)gim->im;
3755    if (!im) return EINA_FALSE;
3756
3757    return im->flags.animated;
3758 }
3759
3760 static int
3761 eng_image_animated_frame_count_get(void *data __UNUSED__, void *image)
3762 {
3763    Evas_GL_Image *gim = image;
3764    Image_Entry *im;
3765
3766    if (!gim) return -1;
3767    im = (Image_Entry *)gim->im;
3768    if (!im) return -1;
3769
3770    if (!im->flags.animated) return -1;
3771    return im->frame_count;
3772 }
3773
3774 static Evas_Image_Animated_Loop_Hint
3775 eng_image_animated_loop_type_get(void *data __UNUSED__, void *image)
3776 {
3777    Evas_GL_Image *gim = image;
3778    Image_Entry *im;
3779
3780    if (!gim) return EVAS_IMAGE_ANIMATED_HINT_NONE;
3781    im = (Image_Entry *)gim->im;
3782    if (!im) return EVAS_IMAGE_ANIMATED_HINT_NONE;
3783
3784    if (!im->flags.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
3785    return im->loop_hint;
3786 }
3787
3788 static int
3789 eng_image_animated_loop_count_get(void *data __UNUSED__, void *image)
3790 {
3791    Evas_GL_Image *gim = image;
3792    Image_Entry *im;
3793
3794    if (!gim) return -1;
3795    im = (Image_Entry *)gim->im;
3796    if (!im) return -1;
3797
3798    if (!im->flags.animated) return -1;
3799    return im->loop_count;
3800 }
3801
3802 static double
3803 eng_image_animated_frame_duration_get(void *data __UNUSED__, void *image, int start_frame, int frame_num)
3804 {
3805    Evas_GL_Image *gim = image;
3806    Image_Entry *im;
3807
3808    if (!gim) return -1;
3809    im = (Image_Entry *)gim->im;
3810    if (!im) return -1;
3811
3812    if (!im->flags.animated) return -1;
3813    return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
3814 }
3815
3816 static Eina_Bool
3817 eng_image_animated_frame_set(void *data __UNUSED__, void *image, int frame_index)
3818 {
3819    Evas_GL_Image *gim = image;
3820    Image_Entry *im;
3821
3822    if (!gim) return EINA_FALSE;
3823    im = (Image_Entry *)gim->im;
3824    if (!im) return EINA_FALSE;
3825
3826    if (!im->flags.animated) return EINA_FALSE;
3827    if (im->cur_frame == frame_index) return EINA_FALSE;
3828
3829    im->cur_frame = frame_index;
3830    return EINA_TRUE;
3831 }
3832
3833 static Eina_Bool
3834 eng_image_can_region_get(void *data __UNUSED__, void *image)
3835 {
3836    Evas_GL_Image *gim = image;
3837    Image_Entry *im;
3838    if (!gim) return EINA_FALSE;
3839    im = (Image_Entry *)gim->im;
3840    if (!im) return EINA_FALSE;
3841    return ((Evas_Image_Load_Func*) im->info.loader)->do_region;
3842 }
3843
3844
3845 static void
3846 eng_image_max_size_get(void *data, int *maxw, int *maxh)
3847 {
3848    Render_Engine *re = (Render_Engine *)data;
3849    if (maxw) *maxw = re->win->gl_context->shared->info.max_texture_size;
3850    if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size;
3851 }
3852
3853 static int
3854 module_open(Evas_Module *em)
3855 {
3856    static Eina_Bool xrm_inited = EINA_FALSE;
3857    if (!xrm_inited)
3858      {
3859         xrm_inited = EINA_TRUE;
3860         XrmInitialize();
3861      }
3862
3863    if (!em) return 0;
3864    if (!evas_gl_common_module_open()) return 0;
3865    /* get whatever engine module we inherit from */
3866    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
3867    if (_evas_engine_GL_X11_log_dom < 0)
3868      _evas_engine_GL_X11_log_dom = eina_log_domain_register
3869        ("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
3870    if (_evas_engine_GL_X11_log_dom < 0)
3871      {
3872         EINA_LOG_ERR("Can not create a module log domain.");
3873         return 0;
3874      }
3875    /* store it for later use */
3876    func = pfunc;
3877    /* now to override methods */
3878    #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
3879    ORD(info);
3880    ORD(info_free);
3881    ORD(setup);
3882    ORD(canvas_alpha_get);
3883    ORD(output_free);
3884    ORD(output_resize);
3885    ORD(output_tile_size_set);
3886    ORD(output_redraws_rect_add);
3887    ORD(output_redraws_rect_del);
3888    ORD(output_redraws_clear);
3889    ORD(output_redraws_next_update_get);
3890    ORD(output_redraws_next_update_push);
3891    ORD(context_cutout_add);
3892    ORD(context_cutout_clear);
3893    ORD(output_flush);
3894    ORD(output_idle_flush);
3895    ORD(output_dump);
3896    ORD(rectangle_draw);
3897    ORD(line_draw);
3898    ORD(polygon_point_add);
3899    ORD(polygon_points_clear);
3900    ORD(polygon_draw);
3901
3902    ORD(image_load);
3903    ORD(image_new_from_data);
3904    ORD(image_new_from_copied_data);
3905    ORD(image_free);
3906    ORD(image_size_get);
3907    ORD(image_size_set);
3908    ORD(image_dirty_region);
3909    ORD(image_data_get);
3910    ORD(image_data_put);
3911    ORD(image_data_preload_request);
3912    ORD(image_data_preload_cancel);
3913    ORD(image_alpha_set);
3914    ORD(image_alpha_get);
3915    ORD(image_border_set);
3916    ORD(image_border_get);
3917    ORD(image_draw);
3918    ORD(image_comment_get);
3919    ORD(image_format_get);
3920    ORD(image_colorspace_set);
3921    ORD(image_colorspace_get);
3922    ORD(image_can_region_get);
3923    ORD(image_mask_create);
3924    ORD(image_native_set);
3925    ORD(image_native_get);
3926 #if 0 // filtering disabled
3927    ORD(image_draw_filtered);
3928    ORD(image_filtered_get);
3929    ORD(image_filtered_save);
3930    ORD(image_filtered_free);
3931 #endif
3932
3933    ORD(font_draw);
3934
3935    ORD(image_scale_hint_set);
3936    ORD(image_scale_hint_get);
3937    ORD(image_stride_get);
3938
3939    ORD(image_map_draw);
3940    ORD(image_map_surface_new);
3941    ORD(image_map_surface_free);
3942
3943    ORD(image_content_hint_set);
3944    ORD(image_content_hint_get);
3945
3946    ORD(image_cache_flush);
3947    ORD(image_cache_set);
3948    ORD(image_cache_get);
3949
3950    ORD(gl_surface_create);
3951    ORD(gl_surface_destroy);
3952    ORD(gl_context_create);
3953    ORD(gl_context_destroy);
3954    ORD(gl_make_current);
3955    ORD(gl_string_query);
3956    ORD(gl_proc_address_get);
3957    ORD(gl_native_surface_get);
3958    ORD(gl_api_get);
3959
3960    ORD(image_load_error_get);
3961
3962    /* now advertise out own api */
3963    ORD(image_animated_get);
3964    ORD(image_animated_frame_count_get);
3965    ORD(image_animated_loop_type_get);
3966    ORD(image_animated_loop_count_get);
3967    ORD(image_animated_frame_duration_get);
3968    ORD(image_animated_frame_set);
3969
3970    ORD(image_max_size_get);
3971
3972    /* now advertise out own api */
3973    em->functions = (void *)(&func);
3974    return 1;
3975 }
3976
3977 static void
3978 module_close(Evas_Module *em __UNUSED__)
3979 {
3980     eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
3981 /*   
3982     if (xrdb_user.db)
3983       {
3984          XrmDestroyDatabase(xrdb_user.db);
3985          xrdb_user.last_stat = 0;
3986          xrdb_user.last_mtime = 0;
3987          xrdb_user.db = NULL;
3988       }
3989  */
3990     evas_gl_common_module_close();
3991 }
3992
3993 static Evas_Module_Api evas_modapi =
3994 {
3995    EVAS_MODULE_API_VERSION,
3996    "gl_x11",
3997    "none",
3998    {
3999      module_open,
4000      module_close
4001    }
4002 };
4003
4004 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
4005
4006 #ifndef EVAS_STATIC_BUILD_GL_XLIB
4007 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
4008 #endif
4009
4010 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/