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