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