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