1 #include "evas_common.h" /* Also includes international specific stuff */
2 #include "evas_engine.h"
4 #include <dlfcn.h> /* dlopen,dlclose,etc */
5 #define EVAS_GL_NO_GL_H_CHECK 1
8 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
10 # if defined(GLES_VARIETY_S3C6410)
11 # elif defined(GLES_VARIETY_SGX)
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;
23 Evas_GL_X11_Window *win;
24 Evas_Engine_Info_GL_X11 *info;
28 XrmDatabase xrdb; // xres - dpi
29 struct { // xres - dpi
30 int dpi; // xres - dpi
37 struct _Render_Engine_GL_Surface
45 // Render target texture/buffers
47 GLint rt_internal_fmt;
52 GLenum rb_stencil_fmt;
54 Render_Engine_GL_Context *current_ctx;
57 struct _Render_Engine_GL_Context
60 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
68 Render_Engine_GL_Surface *current_sfc;
71 static int initted = 0;
72 static int gl_wins = 0;
73 static Render_Engine_GL_Context *current_evgl_ctx;
75 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
77 #ifndef EGL_NATIVE_PIXMAP_KHR
78 # define EGL_NATIVE_PIXMAP_KHR 0x30b0
80 typedef void (*_eng_fn) (void);
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) ();
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;
96 typedef void (*_eng_fn) (void);
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) ();
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;
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)
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);
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);
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);
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);
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);
155 FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
157 FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
158 FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
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)
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);
168 FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
169 FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
170 FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
172 FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
173 FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
174 FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
176 FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
178 FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
180 FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
181 FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
182 FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
184 FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
185 FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
186 FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
188 FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
189 FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
190 FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
192 FINDSYM(glsym_glxSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
193 FINDSYM(glsym_glxSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
195 FINDSYM(glsym_glxSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
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;
203 /* Function table for GL APIs */
204 static Evas_GL_API gl_funcs;
212 static struct xrdb_user xrdb_user = {0, 0, NULL};
215 xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
217 time_t last = xrdb_user.last_stat, now = time(NULL);
219 xrdb_user.last_stat = now;
220 if (last != now) /* don't stat() more than once every second */
223 const char *home = getenv("HOME");
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)
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;
238 if (!xrdb_user.db) return EINA_FALSE;
239 return XrmGetResource(xrdb_user.db, name, cls, type, val);
244 XrmDestroyDatabase(xrdb_user.db);
247 xrdb_user.last_mtime = 0;
254 Evas_Engine_Info_GL_X11 *info;
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;
267 eng_info_free(Evas *e __UNUSED__, void *info)
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;
277 _re_wincheck(Render_Engine *re)
279 if (re->win->surf) return 1;
280 eng_window_resurf(re->win);
283 ERR("GL engine can't re-create window surface!");
289 _re_winfree(Render_Engine *re)
291 if (!re->win->surf) return;
292 eng_window_unsurf(re->win);
296 eng_setup(Evas *e, void *in)
299 Evas_Engine_Info_GL_X11 *info;
301 info = (Evas_Engine_Info_GL_X11 *)in;
302 if (!e->engine.data.output)
304 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
308 if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
310 re = calloc(1, sizeof(Render_Engine));
314 e->engine.data.output = re;
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,
326 re->info->info.destination_alpha,
327 re->info->info.rotation);
331 e->engine.data.output = NULL;
341 re->xr.dpi = 75000; // dpy * 1000
343 status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
344 if ((!status) || (!type))
346 if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display);
348 status = XrmGetResource(re->xrdb,
349 "Xft.dpi", "Xft.Dpi", &type, &val);
352 if ((status) && (type))
354 if (!strcmp(type, "String"))
356 const char *str, *dp;
359 dp = strchr(str, '.');
360 if (!dp) dp = strchr(str, ',');
367 buf = alloca(dp - str + 1);
368 strncpy(buf, str, dp - str);
370 len = strlen(dp + 1);
371 subdpi = atoi(dp + 1);
375 for (i = len; i < 3; i++) subdpi *= 10;
379 for (i = len; i > 3; i--) subdpi /= 10;
381 re->xr.dpi = atoi(buf) * 1000;
384 re->xr.dpi = atoi(str) * 1000;
385 evas_common_font_dpi_set(re->xr.dpi / 1000);
392 evas_common_cpu_init();
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();
409 re = e->engine.data.output;
410 if (_re_wincheck(re))
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))
425 re->win->gl_context->references++;
426 eng_window_free(re->win);
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,
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--;
448 else if ((re->win->w != e->output.w) ||
449 (re->win->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);
466 if (!e->engine.data.output)
470 eng_window_free(re->win);
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);
482 /* we don't need this actually as evas_render does it
485 glClearColor(0.0, 0.0, 0.0, 0.0);
486 glClear(GL_COLOR_BUFFER_BIT);
495 eng_output_free(void *data)
499 re = (Render_Engine *)data;
503 // NOTE: XrmGetDatabase() result is shared per connection, do not free it.
504 // if (re->xrdb) XrmDestroyDatabase(re->xrdb);
508 eng_window_free(re->win);
513 if ((initted == 1) && (gl_wins == 0))
515 evas_common_image_shutdown();
516 evas_common_font_shutdown();
522 eng_output_resize(void *data, int w, int h)
526 re = (Render_Engine *)data;
529 eng_window_use(re->win);
530 evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
534 eng_output_tile_size_set(void *data __UNUSED__, int w __UNUSED__, int h __UNUSED__)
539 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
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)
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;
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;
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;
570 re->win->draw.redraw = 1;
574 eng_output_redraws_rect_del(void *data __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
579 eng_output_redraws_clear(void *data)
583 re = (Render_Engine *)data;
584 re->win->draw.redraw = 0;
585 // INF("GL: finish update cycle!");
588 /* vsync games - not for now though */
589 #define VSYNC_TO_SCREEN 1
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)
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
602 eng_window_use(NULL);
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;
617 /* we don't need this actually as evas_render does it
620 glClearColor(0.0, 0.0, 0.0, 0.0);
621 glClear(GL_COLOR_BUFFER_BIT);
624 return re->win->gl_context->def_surface;
627 //#define FRAMECOUNT 1
633 struct timeval timev;
635 gettimeofday(&timev, NULL);
636 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
640 static int safe_native = -1;
643 eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
647 static double pt = 0.0;
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)
659 const char *s = getenv("EVAS_GL_SAFE_NATIVE");
661 if (s) safe_native = atoi(s);
664 s = (const char *)glGetString(GL_RENDERER);
667 if (strstr(s, "PowerVR SGX 540") ||
668 strstr(s, "Mali-400 MP"))
673 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
674 // this is needed to make sure all previous rendering is flushed to
677 double t0 = get_time();
681 // previous rendering should be done and swapped
682 if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
684 double t1 = get_time();
686 printf("... %1.5f -> %1.5f | ", ta, tb);
688 // if (eglGetError() != EGL_SUCCESS)
690 // printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
693 // previous rendering should be done and swapped
694 if (!safe_native) glXWaitX();
696 //x// printf("frame -> push\n");
700 eng_output_flush(void *data)
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);
711 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
713 double t0 = get_time();
717 if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
718 else eglSwapInterval(re->win->egl_disp, 0);
721 if (re->info->callback.pre_swap)
723 re->info->callback.pre_swap(re->info->callback.data, re->evas);
725 eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
726 if (!safe_native) eglWaitGL();
727 if (re->info->callback.post_swap)
729 re->info->callback.post_swap(re->info->callback.data, re->evas);
732 double t1 = get_time();
733 printf("%1.5f\n", t1 - t0);
735 // if (eglGetError() != EGL_SUCCESS)
737 // printf("Error: eglSwapBuffers() fail.\n");
740 #ifdef VSYNC_TO_SCREEN
741 if ((re->info->vsync)/* || (1)*/)
743 if (glsym_glxSwapIntervalEXT)
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);
752 if (glsym_glxSwapIntervalSGI)
756 if (re->info->vsync) glsym_glxSwapIntervalSGI(1);
757 else glsym_glxSwapIntervalSGI(0);
763 if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
767 glsym_glXGetVideoSync(&rc);
768 glsym_glXWaitVideoSync(1, 0, &rc);
773 if (re->info->callback.pre_swap)
775 re->info->callback.pre_swap(re->info->callback.data, re->evas);
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))
786 glXSwapBuffers(re->win->disp, re->win->win);
787 if (!safe_native) glXWaitGL();
792 // FIXME: this doesn't work.. why oh why?
795 // fimxe - reset when done
796 // glEnable(GL_SCISSOR_TEST);
797 glDrawBuffer(GL_FRONT);
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;
805 // glScissor(sx, sy, sw, sh);
806 glRasterPos2i(sx, re->win->h - sy);
807 glCopyPixels(sx, sy, sw, sh, GL_COLOR);
810 // glDisable(GL_SCISSOR_TEST);
811 glDrawBuffer(GL_BACK);
815 if (re->info->callback.post_swap)
817 re->info->callback.post_swap(re->info->callback.data, re->evas);
823 eng_output_idle_flush(void *data)
827 re = (Render_Engine *)data;
831 eng_output_dump(void *data)
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);
843 eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
845 // Render_Engine *re;
847 // re = (Render_Engine *)data;
848 // re->win->gl_context->dc = context;
849 evas_common_draw_context_add_cutout(context, x, y, w, h);
853 eng_context_cutout_clear(void *data __UNUSED__, void *context)
855 // Render_Engine *re;
857 // re = (Render_Engine *)data;
858 // re->win->gl_context->dc = context;
859 evas_common_draw_context_clear_cutouts(context);
863 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
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);
875 eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
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);
887 eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
891 re = (Render_Engine *)data;
892 return evas_gl_common_poly_point_add(polygon, x, y);
896 eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
900 re = (Render_Engine *)data;
901 return evas_gl_common_poly_points_clear(polygon);
905 eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *polygon, int x, int y)
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);
917 eng_image_alpha_get(void *data __UNUSED__, void *image)
919 // Render_Engine *re;
922 // re = (Render_Engine *)data;
923 if (!image) return 1;
929 eng_image_colorspace_get(void *data __UNUSED__, void *image)
931 // Render_Engine *re;
934 // re = (Render_Engine *)data;
935 if (!image) return EVAS_COLORSPACE_ARGB8888;
941 eng_image_mask_create(void *data __UNUSED__, void *image)
947 if (!im->im->image.data)
948 evas_cache_image_load_data(&im->im->cache_entry);
950 im->tex = evas_gl_common_texture_new(im->gc, im->im);
955 eng_image_alpha_set(void *data, void *image, int has_alpha)
960 re = (Render_Engine *)data;
961 if (!image) return NULL;
963 if (im->alpha == has_alpha) return image;
966 im->alpha = has_alpha;
969 eng_window_use(re->win);
970 if ((im->tex) && (im->tex->pt->dyn.img))
972 im->alpha = has_alpha;
973 im->tex->alpha = im->alpha;
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)
982 Evas_GL_Image *im_new;
984 im_new = evas_gl_common_image_new_from_copied_data
985 (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
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);
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;
1001 eng_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
1003 // Render_Engine *re;
1005 // re = (Render_Engine *)data;
1010 eng_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
1012 // Render_Engine *re;
1014 // re = (Render_Engine *)data;
1018 eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
1020 // Render_Engine *re;
1023 // re = (Render_Engine *)data;
1024 if (!image) return NULL;
1026 if (!im->im) return NULL;
1027 return im->im->info.comment;
1031 eng_image_format_get(void *data __UNUSED__, void *image)
1033 // Render_Engine *re;
1036 // re = (Render_Engine *)data;
1042 eng_image_colorspace_set(void *data, void *image, int cspace)
1047 re = (Render_Engine *)data;
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);
1057 case EVAS_COLORSPACE_ARGB8888:
1060 if (!im->cs.no_free) free(im->cs.data);
1065 case EVAS_COLORSPACE_YCBCR422P601_PL:
1066 case EVAS_COLORSPACE_YCBCR422P709_PL:
1067 case EVAS_COLORSPACE_YCBCR422601_PL:
1068 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1069 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1070 if (im->tex) evas_gl_common_texture_free(im->tex);
1074 if (!im->cs.no_free) free(im->cs.data);
1076 if (im->im->cache_entry.h > 0)
1078 calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
1087 im->cs.space = cspace;
1090 /////////////////////////////////////////////////////////////////////////
1093 typedef struct _Native Native;
1097 Evas_Native_Surface ns;
1101 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1109 // FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
1110 // (i am sure this is the reason) not to mention seemingly superfluous. but
1111 // i need to enable it for it to work on fglrx at least. havent tried nvidia.
1113 // why is this the case? does anyone know? has anyone tried it on other gfx
1116 //#define GLX_TEX_PIXMAP_RECREATE 1
1119 _native_bind_cb(void *data, void *image)
1121 Evas_GL_Image *im = image;
1122 Native *n = im->native.data;
1124 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1126 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1129 if (glsym_glEGLImageTargetTexture2DOES)
1131 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
1132 if (eglGetError() != EGL_SUCCESS)
1133 ERR("glEGLImageTargetTexture2DOES() failed.");
1136 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
1139 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1140 Render_Engine *re = data;
1142 if (glsym_glXBindTexImage)
1144 glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
1145 GLX_FRONT_LEFT_EXT, NULL);
1146 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1149 ERR("Try glXBindTexImage on GLX with no support");
1153 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1155 glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
1156 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1163 _native_unbind_cb(void *data, void *image)
1165 Evas_GL_Image *im = image;
1166 Native *n = im->native.data;
1168 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1170 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1173 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1174 Render_Engine *re = data;
1176 if (glsym_glXReleaseTexImage)
1178 glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1179 GLX_FRONT_LEFT_EXT);
1180 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1183 ERR("Try glXReleaseTexImage on GLX with no support");
1187 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1189 glBindTexture(GL_TEXTURE_2D, 0);
1190 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1197 _native_free_cb(void *data, void *image)
1199 Render_Engine *re = data;
1200 Evas_GL_Image *im = image;
1201 Native *n = im->native.data;
1202 uint32_t pmid, texid;
1204 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1207 eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1208 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1211 if (glsym_eglDestroyImage)
1213 glsym_eglDestroyImage(re->win->egl_disp,
1215 if (eglGetError() != EGL_SUCCESS)
1216 ERR("eglDestroyImage() failed.");
1219 ERR("Try eglDestroyImage on EGL with no support");
1222 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1225 if (im->native.loose)
1227 if (glsym_glXReleaseTexImage)
1229 glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1230 GLX_FRONT_LEFT_EXT);
1231 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1234 ERR("Try glXReleaseTexImage on GLX with no support");
1236 if (glsym_glXDestroyPixmap)
1238 glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
1239 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1242 ERR("Try glXDestroyPixmap on GLX with no support");
1248 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1250 texid = n->ns.data.opengl.texture_id;
1251 eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
1253 im->native.data = NULL;
1254 im->native.func.data = NULL;
1255 im->native.func.bind = NULL;
1256 im->native.func.unbind = NULL;
1257 im->native.func.free = NULL;
1262 eng_image_native_set(void *data, void *image, void *native)
1264 Render_Engine *re = (Render_Engine *)data;
1265 Evas_Native_Surface *ns = native;
1266 Evas_GL_Image *im = image, *im2 = NULL;
1270 uint32_t pmid, texid;
1271 unsigned int tex = 0;
1272 unsigned int fbo = 0;
1276 if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
1278 im = evas_gl_common_image_new_from_data(re->win->gl_context,
1282 EVAS_COLORSPACE_ARGB8888);
1290 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1292 vis = ns->data.x11.visual;
1293 pm = ns->data.x11.pixmap;
1294 if (im->native.data)
1296 Evas_Native_Surface *ens = im->native.data;
1297 if ((ens->data.x11.visual == vis) &&
1298 (ens->data.x11.pixmap == pm))
1302 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1304 tex = ns->data.opengl.texture_id;
1305 fbo = ns->data.opengl.framebuffer_id;
1306 if (im->native.data)
1308 Evas_Native_Surface *ens = im->native.data;
1309 if ((ens->data.opengl.texture_id == tex) &&
1310 (ens->data.opengl.framebuffer_id == fbo))
1315 if ((!ns) && (!im->native.data)) return im;
1317 eng_window_use(re->win);
1319 if (im->native.data)
1321 if (im->native.func.free)
1322 im->native.func.free(im->native.func.data, im);
1323 evas_gl_common_image_native_disable(im);
1328 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1331 im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
1332 if (im2 == im) return im;
1335 n = im2->native.data;
1338 evas_gl_common_image_ref(im2);
1339 evas_gl_common_image_free(im);
1344 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1347 im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
1348 if (im2 == im) return im;
1351 n = im2->native.data;
1354 evas_gl_common_image_ref(im2);
1355 evas_gl_common_image_free(im);
1361 im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
1362 im->w, im->h, NULL, im->alpha,
1363 EVAS_COLORSPACE_ARGB8888);
1364 evas_gl_common_image_free(im);
1366 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1368 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1371 n = calloc(1, sizeof(Native));
1374 EGLConfig egl_config;
1375 int config_attrs[20];
1376 int num_config, i = 0;
1378 eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1380 config_attrs[i++] = EGL_RED_SIZE;
1381 config_attrs[i++] = 8;
1382 config_attrs[i++] = EGL_GREEN_SIZE;
1383 config_attrs[i++] = 8;
1384 config_attrs[i++] = EGL_BLUE_SIZE;
1385 config_attrs[i++] = 8;
1386 config_attrs[i++] = EGL_ALPHA_SIZE;
1387 config_attrs[i++] = 8;
1388 config_attrs[i++] = EGL_DEPTH_SIZE;
1389 config_attrs[i++] = 0;
1390 config_attrs[i++] = EGL_STENCIL_SIZE;
1391 config_attrs[i++] = 0;
1392 config_attrs[i++] = EGL_RENDERABLE_TYPE;
1393 config_attrs[i++] = EGL_OPENGL_ES2_BIT;
1394 config_attrs[i++] = EGL_SURFACE_TYPE;
1395 config_attrs[i++] = EGL_PIXMAP_BIT;
1396 config_attrs[i++] = EGL_NONE;
1398 if (!eglChooseConfig(re->win->egl_disp, config_attrs,
1399 &egl_config, 1, &num_config))
1400 ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
1401 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1404 if (glsym_eglCreateImage)
1405 n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
1407 EGL_NATIVE_PIXMAP_KHR,
1411 ERR("Try eglCreateImage on EGL with no support");
1412 if (!n->egl_surface)
1413 ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
1414 im->native.yinvert = 1;
1415 im->native.loose = 0;
1416 im->native.data = n;
1417 im->native.func.data = re;
1418 im->native.func.bind = _native_bind_cb;
1419 im->native.func.unbind = _native_unbind_cb;
1420 im->native.func.free = _native_free_cb;
1421 im->native.target = GL_TEXTURE_2D;
1422 im->native.mipmap = 0;
1423 evas_gl_common_image_native_enable(im);
1427 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1431 unsigned int w, h, depth = 32, border;
1434 // fixme: round trip :(
1435 XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
1436 &w, &h, &border, &depth);
1437 n = calloc(1, sizeof(Native));
1441 unsigned int target = 0;
1444 eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1445 if ((re->win->depth_cfg[depth].tex_target &
1446 GLX_TEXTURE_2D_BIT_EXT)
1447 // && (1) // we assume npo2 for now
1448 // size is pow2 || mnpo2 supported
1450 target = GLX_TEXTURE_2D_EXT;
1451 else if ((re->win->depth_cfg[depth].tex_target &
1452 GLX_TEXTURE_RECTANGLE_BIT_EXT))
1454 ERR("rect!!! (not handled)");
1455 target = GLX_TEXTURE_RECTANGLE_EXT;
1459 ERR("broken text-from-pixmap");
1460 if (!(re->win->depth_cfg[depth].tex_target &
1461 GLX_TEXTURE_2D_BIT_EXT))
1462 target = GLX_TEXTURE_RECTANGLE_EXT;
1463 else if (!(re->win->depth_cfg[depth].tex_target &
1464 GLX_TEXTURE_RECTANGLE_BIT_EXT))
1465 target = GLX_TEXTURE_2D_EXT;
1469 pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
1470 pixmap_att[i++] = re->win->depth_cfg[depth].tex_format;
1471 pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
1472 pixmap_att[i++] = re->win->depth_cfg[depth].mipmap;
1476 pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
1477 pixmap_att[i++] = target;
1480 pixmap_att[i++] = 0;
1482 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1485 n->fbc = re->win->depth_cfg[depth].fbc;
1486 if (glsym_glXCreatePixmap)
1487 n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
1492 ERR("Try glXCreatePixmap on GLX with no support");
1495 // printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
1496 // n, pm, w, h, depth, n->glx_pixmap);
1499 ERR("no target :(");
1500 if (glsym_glXQueryDrawable)
1501 glsym_glXQueryDrawable(re->win->disp,
1503 GLX_TEXTURE_TARGET_EXT,
1506 if (target == GLX_TEXTURE_2D_EXT)
1508 im->native.target = GL_TEXTURE_2D;
1509 im->native.mipmap = re->win->depth_cfg[depth].mipmap;
1511 # ifdef GL_TEXTURE_RECTANGLE_ARB
1512 else if (target == GLX_TEXTURE_RECTANGLE_EXT)
1514 im->native.target = GL_TEXTURE_RECTANGLE_ARB;
1515 im->native.mipmap = 0;
1520 im->native.target = GL_TEXTURE_2D;
1521 im->native.mipmap = 0;
1522 ERR("still unknown target");
1526 ERR("GLX Pixmap create fail");
1527 im->native.yinvert = re->win->depth_cfg[depth].yinvert;
1528 im->native.loose = re->win->detected.loose_binding;
1529 im->native.data = n;
1530 im->native.func.data = re;
1531 im->native.func.bind = _native_bind_cb;
1532 im->native.func.unbind = _native_unbind_cb;
1533 im->native.func.free = _native_free_cb;
1535 evas_gl_common_image_native_enable(im);
1541 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1545 n = calloc(1, sizeof(Native));
1548 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1550 eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
1554 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1561 im->native.yinvert = 0;
1562 im->native.loose = 0;
1563 im->native.data = n;
1564 im->native.func.data = re;
1565 im->native.func.bind = _native_bind_cb;
1566 im->native.func.unbind = _native_unbind_cb;
1567 im->native.func.free = _native_free_cb;
1568 im->native.target = GL_TEXTURE_2D;
1569 im->native.mipmap = 0;
1571 // FIXME: need to implement mapping sub texture regions
1572 // x, y, w, h for possible texture atlasing
1574 evas_gl_common_image_native_enable(im);
1583 eng_image_native_get(void *data __UNUSED__, void *image)
1585 Evas_GL_Image *im = image;
1587 if (!im) return NULL;
1588 n = im->native.data;
1589 if (!n) return NULL;
1593 #if 0 // filtering disabled
1595 eng_image_draw_filtered(void *data, void *context, void *surface,
1596 void *image, Evas_Filter_Info *filter)
1598 Render_Engine *re = data;
1601 eng_window_use(re->win);
1602 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1603 re->win->gl_context->dc = context;
1605 evas_gl_common_filter_draw(re->win->gl_context, image, filter);
1608 static Filtered_Image *
1609 eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
1611 return evas_gl_common_image_filtered_get(im, key, keylen);
1614 static Filtered_Image *
1615 eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
1617 return evas_gl_common_image_filtered_save(im, fim, key, keylen);
1621 eng_image_filtered_free(void *im, Filtered_Image *fim)
1623 evas_gl_common_image_filtered_free(im, fim);
1630 /////////////////////////////////////////////////////////////////////////
1633 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
1637 re = (Render_Engine *)data;
1638 *error = EVAS_LOAD_ERROR_NONE;
1639 eng_window_use(re->win);
1640 return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
1644 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
1648 re = (Render_Engine *)data;
1649 eng_window_use(re->win);
1650 return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
1654 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
1658 re = (Render_Engine *)data;
1659 eng_window_use(re->win);
1660 return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
1664 eng_image_free(void *data, void *image)
1668 re = (Render_Engine *)data;
1670 eng_window_use(re->win);
1671 evas_gl_common_image_free(image);
1675 eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
1683 if (w) *w = ((Evas_GL_Image *)image)->w;
1684 if (h) *h = ((Evas_GL_Image *)image)->h;
1688 eng_image_size_set(void *data, void *image, int w, int h)
1691 Evas_GL_Image *im = image;
1692 Evas_GL_Image *im_old;
1694 re = (Render_Engine *)data;
1695 if (!im) return NULL;
1696 if (im->native.data)
1702 eng_window_use(re->win);
1703 if ((im->tex) && (im->tex->pt->dyn.img))
1705 evas_gl_common_texture_free(im->tex);
1709 im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
1714 switch (eng_image_colorspace_get(data, image))
1716 case EVAS_COLORSPACE_YCBCR422P601_PL:
1717 case EVAS_COLORSPACE_YCBCR422P709_PL:
1718 case EVAS_COLORSPACE_YCBCR422601_PL:
1719 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1720 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1726 ((int)im_old->im->cache_entry.w == w) &&
1727 ((int)im_old->im->cache_entry.h == h))
1731 im = evas_gl_common_image_new(re->win->gl_context, w, h,
1732 eng_image_alpha_get(data, image),
1733 eng_image_colorspace_get(data, image));
1735 evas_common_load_image_data_from_file(im_old->im);
1736 if (im_old->im->image->data)
1738 evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
1739 evas_common_cpu_end_opt();
1742 evas_gl_common_image_free(im_old);
1745 im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
1750 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
1753 Evas_GL_Image *im = image;
1755 re = (Render_Engine *)data;
1756 if (!image) return NULL;
1757 if (im->native.data) return image;
1758 eng_window_use(re->win);
1759 evas_gl_common_image_dirty(image, x, y, w, h);
1764 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
1770 re = (Render_Engine *)data;
1774 if (err) *err = EVAS_LOAD_ERROR_GENERIC;
1778 if (im->native.data)
1781 if (err) *err = EVAS_LOAD_ERROR_NONE;
1785 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1786 eng_window_use(re->win);
1788 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
1790 *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1792 if (!im->tex->pt->dyn.data)
1794 glsym_eglDestroyImage(re->win->egl_disp, im->tex->pt->dyn.img);
1795 im->tex->pt->dyn.img = NULL;
1796 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1799 if (err) *err = EVAS_LOAD_ERROR_NONE;
1803 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
1805 *image_data = im->tex->pt->dyn.data;
1806 if (err) *err = EVAS_LOAD_ERROR_NONE;
1810 eng_window_use(re->win);
1813 /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
1814 so it is need to add code which check im->im's NULL value*/
1819 if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
1823 error = evas_cache_image_load_data(&im->im->cache_entry);
1824 switch (im->cs.space)
1826 case EVAS_COLORSPACE_ARGB8888:
1829 if (im->references > 1)
1831 Evas_GL_Image *im_new;
1833 im_new = evas_gl_common_image_new_from_copied_data
1834 (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
1836 eng_image_alpha_get(data, image),
1837 eng_image_colorspace_get(data, image));
1841 if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
1844 evas_gl_common_image_free(im);
1848 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1850 *image_data = im->im->image.data;
1852 case EVAS_COLORSPACE_YCBCR422P601_PL:
1853 case EVAS_COLORSPACE_YCBCR422P709_PL:
1854 case EVAS_COLORSPACE_YCBCR422601_PL:
1855 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1856 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1857 *image_data = im->cs.data;
1863 if (err) *err = error;
1868 eng_image_data_put(void *data, void *image, DATA32 *image_data)
1871 Evas_GL_Image *im, *im2;
1873 re = (Render_Engine *)data;
1874 if (!image) return NULL;
1876 if (im->native.data) return image;
1877 eng_window_use(re->win);
1878 if ((im->tex) && (im->tex->pt)
1879 && (im->tex->pt->dyn.data)
1880 && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
1882 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1883 glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1885 if (im->tex->pt->dyn.data == image_data)
1887 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1894 w = im->im->cache_entry.w;
1895 h = im->im->cache_entry.h;
1896 im2 = eng_image_new_from_data(data, w, h, image_data,
1897 eng_image_alpha_get(data, image),
1898 eng_image_colorspace_get(data, image));
1899 if (!im2) return im;
1900 evas_gl_common_image_free(im);
1902 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1906 switch (im->cs.space)
1908 case EVAS_COLORSPACE_ARGB8888:
1909 if (image_data != im->im->image.data)
1913 w = im->im->cache_entry.w;
1914 h = im->im->cache_entry.h;
1915 im2 = eng_image_new_from_data(data, w, h, image_data,
1916 eng_image_alpha_get(data, image),
1917 eng_image_colorspace_get(data, image));
1918 if (!im2) return im;
1919 evas_gl_common_image_free(im);
1923 case EVAS_COLORSPACE_YCBCR422P601_PL:
1924 case EVAS_COLORSPACE_YCBCR422P709_PL:
1925 case EVAS_COLORSPACE_YCBCR422601_PL:
1926 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1927 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1928 if (image_data != im->cs.data)
1932 if (!im->cs.no_free) free(im->cs.data);
1934 im->cs.data = image_data;
1941 /* hmmm - but if we wrote... why bother? */
1942 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1947 eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
1949 Evas_GL_Image *gim = image;
1953 if (gim->native.data) return;
1954 im = (RGBA_Image *)gim->im;
1956 evas_cache_image_preload_data(&im->cache_entry, target);
1960 eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
1962 Evas_GL_Image *gim = image;
1966 if (gim->native.data) return;
1967 im = (RGBA_Image *)gim->im;
1969 evas_cache_image_preload_cancel(&im->cache_entry, target);
1973 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
1977 re = (Render_Engine *)data;
1979 eng_window_use(re->win);
1980 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1981 re->win->gl_context->dc = context;
1982 evas_gl_common_image_draw(re->win->gl_context, image,
1983 src_x, src_y, src_w, src_h,
1984 dst_x, dst_y, dst_w, dst_h,
1989 eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
1991 if (image) evas_gl_common_image_scale_hint_set(image, hint);
1995 eng_image_scale_hint_get(void *data __UNUSED__, void *image)
1997 Evas_GL_Image *gim = image;
1998 if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
1999 return gim->scale_hint;
2003 eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
2005 Evas_GL_Image *gim = image;
2008 re = (Render_Engine *)data;
2010 eng_window_use(re->win);
2011 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2012 re->win->gl_context->dc = context;
2015 // FIXME: nash - you didn't fix this
2018 if ((p[0].x == p[3].x) &&
2019 (p[1].x == p[2].x) &&
2020 (p[0].y == p[1].y) &&
2021 (p[3].y == p[2].y) &&
2022 (p[0].x <= p[1].x) &&
2023 (p[0].y <= p[2].y) &&
2026 (p[1].u == (gim->w << FP)) &&
2028 (p[2].u == (gim->w << FP)) &&
2029 (p[2].v == (gim->h << FP)) &&
2031 (p[3].v == (gim->h << FP)) &&
2032 (p[0].col == 0xffffffff) &&
2033 (p[1].col == 0xffffffff) &&
2034 (p[2].col == 0xffffffff) &&
2035 (p[3].col == 0xffffffff))
2041 dw = (p[2].x >> FP) - dx;
2042 dh = (p[2].y >> FP) - dy;
2043 eng_image_draw(data, context, surface, image,
2044 0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
2048 evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
2054 eng_image_map_surface_new(void *data, int w, int h, int alpha)
2058 re = (Render_Engine *)data;
2059 return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
2063 eng_image_map_surface_free(void *data __UNUSED__, void *surface)
2065 evas_gl_common_image_free(surface);
2069 eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
2071 if (image) evas_gl_common_image_content_hint_set(image, hint);
2075 eng_image_content_hint_get(void *data __UNUSED__, void *image)
2077 Evas_GL_Image *gim = image;
2078 if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
2079 return gim->content_hint;
2083 eng_image_cache_flush(void *data)
2088 re = (Render_Engine *)data;
2090 tmp_size = evas_common_image_get_cache();
2091 evas_common_image_set_cache(0);
2092 evas_common_rgba_image_scalecache_flush();
2093 evas_gl_common_image_cache_flush(re->win->gl_context);
2094 evas_common_image_set_cache(tmp_size);
2098 eng_image_cache_set(void *data, int bytes)
2102 re = (Render_Engine *)data;
2103 evas_common_image_set_cache(bytes);
2104 evas_common_rgba_image_scalecache_size_set(bytes);
2105 evas_gl_common_image_cache_flush(re->win->gl_context);
2109 eng_image_cache_get(void *data __UNUSED__)
2111 return evas_common_image_get_cache();
2115 eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
2117 Evas_GL_Image *im = image;
2119 if ((im->tex) && (im->tex->pt->dyn.img))
2120 *stride = im->tex->pt->dyn.stride;
2122 *stride = im->w * 4;
2126 eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
2130 re = (Render_Engine *)data;
2131 eng_window_use(re->win);
2132 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2133 re->win->gl_context->dc = context;
2135 // FIXME: put im into context so we can free it
2136 static RGBA_Image *im = NULL;
2139 im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
2140 im->cache_entry.w = re->win->w;
2141 im->cache_entry.h = re->win->h;
2142 evas_common_draw_context_font_ext_set(context,
2143 re->win->gl_context,
2144 evas_gl_font_texture_new,
2145 evas_gl_font_texture_free,
2146 evas_gl_font_texture_draw);
2147 evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
2149 evas_common_draw_context_font_ext_set(context,
2158 eng_canvas_alpha_get(void *data, void *info __UNUSED__)
2160 Render_Engine *re = (Render_Engine *)data;
2161 return re->win->alpha;
2165 _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2167 // Also initialize pixel format here as well...
2168 switch(cfg->color_format)
2171 sfc->rt_fmt = GL_RGB;
2172 sfc->rt_internal_fmt = GL_RGB;
2174 case EVAS_GL_RGBA_8:
2175 sfc->rt_fmt = GL_RGBA;
2176 sfc->rt_internal_fmt = GL_RGBA;
2178 case EVAS_GL_RGB_32:
2179 // Only supported on some hw
2180 // Fill it in later...
2181 case EVAS_GL_RGBA_32:
2182 // Only supported on some hw
2183 // Fill it in later...
2185 ERR("Invalid Color Format!");
2189 switch(cfg->depth_bits)
2191 case EVAS_GL_DEPTH_NONE:
2193 case EVAS_GL_DEPTH_BIT_8:
2194 case EVAS_GL_DEPTH_BIT_16:
2195 case EVAS_GL_DEPTH_BIT_24:
2196 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2197 // 24 bit doesn't work... just cover it with 16 for now..
2198 sfc->rb_depth_fmt = GL_DEPTH_COMPONENT16;
2200 sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
2203 case EVAS_GL_DEPTH_BIT_32:
2205 ERR("Unsupported Depth Bits Format!");
2209 switch(cfg->stencil_bits)
2211 case EVAS_GL_STENCIL_NONE:
2213 case EVAS_GL_STENCIL_BIT_1:
2214 case EVAS_GL_STENCIL_BIT_2:
2215 case EVAS_GL_STENCIL_BIT_4:
2216 case EVAS_GL_STENCIL_BIT_8:
2217 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2218 sfc->rb_stencil_fmt = GL_STENCIL_INDEX8;
2220 sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
2223 case EVAS_GL_STENCIL_BIT_16:
2225 ERR("Unsupported Stencil Bits Format!");
2229 // Do Packed Depth24_Stencil8 Later...
2235 _create_rt_buffers(Render_Engine *data __UNUSED__,
2236 Render_Engine_GL_Surface *sfc)
2238 // Render Target texture
2239 glGenTextures(1, &sfc->rt_tex );
2240 glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
2241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2243 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2244 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2245 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
2246 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2247 glBindTexture(GL_TEXTURE_2D, 0);
2249 // Depth RenderBuffer - Create storage here...
2250 if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2252 glGenRenderbuffers(1, &sfc->rb_depth);
2253 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2254 glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
2256 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2259 // Stencil RenderBuffer - Create Storage here...
2260 if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2262 glGenRenderbuffers(1, &sfc->rb_stencil);
2263 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2264 glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
2266 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2273 _attach_fbo_surface(Render_Engine *data __UNUSED__,
2274 Render_Engine_GL_Surface *sfc,
2275 Render_Engine_GL_Context *ctx)
2280 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2281 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2282 GL_TEXTURE_2D, sfc->rt_tex, 0);
2284 // Depth RenderBuffer - Attach it to FBO
2285 if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2287 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2288 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
2289 GL_RENDERBUFFER, sfc->rb_depth);
2290 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2293 // Stencil RenderBuffer - Attach it to FBO
2294 if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2296 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2297 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
2298 GL_RENDERBUFFER, sfc->rb_stencil);
2299 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2302 // Check FBO for completeness
2303 fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2304 if (fb_status != GL_FRAMEBUFFER_COMPLETE)
2306 ERR("FBO not complete!");
2314 eng_gl_surface_create(void *data, void *config, int w, int h)
2317 Render_Engine_GL_Surface *sfc;
2318 Evas_GL_Config *cfg;
2321 sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
2323 if (!sfc) return NULL;
2325 re = (Render_Engine *)data;
2326 cfg = (Evas_GL_Config *)config;
2328 sfc->initialized = 0;
2329 sfc->fbo_attached = 0;
2332 sfc->depth_bits = cfg->depth_bits;
2333 sfc->stencil_bits = cfg->stencil_bits;
2336 sfc->rb_stencil = 0;
2338 // Set the internal format based on the config
2339 if (!_set_internal_config(sfc, cfg))
2341 ERR("Unsupported Format!");
2346 // Create Render Target Texture/Buffers if not initialized
2347 if (!sfc->initialized)
2349 // I'm using evas's original context to create the render target texture
2350 // This is to prevent awkwardness in using native_surface_get() function
2351 // If the rt texture creation is deferred till the context is created and
2352 // make_current called, the user can't call native_surface_get() right
2353 // after the surface is created. hence this is done here using evas' context.
2354 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2355 ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]);
2357 ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2361 ERR("xxxMakeCurrent() failed!");
2366 // Create Render texture
2367 if (!_create_rt_buffers(re, sfc))
2369 ERR("_create_rt_buffers() failed.");
2374 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2375 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2376 EGL_NO_SURFACE, EGL_NO_CONTEXT);
2378 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2382 ERR("xxxMakeCurrent() failed!");
2386 sfc->initialized = 1;
2393 eng_gl_surface_destroy(void *data, void *surface)
2396 Render_Engine_GL_Surface *sfc;
2399 re = (Render_Engine *)data;
2400 sfc = (Render_Engine_GL_Surface*)surface;
2402 // I'm using evas's original context to delete the created fbo and texture
2403 // This is because the fbo/texture was created in the user created context
2404 // but the context can be destroyed already...
2405 // I don't think this is the best way but at least for now this is A WAY.
2406 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2407 ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]);
2409 ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2413 ERR("xxxMakeCurrent() failed!");
2417 // Delete FBO/RBO and Texture here
2418 if (glIsTexture(sfc->rt_tex))
2419 glDeleteTextures(1, &sfc->rt_tex);
2421 if (glIsBuffer(sfc->rb_depth))
2422 glDeleteRenderbuffers(1, &sfc->rb_depth);
2424 if (glIsBuffer(sfc->rb_stencil))
2425 glDeleteRenderbuffers(1, &sfc->rb_stencil);
2428 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2429 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2431 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2435 ERR("xxxMakeCurrent() failed!");
2446 eng_gl_context_create(void *data, void *share_context)
2449 Render_Engine_GL_Context *ctx;
2450 Render_Engine_GL_Context *share_ctx;
2451 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2452 int context_attrs[3];
2455 ctx = calloc(1, sizeof(Render_Engine_GL_Context));
2457 if (!ctx) return NULL;
2459 re = (Render_Engine *)data;
2460 share_ctx = (Render_Engine_GL_Context *)share_context;
2462 // Set the share context to Evas' GL context if share_context is NULL.
2463 // Otherwise set it to the given share_context.
2464 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2466 context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
2467 context_attrs[1] = 2;
2468 context_attrs[2] = EGL_NONE;
2472 ctx->context = eglCreateContext(re->win->egl_disp,
2473 re->win->egl_config,
2474 share_ctx->context, // Share Context
2479 ctx->context = eglCreateContext(re->win->egl_disp,
2480 re->win->egl_config,
2481 re->win->egl_context[0], // Evas' GL Context
2487 ERR("eglCreateContext() fail. code=%#x", eglGetError());
2494 ctx->context = glXCreateContext(re->info->info.display,
2495 re->win->visualinfo,
2496 share_ctx->context, // Share Context
2501 ctx->context = glXCreateContext(re->info->info.display,
2502 re->win->visualinfo,
2503 re->win->context, // Evas' GL Context
2509 ERR("glXCreateContext() fail.");
2514 ctx->initialized = 0;
2515 ctx->context_fbo = 0;
2516 ctx->current_sfc = NULL;
2522 eng_gl_context_destroy(void *data, void *context)
2525 Render_Engine_GL_Context *ctx;
2528 re = (Render_Engine *)data;
2529 ctx = (Render_Engine_GL_Context*)context;
2531 // 1. Do a make current with the given context
2532 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2533 ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0],
2534 re->win->egl_surface[0], ctx->context);
2536 ret = glXMakeCurrent(re->info->info.display, re->win->win,
2541 ERR("xxxMakeCurrent() failed!");
2545 // 2. Delete the FBO
2546 if (glIsBuffer(ctx->context_fbo))
2547 glDeleteBuffers(1, &ctx->context_fbo);
2549 // 3. Destroy the Context
2550 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2551 eglDestroyContext(re->win->egl_disp, ctx->context);
2553 ctx->context = EGL_NO_CONTEXT;
2555 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2556 EGL_NO_SURFACE, EGL_NO_CONTEXT);
2558 glXDestroyContext(re->info->info.display, ctx->context);
2562 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2566 ERR("xxxMakeCurrent() failed!");
2577 eng_gl_make_current(void *data, void *surface, void *context)
2580 Render_Engine_GL_Surface *sfc;
2581 Render_Engine_GL_Context *ctx;
2584 re = (Render_Engine *)data;
2585 sfc = (Render_Engine_GL_Surface*)surface;
2586 ctx = (Render_Engine_GL_Context*)context;
2588 // Unset surface/context
2589 if ((!sfc) || (!ctx))
2591 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2592 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2593 EGL_NO_SURFACE, EGL_NO_CONTEXT);
2595 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2599 ERR("xxxMakeCurrent() failed!");
2603 ctx->current_sfc = NULL;
2604 sfc->current_ctx = NULL;
2605 current_evgl_ctx = NULL;
2609 // Don't do a make current if it's already current
2610 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2611 if ((eglGetCurrentContext() == ctx->context) &&
2612 (eglGetCurrentSurface(EGL_READ) == re->win->egl_surface[0]) &&
2613 (eglGetCurrentSurface(EGL_DRAW) == re->win->egl_surface[0]) )
2616 DBG("Context same\n");
2620 if ((glXGetCurrentContext() == ctx->context) &&
2621 (glXGetCurrentDrawable() == re->win->win) )
2623 DBG("Context same\n");
2629 // Flush remainder of what's in Evas' pipeline
2631 eng_window_use(NULL);
2634 // Set the context current
2635 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2636 ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0],
2637 re->win->egl_surface[0], ctx->context);
2640 ERR("xxxMakeCurrent() failed!");
2644 ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
2647 ERR("xxxMakeCurrent() failed!");
2652 // Create FBO if not already created
2653 if (!ctx->initialized)
2655 glGenFramebuffers(1, &ctx->context_fbo);
2656 ctx->initialized = 1;
2659 // Attach FBO if it hasn't been attached or if surface changed
2660 if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
2662 if (!_attach_fbo_surface(re, sfc, ctx))
2664 ERR("_attach_fbo_surface() failed.");
2668 if (ctx->current_fbo)
2669 // Bind to the previously bound buffer
2670 glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
2673 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2675 sfc->fbo_attached = 1;
2678 // Set the current surface/context
2679 ctx->current_sfc = sfc;
2680 sfc->current_ctx = ctx;
2681 current_evgl_ctx = ctx;
2687 eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
2689 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2690 if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
2691 return dlsym(RTLD_DEFAULT, name);
2693 if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
2694 return dlsym(RTLD_DEFAULT, name);
2699 eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
2702 Render_Engine_GL_Surface *sfc;
2703 Evas_Native_Surface *ns;
2705 re = (Render_Engine *)data;
2706 sfc = (Render_Engine_GL_Surface*)surface;
2707 ns = (Evas_Native_Surface*)native_surface;
2709 ns->type = EVAS_NATIVE_SURFACE_OPENGL;
2710 ns->version = EVAS_NATIVE_SURFACE_VERSION;
2711 ns->data.opengl.texture_id = sfc->rt_tex;
2712 //ns->data.opengl.framebuffer_id = sfc->fbo;
2713 //ns->data.opengl.framebuffer_id = ctx->context_fbo;
2714 ns->data.opengl.x = 0;
2715 ns->data.opengl.y = 0;
2716 ns->data.opengl.w = sfc->w;
2717 ns->data.opengl.h = sfc->h;
2724 evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
2726 Render_Engine_GL_Context *ctx = current_evgl_ctx;
2728 // Take care of BindFramebuffer 0 issue
2733 glBindFramebuffer(target, ctx->context_fbo);
2734 ctx->current_fbo = 0;
2739 glBindFramebuffer(target, framebuffer);
2741 // Save this for restore when doing make current
2743 ctx->current_fbo = framebuffer;
2748 evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
2750 // Add logic to take care when renderbuffer=0
2751 // On a second thought we don't need this
2752 glBindRenderbuffer(target, renderbuffer);
2756 evgl_glClearDepthf(GLclampf depth)
2758 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2759 glClearDepthf(depth);
2761 glClearDepth(depth);
2766 evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
2768 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2769 glDepthRangef(zNear, zFar);
2771 glDepthRange(zNear, zFar);
2776 evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2778 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2779 glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
2783 range[0] = -126; // floor(log2(FLT_MIN))
2784 range[1] = 127; // floor(log2(FLT_MAX))
2788 precision[0] = 24; // floor(-log2((1.0/16777218.0)));
2791 shadertype = precisiontype = 0;
2796 evgl_glReleaseShaderCompiler(void)
2798 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2799 glReleaseShaderCompiler();
2805 evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
2807 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2808 glShaderBinary(n, shaders, binaryformat, binary, length);
2810 // FIXME: need to dlsym/getprocaddress for this
2812 n = binaryformat = length = 0;
2813 shaders = binary = 0;
2820 eng_gl_api_get(void *data)
2824 re = (Render_Engine *)data;
2826 gl_funcs.version = EVAS_GL_API_VERSION;
2828 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
2829 ORD(glActiveTexture);
2830 ORD(glAttachShader);
2831 ORD(glBindAttribLocation);
2835 ORD(glBlendEquation);
2836 ORD(glBlendEquationSeparate);
2838 ORD(glBlendFuncSeparate);
2840 ORD(glBufferSubData);
2841 ORD(glCheckFramebufferStatus);
2844 // ORD(glClearDepthf);
2845 ORD(glClearStencil);
2847 ORD(glCompileShader);
2848 ORD(glCompressedTexImage2D);
2849 ORD(glCompressedTexSubImage2D);
2850 ORD(glCopyTexImage2D);
2851 ORD(glCopyTexSubImage2D);
2852 ORD(glCreateProgram);
2853 ORD(glCreateShader);
2855 ORD(glDeleteBuffers);
2856 ORD(glDeleteFramebuffers);
2857 ORD(glDeleteProgram);
2858 ORD(glDeleteRenderbuffers);
2859 ORD(glDeleteShader);
2860 ORD(glDeleteTextures);
2863 // ORD(glDepthRangef);
2864 ORD(glDetachShader);
2866 ORD(glDisableVertexAttribArray);
2868 ORD(glDrawElements);
2870 ORD(glEnableVertexAttribArray);
2873 ORD(glFramebufferRenderbuffer);
2874 ORD(glFramebufferTexture2D);
2877 ORD(glGenerateMipmap);
2878 ORD(glGenFramebuffers);
2879 ORD(glGenRenderbuffers);
2881 ORD(glGetActiveAttrib);
2882 ORD(glGetActiveUniform);
2883 ORD(glGetAttachedShaders);
2884 ORD(glGetAttribLocation);
2886 ORD(glGetBufferParameteriv);
2889 ORD(glGetFramebufferAttachmentParameteriv);
2891 ORD(glGetProgramiv);
2892 ORD(glGetProgramInfoLog);
2893 ORD(glGetRenderbufferParameteriv);
2895 ORD(glGetShaderInfoLog);
2896 // ORD(glGetShaderPrecisionFormat);
2897 ORD(glGetShaderSource);
2899 ORD(glGetTexParameterfv);
2900 ORD(glGetTexParameteriv);
2901 ORD(glGetUniformfv);
2902 ORD(glGetUniformiv);
2903 ORD(glGetUniformLocation);
2904 ORD(glGetVertexAttribfv);
2905 ORD(glGetVertexAttribiv);
2906 ORD(glGetVertexAttribPointerv);
2910 ORD(glIsFramebuffer);
2912 ORD(glIsRenderbuffer);
2918 ORD(glPolygonOffset);
2920 // ORD(glReleaseShaderCompiler);
2921 ORD(glRenderbufferStorage);
2922 ORD(glSampleCoverage);
2924 // ORD(glShaderBinary);
2925 ORD(glShaderSource);
2927 ORD(glStencilFuncSeparate);
2929 ORD(glStencilMaskSeparate);
2931 ORD(glStencilOpSeparate);
2933 ORD(glTexParameterf);
2934 ORD(glTexParameterfv);
2935 ORD(glTexParameteri);
2936 ORD(glTexParameteriv);
2937 ORD(glTexSubImage2D);
2954 ORD(glUniformMatrix2fv);
2955 ORD(glUniformMatrix3fv);
2956 ORD(glUniformMatrix4fv);
2958 ORD(glValidateProgram);
2959 ORD(glVertexAttrib1f);
2960 ORD(glVertexAttrib1fv);
2961 ORD(glVertexAttrib2f);
2962 ORD(glVertexAttrib2fv);
2963 ORD(glVertexAttrib3f);
2964 ORD(glVertexAttrib3fv);
2965 ORD(glVertexAttrib4f);
2966 ORD(glVertexAttrib4fv);
2967 ORD(glVertexAttribPointer);
2971 // Override functions wrapped by Evas_GL
2972 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
2973 ORD(glBindFramebuffer);
2974 ORD(glBindRenderbuffer);
2976 // GLES2.0 API compat on top of desktop gl
2979 ORD(glGetShaderPrecisionFormat);
2980 ORD(glReleaseShaderCompiler);
2981 ORD(glShaderBinary);
2990 eng_image_load_error_get(void *data __UNUSED__, void *image)
2994 if (!image) return EVAS_LOAD_ERROR_NONE;
2996 return im->im->cache_entry.load_error;
3000 eng_image_animated_get(void *data __UNUSED__, void *image)
3004 if (!image) return EINA_FALSE;
3006 return im->flags.animated;
3010 eng_image_animated_frame_count_get(void *data __UNUSED__, void *image)
3014 if (!image) return -1;
3016 if (!im->flags.animated) return -1;
3017 return im->frame_count;
3020 static Evas_Image_Animated_Loop_Hint
3021 eng_image_animated_loop_type_get(void *data __UNUSED__, void *image)
3025 if (!image) return EVAS_IMAGE_ANIMATED_HINT_NONE;
3027 if (!im->flags.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
3028 return im->loop_hint;
3032 eng_image_animated_loop_count_get(void *data __UNUSED__, void *image)
3036 if (!image) return -1;
3038 if (!im->flags.animated) return -1;
3039 return im->loop_count;
3043 eng_image_animated_frame_duration_get(void *data __UNUSED__, void *image, int start_frame, int frame_num)
3047 if (!image) return -1;
3049 if (!im->flags.animated) return -1;
3050 return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
3054 eng_image_animated_frame_set(void *data __UNUSED__, void *image, int frame_index)
3058 if (!image) return EINA_FALSE;
3060 if (!im->flags.animated) return EINA_FALSE;
3061 if (im->cur_frame == frame_index) return EINA_FALSE;
3063 im->cur_frame = frame_index;
3068 module_open(Evas_Module *em)
3070 static Eina_Bool xrm_inited = EINA_FALSE;
3073 xrm_inited = EINA_TRUE;
3078 if (!evas_gl_common_module_open()) return 0;
3079 /* get whatever engine module we inherit from */
3080 if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
3081 if (_evas_engine_GL_X11_log_dom < 0)
3082 _evas_engine_GL_X11_log_dom = eina_log_domain_register
3083 ("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
3084 if (_evas_engine_GL_X11_log_dom < 0)
3086 EINA_LOG_ERR("Can not create a module log domain.");
3089 /* store it for later use */
3091 /* now to override methods */
3092 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
3096 ORD(canvas_alpha_get);
3099 ORD(output_tile_size_set);
3100 ORD(output_redraws_rect_add);
3101 ORD(output_redraws_rect_del);
3102 ORD(output_redraws_clear);
3103 ORD(output_redraws_next_update_get);
3104 ORD(output_redraws_next_update_push);
3105 ORD(context_cutout_add);
3106 ORD(context_cutout_clear);
3108 ORD(output_idle_flush);
3110 ORD(rectangle_draw);
3112 ORD(polygon_point_add);
3113 ORD(polygon_points_clear);
3117 ORD(image_new_from_data);
3118 ORD(image_new_from_copied_data);
3120 ORD(image_size_get);
3121 ORD(image_size_set);
3122 ORD(image_dirty_region);
3123 ORD(image_data_get);
3124 ORD(image_data_put);
3125 ORD(image_data_preload_request);
3126 ORD(image_data_preload_cancel);
3127 ORD(image_alpha_set);
3128 ORD(image_alpha_get);
3129 ORD(image_border_set);
3130 ORD(image_border_get);
3132 ORD(image_comment_get);
3133 ORD(image_format_get);
3134 ORD(image_colorspace_set);
3135 ORD(image_colorspace_get);
3136 ORD(image_mask_create);
3137 ORD(image_native_set);
3138 ORD(image_native_get);
3139 #if 0 // filtering disabled
3140 ORD(image_draw_filtered);
3141 ORD(image_filtered_get);
3142 ORD(image_filtered_save);
3143 ORD(image_filtered_free);
3148 ORD(image_scale_hint_set);
3149 ORD(image_scale_hint_get);
3150 ORD(image_stride_get);
3152 ORD(image_map_draw);
3153 ORD(image_map_surface_new);
3154 ORD(image_map_surface_free);
3156 ORD(image_content_hint_set);
3157 ORD(image_content_hint_get);
3159 ORD(image_cache_flush);
3160 ORD(image_cache_set);
3161 ORD(image_cache_get);
3163 ORD(gl_surface_create);
3164 ORD(gl_surface_destroy);
3165 ORD(gl_context_create);
3166 ORD(gl_context_destroy);
3167 ORD(gl_make_current);
3168 ORD(gl_proc_address_get);
3169 ORD(gl_native_surface_get);
3173 ORD(image_load_error_get);
3175 /* now advertise out own api */
3176 ORD(image_animated_get);
3177 ORD(image_animated_frame_count_get);
3178 ORD(image_animated_loop_type_get);
3179 ORD(image_animated_loop_count_get);
3180 ORD(image_animated_frame_duration_get);
3181 ORD(image_animated_frame_set);
3183 /* now advertise out own api */
3184 em->functions = (void *)(&func);
3189 module_close(Evas_Module *em __UNUSED__)
3191 eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
3194 XrmDestroyDatabase(xrdb_user.db);
3195 xrdb_user.last_stat = 0;
3196 xrdb_user.last_mtime = 0;
3197 xrdb_user.db = NULL;
3199 evas_gl_common_module_close();
3202 static Evas_Module_Api evas_modapi =
3204 EVAS_MODULE_API_VERSION,
3213 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
3215 #ifndef EVAS_STATIC_BUILD_GL_XLIB
3216 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
3219 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/