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