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