9dd9923a5d40b24594a13e38a8de19a601ac5d1a
[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         if (im->tex) evas_gl_common_texture_free(im->tex);
1068         im->tex = NULL;
1069         if (im->cs.data)
1070           {
1071              if (!im->cs.no_free) free(im->cs.data);
1072           }
1073         if (im->im->cache_entry.h > 0)
1074           im->cs.data =
1075           calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
1076         else
1077           im->cs.data = NULL;
1078         im->cs.no_free = 0;
1079         break;
1080       default:
1081         abort();
1082         break;
1083      }
1084    im->cs.space = cspace;
1085 }
1086
1087 /////////////////////////////////////////////////////////////////////////
1088 //
1089 //
1090 typedef struct _Native Native;
1091
1092 struct _Native
1093 {
1094    Evas_Native_Surface ns;
1095    Pixmap     pixmap;
1096    Visual    *visual;
1097
1098 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1099    void      *egl_surface;
1100 #else
1101    void  *fbc;
1102    XID    glx_pixmap;
1103 #endif
1104 };
1105
1106 // FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
1107 // (i am sure this is the reason)  not to mention seemingly superfluous. but
1108 // i need to enable it for it to work on fglrx at least. havent tried nvidia.
1109 //
1110 // why is this the case? does anyone know? has anyone tried it on other gfx
1111 // drivers?
1112 //
1113 //#define GLX_TEX_PIXMAP_RECREATE 1
1114
1115 static void
1116 _native_bind_cb(void *data, void *image)
1117 {
1118    Evas_GL_Image *im = image;
1119    Native *n = im->native.data;
1120
1121   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1122     {
1123 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1124       if (n->egl_surface)
1125         {
1126           if (glsym_glEGLImageTargetTexture2DOES)
1127             {
1128               glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
1129               if (eglGetError() != EGL_SUCCESS)
1130                 ERR("glEGLImageTargetTexture2DOES() failed.");
1131             }
1132           else
1133             ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
1134         }
1135 #else
1136 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1137       Render_Engine *re = data;
1138
1139       if (glsym_glXBindTexImage)
1140         {
1141           glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
1142                                 GLX_FRONT_LEFT_EXT, NULL);
1143           GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1144         }
1145       else
1146         ERR("Try glXBindTexImage on GLX with no support");
1147 # endif
1148 #endif
1149     }
1150   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1151     {
1152       glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
1153       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1154     }
1155    return;
1156    data = NULL;
1157 }
1158
1159 static void
1160 _native_unbind_cb(void *data, void *image)
1161 {
1162   Evas_GL_Image *im = image;
1163   Native *n = im->native.data;
1164
1165   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1166     {
1167 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1168       // nothing
1169 #else
1170 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1171       Render_Engine *re = data;
1172
1173       if (glsym_glXReleaseTexImage)
1174         {
1175           glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1176                                    GLX_FRONT_LEFT_EXT);
1177           GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1178         }
1179       else
1180         ERR("Try glXReleaseTexImage on GLX with no support");
1181 # endif
1182 #endif
1183     }
1184   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1185     {
1186       glBindTexture(GL_TEXTURE_2D, 0);
1187       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1188     }
1189    return;
1190    data = NULL;
1191 }
1192
1193 static void
1194 _native_free_cb(void *data, void *image)
1195 {
1196   Render_Engine *re = data;
1197   Evas_GL_Image *im = image;
1198   Native *n = im->native.data;
1199   uint32_t pmid, texid;
1200
1201   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1202     {
1203       pmid = n->pixmap;
1204       eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1205 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1206       if (n->egl_surface)
1207         {
1208           if (glsym_eglDestroyImage)
1209             {
1210               glsym_eglDestroyImage(re->win->egl_disp,
1211                                     n->egl_surface);
1212               if (eglGetError() != EGL_SUCCESS)
1213                 ERR("eglDestroyImage() failed.");
1214             }
1215           else
1216             ERR("Try eglDestroyImage on EGL with no support");
1217         }
1218 #else
1219 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1220       if (n->glx_pixmap)
1221         {
1222           if (im->native.loose)
1223             {
1224               if (glsym_glXReleaseTexImage)
1225                 {
1226                   glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1227                                            GLX_FRONT_LEFT_EXT);
1228                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1229                 }
1230               else
1231                 ERR("Try glXReleaseTexImage on GLX with no support");
1232             }
1233           if (glsym_glXDestroyPixmap)
1234             {
1235               glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
1236               GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1237             }
1238           else
1239             ERR("Try glXDestroyPixmap on GLX with no support");
1240           n->glx_pixmap = 0;
1241         }
1242 # endif
1243 #endif
1244     }
1245   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1246     {
1247       texid = n->ns.data.opengl.texture_id;
1248       eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
1249     }
1250   im->native.data        = NULL;
1251   im->native.func.data   = NULL;
1252   im->native.func.bind   = NULL;
1253   im->native.func.unbind = NULL;
1254   im->native.func.free   = NULL;
1255   free(n);
1256 }
1257
1258 static void *
1259 eng_image_native_set(void *data, void *image, void *native)
1260 {
1261   Render_Engine *re = (Render_Engine *)data;
1262   Evas_Native_Surface *ns = native;
1263   Evas_GL_Image *im = image, *im2 = NULL;
1264   Visual *vis = NULL;
1265   Pixmap pm = 0;
1266   Native *n = NULL;
1267   uint32_t pmid, texid;
1268   unsigned int tex = 0;
1269   unsigned int fbo = 0;
1270
1271   if (!im)
1272     {
1273        if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
1274          {
1275             im = evas_gl_common_image_new_from_data(re->win->gl_context,
1276                                                     ns->data.opengl.w,
1277                                                     ns->data.opengl.h,
1278                                                     NULL, 1,
1279                                                     EVAS_COLORSPACE_ARGB8888);
1280          }
1281        else
1282            return NULL;
1283     }
1284
1285   if (ns)
1286     {
1287       if (ns->type == EVAS_NATIVE_SURFACE_X11)
1288         {
1289           vis = ns->data.x11.visual;
1290           pm = ns->data.x11.pixmap;
1291           if (im->native.data)
1292             {
1293               Evas_Native_Surface *ens = im->native.data;
1294               if ((ens->data.x11.visual == vis) &&
1295                   (ens->data.x11.pixmap == pm))
1296                 return im;
1297             }
1298         }
1299       else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1300         {
1301           tex = ns->data.opengl.texture_id;
1302           fbo = ns->data.opengl.framebuffer_id;
1303           if (im->native.data)
1304             {
1305               Evas_Native_Surface *ens = im->native.data;
1306               if ((ens->data.opengl.texture_id == tex) &&
1307                   (ens->data.opengl.framebuffer_id == fbo))
1308                 return im;
1309             }
1310         }
1311     }
1312   if ((!ns) && (!im->native.data)) return im;
1313
1314   eng_window_use(re->win);
1315
1316   if (im->native.data)
1317     {
1318       if (im->native.func.free)
1319         im->native.func.free(im->native.func.data, im);
1320       evas_gl_common_image_native_disable(im);
1321     }
1322
1323   if (!ns) return im;
1324
1325   if (ns->type == EVAS_NATIVE_SURFACE_X11)
1326     {
1327       pmid = pm;
1328       im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
1329       if (im2 == im) return im;
1330       if (im2)
1331         {
1332            n = im2->native.data;
1333            if (n)
1334              {
1335                 evas_gl_common_image_ref(im2);
1336                 evas_gl_common_image_free(im);
1337                 return im2;
1338              }
1339         }
1340     }
1341   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1342     {
1343        texid = tex;
1344        im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
1345        if (im2 == im) return im;
1346        if (im2)
1347          {
1348             n = im2->native.data;
1349             if (n)
1350               {
1351                  evas_gl_common_image_ref(im2);
1352                  evas_gl_common_image_free(im);
1353                  return im2;
1354               }
1355          }
1356
1357     }
1358   im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
1359                                            im->w, im->h, NULL, im->alpha,
1360                                            EVAS_COLORSPACE_ARGB8888);
1361   evas_gl_common_image_free(im);
1362   im = im2;
1363   if (ns->type == EVAS_NATIVE_SURFACE_X11)
1364     {
1365 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1366       if (native)
1367         {
1368           n = calloc(1, sizeof(Native));
1369           if (n)
1370             {
1371               EGLConfig egl_config;
1372               int config_attrs[20];
1373               int num_config, i = 0;
1374
1375               eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1376
1377               config_attrs[i++] = EGL_RED_SIZE;
1378               config_attrs[i++] = 8;
1379               config_attrs[i++] = EGL_GREEN_SIZE;
1380               config_attrs[i++] = 8;
1381               config_attrs[i++] = EGL_BLUE_SIZE;
1382               config_attrs[i++] = 8;
1383               config_attrs[i++] = EGL_ALPHA_SIZE;
1384               config_attrs[i++] = 8;
1385               config_attrs[i++] = EGL_DEPTH_SIZE;
1386               config_attrs[i++] = 0;
1387               config_attrs[i++] = EGL_STENCIL_SIZE;
1388               config_attrs[i++] = 0;
1389               config_attrs[i++] = EGL_RENDERABLE_TYPE;
1390               config_attrs[i++] = EGL_OPENGL_ES2_BIT;
1391               config_attrs[i++] = EGL_SURFACE_TYPE;
1392               config_attrs[i++] = EGL_PIXMAP_BIT;
1393               config_attrs[i++] = EGL_NONE;
1394
1395               if (!eglChooseConfig(re->win->egl_disp, config_attrs,
1396                                    &egl_config, 1, &num_config))
1397                 ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
1398               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1399               n->pixmap = pm;
1400               n->visual = vis;
1401               if (glsym_eglCreateImage)
1402                 n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
1403                                                       EGL_NO_CONTEXT,
1404                                                       EGL_NATIVE_PIXMAP_KHR,
1405                                                       (void *)pm,
1406                                                       NULL);
1407               else
1408                 ERR("Try eglCreateImage on EGL with no support");
1409               if (!n->egl_surface)
1410                 ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
1411               im->native.yinvert     = 1;
1412               im->native.loose       = 0;
1413               im->native.data        = n;
1414               im->native.func.data   = re;
1415               im->native.func.bind   = _native_bind_cb;
1416               im->native.func.unbind = _native_unbind_cb;
1417               im->native.func.free   = _native_free_cb;
1418               im->native.target      = GL_TEXTURE_2D;
1419               im->native.mipmap      = 0;
1420               evas_gl_common_image_native_enable(im);
1421             }
1422         }
1423 #else
1424 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1425       if (native)
1426         {
1427           int dummy;
1428           unsigned int w, h, depth = 32, border;
1429           Window wdummy;
1430
1431           // fixme: round trip :(
1432           XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
1433                        &w, &h, &border, &depth);
1434           n = calloc(1, sizeof(Native));
1435           if (n)
1436             {
1437               int pixmap_att[20];
1438               unsigned int target = 0;
1439               unsigned int i = 0;
1440
1441               eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1442               if ((re->win->depth_cfg[depth].tex_target &
1443                    GLX_TEXTURE_2D_BIT_EXT)
1444                   //                 && (1) // we assume npo2 for now
1445                   // size is pow2 || mnpo2 supported
1446                  )
1447                 target = GLX_TEXTURE_2D_EXT;
1448               else if ((re->win->depth_cfg[depth].tex_target &
1449                         GLX_TEXTURE_RECTANGLE_BIT_EXT))
1450                 {
1451                   ERR("rect!!! (not handled)");
1452                   target = GLX_TEXTURE_RECTANGLE_EXT;
1453                 }
1454               if (!target)
1455                 {
1456                   ERR("broken text-from-pixmap");
1457                   if (!(re->win->depth_cfg[depth].tex_target &
1458                         GLX_TEXTURE_2D_BIT_EXT))
1459                     target = GLX_TEXTURE_RECTANGLE_EXT;
1460                   else if (!(re->win->depth_cfg[depth].tex_target &
1461                              GLX_TEXTURE_RECTANGLE_BIT_EXT))
1462                     target = GLX_TEXTURE_2D_EXT;
1463                 }
1464
1465
1466               pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
1467               pixmap_att[i++] = re->win->depth_cfg[depth].tex_format;
1468               pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
1469               pixmap_att[i++] = re->win->depth_cfg[depth].mipmap;
1470
1471               if (target)
1472                 {
1473                   pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
1474                   pixmap_att[i++] = target;
1475                 }
1476
1477               pixmap_att[i++] = 0;
1478
1479               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1480               n->pixmap = pm;
1481               n->visual = vis;
1482               n->fbc = re->win->depth_cfg[depth].fbc;
1483               if (glsym_glXCreatePixmap)
1484                 n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
1485                                                       n->fbc,
1486                                                       n->pixmap,
1487                                                       pixmap_att);
1488               else
1489                 ERR("Try glXCreatePixmap on GLX with no support");
1490               if (n->glx_pixmap)
1491                 {
1492 //                  printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
1493 //                         n, pm, w, h, depth, n->glx_pixmap);
1494                   if (!target)
1495                     {
1496                       ERR("no target :(");
1497                       if (glsym_glXQueryDrawable)
1498                         glsym_glXQueryDrawable(re->win->disp,
1499                                                n->pixmap,
1500                                                GLX_TEXTURE_TARGET_EXT,
1501                                                &target);
1502                     }
1503                   if (target == GLX_TEXTURE_2D_EXT)
1504                     {
1505                       im->native.target = GL_TEXTURE_2D;
1506                       im->native.mipmap = re->win->depth_cfg[depth].mipmap;
1507                     }
1508 #  ifdef GL_TEXTURE_RECTANGLE_ARB
1509                   else if (target == GLX_TEXTURE_RECTANGLE_EXT)
1510                     {
1511                       im->native.target = GL_TEXTURE_RECTANGLE_ARB;
1512                       im->native.mipmap = 0;
1513                     }
1514 #  endif
1515                   else
1516                     {
1517                       im->native.target = GL_TEXTURE_2D;
1518                       im->native.mipmap = 0;
1519                       ERR("still unknown target");
1520                     }
1521                 }
1522               else
1523                 ERR("GLX Pixmap create fail");
1524               im->native.yinvert     = re->win->depth_cfg[depth].yinvert;
1525               im->native.loose       = re->win->detected.loose_binding;
1526               im->native.data        = n;
1527               im->native.func.data   = re;
1528               im->native.func.bind   = _native_bind_cb;
1529               im->native.func.unbind = _native_unbind_cb;
1530               im->native.func.free   = _native_free_cb;
1531
1532               evas_gl_common_image_native_enable(im);
1533             }
1534         }
1535 # endif
1536 #endif
1537     }
1538   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1539     {
1540       if (native)
1541         {
1542           n = calloc(1, sizeof(Native));
1543           if (n)
1544             {
1545               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1546
1547               eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
1548
1549               n->pixmap = 0;
1550               n->visual = 0;
1551 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1552               n->egl_surface = 0;
1553 #else
1554               n->fbc = 0;
1555               n->glx_pixmap = 0;
1556 #endif
1557
1558               im->native.yinvert     = 0;
1559               im->native.loose       = 0;
1560               im->native.data        = n;
1561               im->native.func.data   = re;
1562               im->native.func.bind   = _native_bind_cb;
1563               im->native.func.unbind = _native_unbind_cb;
1564               im->native.func.free   = _native_free_cb;
1565               im->native.target      = GL_TEXTURE_2D;
1566               im->native.mipmap      = 0;
1567
1568               // FIXME: need to implement mapping sub texture regions
1569               // x, y, w, h for possible texture atlasing
1570
1571               evas_gl_common_image_native_enable(im);
1572             }
1573         }
1574
1575     }
1576    return im;
1577 }
1578
1579 static void *
1580 eng_image_native_get(void *data __UNUSED__, void *image)
1581 {
1582    Evas_GL_Image *im = image;
1583    Native *n;
1584    if (!im) return NULL;
1585    n = im->native.data;
1586    if (!n) return NULL;
1587    return &(n->ns);
1588 }
1589
1590 #if 0 // filtering disabled
1591 static void
1592 eng_image_draw_filtered(void *data, void *context, void *surface,
1593                         void *image, Evas_Filter_Info *filter)
1594 {
1595    Render_Engine *re = data;
1596
1597    if (!image) return;
1598    eng_window_use(re->win);
1599    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1600    re->win->gl_context->dc = context;
1601
1602    evas_gl_common_filter_draw(re->win->gl_context, image, filter);
1603 }
1604
1605 static Filtered_Image *
1606 eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
1607 {
1608    return evas_gl_common_image_filtered_get(im, key, keylen);
1609 }
1610
1611 static Filtered_Image *
1612 eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
1613 {
1614    return evas_gl_common_image_filtered_save(im, fim, key, keylen);
1615 }
1616
1617 static void
1618 eng_image_filtered_free(void *im, Filtered_Image *fim)
1619 {
1620    evas_gl_common_image_filtered_free(im, fim);
1621 }
1622 #endif
1623
1624
1625 //
1626 //
1627 /////////////////////////////////////////////////////////////////////////
1628
1629 static void *
1630 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
1631 {
1632    Render_Engine *re;
1633
1634    re = (Render_Engine *)data;
1635    *error = EVAS_LOAD_ERROR_NONE;
1636    eng_window_use(re->win);
1637    return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
1638 }
1639
1640 static void *
1641 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
1642 {
1643    Render_Engine *re;
1644
1645    re = (Render_Engine *)data;
1646    eng_window_use(re->win);
1647    return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
1648 }
1649
1650 static void *
1651 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
1652 {
1653    Render_Engine *re;
1654
1655    re = (Render_Engine *)data;
1656    eng_window_use(re->win);
1657    return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
1658 }
1659
1660 static void
1661 eng_image_free(void *data, void *image)
1662 {
1663    Render_Engine *re;
1664
1665    re = (Render_Engine *)data;
1666    if (!image) return;
1667    eng_window_use(re->win);
1668    evas_gl_common_image_free(image);
1669 }
1670
1671 static void
1672 eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
1673 {
1674    if (!image)
1675      {
1676         *w = 0;
1677         *h = 0;
1678         return;
1679      }
1680    if (w) *w = ((Evas_GL_Image *)image)->w;
1681    if (h) *h = ((Evas_GL_Image *)image)->h;
1682 }
1683
1684 static void *
1685 eng_image_size_set(void *data, void *image, int w, int h)
1686 {
1687    Render_Engine *re;
1688    Evas_GL_Image *im = image;
1689    Evas_GL_Image *im_old;
1690
1691    re = (Render_Engine *)data;
1692    if (!im) return NULL;
1693    if (im->native.data)
1694      {
1695         im->w = w;
1696         im->h = h;
1697         return image;
1698      }
1699    eng_window_use(re->win);
1700    if ((im->tex) && (im->tex->pt->dyn.img))
1701      {
1702         evas_gl_common_texture_free(im->tex);
1703         im->tex = NULL;
1704         im->w = w;
1705         im->h = h;
1706         im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
1707         return image;
1708      }
1709    im_old = image;
1710    if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1711        (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL))
1712      w &= ~0x1;
1713    if ((im_old) &&
1714        ((int)im_old->im->cache_entry.w == w) &&
1715        ((int)im_old->im->cache_entry.h == h))
1716      return image;
1717    if (im_old)
1718      {
1719         im = evas_gl_common_image_new(re->win->gl_context, w, h,
1720                                       eng_image_alpha_get(data, image),
1721                                       eng_image_colorspace_get(data, image));
1722 /*
1723         evas_common_load_image_data_from_file(im_old->im);
1724         if (im_old->im->image->data)
1725           {
1726              evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
1727              evas_common_cpu_end_opt();
1728           }
1729  */
1730         evas_gl_common_image_free(im_old);
1731      }
1732    else
1733      im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
1734    return im;
1735 }
1736
1737 static void *
1738 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
1739 {
1740    Render_Engine *re;
1741    Evas_GL_Image *im = image;
1742
1743    re = (Render_Engine *)data;
1744    if (!image) return NULL;
1745    if (im->native.data) return image;
1746    eng_window_use(re->win);
1747    evas_gl_common_image_dirty(image, x, y, w, h);
1748    return image;
1749 }
1750
1751 static void *
1752 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
1753 {
1754    Render_Engine *re;
1755    Evas_GL_Image *im;
1756    int error;
1757
1758    re = (Render_Engine *)data;
1759    if (!image)
1760      {
1761         *image_data = NULL;
1762         if (err) *err = EVAS_LOAD_ERROR_GENERIC;
1763         return NULL;
1764      }
1765    im = image;
1766    if (im->native.data)
1767      {
1768         *image_data = NULL;
1769         if (err) *err = EVAS_LOAD_ERROR_NONE;
1770         return im;
1771      }
1772
1773 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1774    eng_window_use(re->win);
1775
1776    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img))
1777      {
1778         *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1779
1780         if (!im->tex->pt->dyn.data)
1781           {
1782              glsym_eglDestroyImage(re->win->egl_disp, im->tex->pt->dyn.img);
1783              im->tex->pt->dyn.img = NULL;
1784              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1785           }
1786
1787         if (err) *err = EVAS_LOAD_ERROR_NONE;
1788         return im;
1789      }
1790 #else
1791    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
1792      {
1793         *image_data = im->tex->pt->dyn.data;
1794         if (err) *err = EVAS_LOAD_ERROR_NONE;
1795         return im;
1796      }
1797
1798    eng_window_use(re->win);
1799 #endif
1800
1801    error = evas_cache_image_load_data(&im->im->cache_entry);
1802    switch (im->cs.space)
1803      {
1804       case EVAS_COLORSPACE_ARGB8888:
1805         if (to_write)
1806           {
1807              if (im->references > 1)
1808                {
1809                   Evas_GL_Image *im_new;
1810
1811                   im_new = evas_gl_common_image_new_from_copied_data
1812                      (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
1813                          im->im->image.data,
1814                          eng_image_alpha_get(data, image),
1815                          eng_image_colorspace_get(data, image));
1816                   if (!im_new)
1817                     {
1818                        *image_data = NULL;
1819                        if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
1820                        return im;
1821                     }
1822                   evas_gl_common_image_free(im);
1823                   im = im_new;
1824                }
1825              else
1826                evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1827           }
1828         *image_data = im->im->image.data;
1829         break;
1830       case EVAS_COLORSPACE_YCBCR422P601_PL:
1831       case EVAS_COLORSPACE_YCBCR422P709_PL:
1832         *image_data = im->cs.data;
1833         break;
1834       default:
1835         abort();
1836         break;
1837      }
1838    if (err) *err = error;
1839    return im;
1840 }
1841
1842 static void *
1843 eng_image_data_put(void *data, void *image, DATA32 *image_data)
1844 {
1845    Render_Engine *re;
1846    Evas_GL_Image *im, *im2;
1847
1848    re = (Render_Engine *)data;
1849    if (!image) return NULL;
1850    im = image;
1851    if (im->native.data) return image;
1852    eng_window_use(re->win);
1853    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
1854      {
1855 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1856         glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1857 #endif
1858         if (im->tex->pt->dyn.data == image_data)
1859           {
1860              return image;
1861           }
1862         else
1863           {
1864              int w, h;
1865
1866              w = im->im->cache_entry.w;
1867              h = im->im->cache_entry.h;
1868              im2 = eng_image_new_from_data(data, w, h, image_data,
1869                                            eng_image_alpha_get(data, image),
1870                                            eng_image_colorspace_get(data, image));
1871              if (!im2) return im;
1872              evas_gl_common_image_free(im);
1873              im = im2;
1874              evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1875              return im;
1876           }
1877      }
1878    switch (im->cs.space)
1879      {
1880       case EVAS_COLORSPACE_ARGB8888:
1881         if (image_data != im->im->image.data)
1882           {
1883              int w, h;
1884
1885              w = im->im->cache_entry.w;
1886              h = im->im->cache_entry.h;
1887              im2 = eng_image_new_from_data(data, w, h, image_data,
1888                                            eng_image_alpha_get(data, image),
1889                                            eng_image_colorspace_get(data, image));
1890              if (!im2) return im;
1891              evas_gl_common_image_free(im);
1892              im = im2;
1893           }
1894         break;
1895       case EVAS_COLORSPACE_YCBCR422P601_PL:
1896       case EVAS_COLORSPACE_YCBCR422P709_PL:
1897         if (image_data != im->cs.data)
1898           {
1899              if (im->cs.data)
1900                {
1901                   if (!im->cs.no_free) free(im->cs.data);
1902                }
1903              im->cs.data = image_data;
1904           }
1905         break;
1906       default:
1907         abort();
1908         break;
1909      }
1910    /* hmmm - but if we wrote... why bother? */
1911    evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1912    return im;
1913 }
1914
1915 static void
1916 eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
1917 {
1918    Evas_GL_Image *gim = image;
1919    RGBA_Image *im;
1920
1921    if (!gim) return;
1922    if (gim->native.data) return;
1923    im = (RGBA_Image *)gim->im;
1924    if (!im) return;
1925    evas_cache_image_preload_data(&im->cache_entry, target);
1926 }
1927
1928 static void
1929 eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
1930 {
1931    Evas_GL_Image *gim = image;
1932    RGBA_Image *im;
1933
1934    if (!gim) return;
1935    if (gim->native.data) return;
1936    im = (RGBA_Image *)gim->im;
1937    if (!im) return;
1938    evas_cache_image_preload_cancel(&im->cache_entry, target);
1939 }
1940
1941 static void
1942 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)
1943 {
1944    Render_Engine *re;
1945
1946    re = (Render_Engine *)data;
1947    if (!image) return;
1948    eng_window_use(re->win);
1949    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1950    re->win->gl_context->dc = context;
1951    evas_gl_common_image_draw(re->win->gl_context, image,
1952                              src_x, src_y, src_w, src_h,
1953                              dst_x, dst_y, dst_w, dst_h,
1954                              smooth);
1955 }
1956
1957 static void
1958 eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
1959 {
1960    if (image) evas_gl_common_image_scale_hint_set(image, hint);
1961 }
1962
1963 static int
1964 eng_image_scale_hint_get(void *data __UNUSED__, void *image)
1965 {
1966    Evas_GL_Image *gim = image;
1967    if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
1968    return gim->scale_hint;
1969 }
1970
1971 static void
1972 eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
1973 {
1974    Evas_GL_Image *gim = image;
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    if (npoints != 4)
1983      {
1984         // FIXME: nash - you didn't fix this
1985         abort();
1986      }
1987    if ((p[0].x == p[3].x) &&
1988        (p[1].x == p[2].x) &&
1989        (p[0].y == p[1].y) &&
1990        (p[3].y == p[2].y) &&
1991        (p[0].x <= p[1].x) &&
1992        (p[0].y <= p[2].y) &&
1993        (p[0].u == 0) &&
1994        (p[0].v == 0) &&
1995        (p[1].u == (gim->w << FP)) &&
1996        (p[1].v == 0) &&
1997        (p[2].u == (gim->w << FP)) &&
1998        (p[2].v == (gim->h << FP)) &&
1999        (p[3].u == 0) &&
2000        (p[3].v == (gim->h << FP)) &&
2001        (p[0].col == 0xffffffff) &&
2002        (p[1].col == 0xffffffff) &&
2003        (p[2].col == 0xffffffff) &&
2004        (p[3].col == 0xffffffff))
2005      {
2006         int dx, dy, dw, dh;
2007
2008         dx = p[0].x >> FP;
2009         dy = p[0].y >> FP;
2010         dw = (p[2].x >> FP) - dx;
2011         dh = (p[2].y >> FP) - dy;
2012         eng_image_draw(data, context, surface, image,
2013                        0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
2014      }
2015    else
2016      {
2017         evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
2018                                       smooth, level);
2019      }
2020 }
2021
2022 static void *
2023 eng_image_map_surface_new(void *data, int w, int h, int alpha)
2024 {
2025    Render_Engine *re;
2026
2027    re = (Render_Engine *)data;
2028    return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
2029 }
2030
2031 static void
2032 eng_image_map_surface_free(void *data __UNUSED__, void *surface)
2033 {
2034    evas_gl_common_image_free(surface);
2035 }
2036
2037 static void
2038 eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
2039 {
2040    if (image) evas_gl_common_image_content_hint_set(image, hint);
2041 }
2042
2043 static int
2044 eng_image_content_hint_get(void *data __UNUSED__, void *image)
2045 {
2046    Evas_GL_Image *gim = image;
2047    if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
2048    return gim->content_hint;
2049 }
2050
2051 static void
2052 eng_image_cache_flush(void *data)
2053 {
2054    Render_Engine *re;
2055    int tmp_size;
2056
2057    re = (Render_Engine *)data;
2058
2059    tmp_size = evas_common_image_get_cache();
2060    evas_common_image_set_cache(0);
2061    evas_common_rgba_image_scalecache_flush();
2062    evas_gl_common_image_cache_flush(re->win->gl_context);
2063    evas_common_image_set_cache(tmp_size);
2064 }
2065
2066 static void
2067 eng_image_cache_set(void *data, int bytes)
2068 {
2069    Render_Engine *re;
2070
2071    re = (Render_Engine *)data;
2072    evas_common_image_set_cache(bytes);
2073    evas_common_rgba_image_scalecache_size_set(bytes);
2074    evas_gl_common_image_cache_flush(re->win->gl_context);
2075 }
2076
2077 static int
2078 eng_image_cache_get(void *data __UNUSED__)
2079 {
2080    return evas_common_image_get_cache();
2081 }
2082
2083 static void
2084 eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
2085 {
2086    Evas_GL_Image *im = image;
2087
2088    if ((im->tex) && (im->tex->pt->dyn.img))
2089      *stride = im->tex->pt->dyn.stride;
2090    else
2091      *stride = im->w * 4;
2092 }
2093
2094 static void
2095 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)
2096 {
2097    Render_Engine *re;
2098
2099    re = (Render_Engine *)data;
2100    eng_window_use(re->win);
2101    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2102    re->win->gl_context->dc = context;
2103      {
2104         // FIXME: put im into context so we can free it
2105         static RGBA_Image *im = NULL;
2106
2107         if (!im)
2108           im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
2109         im->cache_entry.w = re->win->w;
2110         im->cache_entry.h = re->win->h;
2111         evas_common_draw_context_font_ext_set(context,
2112                                               re->win->gl_context,
2113                                               evas_gl_font_texture_new,
2114                                               evas_gl_font_texture_free,
2115                                               evas_gl_font_texture_draw);
2116         evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
2117                               intl_props);
2118         evas_common_draw_context_font_ext_set(context,
2119                                               NULL,
2120                                               NULL,
2121                                               NULL,
2122                                               NULL);
2123      }
2124 }
2125
2126 static Eina_Bool
2127 eng_canvas_alpha_get(void *data, void *info __UNUSED__)
2128 {
2129    Render_Engine *re = (Render_Engine *)data;
2130    return re->win->alpha;
2131 }
2132
2133 static int
2134 _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2135 {
2136    // Also initialize pixel format here as well...
2137    switch(cfg->color_format)
2138      {
2139       case EVAS_GL_RGB_8:
2140          sfc->rt_fmt          = GL_RGB;
2141          sfc->rt_internal_fmt = GL_RGB;
2142          break;
2143       case EVAS_GL_RGBA_8:
2144          sfc->rt_fmt          = GL_RGBA;
2145          sfc->rt_internal_fmt = GL_RGBA;
2146          break;
2147       case EVAS_GL_RGB_32:
2148          // Only supported on some hw
2149          // Fill it in later...
2150       case EVAS_GL_RGBA_32:
2151          // Only supported on some hw
2152          // Fill it in later...
2153       default:
2154          ERR("Invalid Color Format!");
2155          return 0;
2156      }
2157
2158    switch(cfg->depth_bits)
2159      {
2160       case EVAS_GL_DEPTH_NONE:
2161          break;
2162       case EVAS_GL_DEPTH_BIT_8:
2163       case EVAS_GL_DEPTH_BIT_16:
2164       case EVAS_GL_DEPTH_BIT_24:
2165 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2166          // 24 bit doesn't work... just cover it with 16 for now..
2167          sfc->rb_depth_fmt = GL_DEPTH_COMPONENT16;
2168 #else
2169          sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
2170 #endif
2171          break;
2172       case EVAS_GL_DEPTH_BIT_32:
2173       default:
2174          ERR("Unsupported Depth Bits Format!");
2175          return 0;
2176      }
2177
2178    switch(cfg->stencil_bits)
2179      {
2180       case EVAS_GL_STENCIL_NONE:
2181          break;
2182       case EVAS_GL_STENCIL_BIT_1:
2183       case EVAS_GL_STENCIL_BIT_2:
2184       case EVAS_GL_STENCIL_BIT_4:
2185       case EVAS_GL_STENCIL_BIT_8:
2186 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2187          sfc->rb_stencil_fmt = GL_STENCIL_INDEX8;
2188 #else
2189          sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
2190 #endif
2191          break;
2192       case EVAS_GL_STENCIL_BIT_16:
2193       default:
2194          ERR("Unsupported Stencil Bits Format!");
2195          return 0;
2196      }
2197
2198    // Do Packed Depth24_Stencil8 Later...
2199
2200    return 1;
2201 }
2202
2203 static int
2204 _create_rt_buffers(Render_Engine *data __UNUSED__,
2205                    Render_Engine_GL_Surface *sfc)
2206 {
2207    // Render Target texture
2208    glGenTextures(1, &sfc->rt_tex );
2209    glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
2210    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2211    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2212    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2213    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2214    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
2215                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2216    glBindTexture(GL_TEXTURE_2D, 0);
2217
2218    // Depth RenderBuffer - Create storage here...
2219    if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2220      {
2221         glGenRenderbuffers(1, &sfc->rb_depth);
2222         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2223         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
2224                               sfc->w, sfc->h);
2225         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2226      }
2227
2228    // Stencil RenderBuffer - Create Storage here...
2229    if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2230      {
2231         glGenRenderbuffers(1, &sfc->rb_stencil);
2232         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2233         glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
2234                               sfc->w, sfc->h);
2235         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2236      }
2237
2238    return 1;
2239 }
2240
2241 static int
2242 _attach_fbo_surface(Render_Engine *data __UNUSED__,
2243                     Render_Engine_GL_Surface *sfc,
2244                     Render_Engine_GL_Context *ctx)
2245 {
2246    int fb_status;
2247
2248    // FBO
2249    glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2250    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2251                           GL_TEXTURE_2D, sfc->rt_tex, 0);
2252
2253    // Depth RenderBuffer - Attach it to FBO
2254    if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2255      {
2256         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2257         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
2258                                   GL_RENDERBUFFER, sfc->rb_depth);
2259         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2260      }
2261
2262    // Stencil RenderBuffer - Attach it to FBO
2263    if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2264      {
2265         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2266         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
2267                                   GL_RENDERBUFFER, sfc->rb_stencil);
2268         glBindRenderbuffer(GL_RENDERBUFFER, 0);
2269      }
2270
2271    // Check FBO for completeness
2272    fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2273    if (fb_status != GL_FRAMEBUFFER_COMPLETE)
2274      {
2275         ERR("FBO not complete!");
2276         return 0;
2277      }
2278
2279    return 1;
2280 }
2281
2282 static void *
2283 eng_gl_surface_create(void *data, void *config, int w, int h)
2284 {
2285    Render_Engine *re;
2286    Render_Engine_GL_Surface *sfc;
2287    Evas_GL_Config *cfg;
2288    int ret;
2289
2290    sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
2291
2292    if (!sfc) return NULL;
2293
2294    re  = (Render_Engine *)data;
2295    cfg = (Evas_GL_Config *)config;
2296
2297    sfc->initialized  = 0;
2298    sfc->fbo_attached = 0;
2299    sfc->w            = w;
2300    sfc->h            = h;
2301    sfc->depth_bits   = cfg->depth_bits;
2302    sfc->stencil_bits = cfg->stencil_bits;
2303    sfc->rt_tex       = 0;
2304    sfc->rb_depth     = 0;
2305    sfc->rb_stencil   = 0;
2306
2307    // Set the internal format based on the config
2308    if (!_set_internal_config(sfc, cfg))
2309      {
2310         ERR("Unsupported Format!");
2311         free(sfc);
2312         return NULL;
2313      }
2314
2315    // Create Render Target Texture/Buffers if not initialized
2316    if (!sfc->initialized)
2317      {
2318         // I'm using evas's original context to create the render target texture
2319         // This is to prevent awkwardness in using native_surface_get() function
2320         // If the rt texture creation is deferred till the context is created and
2321         // make_current called, the user can't call native_surface_get() right
2322         // after the surface is created. hence this is done here using evas' context.
2323 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2324         ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]);
2325 #else
2326         ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2327 #endif
2328         if (!ret)
2329           {
2330              ERR("xxxMakeCurrent() failed!");
2331              free(sfc);
2332              return NULL;
2333           }
2334
2335         // Create Render texture
2336         if (!_create_rt_buffers(re, sfc))
2337           {
2338              ERR("_create_rt_buffers() failed.");
2339              free(sfc);
2340              return NULL;
2341           }
2342
2343 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2344         ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2345                              EGL_NO_SURFACE, EGL_NO_CONTEXT);
2346 #else
2347         ret = glXMakeCurrent(re->info->info.display, None, NULL);
2348 #endif
2349         if (!ret)
2350           {
2351              ERR("xxxMakeCurrent() failed!");
2352              free(sfc);
2353              return 0;
2354           }
2355         sfc->initialized = 1;
2356      }
2357
2358    return sfc;
2359 }
2360
2361 static int
2362 eng_gl_surface_destroy(void *data, void *surface)
2363 {
2364    Render_Engine *re;
2365    Render_Engine_GL_Surface *sfc;
2366    int ret;
2367
2368    re  = (Render_Engine *)data;
2369    sfc = (Render_Engine_GL_Surface*)surface;
2370
2371    // I'm using evas's original context to delete the created fbo and texture
2372    // This is because the fbo/texture was created in the user created context
2373    // but the context can be destroyed already...
2374    // I don't think this is the best way but at least for now this is A WAY.
2375 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2376    ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]);
2377 #else
2378    ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2379 #endif
2380    if (!ret)
2381      {
2382         ERR("xxxMakeCurrent() failed!");
2383         return 0;
2384      }
2385
2386    // Delete FBO/RBO and Texture here
2387    if (glIsTexture(sfc->rt_tex))
2388      glDeleteTextures(1, &sfc->rt_tex);
2389
2390    if (glIsBuffer(sfc->rb_depth))
2391      glDeleteRenderbuffers(1, &sfc->rb_depth);
2392
2393    if (glIsBuffer(sfc->rb_stencil))
2394      glDeleteRenderbuffers(1, &sfc->rb_stencil);
2395
2396
2397 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2398    ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2399 #else
2400    ret = glXMakeCurrent(re->info->info.display, None, NULL);
2401 #endif
2402    if (!ret)
2403      {
2404         ERR("xxxMakeCurrent() failed!");
2405         return 0;
2406      }
2407
2408    free(sfc);
2409    surface = NULL;
2410
2411    return 1;
2412 }
2413
2414 static void *
2415 eng_gl_context_create(void *data, void *share_context)
2416 {
2417    Render_Engine *re;
2418    Render_Engine_GL_Context *ctx;
2419    Render_Engine_GL_Context *share_ctx;
2420 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2421    int context_attrs[3];
2422 #endif
2423
2424    ctx = calloc(1, sizeof(Render_Engine_GL_Context));
2425
2426    if (!ctx) return NULL;
2427
2428    re = (Render_Engine *)data;
2429    share_ctx = (Render_Engine_GL_Context *)share_context;
2430
2431    // Set the share context to Evas' GL context if share_context is NULL.
2432    // Otherwise set it to the given share_context.
2433 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2434    // EGL
2435    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
2436    context_attrs[1] = 2;
2437    context_attrs[2] = EGL_NONE;
2438
2439    if (share_ctx)
2440      {
2441         ctx->context = eglCreateContext(re->win->egl_disp,
2442                                         re->win->egl_config,
2443                                         share_ctx->context,      // Share Context
2444                                         context_attrs);
2445      }
2446    else
2447      {
2448         ctx->context = eglCreateContext(re->win->egl_disp,
2449                                         re->win->egl_config,
2450                                         re->win->egl_context[0], // Evas' GL Context
2451                                         context_attrs);
2452      }
2453
2454    if (!ctx->context)
2455      {
2456         ERR("eglCreateContext() fail. code=%#x", eglGetError());
2457         return NULL;
2458      }
2459 #else
2460    // GLX
2461    if (share_context)
2462      {
2463         ctx->context = glXCreateContext(re->info->info.display,
2464                                         re->win->visualinfo,
2465                                         share_ctx->context,    // Share Context
2466                                         1);
2467      }
2468    else
2469      {
2470         ctx->context = glXCreateContext(re->info->info.display,
2471                                         re->win->visualinfo,
2472                                         re->win->context,      // Evas' GL Context
2473                                         1);
2474      }
2475
2476    if (!ctx->context)
2477      {
2478         ERR("glXCreateContext() fail.");
2479         return NULL;
2480      }
2481 #endif
2482
2483    ctx->initialized = 0;
2484    ctx->context_fbo = 0;
2485    ctx->current_sfc = NULL;
2486
2487    return ctx;
2488 }
2489
2490 static int
2491 eng_gl_context_destroy(void *data, void *context)
2492 {
2493    Render_Engine *re;
2494    Render_Engine_GL_Context *ctx;
2495    int ret;
2496
2497    re  = (Render_Engine *)data;
2498    ctx = (Render_Engine_GL_Context*)context;
2499
2500    // 1. Do a make current with the given context
2501 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2502    ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0],
2503                         re->win->egl_surface[0], ctx->context);
2504 #else
2505    ret = glXMakeCurrent(re->info->info.display, re->win->win,
2506                         ctx->context);
2507 #endif
2508    if (!ret)
2509      {
2510         ERR("xxxMakeCurrent() failed!");
2511         return 0;
2512      }
2513
2514    // 2. Delete the FBO
2515    if (glIsBuffer(ctx->context_fbo))
2516      glDeleteBuffers(1, &ctx->context_fbo);
2517
2518    // 3. Destroy the Context
2519 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2520    eglDestroyContext(re->win->egl_disp, ctx->context);
2521
2522    ctx->context = EGL_NO_CONTEXT;
2523
2524    ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2525                         EGL_NO_SURFACE, EGL_NO_CONTEXT);
2526 #else
2527    glXDestroyContext(re->info->info.display, ctx->context);
2528
2529    ctx->context = 0;
2530
2531    ret = glXMakeCurrent(re->info->info.display, None, NULL);
2532 #endif
2533    if (!ret)
2534      {
2535         ERR("xxxMakeCurrent() failed!");
2536         return 0;
2537      }
2538
2539    free(ctx);
2540    context = NULL;
2541
2542    return 1;
2543 }
2544
2545 static int
2546 eng_gl_make_current(void *data, void *surface, void *context)
2547 {
2548    Render_Engine *re;
2549    Render_Engine_GL_Surface *sfc;
2550    Render_Engine_GL_Context *ctx;
2551    int ret = 0;
2552
2553    re  = (Render_Engine *)data;
2554    sfc = (Render_Engine_GL_Surface*)surface;
2555    ctx = (Render_Engine_GL_Context*)context;
2556
2557    // Unset surface/context
2558    if ((!sfc) || (!ctx))
2559      {
2560 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2561         ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2562                              EGL_NO_SURFACE, EGL_NO_CONTEXT);
2563 #else
2564         ret = glXMakeCurrent(re->info->info.display, None, NULL);
2565 #endif
2566         if (!ret)
2567           {
2568              ERR("xxxMakeCurrent() failed!");
2569              return 0;
2570           }
2571
2572         ctx->current_sfc = NULL;
2573         sfc->current_ctx = NULL;
2574         return ret;
2575      }
2576
2577    // Don't do a make current if it's already current
2578 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2579    if ((eglGetCurrentContext() == ctx->context) && 
2580        (eglGetCurrentSurface(EGL_READ) == re->win->egl_surface[0]) &&
2581        (eglGetCurrentSurface(EGL_DRAW) == re->win->egl_surface[0]) ) 
2582      {
2583
2584         DBG("Context same\n");
2585         return 1;
2586      }
2587 #else
2588    if ((glXGetCurrentContext() == ctx->context) &&
2589        (glXGetCurrentDrawable() == re->win->win) )
2590      {
2591         DBG("Context same\n");
2592         return 1;
2593      }
2594 #endif
2595
2596
2597    // Flush remainder of what's in Evas' pipeline
2598    if (re->win)
2599       eng_window_use(NULL);
2600
2601
2602    // Set the context current
2603 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2604    ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], 
2605                               re->win->egl_surface[0], ctx->context);
2606    if (!ret)
2607      {
2608         ERR("xxxMakeCurrent() failed!");
2609         return 0;
2610      }
2611 #else
2612    ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
2613    if (!ret) 
2614      {
2615         ERR("xxxMakeCurrent() failed!");
2616         return 0;
2617      }
2618 #endif
2619
2620    // Create FBO if not already created
2621    if (!ctx->initialized)
2622      {
2623         glGenFramebuffers(1, &ctx->context_fbo);
2624         ctx->initialized = 1;
2625      }
2626
2627    // Attach FBO if it hasn't been attached or if surface changed
2628    if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
2629      {
2630         if (!_attach_fbo_surface(re, sfc, ctx))
2631           {
2632              ERR("_attach_fbo_surface() failed.");
2633              return 0;
2634           }
2635
2636         if (ctx->current_fbo)
2637            // Bind to the previously bound buffer
2638            glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
2639         else
2640            // Bind FBO
2641            glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2642      }
2643
2644    // Set the current surface/context
2645    ctx->current_sfc = sfc;
2646    sfc->current_ctx = ctx;
2647
2648    current_evgl_ctx = ctx;
2649
2650    return 1;
2651 }
2652
2653 static void *
2654 eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
2655 {
2656 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2657    if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
2658    return dlsym(RTLD_DEFAULT, name);
2659 #else
2660    if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
2661    return dlsym(RTLD_DEFAULT, name);
2662 #endif
2663 }
2664
2665 static int
2666 eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
2667 {
2668    Render_Engine *re;
2669    Render_Engine_GL_Surface *sfc;
2670    Evas_Native_Surface *ns;
2671
2672    re  = (Render_Engine *)data;
2673    sfc = (Render_Engine_GL_Surface*)surface;
2674    ns  = (Evas_Native_Surface*)native_surface;
2675
2676    ns->type = EVAS_NATIVE_SURFACE_OPENGL;
2677    ns->version = EVAS_NATIVE_SURFACE_VERSION;
2678    ns->data.opengl.texture_id = sfc->rt_tex;
2679    //ns->data.opengl.framebuffer_id = sfc->fbo;
2680    //ns->data.opengl.framebuffer_id = ctx->context_fbo;
2681    ns->data.opengl.x = 0;
2682    ns->data.opengl.y = 0;
2683    ns->data.opengl.w = sfc->w;
2684    ns->data.opengl.h = sfc->h;
2685
2686    return 1;
2687 }
2688
2689 #if 1
2690 static void
2691 evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
2692 {
2693    Render_Engine_GL_Context *ctx = current_evgl_ctx;
2694
2695    // Take care of BindFramebuffer 0 issue
2696    if (framebuffer==0)
2697      {
2698         if (ctx)
2699           {
2700              glBindFramebuffer(target, ctx->context_fbo);
2701              ctx->current_fbo = 0;
2702           }
2703      }
2704    else
2705      {
2706         glBindFramebuffer(target, framebuffer);
2707
2708         // Save this for restore when doing make current
2709         if (ctx)
2710            ctx->current_fbo = framebuffer;
2711      }
2712 }
2713
2714 static void
2715 evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
2716 {
2717    // Add logic to take care when renderbuffer=0
2718    // On a second thought we don't need this
2719    glBindRenderbuffer(target, renderbuffer);
2720 }
2721
2722 static void
2723 evgl_glClearDepthf(GLclampf depth)
2724 {
2725 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2726    glClearDepthf(depth);
2727 #else
2728    glClearDepth(depth);
2729 #endif
2730 }
2731
2732 static void
2733 evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
2734 {
2735 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2736    glDepthRangef(zNear, zFar);
2737 #else
2738    glDepthRange(zNear, zFar);
2739 #endif
2740 }
2741
2742 static void
2743 evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2744 {
2745 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2746    glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
2747 #else
2748    if (range)
2749      {
2750         range[0] = -126; // floor(log2(FLT_MIN))
2751         range[1] = 127; // floor(log2(FLT_MAX))
2752      }
2753    if (precision)
2754      {
2755         precision[0] = 24; // floor(-log2((1.0/16777218.0)));
2756      }
2757    return;
2758    shadertype = precisiontype = 0;
2759 #endif
2760 }
2761
2762 static void
2763 evgl_glReleaseShaderCompiler(void)
2764 {
2765 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2766    glReleaseShaderCompiler();
2767 #else
2768 #endif
2769 }
2770
2771 static void
2772 evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
2773 {
2774 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2775    glShaderBinary(n, shaders, binaryformat, binary, length);
2776 #else
2777 // FIXME: need to dlsym/getprocaddress for this
2778    return;
2779    n = binaryformat = length = 0;
2780    shaders = binary = 0;
2781 #endif
2782 }
2783
2784 #endif
2785
2786 static void *
2787 eng_gl_api_get(void *data)
2788 {
2789    Render_Engine *re;
2790
2791    re  = (Render_Engine *)data;
2792
2793    gl_funcs.version = EVAS_GL_API_VERSION;
2794 #if 1
2795 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
2796    ORD(glActiveTexture);
2797    ORD(glAttachShader);
2798    ORD(glBindAttribLocation);
2799    ORD(glBindBuffer);
2800    ORD(glBindTexture);
2801    ORD(glBlendColor);
2802    ORD(glBlendEquation);
2803    ORD(glBlendEquationSeparate);
2804    ORD(glBlendFunc);
2805    ORD(glBlendFuncSeparate);
2806    ORD(glBufferData);
2807    ORD(glBufferSubData);
2808    ORD(glCheckFramebufferStatus);
2809    ORD(glClear);
2810    ORD(glClearColor);
2811 //   ORD(glClearDepthf);
2812    ORD(glClearStencil);
2813    ORD(glColorMask);
2814    ORD(glCompileShader);
2815    ORD(glCompressedTexImage2D);
2816    ORD(glCompressedTexSubImage2D);
2817    ORD(glCopyTexImage2D);
2818    ORD(glCopyTexSubImage2D);
2819    ORD(glCreateProgram);
2820    ORD(glCreateShader);
2821    ORD(glCullFace);
2822    ORD(glDeleteBuffers);
2823    ORD(glDeleteFramebuffers);
2824    ORD(glDeleteProgram);
2825    ORD(glDeleteRenderbuffers);
2826    ORD(glDeleteShader);
2827    ORD(glDeleteTextures);
2828    ORD(glDepthFunc);
2829    ORD(glDepthMask);
2830 //   ORD(glDepthRangef);
2831    ORD(glDetachShader);
2832    ORD(glDisable);
2833    ORD(glDisableVertexAttribArray);
2834    ORD(glDrawArrays);
2835    ORD(glDrawElements);
2836    ORD(glEnable);
2837    ORD(glEnableVertexAttribArray);
2838    ORD(glFinish);
2839    ORD(glFlush);
2840    ORD(glFramebufferRenderbuffer);
2841    ORD(glFramebufferTexture2D);
2842    ORD(glFrontFace);
2843    ORD(glGenBuffers);
2844    ORD(glGenerateMipmap);
2845    ORD(glGenFramebuffers);
2846    ORD(glGenRenderbuffers);
2847    ORD(glGenTextures);
2848    ORD(glGetActiveAttrib);
2849    ORD(glGetActiveUniform);
2850    ORD(glGetAttachedShaders);
2851    ORD(glGetAttribLocation);
2852    ORD(glGetBooleanv);
2853    ORD(glGetBufferParameteriv);
2854    ORD(glGetError);
2855    ORD(glGetFloatv);
2856    ORD(glGetFramebufferAttachmentParameteriv);
2857    ORD(glGetIntegerv);
2858    ORD(glGetProgramiv);
2859    ORD(glGetProgramInfoLog);
2860    ORD(glGetRenderbufferParameteriv);
2861    ORD(glGetShaderiv);
2862    ORD(glGetShaderInfoLog);
2863 //   ORD(glGetShaderPrecisionFormat);
2864    ORD(glGetShaderSource);
2865    ORD(glGetString);
2866    ORD(glGetTexParameterfv);
2867    ORD(glGetTexParameteriv);
2868    ORD(glGetUniformfv);
2869    ORD(glGetUniformiv);
2870    ORD(glGetUniformLocation);
2871    ORD(glGetVertexAttribfv);
2872    ORD(glGetVertexAttribiv);
2873    ORD(glGetVertexAttribPointerv);
2874    ORD(glHint);
2875    ORD(glIsBuffer);
2876    ORD(glIsEnabled);
2877    ORD(glIsFramebuffer);
2878    ORD(glIsProgram);
2879    ORD(glIsRenderbuffer);
2880    ORD(glIsShader);
2881    ORD(glIsTexture);
2882    ORD(glLineWidth);
2883    ORD(glLinkProgram);
2884    ORD(glPixelStorei);
2885    ORD(glPolygonOffset);
2886    ORD(glReadPixels);
2887 //   ORD(glReleaseShaderCompiler);
2888    ORD(glRenderbufferStorage);
2889    ORD(glSampleCoverage);
2890    ORD(glScissor);
2891 //   ORD(glShaderBinary);
2892    ORD(glShaderSource);
2893    ORD(glStencilFunc);
2894    ORD(glStencilFuncSeparate);
2895    ORD(glStencilMask);
2896    ORD(glStencilMaskSeparate);
2897    ORD(glStencilOp);
2898    ORD(glStencilOpSeparate);
2899    ORD(glTexImage2D);
2900    ORD(glTexParameterf);
2901    ORD(glTexParameterfv);
2902    ORD(glTexParameteri);
2903    ORD(glTexParameteriv);
2904    ORD(glTexSubImage2D);
2905    ORD(glUniform1f);
2906    ORD(glUniform1fv);
2907    ORD(glUniform1i);
2908    ORD(glUniform1iv);
2909    ORD(glUniform2f);
2910    ORD(glUniform2fv);
2911    ORD(glUniform2i);
2912    ORD(glUniform2iv);
2913    ORD(glUniform3f);
2914    ORD(glUniform3fv);
2915    ORD(glUniform3i);
2916    ORD(glUniform3iv);
2917    ORD(glUniform4f);
2918    ORD(glUniform4fv);
2919    ORD(glUniform4i);
2920    ORD(glUniform4iv);
2921    ORD(glUniformMatrix2fv);
2922    ORD(glUniformMatrix3fv);
2923    ORD(glUniformMatrix4fv);
2924    ORD(glUseProgram);
2925    ORD(glValidateProgram);
2926    ORD(glVertexAttrib1f);
2927    ORD(glVertexAttrib1fv);
2928    ORD(glVertexAttrib2f);
2929    ORD(glVertexAttrib2fv);
2930    ORD(glVertexAttrib3f);
2931    ORD(glVertexAttrib3fv);
2932    ORD(glVertexAttrib4f);
2933    ORD(glVertexAttrib4fv);
2934    ORD(glVertexAttribPointer);
2935    ORD(glViewport);
2936 #undef ORD
2937
2938 // Override functions wrapped by Evas_GL
2939 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
2940    ORD(glBindFramebuffer);
2941    ORD(glBindRenderbuffer);
2942
2943 // GLES2.0 API compat on top of desktop gl
2944    ORD(glClearDepthf);
2945    ORD(glDepthRangef);
2946    ORD(glGetShaderPrecisionFormat);
2947    ORD(glReleaseShaderCompiler);
2948    ORD(glShaderBinary);
2949 #undef ORD
2950
2951 #endif
2952
2953    return &gl_funcs;
2954 }
2955
2956 static int
2957 eng_image_load_error_get(void *data __UNUSED__, void *image)
2958 {
2959    Evas_GL_Image *im;
2960
2961    if (!image) return EVAS_LOAD_ERROR_NONE;
2962    im = image;
2963    return im->im->cache_entry.load_error;
2964 }
2965
2966 static Eina_Bool
2967 eng_image_animated_get(void *data __UNUSED__, void *image)
2968 {
2969    Image_Entry *im;
2970
2971    if (!image) return EINA_FALSE;
2972    im = image;
2973    return im->flags.animated;
2974 }
2975
2976 static int
2977 eng_image_animated_frame_count_get(void *data __UNUSED__, void *image)
2978 {
2979    Image_Entry *im;
2980
2981    if (!image) return -1;
2982    im = image;
2983    if (!im->flags.animated) return -1;
2984    return im->frame_count;
2985 }
2986
2987 static Evas_Image_Animated_Loop_Hint
2988 eng_image_animated_loop_type_get(void *data __UNUSED__, void *image)
2989 {
2990    Image_Entry *im;
2991
2992    if (!image) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2993    im = image;
2994    if (!im->flags.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2995    return im->loop_hint;
2996 }
2997
2998 static int
2999 eng_image_animated_loop_count_get(void *data __UNUSED__, void *image)
3000 {
3001    Image_Entry *im;
3002
3003    if (!image) return -1;
3004    im = image;
3005    if (!im->flags.animated) return -1;
3006    return im->loop_count;
3007 }
3008
3009 static double
3010 eng_image_animated_frame_duration_get(void *data __UNUSED__, void *image, int start_frame, int frame_num)
3011 {
3012    Image_Entry *im;
3013
3014    if (!image) return -1;
3015    im = image;
3016    if (!im->flags.animated) return -1;
3017    return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
3018 }
3019
3020 static Eina_Bool
3021 eng_image_animated_frame_set(void *data __UNUSED__, void *image, int frame_index)
3022 {
3023    Image_Entry *im;
3024
3025    if (!image) return EINA_FALSE;
3026    im = image;
3027    if (!im->flags.animated) return EINA_FALSE;
3028    if (im->cur_frame == frame_index) return EINA_FALSE;
3029
3030    im->cur_frame = frame_index;
3031    return EINA_TRUE;
3032 }
3033
3034 static int
3035 module_open(Evas_Module *em)
3036 {
3037    static Eina_Bool xrm_inited = EINA_FALSE;
3038    if (!xrm_inited)
3039      {
3040         xrm_inited = EINA_TRUE;
3041         XrmInitialize();
3042      }
3043
3044    if (!em) return 0;
3045    if (!evas_gl_common_module_open()) return 0;
3046    /* get whatever engine module we inherit from */
3047    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
3048    if (_evas_engine_GL_X11_log_dom < 0)
3049      _evas_engine_GL_X11_log_dom = eina_log_domain_register
3050        ("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
3051    if (_evas_engine_GL_X11_log_dom < 0)
3052      {
3053         EINA_LOG_ERR("Can not create a module log domain.");
3054         return 0;
3055      }
3056    /* store it for later use */
3057    func = pfunc;
3058    /* now to override methods */
3059    #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
3060    ORD(info);
3061    ORD(info_free);
3062    ORD(setup);
3063    ORD(canvas_alpha_get);
3064    ORD(output_free);
3065    ORD(output_resize);
3066    ORD(output_tile_size_set);
3067    ORD(output_redraws_rect_add);
3068    ORD(output_redraws_rect_del);
3069    ORD(output_redraws_clear);
3070    ORD(output_redraws_next_update_get);
3071    ORD(output_redraws_next_update_push);
3072    ORD(context_cutout_add);
3073    ORD(context_cutout_clear);
3074    ORD(output_flush);
3075    ORD(output_idle_flush);
3076    ORD(output_dump);
3077    ORD(rectangle_draw);
3078    ORD(line_draw);
3079    ORD(polygon_point_add);
3080    ORD(polygon_points_clear);
3081    ORD(polygon_draw);
3082
3083    ORD(image_load);
3084    ORD(image_new_from_data);
3085    ORD(image_new_from_copied_data);
3086    ORD(image_free);
3087    ORD(image_size_get);
3088    ORD(image_size_set);
3089    ORD(image_dirty_region);
3090    ORD(image_data_get);
3091    ORD(image_data_put);
3092    ORD(image_data_preload_request);
3093    ORD(image_data_preload_cancel);
3094    ORD(image_alpha_set);
3095    ORD(image_alpha_get);
3096    ORD(image_border_set);
3097    ORD(image_border_get);
3098    ORD(image_draw);
3099    ORD(image_comment_get);
3100    ORD(image_format_get);
3101    ORD(image_colorspace_set);
3102    ORD(image_colorspace_get);
3103    ORD(image_mask_create);
3104    ORD(image_native_set);
3105    ORD(image_native_get);
3106 #if 0 // filtering disabled
3107    ORD(image_draw_filtered);
3108    ORD(image_filtered_get);
3109    ORD(image_filtered_save);
3110    ORD(image_filtered_free);
3111 #endif
3112
3113    ORD(font_draw);
3114
3115    ORD(image_scale_hint_set);
3116    ORD(image_scale_hint_get);
3117    ORD(image_stride_get);
3118
3119    ORD(image_map_draw);
3120    ORD(image_map_surface_new);
3121    ORD(image_map_surface_free);
3122
3123    ORD(image_content_hint_set);
3124    ORD(image_content_hint_get);
3125
3126    ORD(image_cache_flush);
3127    ORD(image_cache_set);
3128    ORD(image_cache_get);
3129
3130    ORD(gl_surface_create);
3131    ORD(gl_surface_destroy);
3132    ORD(gl_context_create);
3133    ORD(gl_context_destroy);
3134    ORD(gl_make_current);
3135    ORD(gl_proc_address_get);
3136    ORD(gl_native_surface_get);
3137
3138    ORD(gl_api_get);
3139
3140    ORD(image_load_error_get);
3141
3142    /* now advertise out own api */
3143    ORD(image_animated_get);
3144    ORD(image_animated_frame_count_get);
3145    ORD(image_animated_loop_type_get);
3146    ORD(image_animated_loop_count_get);
3147    ORD(image_animated_frame_duration_get);
3148    ORD(image_animated_frame_set);
3149
3150    /* now advertise out own api */
3151    em->functions = (void *)(&func);
3152    return 1;
3153 }
3154
3155 static void
3156 module_close(Evas_Module *em __UNUSED__)
3157 {
3158     eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
3159     if (xrdb_user.db)
3160       {
3161          XrmDestroyDatabase(xrdb_user.db);
3162          xrdb_user.last_stat = 0;
3163          xrdb_user.last_mtime = 0;
3164          xrdb_user.db = NULL;
3165       }
3166     evas_gl_common_module_close();
3167 }
3168
3169 static Evas_Module_Api evas_modapi =
3170 {
3171    EVAS_MODULE_API_VERSION,
3172    "gl_x11",
3173    "none",
3174    {
3175      module_open,
3176      module_close
3177    }
3178 };
3179
3180 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
3181
3182 #ifndef EVAS_STATIC_BUILD_GL_XLIB
3183 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
3184 #endif
3185
3186 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/