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 if (im->tex) evas_gl_common_texture_free(im->tex);
1071 if (!im->cs.no_free) free(im->cs.data);
1073 if (im->im->cache_entry.h > 0)
1075 calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
1084 im->cs.space = cspace;
1087 /////////////////////////////////////////////////////////////////////////
1090 typedef struct _Native Native;
1094 Evas_Native_Surface ns;
1098 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
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.
1110 // why is this the case? does anyone know? has anyone tried it on other gfx
1113 //#define GLX_TEX_PIXMAP_RECREATE 1
1116 _native_bind_cb(void *data, void *image)
1118 Evas_GL_Image *im = image;
1119 Native *n = im->native.data;
1121 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1123 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1126 if (glsym_glEGLImageTargetTexture2DOES)
1128 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
1129 if (eglGetError() != EGL_SUCCESS)
1130 ERR("glEGLImageTargetTexture2DOES() failed.");
1133 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
1136 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1137 Render_Engine *re = data;
1139 if (glsym_glXBindTexImage)
1141 glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
1142 GLX_FRONT_LEFT_EXT, NULL);
1143 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1146 ERR("Try glXBindTexImage on GLX with no support");
1150 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1152 glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
1153 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1160 _native_unbind_cb(void *data, void *image)
1162 Evas_GL_Image *im = image;
1163 Native *n = im->native.data;
1165 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1167 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1170 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1171 Render_Engine *re = data;
1173 if (glsym_glXReleaseTexImage)
1175 glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1176 GLX_FRONT_LEFT_EXT);
1177 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1180 ERR("Try glXReleaseTexImage on GLX with no support");
1184 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1186 glBindTexture(GL_TEXTURE_2D, 0);
1187 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1194 _native_free_cb(void *data, void *image)
1196 Render_Engine *re = data;
1197 Evas_GL_Image *im = image;
1198 Native *n = im->native.data;
1199 uint32_t pmid, texid;
1201 if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1204 eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
1205 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1208 if (glsym_eglDestroyImage)
1210 glsym_eglDestroyImage(re->win->egl_disp,
1212 if (eglGetError() != EGL_SUCCESS)
1213 ERR("eglDestroyImage() failed.");
1216 ERR("Try eglDestroyImage on EGL with no support");
1219 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1222 if (im->native.loose)
1224 if (glsym_glXReleaseTexImage)
1226 glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
1227 GLX_FRONT_LEFT_EXT);
1228 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1231 ERR("Try glXReleaseTexImage on GLX with no support");
1233 if (glsym_glXDestroyPixmap)
1235 glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
1236 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1239 ERR("Try glXDestroyPixmap on GLX with no support");
1245 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1247 texid = n->ns.data.opengl.texture_id;
1248 eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
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;
1259 eng_image_native_set(void *data, void *image, void *native)
1261 Render_Engine *re = (Render_Engine *)data;
1262 Evas_Native_Surface *ns = native;
1263 Evas_GL_Image *im = image, *im2 = NULL;
1267 uint32_t pmid, texid;
1268 unsigned int tex = 0;
1269 unsigned int fbo = 0;
1273 if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
1275 im = evas_gl_common_image_new_from_data(re->win->gl_context,
1279 EVAS_COLORSPACE_ARGB8888);
1287 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1289 vis = ns->data.x11.visual;
1290 pm = ns->data.x11.pixmap;
1291 if (im->native.data)
1293 Evas_Native_Surface *ens = im->native.data;
1294 if ((ens->data.x11.visual == vis) &&
1295 (ens->data.x11.pixmap == pm))
1299 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1301 tex = ns->data.opengl.texture_id;
1302 fbo = ns->data.opengl.framebuffer_id;
1303 if (im->native.data)
1305 Evas_Native_Surface *ens = im->native.data;
1306 if ((ens->data.opengl.texture_id == tex) &&
1307 (ens->data.opengl.framebuffer_id == fbo))
1312 if ((!ns) && (!im->native.data)) return im;
1314 eng_window_use(re->win);
1316 if (im->native.data)
1318 if (im->native.func.free)
1319 im->native.func.free(im->native.func.data, im);
1320 evas_gl_common_image_native_disable(im);
1325 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1328 im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
1329 if (im2 == im) return im;
1332 n = im2->native.data;
1335 evas_gl_common_image_ref(im2);
1336 evas_gl_common_image_free(im);
1341 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1344 im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
1345 if (im2 == im) return im;
1348 n = im2->native.data;
1351 evas_gl_common_image_ref(im2);
1352 evas_gl_common_image_free(im);
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);
1363 if (ns->type == EVAS_NATIVE_SURFACE_X11)
1365 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1368 n = calloc(1, sizeof(Native));
1371 EGLConfig egl_config;
1372 int config_attrs[20];
1373 int num_config, i = 0;
1375 eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
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;
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));
1401 if (glsym_eglCreateImage)
1402 n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
1404 EGL_NATIVE_PIXMAP_KHR,
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);
1424 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1428 unsigned int w, h, depth = 32, border;
1431 // fixme: round trip :(
1432 XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
1433 &w, &h, &border, &depth);
1434 n = calloc(1, sizeof(Native));
1438 unsigned int target = 0;
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
1447 target = GLX_TEXTURE_2D_EXT;
1448 else if ((re->win->depth_cfg[depth].tex_target &
1449 GLX_TEXTURE_RECTANGLE_BIT_EXT))
1451 ERR("rect!!! (not handled)");
1452 target = GLX_TEXTURE_RECTANGLE_EXT;
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;
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;
1473 pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
1474 pixmap_att[i++] = target;
1477 pixmap_att[i++] = 0;
1479 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1482 n->fbc = re->win->depth_cfg[depth].fbc;
1483 if (glsym_glXCreatePixmap)
1484 n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
1489 ERR("Try glXCreatePixmap on GLX with no support");
1492 // printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
1493 // n, pm, w, h, depth, n->glx_pixmap);
1496 ERR("no target :(");
1497 if (glsym_glXQueryDrawable)
1498 glsym_glXQueryDrawable(re->win->disp,
1500 GLX_TEXTURE_TARGET_EXT,
1503 if (target == GLX_TEXTURE_2D_EXT)
1505 im->native.target = GL_TEXTURE_2D;
1506 im->native.mipmap = re->win->depth_cfg[depth].mipmap;
1508 # ifdef GL_TEXTURE_RECTANGLE_ARB
1509 else if (target == GLX_TEXTURE_RECTANGLE_EXT)
1511 im->native.target = GL_TEXTURE_RECTANGLE_ARB;
1512 im->native.mipmap = 0;
1517 im->native.target = GL_TEXTURE_2D;
1518 im->native.mipmap = 0;
1519 ERR("still unknown target");
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;
1532 evas_gl_common_image_native_enable(im);
1538 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1542 n = calloc(1, sizeof(Native));
1545 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1547 eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
1551 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
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;
1568 // FIXME: need to implement mapping sub texture regions
1569 // x, y, w, h for possible texture atlasing
1571 evas_gl_common_image_native_enable(im);
1580 eng_image_native_get(void *data __UNUSED__, void *image)
1582 Evas_GL_Image *im = image;
1584 if (!im) return NULL;
1585 n = im->native.data;
1586 if (!n) return NULL;
1590 #if 0 // filtering disabled
1592 eng_image_draw_filtered(void *data, void *context, void *surface,
1593 void *image, Evas_Filter_Info *filter)
1595 Render_Engine *re = data;
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;
1602 evas_gl_common_filter_draw(re->win->gl_context, image, filter);
1605 static Filtered_Image *
1606 eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
1608 return evas_gl_common_image_filtered_get(im, key, keylen);
1611 static Filtered_Image *
1612 eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
1614 return evas_gl_common_image_filtered_save(im, fim, key, keylen);
1618 eng_image_filtered_free(void *im, Filtered_Image *fim)
1620 evas_gl_common_image_filtered_free(im, fim);
1627 /////////////////////////////////////////////////////////////////////////
1630 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
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);
1641 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
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);
1651 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
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);
1661 eng_image_free(void *data, void *image)
1665 re = (Render_Engine *)data;
1667 eng_window_use(re->win);
1668 evas_gl_common_image_free(image);
1672 eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
1680 if (w) *w = ((Evas_GL_Image *)image)->w;
1681 if (h) *h = ((Evas_GL_Image *)image)->h;
1685 eng_image_size_set(void *data, void *image, int w, int h)
1688 Evas_GL_Image *im = image;
1689 Evas_GL_Image *im_old;
1691 re = (Render_Engine *)data;
1692 if (!im) return NULL;
1693 if (im->native.data)
1699 eng_window_use(re->win);
1700 if ((im->tex) && (im->tex->pt->dyn.img))
1702 evas_gl_common_texture_free(im->tex);
1706 im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
1710 if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1711 (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL))
1714 ((int)im_old->im->cache_entry.w == w) &&
1715 ((int)im_old->im->cache_entry.h == h))
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));
1723 evas_common_load_image_data_from_file(im_old->im);
1724 if (im_old->im->image->data)
1726 evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
1727 evas_common_cpu_end_opt();
1730 evas_gl_common_image_free(im_old);
1733 im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
1738 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
1741 Evas_GL_Image *im = image;
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);
1752 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
1758 re = (Render_Engine *)data;
1762 if (err) *err = EVAS_LOAD_ERROR_GENERIC;
1766 if (im->native.data)
1769 if (err) *err = EVAS_LOAD_ERROR_NONE;
1773 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1774 eng_window_use(re->win);
1776 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img))
1778 *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1780 if (!im->tex->pt->dyn.data)
1782 glsym_eglDestroyImage(re->win->egl_disp, im->tex->pt->dyn.img);
1783 im->tex->pt->dyn.img = NULL;
1784 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1787 if (err) *err = EVAS_LOAD_ERROR_NONE;
1791 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
1793 *image_data = im->tex->pt->dyn.data;
1794 if (err) *err = EVAS_LOAD_ERROR_NONE;
1798 eng_window_use(re->win);
1801 error = evas_cache_image_load_data(&im->im->cache_entry);
1802 switch (im->cs.space)
1804 case EVAS_COLORSPACE_ARGB8888:
1807 if (im->references > 1)
1809 Evas_GL_Image *im_new;
1811 im_new = evas_gl_common_image_new_from_copied_data
1812 (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
1814 eng_image_alpha_get(data, image),
1815 eng_image_colorspace_get(data, image));
1819 if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
1822 evas_gl_common_image_free(im);
1826 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1828 *image_data = im->im->image.data;
1830 case EVAS_COLORSPACE_YCBCR422P601_PL:
1831 case EVAS_COLORSPACE_YCBCR422P709_PL:
1832 *image_data = im->cs.data;
1838 if (err) *err = error;
1843 eng_image_data_put(void *data, void *image, DATA32 *image_data)
1846 Evas_GL_Image *im, *im2;
1848 re = (Render_Engine *)data;
1849 if (!image) return NULL;
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))
1855 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1856 glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
1858 if (im->tex->pt->dyn.data == image_data)
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);
1874 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1878 switch (im->cs.space)
1880 case EVAS_COLORSPACE_ARGB8888:
1881 if (image_data != im->im->image.data)
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);
1895 case EVAS_COLORSPACE_YCBCR422P601_PL:
1896 case EVAS_COLORSPACE_YCBCR422P709_PL:
1897 if (image_data != im->cs.data)
1901 if (!im->cs.no_free) free(im->cs.data);
1903 im->cs.data = image_data;
1910 /* hmmm - but if we wrote... why bother? */
1911 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
1916 eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
1918 Evas_GL_Image *gim = image;
1922 if (gim->native.data) return;
1923 im = (RGBA_Image *)gim->im;
1925 evas_cache_image_preload_data(&im->cache_entry, target);
1929 eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
1931 Evas_GL_Image *gim = image;
1935 if (gim->native.data) return;
1936 im = (RGBA_Image *)gim->im;
1938 evas_cache_image_preload_cancel(&im->cache_entry, target);
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)
1946 re = (Render_Engine *)data;
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,
1958 eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
1960 if (image) evas_gl_common_image_scale_hint_set(image, hint);
1964 eng_image_scale_hint_get(void *data __UNUSED__, void *image)
1966 Evas_GL_Image *gim = image;
1967 if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
1968 return gim->scale_hint;
1972 eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
1974 Evas_GL_Image *gim = image;
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;
1984 // FIXME: nash - you didn't fix this
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) &&
1995 (p[1].u == (gim->w << FP)) &&
1997 (p[2].u == (gim->w << FP)) &&
1998 (p[2].v == (gim->h << FP)) &&
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))
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);
2017 evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
2023 eng_image_map_surface_new(void *data, int w, int h, int alpha)
2027 re = (Render_Engine *)data;
2028 return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
2032 eng_image_map_surface_free(void *data __UNUSED__, void *surface)
2034 evas_gl_common_image_free(surface);
2038 eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
2040 if (image) evas_gl_common_image_content_hint_set(image, hint);
2044 eng_image_content_hint_get(void *data __UNUSED__, void *image)
2046 Evas_GL_Image *gim = image;
2047 if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
2048 return gim->content_hint;
2052 eng_image_cache_flush(void *data)
2057 re = (Render_Engine *)data;
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);
2067 eng_image_cache_set(void *data, int bytes)
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);
2078 eng_image_cache_get(void *data __UNUSED__)
2080 return evas_common_image_get_cache();
2084 eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
2086 Evas_GL_Image *im = image;
2088 if ((im->tex) && (im->tex->pt->dyn.img))
2089 *stride = im->tex->pt->dyn.stride;
2091 *stride = im->w * 4;
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)
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;
2104 // FIXME: put im into context so we can free it
2105 static RGBA_Image *im = NULL;
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,
2118 evas_common_draw_context_font_ext_set(context,
2127 eng_canvas_alpha_get(void *data, void *info __UNUSED__)
2129 Render_Engine *re = (Render_Engine *)data;
2130 return re->win->alpha;
2134 _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2136 // Also initialize pixel format here as well...
2137 switch(cfg->color_format)
2140 sfc->rt_fmt = GL_RGB;
2141 sfc->rt_internal_fmt = GL_RGB;
2143 case EVAS_GL_RGBA_8:
2144 sfc->rt_fmt = GL_RGBA;
2145 sfc->rt_internal_fmt = GL_RGBA;
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...
2154 ERR("Invalid Color Format!");
2158 switch(cfg->depth_bits)
2160 case EVAS_GL_DEPTH_NONE:
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;
2169 sfc->rb_depth_fmt = GL_DEPTH_COMPONENT;
2172 case EVAS_GL_DEPTH_BIT_32:
2174 ERR("Unsupported Depth Bits Format!");
2178 switch(cfg->stencil_bits)
2180 case EVAS_GL_STENCIL_NONE:
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;
2189 sfc->rb_stencil_fmt = GL_STENCIL_INDEX;
2192 case EVAS_GL_STENCIL_BIT_16:
2194 ERR("Unsupported Stencil Bits Format!");
2198 // Do Packed Depth24_Stencil8 Later...
2204 _create_rt_buffers(Render_Engine *data __UNUSED__,
2205 Render_Engine_GL_Surface *sfc)
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);
2218 // Depth RenderBuffer - Create storage here...
2219 if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
2221 glGenRenderbuffers(1, &sfc->rb_depth);
2222 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
2223 glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
2225 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2228 // Stencil RenderBuffer - Create Storage here...
2229 if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
2231 glGenRenderbuffers(1, &sfc->rb_stencil);
2232 glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
2233 glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
2235 glBindRenderbuffer(GL_RENDERBUFFER, 0);
2242 _attach_fbo_surface(Render_Engine *data __UNUSED__,
2243 Render_Engine_GL_Surface *sfc,
2244 Render_Engine_GL_Context *ctx)
2249 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2250 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2251 GL_TEXTURE_2D, sfc->rt_tex, 0);
2253 // Depth RenderBuffer - Attach it to FBO
2254 if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
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);
2262 // Stencil RenderBuffer - Attach it to FBO
2263 if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
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);
2271 // Check FBO for completeness
2272 fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2273 if (fb_status != GL_FRAMEBUFFER_COMPLETE)
2275 ERR("FBO not complete!");
2283 eng_gl_surface_create(void *data, void *config, int w, int h)
2286 Render_Engine_GL_Surface *sfc;
2287 Evas_GL_Config *cfg;
2290 sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
2292 if (!sfc) return NULL;
2294 re = (Render_Engine *)data;
2295 cfg = (Evas_GL_Config *)config;
2297 sfc->initialized = 0;
2298 sfc->fbo_attached = 0;
2301 sfc->depth_bits = cfg->depth_bits;
2302 sfc->stencil_bits = cfg->stencil_bits;
2305 sfc->rb_stencil = 0;
2307 // Set the internal format based on the config
2308 if (!_set_internal_config(sfc, cfg))
2310 ERR("Unsupported Format!");
2315 // Create Render Target Texture/Buffers if not initialized
2316 if (!sfc->initialized)
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]);
2326 ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2330 ERR("xxxMakeCurrent() failed!");
2335 // Create Render texture
2336 if (!_create_rt_buffers(re, sfc))
2338 ERR("_create_rt_buffers() failed.");
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);
2347 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2351 ERR("xxxMakeCurrent() failed!");
2355 sfc->initialized = 1;
2362 eng_gl_surface_destroy(void *data, void *surface)
2365 Render_Engine_GL_Surface *sfc;
2368 re = (Render_Engine *)data;
2369 sfc = (Render_Engine_GL_Surface*)surface;
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]);
2378 ret = glXMakeCurrent(re->info->info.display, re->win->win, re->win->context);
2382 ERR("xxxMakeCurrent() failed!");
2386 // Delete FBO/RBO and Texture here
2387 if (glIsTexture(sfc->rt_tex))
2388 glDeleteTextures(1, &sfc->rt_tex);
2390 if (glIsBuffer(sfc->rb_depth))
2391 glDeleteRenderbuffers(1, &sfc->rb_depth);
2393 if (glIsBuffer(sfc->rb_stencil))
2394 glDeleteRenderbuffers(1, &sfc->rb_stencil);
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);
2400 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2404 ERR("xxxMakeCurrent() failed!");
2415 eng_gl_context_create(void *data, void *share_context)
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];
2424 ctx = calloc(1, sizeof(Render_Engine_GL_Context));
2426 if (!ctx) return NULL;
2428 re = (Render_Engine *)data;
2429 share_ctx = (Render_Engine_GL_Context *)share_context;
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)
2435 context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
2436 context_attrs[1] = 2;
2437 context_attrs[2] = EGL_NONE;
2441 ctx->context = eglCreateContext(re->win->egl_disp,
2442 re->win->egl_config,
2443 share_ctx->context, // Share Context
2448 ctx->context = eglCreateContext(re->win->egl_disp,
2449 re->win->egl_config,
2450 re->win->egl_context[0], // Evas' GL Context
2456 ERR("eglCreateContext() fail. code=%#x", eglGetError());
2463 ctx->context = glXCreateContext(re->info->info.display,
2464 re->win->visualinfo,
2465 share_ctx->context, // Share Context
2470 ctx->context = glXCreateContext(re->info->info.display,
2471 re->win->visualinfo,
2472 re->win->context, // Evas' GL Context
2478 ERR("glXCreateContext() fail.");
2483 ctx->initialized = 0;
2484 ctx->context_fbo = 0;
2485 ctx->current_sfc = NULL;
2491 eng_gl_context_destroy(void *data, void *context)
2494 Render_Engine_GL_Context *ctx;
2497 re = (Render_Engine *)data;
2498 ctx = (Render_Engine_GL_Context*)context;
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);
2505 ret = glXMakeCurrent(re->info->info.display, re->win->win,
2510 ERR("xxxMakeCurrent() failed!");
2514 // 2. Delete the FBO
2515 if (glIsBuffer(ctx->context_fbo))
2516 glDeleteBuffers(1, &ctx->context_fbo);
2518 // 3. Destroy the Context
2519 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2520 eglDestroyContext(re->win->egl_disp, ctx->context);
2522 ctx->context = EGL_NO_CONTEXT;
2524 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
2525 EGL_NO_SURFACE, EGL_NO_CONTEXT);
2527 glXDestroyContext(re->info->info.display, ctx->context);
2531 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2535 ERR("xxxMakeCurrent() failed!");
2546 eng_gl_make_current(void *data, void *surface, void *context)
2549 Render_Engine_GL_Surface *sfc;
2550 Render_Engine_GL_Context *ctx;
2553 re = (Render_Engine *)data;
2554 sfc = (Render_Engine_GL_Surface*)surface;
2555 ctx = (Render_Engine_GL_Context*)context;
2557 // Unset surface/context
2558 if ((!sfc) || (!ctx))
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);
2564 ret = glXMakeCurrent(re->info->info.display, None, NULL);
2568 ERR("xxxMakeCurrent() failed!");
2572 ctx->current_sfc = NULL;
2573 sfc->current_ctx = NULL;
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]) )
2584 DBG("Context same\n");
2588 if ((glXGetCurrentContext() == ctx->context) &&
2589 (glXGetCurrentDrawable() == re->win->win) )
2591 DBG("Context same\n");
2597 // Flush remainder of what's in Evas' pipeline
2599 eng_window_use(NULL);
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);
2608 ERR("xxxMakeCurrent() failed!");
2612 ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
2615 ERR("xxxMakeCurrent() failed!");
2620 // Create FBO if not already created
2621 if (!ctx->initialized)
2623 glGenFramebuffers(1, &ctx->context_fbo);
2624 ctx->initialized = 1;
2627 // Attach FBO if it hasn't been attached or if surface changed
2628 if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
2630 if (!_attach_fbo_surface(re, sfc, ctx))
2632 ERR("_attach_fbo_surface() failed.");
2636 if (ctx->current_fbo)
2637 // Bind to the previously bound buffer
2638 glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
2641 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
2644 // Set the current surface/context
2645 ctx->current_sfc = sfc;
2646 sfc->current_ctx = ctx;
2648 current_evgl_ctx = ctx;
2654 eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
2656 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2657 if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
2658 return dlsym(RTLD_DEFAULT, name);
2660 if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
2661 return dlsym(RTLD_DEFAULT, name);
2666 eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
2669 Render_Engine_GL_Surface *sfc;
2670 Evas_Native_Surface *ns;
2672 re = (Render_Engine *)data;
2673 sfc = (Render_Engine_GL_Surface*)surface;
2674 ns = (Evas_Native_Surface*)native_surface;
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;
2691 evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
2693 Render_Engine_GL_Context *ctx = current_evgl_ctx;
2695 // Take care of BindFramebuffer 0 issue
2700 glBindFramebuffer(target, ctx->context_fbo);
2701 ctx->current_fbo = 0;
2706 glBindFramebuffer(target, framebuffer);
2708 // Save this for restore when doing make current
2710 ctx->current_fbo = framebuffer;
2715 evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
2717 // Add logic to take care when renderbuffer=0
2718 // On a second thought we don't need this
2719 glBindRenderbuffer(target, renderbuffer);
2723 evgl_glClearDepthf(GLclampf depth)
2725 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2726 glClearDepthf(depth);
2728 glClearDepth(depth);
2733 evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
2735 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2736 glDepthRangef(zNear, zFar);
2738 glDepthRange(zNear, zFar);
2743 evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2745 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2746 glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
2750 range[0] = -126; // floor(log2(FLT_MIN))
2751 range[1] = 127; // floor(log2(FLT_MAX))
2755 precision[0] = 24; // floor(-log2((1.0/16777218.0)));
2758 shadertype = precisiontype = 0;
2763 evgl_glReleaseShaderCompiler(void)
2765 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2766 glReleaseShaderCompiler();
2772 evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
2774 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2775 glShaderBinary(n, shaders, binaryformat, binary, length);
2777 // FIXME: need to dlsym/getprocaddress for this
2779 n = binaryformat = length = 0;
2780 shaders = binary = 0;
2787 eng_gl_api_get(void *data)
2791 re = (Render_Engine *)data;
2793 gl_funcs.version = EVAS_GL_API_VERSION;
2795 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
2796 ORD(glActiveTexture);
2797 ORD(glAttachShader);
2798 ORD(glBindAttribLocation);
2802 ORD(glBlendEquation);
2803 ORD(glBlendEquationSeparate);
2805 ORD(glBlendFuncSeparate);
2807 ORD(glBufferSubData);
2808 ORD(glCheckFramebufferStatus);
2811 // ORD(glClearDepthf);
2812 ORD(glClearStencil);
2814 ORD(glCompileShader);
2815 ORD(glCompressedTexImage2D);
2816 ORD(glCompressedTexSubImage2D);
2817 ORD(glCopyTexImage2D);
2818 ORD(glCopyTexSubImage2D);
2819 ORD(glCreateProgram);
2820 ORD(glCreateShader);
2822 ORD(glDeleteBuffers);
2823 ORD(glDeleteFramebuffers);
2824 ORD(glDeleteProgram);
2825 ORD(glDeleteRenderbuffers);
2826 ORD(glDeleteShader);
2827 ORD(glDeleteTextures);
2830 // ORD(glDepthRangef);
2831 ORD(glDetachShader);
2833 ORD(glDisableVertexAttribArray);
2835 ORD(glDrawElements);
2837 ORD(glEnableVertexAttribArray);
2840 ORD(glFramebufferRenderbuffer);
2841 ORD(glFramebufferTexture2D);
2844 ORD(glGenerateMipmap);
2845 ORD(glGenFramebuffers);
2846 ORD(glGenRenderbuffers);
2848 ORD(glGetActiveAttrib);
2849 ORD(glGetActiveUniform);
2850 ORD(glGetAttachedShaders);
2851 ORD(glGetAttribLocation);
2853 ORD(glGetBufferParameteriv);
2856 ORD(glGetFramebufferAttachmentParameteriv);
2858 ORD(glGetProgramiv);
2859 ORD(glGetProgramInfoLog);
2860 ORD(glGetRenderbufferParameteriv);
2862 ORD(glGetShaderInfoLog);
2863 // ORD(glGetShaderPrecisionFormat);
2864 ORD(glGetShaderSource);
2866 ORD(glGetTexParameterfv);
2867 ORD(glGetTexParameteriv);
2868 ORD(glGetUniformfv);
2869 ORD(glGetUniformiv);
2870 ORD(glGetUniformLocation);
2871 ORD(glGetVertexAttribfv);
2872 ORD(glGetVertexAttribiv);
2873 ORD(glGetVertexAttribPointerv);
2877 ORD(glIsFramebuffer);
2879 ORD(glIsRenderbuffer);
2885 ORD(glPolygonOffset);
2887 // ORD(glReleaseShaderCompiler);
2888 ORD(glRenderbufferStorage);
2889 ORD(glSampleCoverage);
2891 // ORD(glShaderBinary);
2892 ORD(glShaderSource);
2894 ORD(glStencilFuncSeparate);
2896 ORD(glStencilMaskSeparate);
2898 ORD(glStencilOpSeparate);
2900 ORD(glTexParameterf);
2901 ORD(glTexParameterfv);
2902 ORD(glTexParameteri);
2903 ORD(glTexParameteriv);
2904 ORD(glTexSubImage2D);
2921 ORD(glUniformMatrix2fv);
2922 ORD(glUniformMatrix3fv);
2923 ORD(glUniformMatrix4fv);
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);
2938 // Override functions wrapped by Evas_GL
2939 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
2940 ORD(glBindFramebuffer);
2941 ORD(glBindRenderbuffer);
2943 // GLES2.0 API compat on top of desktop gl
2946 ORD(glGetShaderPrecisionFormat);
2947 ORD(glReleaseShaderCompiler);
2948 ORD(glShaderBinary);
2957 eng_image_load_error_get(void *data __UNUSED__, void *image)
2961 if (!image) return EVAS_LOAD_ERROR_NONE;
2963 return im->im->cache_entry.load_error;
2967 eng_image_animated_get(void *data __UNUSED__, void *image)
2971 if (!image) return EINA_FALSE;
2973 return im->flags.animated;
2977 eng_image_animated_frame_count_get(void *data __UNUSED__, void *image)
2981 if (!image) return -1;
2983 if (!im->flags.animated) return -1;
2984 return im->frame_count;
2987 static Evas_Image_Animated_Loop_Hint
2988 eng_image_animated_loop_type_get(void *data __UNUSED__, void *image)
2992 if (!image) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2994 if (!im->flags.animated) return EVAS_IMAGE_ANIMATED_HINT_NONE;
2995 return im->loop_hint;
2999 eng_image_animated_loop_count_get(void *data __UNUSED__, void *image)
3003 if (!image) return -1;
3005 if (!im->flags.animated) return -1;
3006 return im->loop_count;
3010 eng_image_animated_frame_duration_get(void *data __UNUSED__, void *image, int start_frame, int frame_num)
3014 if (!image) return -1;
3016 if (!im->flags.animated) return -1;
3017 return evas_common_load_rgba_image_frame_duration_from_file(im, start_frame, frame_num);
3021 eng_image_animated_frame_set(void *data __UNUSED__, void *image, int frame_index)
3025 if (!image) return EINA_FALSE;
3027 if (!im->flags.animated) return EINA_FALSE;
3028 if (im->cur_frame == frame_index) return EINA_FALSE;
3030 im->cur_frame = frame_index;
3035 module_open(Evas_Module *em)
3037 static Eina_Bool xrm_inited = EINA_FALSE;
3040 xrm_inited = EINA_TRUE;
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)
3053 EINA_LOG_ERR("Can not create a module log domain.");
3056 /* store it for later use */
3058 /* now to override methods */
3059 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
3063 ORD(canvas_alpha_get);
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);
3075 ORD(output_idle_flush);
3077 ORD(rectangle_draw);
3079 ORD(polygon_point_add);
3080 ORD(polygon_points_clear);
3084 ORD(image_new_from_data);
3085 ORD(image_new_from_copied_data);
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);
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);
3115 ORD(image_scale_hint_set);
3116 ORD(image_scale_hint_get);
3117 ORD(image_stride_get);
3119 ORD(image_map_draw);
3120 ORD(image_map_surface_new);
3121 ORD(image_map_surface_free);
3123 ORD(image_content_hint_set);
3124 ORD(image_content_hint_get);
3126 ORD(image_cache_flush);
3127 ORD(image_cache_set);
3128 ORD(image_cache_get);
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);
3140 ORD(image_load_error_get);
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);
3150 /* now advertise out own api */
3151 em->functions = (void *)(&func);
3156 module_close(Evas_Module *em __UNUSED__)
3158 eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
3161 XrmDestroyDatabase(xrdb_user.db);
3162 xrdb_user.last_stat = 0;
3163 xrdb_user.last_mtime = 0;
3164 xrdb_user.db = NULL;
3166 evas_gl_common_module_close();
3169 static Evas_Module_Api evas_modapi =
3171 EVAS_MODULE_API_VERSION,
3180 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
3182 #ifndef EVAS_STATIC_BUILD_GL_XLIB
3183 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
3186 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/