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