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