diff options
author | Cedric BAIL <c.bail@partner.samsung.com> | 2014-07-04 13:51:32 +0200 |
---|---|---|
committer | Cedric BAIL <c.bail@partner.samsung.com> | 2014-07-04 15:11:22 +0200 |
commit | 14d22c5a080bebf16a3698ce3358c46c0bc9029a (patch) | |
tree | 02c2987f9f15e7a984bbde5390df7560f9dc2a28 | |
parent | 289b3691b049c20441e5f10606461e9e2a7aad6a (diff) | |
download | efl-devs/cedric/refactoring_engine.tar.gz |
evas: migrate GL_X11 to use more infrastructure of software_generic.devs/cedric/refactoring_engine
-rw-r--r-- | src/modules/evas/engines/gl_x11/evas_engine.c | 1374 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_x11/evas_engine.h | 92 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_x11/evas_x_main.c | 312 |
3 files changed, 781 insertions, 997 deletions
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index f26903d430..5838e1e2c1 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -23,43 +23,14 @@ #define EVAS_GL_UPDATE_TILE_SIZE 16 -enum { - MERGE_BOUNDING, - MERGE_FULL -}; - -static int partial_render_debug = -1; -static int partial_rect_union_mode = -1; -static int swap_buffer_debug_mode = -1; -static int swap_buffer_debug = 0; - -enum { - MODE_FULL, - MODE_COPY, - MODE_DOUBLE, - MODE_TRIPLE, - MODE_QUADRUPLE -}; +static int safe_native = -1; typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Tilebuf_Rect *rects; - Tilebuf_Rect *rects_prev[4]; - Eina_Inlist *cur_rect; - - Outbuf *win; - Evas_Engine_Info_GL_X11 *info; - Evas *evas; - Tilebuf *tb; - int end; - int mode; - int w, h; - int vsync; - int lost_back; - int prev_age; - int frame_cnt; + Render_Engine_Software_Generic generic; + Eina_Bool evgl_initted : 1; struct { @@ -72,9 +43,14 @@ struct _Render_Engine E3D_Renderer *renderer_3d; }; +const char *debug_dir; +int swap_buffer_debug_mode = -1; +int swap_buffer_debug = 0; +int partial_render_debug = -1; +int extn_have_buffer_age = 1; + static int initted = 0; static int gl_wins = 0; -static int extn_have_buffer_age = 1; #ifdef GL_GLES static int extn_have_y_inverted = 1; #endif @@ -87,8 +63,6 @@ typedef int (*glsym_func_int) (); typedef unsigned int (*glsym_func_uint) (); typedef const char *(*glsym_func_const_char_ptr) (); -static Eina_Bool eng_preload_make_current(void *data, void *doit); - #ifdef GL_GLES #ifndef EGL_NATIVE_PIXMAP_KHR @@ -195,11 +169,11 @@ evgl_eng_display_get(void *data) } #ifdef GL_GLES - if (re->win) - return (void*)re->win->egl_disp; + if (re->generic.ob) + return (void*)re->generic.ob->egl_disp; #else - if (re->info) - return (void*)re->info->info.display; + if (re->generic.ob->info) + return (void*)re->generic.ob->info->info.display; #endif else return NULL; @@ -218,11 +192,11 @@ evgl_eng_evas_surface_get(void *data) } #ifdef GL_GLES - if (re->win) - return (void*)re->win->egl_surface[0]; + if (re->generic.ob) + return (void*)re->generic.ob->egl_surface[0]; #else - if (re->win) - return (void*)re->win->win; + if (re->generic.ob) + return (void*)re->generic.ob->win; #endif else return NULL; @@ -245,7 +219,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) #ifdef GL_GLES EGLContext ctx = (EGLContext)context; EGLSurface sfc = (EGLSurface)surface; - EGLDisplay dpy = re->win->egl_disp; //eglGetCurrentDisplay(); + EGLDisplay dpy = re->generic.ob->egl_disp; //eglGetCurrentDisplay(); if ((!context) && (!surface)) { @@ -284,7 +258,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) if ((!context) && (!surface)) { - ret = glXMakeCurrent(re->info->info.display, None, NULL); + ret = glXMakeCurrent(re->generic.ob->info->info.display, None, NULL); if (!ret) { ERR("glXMakeCurrent() failed!"); @@ -301,7 +275,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) if (flush) eng_window_use(NULL); // Do a make current - ret = glXMakeCurrent(re->info->info.display, sfc, ctx); + ret = glXMakeCurrent(re->generic.ob->info->info.display, sfc, ctx); if (!ret) { @@ -340,8 +314,8 @@ evgl_eng_native_window_create(void *data) attr.do_not_propagate_mask = NoEventMask; attr.event_mask = 0; - win = XCreateWindow(re->info->info.display, - DefaultRootWindow(re->info->info.display), + win = XCreateWindow(re->generic.ob->info->info.display, + DefaultRootWindow(re->generic.ob->info->info.display), 0, 0, 2, 2, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackingStore | CWOverrideRedirect | @@ -376,7 +350,7 @@ evgl_eng_native_window_destroy(void *data, void *native_window) return 0; } - XDestroyWindow(re->info->info.display, (Window)native_window); + XDestroyWindow(re->generic.ob->info->info.display, (Window)native_window); native_window = NULL; @@ -402,8 +376,8 @@ evgl_eng_window_surface_create(void *data, void *native_window) EGLSurface surface = EGL_NO_SURFACE; // Create resource surface for EGL - surface = eglCreateWindowSurface(re->win->egl_disp, - re->win->egl_config, + surface = eglCreateWindowSurface(re->generic.ob->egl_disp, + re->generic.ob->egl_config, (EGLNativeWindowType)native_window, NULL); if (!surface) @@ -418,7 +392,7 @@ evgl_eng_window_surface_create(void *data, void *native_window) // We don't need to create new one for GLX Window surface; - surface = re->win->win; + surface = re->generic.ob->win; return (void *)surface; */ @@ -446,7 +420,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface) return 0; } - eglDestroySurface(re->win->egl_disp, (EGLSurface)surface); + eglDestroySurface(re->generic.ob->egl_disp, (EGLSurface)surface); #endif return 1; @@ -476,16 +450,16 @@ evgl_eng_context_create(void *data, void *share_ctx) // Share context already assumes that it's sharing with evas' context if (share_ctx) { - context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, + context = eglCreateContext(re->generic.ob->egl_disp, + re->generic.ob->egl_config, (EGLContext)share_ctx, context_attrs); } else { - context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, - re->win->egl_context[0], // Evas' GL Context + context = eglCreateContext(re->generic.ob->egl_disp, + re->generic.ob->egl_config, + re->generic.ob->egl_context[0], // Evas' GL Context context_attrs); } @@ -502,16 +476,16 @@ evgl_eng_context_create(void *data, void *share_ctx) // Share context already assumes that it's sharing with evas' context if (share_ctx) { - context = glXCreateContext(re->info->info.display, - re->win->visualinfo, + context = glXCreateContext(re->generic.ob->info->info.display, + re->generic.ob->visualinfo, (GLXContext)share_ctx, 1); } else { - context = glXCreateContext(re->info->info.display, - re->win->visualinfo, - re->win->context, // Evas' GL Context + context = glXCreateContext(re->generic.ob->info->info.display, + re->generic.ob->visualinfo, + re->generic.ob->context, // Evas' GL Context 1); } @@ -539,9 +513,9 @@ evgl_eng_context_destroy(void *data, void *context) } #ifdef GL_GLES - eglDestroyContext(re->win->egl_disp, (EGLContext)context); + eglDestroyContext(re->generic.ob->egl_disp, (EGLContext)context); #else - glXDestroyContext(re->info->info.display, (GLXContext)context); + glXDestroyContext(re->generic.ob->info->info.display, (GLXContext)context); #endif return 1; @@ -560,10 +534,10 @@ evgl_eng_string_get(void *data) } #ifdef GL_GLES - return eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); + return eglQueryString(re->generic.ob->egl_disp, EGL_EXTENSIONS); #else - return glXQueryExtensionsString(re->info->info.display, - re->info->info.screen); + return glXQueryExtensionsString(re->generic.ob->info->info.display, + re->generic.ob->info->info.screen); #endif } @@ -591,8 +565,8 @@ evgl_eng_rotation_angle_get(void *data) return 0; } - if ((re->win) && (re->win->gl_context)) - return re->win->gl_context->rot; + if ((re->generic.ob) && (re->generic.ob->gl_context)) + return re->generic.ob->gl_context->rot; else { ERR("Unable to retrieve rotation angle."); @@ -712,7 +686,7 @@ gl_extn_veto(Render_Engine *re) { const char *str = NULL; #ifdef GL_GLES - str = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); + str = eglQueryString(re->generic.ob->egl_disp, EGL_EXTENSIONS); if (str) { if (getenv("EVAS_GL_INFO")) @@ -756,8 +730,8 @@ gl_extn_veto(Render_Engine *re) extn_have_buffer_age = 0; } #else - str = glXQueryExtensionsString(re->info->info.display, - re->info->info.screen); + str = glXQueryExtensionsString(re->generic.ob->info->info.display, + re->generic.ob->info->info.screen); if (str) { if (getenv("EVAS_GL_INFO")) @@ -833,25 +807,12 @@ eng_info_free(Evas *eo_e EINA_UNUSED, void *info) free(in); } -static int -_re_wincheck(Render_Engine *re) -{ - if (re->win->surf) return 1; - eng_window_resurf(re->win); - re->lost_back = 1; - if (!re->win->surf) - { - ERR("GL engine can't re-create window surface!"); - } - return 0; -} - static void _re_winfree(Render_Engine *re) { - if (!re->win->surf) return; - evas_gl_preload_render_relax(eng_preload_make_current, re); - eng_window_unsurf(re->win); + if (!re->generic.ob->surf) return; + evas_gl_preload_render_relax(eng_preload_make_current, re->generic.ob); + eng_window_unsurf(re->generic.ob); } static int @@ -869,11 +830,113 @@ eng_setup(Evas *eo_e, void *in) Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); Render_Engine *re; Evas_Engine_Info_GL_X11 *info; + Render_Engine_Swap_Mode swap_mode = MODE_FULL; const char *s; info = (Evas_Engine_Info_GL_X11 *)in; + + if ((s = getenv("EVAS_GL_SWAP_MODE"))) + { + if ((!strcasecmp(s, "full")) || + (!strcasecmp(s, "f"))) + swap_mode = MODE_FULL; + else if ((!strcasecmp(s, "copy")) || + (!strcasecmp(s, "c"))) + swap_mode = MODE_COPY; + else if ((!strcasecmp(s, "double")) || + (!strcasecmp(s, "d")) || + (!strcasecmp(s, "2"))) + swap_mode = MODE_DOUBLE; + else if ((!strcasecmp(s, "triple")) || + (!strcasecmp(s, "t")) || + (!strcasecmp(s, "3"))) + swap_mode = MODE_TRIPLE; + else if ((!strcasecmp(s, "quadruple")) || + (!strcasecmp(s, "q")) || + (!strcasecmp(s, "4"))) + swap_mode = MODE_QUADRUPLE; + } + else + { +// in most gl implementations - egl and glx here that we care about the TEND +// to either swap or copy backbuffer and front buffer, but strictly that is +// not true. technically backbuffer content is totally undefined after a swap +// and thus you MUST re-render all of it, thus MODE_FULL + swap_mode = MODE_FULL; +// BUT... reality is that lmost every implementation copies or swaps so +// triple buffer mode can be used as it is a superset of double buffer and +// copy (though using those explicitly is more efficient). so let's play with +// triple buffer mdoe as a default and see. +// re->mode = MODE_TRIPLE; +// XXX: note - the above seems to break on some older intel chipsets and +// drivers. it seems we CANT depend on backbuffer staying around. bugger! + switch (info->swap_mode) + { + case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL: + swap_mode = MODE_FULL; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY: + swap_mode = MODE_COPY; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE: + swap_mode = MODE_DOUBLE; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE: + swap_mode = MODE_TRIPLE; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE: + swap_mode = MODE_QUADRUPLE; + break; + default: + swap_mode = MODE_AUTO; + break; + } + } + + if (safe_native == -1) + { + s = getenv("EVAS_GL_SAFE_NATIVE"); + safe_native = 0; + if (s) safe_native = atoi(s); + else + { + s = (const char *)glGetString(GL_RENDERER); + if (s) + { + if (strstr(s, "PowerVR SGX 540") || + strstr(s, "Mali-400 MP")) + safe_native = 1; + } + } + } + + // Set this env var to dump files every frame + // Or set the global var in gdb to 1|0 to turn it on and off + if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS")) + swap_buffer_debug = 1; + + if (swap_buffer_debug_mode == -1) + { + if ( +#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) + (getuid() == geteuid()) && +#endif + ((debug_dir = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))) + { + int stat; + // Create a directory with 0775 permission + stat = mkdir(debug_dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1; + } + else + swap_buffer_debug_mode = 0; + } + + if (!e->engine.data.output) { + Outbuf *ob; + Render_Engine_Merge_Mode merge_mode = MERGE_BOUNDING; #ifdef GL_GLES #else int eb, evb; @@ -882,29 +945,56 @@ eng_setup(Evas *eo_e, void *in) #endif re = calloc(1, sizeof(Render_Engine)); if (!re) return 0; - re->info = info; - re->evas = (Evas *)e; - re->w = e->output.w; - re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, - re->info->info.drawable, - re->info->info.screen, - re->info->info.visual, - re->info->info.colormap, - re->info->info.depth, - re->w, - re->h, - re->info->indirect, - re->info->info.destination_alpha, - re->info->info.rotation); - if (!re->win) + ob = eng_window_new(info, eo_e, + info->info.display, + info->info.drawable, + info->info.screen, + info->info.visual, + info->info.colormap, + info->info.depth, + e->output.w, e->output.h, + info->indirect, + info->info.destination_alpha, + info->info.rotation, + swap_mode); + if (!ob) { free(re); return 0; } + + if (!evas_render_engine_software_generic_init(&re->generic, ob, + eng_outbuf_swap_mode, + eng_outbuf_get_rot, + eng_outbuf_reconfigure, + eng_outbuf_region_first_rect, + eng_outbuf_new_region_for_update, + eng_outbuf_push_updated_region, + eng_outbuf_push_free_region_for_update, + NULL, + eng_outbuf_flush, + eng_window_free, + e->output.w, e->output.h)) + { + free(re); + return 0; + } + e->engine.data.output = re; gl_wins++; + if ((s = getenv("EVAS_GL_PARTIAL_MERGE"))) + { + if ((!strcmp(s, "bounding")) || + (!strcmp(s, "b"))) + merge_mode = MERGE_BOUNDING; + else if ((!strcmp(s, "full")) || + (!strcmp(s, "f"))) + merge_mode = MERGE_FULL; + } + + evas_render_engine_software_generic_merge_mode_set(&re->generic, merge_mode); + if (!initted) { gl_symbols(); @@ -929,111 +1019,60 @@ eng_setup(Evas *eo_e, void *in) else { re = e->engine.data.output; - if (re->win && _re_wincheck(re)) + if (re->generic.ob && _re_wincheck(re->generic.ob)) { - if ((re->info->info.display != re->win->disp) || - (re->info->info.drawable != re->win->win) || - (re->info->info.screen != re->win->screen) || - (re->info->info.visual != re->win->visual) || - (re->info->info.colormap != re->win->colormap) || - (re->info->info.depth != re->win->depth) || - (re->info->info.destination_alpha != re->win->alpha)) + if ((re->generic.ob->info->info.display != re->generic.ob->disp) || + (re->generic.ob->info->info.drawable != re->generic.ob->win) || + (re->generic.ob->info->info.screen != re->generic.ob->screen) || + (re->generic.ob->info->info.visual != re->generic.ob->visual) || + (re->generic.ob->info->info.colormap != re->generic.ob->colormap) || + (re->generic.ob->info->info.depth != re->generic.ob->depth) || + (re->generic.ob->info->info.destination_alpha != re->generic.ob->alpha)) { - re->win->gl_context->references++; - eng_window_free(re->win); + Outbuf *ob; + + re->generic.ob->gl_context->references++; + eng_window_free(re->generic.ob); + re->generic.ob = NULL; gl_wins--; - re->w = e->output.w; - re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, - re->info->info.drawable, - re->info->info.screen, - re->info->info.visual, - re->info->info.colormap, - re->info->info.depth, - re->w, - re->h, - re->info->indirect, - re->info->info.destination_alpha, - re->info->info.rotation); - eng_window_use(re->win); - if (re->win) + ob = eng_window_new(info, eo_e, + re->generic.ob->info->info.display, + re->generic.ob->info->info.drawable, + re->generic.ob->info->info.screen, + re->generic.ob->info->info.visual, + re->generic.ob->info->info.colormap, + re->generic.ob->info->info.depth, + e->output.w, e->output.h, + re->generic.ob->info->indirect, + re->generic.ob->info->info.destination_alpha, + re->generic.ob->info->info.rotation, + swap_mode); + eng_window_use(ob); + if (ob) { + evas_render_engine_software_generic_update(&re->generic, ob, + e->output.w, e->output.h); + gl_wins++; - re->win->gl_context->references--; + re->generic.ob->gl_context->references--; } } - else if ((re->win->w != e->output.w) || - (re->win->h != e->output.h) || - (re->info->info.rotation != re->win->rot)) + else if ((re->generic.ob->w != e->output.w) || + (re->generic.ob->h != e->output.h) || + (re->generic.ob->info->info.rotation != re->generic.ob->rot)) { - re->w = e->output.w; - re->h = e->output.h; - re->win->w = e->output.w; - re->win->h = e->output.h; - re->win->rot = re->info->info.rotation; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); + eng_outbuf_reconfigure(re->generic.ob, e->output.w, e->output.h, re->generic.ob->info->info.rotation, 0); + if (re->generic.tb) + evas_common_tilebuf_free(re->generic.tb); + re->generic.tb = evas_common_tilebuf_new(e->output.w, e->output.h); + if (re->generic.tb) + evas_common_tilebuf_set_tile_size(re->generic.tb, + TILESIZE, TILESIZE); } } } - if ((s = getenv("EVAS_GL_SWAP_MODE"))) - { - if ((!strcasecmp(s, "full")) || - (!strcasecmp(s, "f"))) - re->mode = MODE_FULL; - else if ((!strcasecmp(s, "copy")) || - (!strcasecmp(s, "c"))) - re->mode = MODE_COPY; - else if ((!strcasecmp(s, "double")) || - (!strcasecmp(s, "d")) || - (!strcasecmp(s, "2"))) - re->mode = MODE_DOUBLE; - else if ((!strcasecmp(s, "triple")) || - (!strcasecmp(s, "t")) || - (!strcasecmp(s, "3"))) - re->mode = MODE_TRIPLE; - else if ((!strcasecmp(s, "quadruple")) || - (!strcasecmp(s, "q")) || - (!strcasecmp(s, "4"))) - re->mode = MODE_QUADRUPLE; - } - else - { -// in most gl implementations - egl and glx here that we care about the TEND -// to either swap or copy backbuffer and front buffer, but strictly that is -// not true. technically backbuffer content is totally undefined after a swap -// and thus you MUST re-render all of it, thus MODE_FULL - re->mode = MODE_FULL; -// BUT... reality is that lmost every implementation copies or swaps so -// triple buffer mode can be used as it is a superset of double buffer and -// copy (though using those explicitly is more efficient). so let's play with -// triple buffer mdoe as a default and see. -// re->mode = MODE_TRIPLE; -// XXX: note - the above seems to break on some older intel chipsets and -// drivers. it seems we CANT depend on backbuffer staying around. bugger! - switch (info->swap_mode) - { - case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL: - re->mode = MODE_FULL; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY: - re->mode = MODE_COPY; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE: - re->mode = MODE_DOUBLE; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE: - re->mode = MODE_TRIPLE; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE: - re->mode = MODE_QUADRUPLE; - break; - default: - break; - } - } - if (!re->win) + if (!re->generic.ob) { free(re); return 0; @@ -1041,35 +1080,21 @@ eng_setup(Evas *eo_e, void *in) if (!e->engine.data.output) { - if (re->win) + if (re->generic.ob) { - eng_window_free(re->win); + eng_window_free(re->generic.ob); gl_wins--; } free(re); return 0; } - if (re->tb) evas_common_tilebuf_free(re->tb); - re->tb = evas_common_tilebuf_new(re->win->w, re->win->h); - if (!re->tb) - { - if (re->win) - { - eng_window_free(re->win); - gl_wins--; - } - free(re); - return 0; - } - evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE); - evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE); + + evas_render_engine_software_generic_tile_strict_set(&re->generic, EINA_TRUE); if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output); - eng_window_use(re->win); - - re->vsync = 0; + eng_window_use(re->generic.ob); return 1; } @@ -1083,43 +1108,35 @@ eng_output_free(void *data) if (re) { - evas_gl_preload_render_relax(eng_preload_make_current, re); +#ifndef GL_GLES + Display *disp = re->generic.ob->disp; + Window win = re->generic.ob->win; +#endif + + evas_gl_preload_render_relax(eng_preload_make_current, re->generic.ob); #if 0 #ifdef GL_GLES // Destroy the resource surface // Only required for EGL case if (re->surface) - eglDestroySurface(re->win->egl_disp, re->surface); + eglDestroySurface(re->generic.ob->egl_disp, re->surface); #endif // Destroy the resource context _destroy_internal_context(re, context); #endif - if (re->win) - { - if (gl_wins == 1) evgl_engine_shutdown(re); -#ifdef GL_GLES - eng_window_free(re->win); -#else - Display *disp = re->win->disp; - Window win = re->win->win; - eng_window_free(re->win); - if (glsym_glXReleaseBuffersMESA) - glsym_glXReleaseBuffersMESA(disp, win); + if (gl_wins == 1) evgl_engine_shutdown(re); + + evas_render_engine_software_generic_clean(&re->generic); + +#ifndef GL_GLES + if (glsym_glXReleaseBuffersMESA) + glsym_glXReleaseBuffersMESA(disp, win); #endif - gl_wins--; - } - - evas_common_tilebuf_free(re->tb); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); - if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]); - if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]); - if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]); - if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]); + gl_wins--; - free(re); } if ((initted == 1) && (gl_wins == 0)) @@ -1131,164 +1148,23 @@ eng_output_free(void *data) } } -static void -eng_output_resize(void *data, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - re->win->w = w; - re->win->h = h; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot); - evas_common_tilebuf_free(re->tb); - re->tb = evas_common_tilebuf_new(w, h); - if (re->tb) - { - evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE); - evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE); - } -} - -static void -eng_output_tile_size_set(void *data, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_common_tilebuf_set_tile_size(re->tb, w, h); -} - -static void -eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); - evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); -} - -static void -eng_output_redraws_rect_del(void *data, int x, int y, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); -} - -static void -eng_output_redraws_clear(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_common_tilebuf_clear(re->tb); -// INF("GL: finish update cycle!"); -} - -static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4) -{ - Tilebuf_Rect *r, *rects; - Evas_Point p1, p2; - - if (r1) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r) - { - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - } - if (r2) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r) - { - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - } - if (r3) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r) - { - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - } - if (r4) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r4), r) - { - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - } - rects = evas_common_tilebuf_get_render_rects(tb); - - if (partial_rect_union_mode == -1) - { - const char *s = getenv("EVAS_GL_PARTIAL_MERGE"); - if (s) - { - if ((!strcmp(s, "bounding")) || - (!strcmp(s, "b"))) - partial_rect_union_mode = MERGE_BOUNDING; - else if ((!strcmp(s, "full")) || - (!strcmp(s, "f"))) - partial_rect_union_mode = MERGE_FULL; - } - else - partial_rect_union_mode = MERGE_BOUNDING; - } - if (partial_rect_union_mode == MERGE_BOUNDING) - { -// bounding box -> make a bounding box single region update of all regions. -// yes we could try and be smart and figure out size of regions, how far -// apart etc. etc. to try and figure out an optimal "set". this is a tradeoff -// between multiple update regions to render and total pixels to render. - if (rects) - { - p1.x = rects->x; p1.y = rects->y; - p2.x = rects->x + rects->w; p2.y = rects->y + rects->h; - EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) - { - if (r->x < p1.x) p1.x = r->x; - if (r->y < p1.y) p1.y = r->y; - if ((r->x + r->w) > p2.x) p2.x = r->x + r->w; - if ((r->y + r->h) > p2.y) p2.y = r->y + r->h; - } - evas_common_tilebuf_free_render_rects(rects); - rects = calloc(1, sizeof(Tilebuf_Rect)); - if (rects) - { - rects->x = p1.x; - rects->y = p1.y; - rects->w = p2.x - p1.x; - rects->h = p2.y - p1.y; - } - } - } - evas_common_tilebuf_clear(tb); - return rects; -} - /* vsync games - not for now though */ #define VSYNC_TO_SCREEN 1 -static Eina_Bool +Eina_Bool eng_preload_make_current(void *data, void *doit) { - Render_Engine *re = data; + Outbuf *ob = data; if (doit) { #ifdef GL_GLES - if (!eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0])) + if (!eglMakeCurrent(ob->egl_disp, ob->egl_surface[0], ob->egl_surface[0], ob->egl_context[0])) return EINA_FALSE; #else - if (!glXMakeCurrent(re->info->info.display, re->win->win, re->win->context)) + if (!glXMakeCurrent(ob->info->info.display, ob->win, ob->context)) { - ERR("glXMakeCurrent(%p, 0x%x, %p) failed", re->info->info.display, (unsigned int)re->win->win, (void *)re->win->context); + ERR("glXMakeCurrent(%p, 0x%x, %p) failed", ob->info->info.display, (unsigned int)ob->win, (void *)ob->context); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); return EINA_FALSE; } @@ -1297,12 +1173,12 @@ eng_preload_make_current(void *data, void *doit) else { #ifdef GL_GLES - if (!eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) + if (!eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) return EINA_FALSE; #else - if (!glXMakeCurrent(re->info->info.display, None, NULL)) + if (!glXMakeCurrent(ob->info->info.display, None, NULL)) { - ERR("glXMakeCurrent(%p, None, NULL) failed", re->info->info.display); + ERR("glXMakeCurrent(%p, None, NULL) failed", ob->info->info.display); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); return EINA_FALSE; } @@ -1311,435 +1187,6 @@ eng_preload_make_current(void *data, void *doit) return EINA_TRUE; } -static void * -eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) -{ - Render_Engine *re; - Tilebuf_Rect *rect; - Eina_Bool first_rect = EINA_FALSE; - -#define CLEAR_PREV_RECTS(x) \ - do { \ - if (re->rects_prev[x]) \ - evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \ - re->rects_prev[x] = NULL; \ - } while (0) - - re = (Render_Engine *)data; - /* get the upate rect surface - return engine data as dummy */ - if (re->end) - { - re->end = 0; - return NULL; - } - if (!re->rects) - { - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - if (re->rects) - { - if (re->info->swap_mode == EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO) - { - if (extn_have_buffer_age) - { -#ifdef GL_GLES - EGLint age = 0; - - if (!eglQuerySurface(re->win->egl_disp, - re->win->egl_surface[0], - EGL_BUFFER_AGE_EXT, &age)) - age = 0; -#else - unsigned int age = 0; - - if (glsym_glXQueryDrawable) - { - if (re->win->glxwin) - glsym_glXQueryDrawable(re->win->disp, - re->win->glxwin, - GLX_BACK_BUFFER_AGE_EXT, - &age); - else - glsym_glXQueryDrawable(re->win->disp, - re->win->win, - GLX_BACK_BUFFER_AGE_EXT, - &age); - } -#endif - if (age == 1) re->mode = MODE_COPY; - else if (age == 2) re->mode = MODE_DOUBLE; - else if (age == 3) re->mode = MODE_TRIPLE; - else if (age == 4) re->mode = MODE_QUADRUPLE; - else re->mode = MODE_FULL; - if ((int)age != re->prev_age) re->mode = MODE_FULL; - re->prev_age = age; - } - } - if ((re->lost_back) || (re->mode == MODE_FULL)) - { - /* if we lost our backbuffer since the last frame redraw all */ - re->lost_back = 0; - evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->win->w, re->win->h); - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - } - /* ensure we get rid of previous rect lists we dont need if mode - * changed/is appropriate */ - evas_common_tilebuf_clear(re->tb); - CLEAR_PREV_RECTS(3); - re->rects_prev[3] = re->rects_prev[2]; - re->rects_prev[2] = re->rects_prev[1]; - re->rects_prev[1] = re->rects_prev[0]; - re->rects_prev[0] = re->rects; - re->rects = NULL; - switch (re->mode) - { - case MODE_FULL: - case MODE_COPY: // no prev rects needed - re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL); - break; - case MODE_DOUBLE: // double mode - only 1 level of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); - break; - case MODE_TRIPLE: // triple mode - 2 levels of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL); - break; - case MODE_QUADRUPLE: // keep all - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]); - break; - default: - break; - } - first_rect = EINA_TRUE; - } - evas_common_tilebuf_clear(re->tb); - re->cur_rect = EINA_INLIST_GET(re->rects); - } - if (!re->cur_rect) return NULL; - rect = (Tilebuf_Rect *)re->cur_rect; - if (re->rects) - { - re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; - - switch (re->mode) - { - case MODE_COPY: - case MODE_DOUBLE: - case MODE_TRIPLE: - case MODE_QUADRUPLE: - rect = (Tilebuf_Rect *)re->cur_rect; - *x = rect->x; - *y = rect->y; - *w = rect->w; - *h = rect->h; - *cx = rect->x; - *cy = rect->y; - *cw = rect->w; - *ch = rect->h; - re->cur_rect = re->cur_rect->next; - re->win->gl_context->master_clip.enabled = EINA_TRUE; - re->win->gl_context->master_clip.x = rect->x; - re->win->gl_context->master_clip.y = rect->y; - re->win->gl_context->master_clip.w = rect->w; - re->win->gl_context->master_clip.h = rect->h; - break; - case MODE_FULL: - re->cur_rect = NULL; - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = re->win->w; - if (h) *h = re->win->h; - if (cx) *cx = 0; - if (cy) *cy = 0; - if (cw) *cw = re->win->w; - if (ch) *ch = re->win->h; - re->win->gl_context->master_clip.enabled = EINA_FALSE; - break; - default: - break; - } - if (first_rect) - { - evas_gl_preload_render_lock(eng_preload_make_current, re); -#ifdef GL_GLES - // dont need to for egl - eng_window_use() can check for other ctxt's -#else - eng_window_use(NULL); -#endif - eng_window_use(re->win); - if (!_re_wincheck(re)) return NULL; - - evas_gl_common_context_flush(re->win->gl_context); - evas_gl_common_context_newframe(re->win->gl_context); - if (partial_render_debug == -1) - { - if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1; - else partial_render_debug = 0; - } - if (partial_render_debug == 1) - { - glClearColor(0.2, 0.5, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - } - } - if (!re->cur_rect) - { - re->end = 1; - } - return re->win->gl_context->def_surface; - } - return NULL; -} - -static int safe_native = -1; - -static void -eng_output_redraws_next_update_push(void *data, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; - /* put back update surface.. in this case just unflag redraw */ - if (!_re_wincheck(re)) return; - re->win->draw.drew = 1; - evas_gl_common_context_flush(re->win->gl_context); - if (safe_native == -1) - { - const char *s = getenv("EVAS_GL_SAFE_NATIVE"); - safe_native = 0; - if (s) safe_native = atoi(s); - else - { - s = (const char *)glGetString(GL_RENDERER); - if (s) - { - if (strstr(s, "PowerVR SGX 540") || - strstr(s, "Mali-400 MP")) - safe_native = 1; - } - } - } -#ifdef GL_GLES - // this is needed to make sure all previous rendering is flushed to - // buffers/surfaces - // previous rendering should be done and swapped -//xx if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE); -// if (eglGetError() != EGL_SUCCESS) -// { -// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n"); -// } -#else - // previous rendering should be done and swapped -//xx if (!safe_native) glXWaitX(); -#endif -} - -static void -eng_output_flush(void *data, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - static char *dname = NULL; - - re = (Render_Engine *)data; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; - - if (!_re_wincheck(re)) goto end; - if (!re->win->draw.drew) goto end; - - re->win->draw.drew = 0; - eng_window_use(re->win); - evas_gl_common_context_done(re->win->gl_context); - - // Save contents of the framebuffer to a file - if (swap_buffer_debug_mode == -1) - { - if ( -#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) - (getuid() == geteuid()) && -#endif - ((dname = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))) - { - int stat; - // Create a directory with 0775 permission - stat = mkdir(dname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1; - } - else - swap_buffer_debug_mode = 0; - } - - if (swap_buffer_debug_mode == 1) - { - // Set this env var to dump files every frame - // Or set the global var in gdb to 1|0 to turn it on and off - if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS")) - swap_buffer_debug = 1; - - if (swap_buffer_debug) - { - char fname[100]; - int ret = 0; - snprintf(fname, sizeof(fname), "%p", (void*)re->win); - - ret = evas_gl_common_buffer_dump(re->win->gl_context, - (const char*)dname, - (const char*)fname, - re->frame_cnt, - NULL); - if (!ret) swap_buffer_debug_mode = 0; - } - } - -#ifdef GL_GLES - if (!re->vsync) - { - if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1); - else eglSwapInterval(re->win->egl_disp, 0); - re->vsync = 1; - } - if (re->info->callback.pre_swap) - { - re->info->callback.pre_swap(re->info->callback.data, re->evas); - } - if ((glsym_eglSwapBuffersWithDamage) && (re->mode != MODE_FULL)) - { - EGLint num = 0, *rects = NULL, i = 0; - Tilebuf_Rect *r; - - // if partial swaps can be done use re->rects - num = eina_inlist_count(EINA_INLIST_GET(re->rects)); - if (num > 0) - { - rects = alloca(sizeof(EGLint) * 4 * num); - EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r) - { - int gw, gh; - - gw = re->win->gl_context->w; - gh = re->win->gl_context->h; - switch (re->win->rot) - { - case 0: - rects[i + 0] = r->x; - rects[i + 1] = gh - (r->y + r->h); - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - case 90: - rects[i + 0] = r->y; - rects[i + 1] = r->x; - rects[i + 2] = r->h; - rects[i + 3] = r->w; - break; - case 180: - rects[i + 0] = gw - (r->x + r->w); - rects[i + 1] = r->y; - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - case 270: - rects[i + 0] = gh - (r->y + r->h); - rects[i + 1] = gw - (r->x + r->w); - rects[i + 2] = r->h; - rects[i + 3] = r->w; - break; - default: - rects[i + 0] = r->x; - rects[i + 1] = gh - (r->y + r->h); - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - } - i += 4; - } - glsym_eglSwapBuffersWithDamage(re->win->egl_disp, - re->win->egl_surface[0], - rects, num); - } - } - else - eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]); - -//xx if (!safe_native) eglWaitGL(); - if (re->info->callback.post_swap) - { - re->info->callback.post_swap(re->info->callback.data, re->evas); - } -// if (eglGetError() != EGL_SUCCESS) -// { -// printf("Error: eglSwapBuffers() fail.\n"); -// } -#else -#ifdef VSYNC_TO_SCREEN - if (re->info->vsync) - { - if (glsym_glXSwapIntervalEXT) - { - if (!re->vsync) - { - if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1); - else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0); - re->vsync = 1; - } - } - else if (glsym_glXSwapIntervalSGI) - { - if (!re->vsync) - { - if (re->info->vsync) glsym_glXSwapIntervalSGI(1); - else glsym_glXSwapIntervalSGI(0); - re->vsync = 1; - } - } - else - { - if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync)) - { - unsigned int rc; - - glsym_glXGetVideoSync(&rc); - glsym_glXWaitVideoSync(1, 0, &rc); - } - } - } -#endif - if (re->info->callback.pre_swap) - { - re->info->callback.pre_swap(re->info->callback.data, re->evas); - } - // XXX: if partial swaps can be done use re->rects -// measure(0, "swap"); - glXSwapBuffers(re->win->disp, re->win->win); -// measure(1, "swap"); - if (re->info->callback.post_swap) - { - re->info->callback.post_swap(re->info->callback.data, re->evas); - } -#endif - // clear out rects after swap as we may use them during swap - if (re->rects) - { - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = NULL; - } - - re->frame_cnt++; - - end: - evas_gl_preload_render_unlock(eng_preload_make_current, re); -} - -static void -eng_output_idle_flush(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - (void) re; -} - static void eng_output_dump(void *data) { @@ -1748,40 +1195,20 @@ eng_output_dump(void *data) re = (Render_Engine *)data; evas_common_image_image_all_unload(); evas_common_font_font_all_unload(); - evas_gl_common_image_all_unload(re->win->gl_context); + evas_gl_common_image_all_unload(re->generic.ob->gl_context); _re_winfree(re); } static void -eng_context_cutout_add(void *data EINA_UNUSED, void *context, int x, int y, int w, int h) -{ -// Render_Engine *re; -// -// re = (Render_Engine *)data; -// re->win->gl_context->dc = context; - evas_common_draw_context_add_cutout(context, x, y, w, h); -} - -static void -eng_context_cutout_clear(void *data EINA_UNUSED, void *context) -{ -// Render_Engine *re; -// -// re = (Render_Engine *)data; -// re->win->gl_context->dc = context; - evas_common_draw_context_clear_cutouts(context); -} - -static void eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_rect_draw(re->generic.ob->gl_context, x, y, w, h); } static void @@ -1790,10 +1217,10 @@ eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2 Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_line_draw(re->win->gl_context, p1x, p1y, p2x, p2y); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_line_draw(re->generic.ob->gl_context, p1x, p1y, p2x, p2y); } static void * @@ -1822,10 +1249,10 @@ eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *pol Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_poly_draw(re->generic.ob->gl_context, polygon, x, y); } static int @@ -1867,7 +1294,7 @@ eng_image_alpha_set(void *data, void *image, int has_alpha) im->alpha = has_alpha; return image; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt->dyn.img)) { im->alpha = has_alpha; @@ -1962,7 +1389,7 @@ eng_image_colorspace_set(void *data, void *image, Evas_Colorspace cspace) if (im->native.data) return; /* FIXME: can move to gl_common */ if (im->cs.space == cspace) return; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_alloc_ensure(im); evas_cache_image_colorspace(&im->im->cache_entry, cspace); switch (cspace) @@ -2054,7 +1481,7 @@ _native_bind_cb(void *data, void *image) if (glsym_glXBindTexImage) { - glsym_glXBindTexImage(re->win->disp, n->glx_pixmap, + glsym_glXBindTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT, NULL); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2088,7 +1515,7 @@ _native_unbind_cb(void *data, void *image) if (glsym_glXReleaseTexImage) { - glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap, + glsym_glXReleaseTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2117,13 +1544,13 @@ _native_free_cb(void *data, void *image) if (n->ns.type == EVAS_NATIVE_SURFACE_X11) { pmid = n->pixmap; - eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_del(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); #ifdef GL_GLES if (n->egl_surface) { if (glsym_eglDestroyImage) { - glsym_eglDestroyImage(re->win->egl_disp, + glsym_eglDestroyImage(re->generic.ob->egl_disp, n->egl_surface); if (eglGetError() != EGL_SUCCESS) ERR("eglDestroyImage() failed."); @@ -2139,7 +1566,7 @@ _native_free_cb(void *data, void *image) { if (glsym_glXReleaseTexImage) { - glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap, + glsym_glXReleaseTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2148,7 +1575,7 @@ _native_free_cb(void *data, void *image) } if (glsym_glXDestroyPixmap) { - glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap); + glsym_glXDestroyPixmap(re->generic.ob->disp, n->glx_pixmap); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } else @@ -2161,7 +1588,7 @@ _native_free_cb(void *data, void *image) else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) { texid = n->ns.data.opengl.texture_id; - eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im); + eina_hash_del(re->generic.ob->gl_context->shared->native_tex_hash, &texid, im); } im->native.data = NULL; im->native.func.data = NULL; @@ -2188,7 +1615,7 @@ eng_image_native_set(void *data, void *image, void *native) { if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL)) { - im = evas_gl_common_image_new_from_data(re->win->gl_context, + im = evas_gl_common_image_new_from_data(re->generic.ob->gl_context, ns->data.opengl.w, ns->data.opengl.h, NULL, 1, @@ -2227,7 +1654,7 @@ eng_image_native_set(void *data, void *image, void *native) } if ((!ns) && (!im->native.data)) return im; - eng_window_use(re->win); + eng_window_use(re->generic.ob); if (im->native.data) { @@ -2241,7 +1668,7 @@ eng_image_native_set(void *data, void *image, void *native) if (ns->type == EVAS_NATIVE_SURFACE_X11) { pmid = pm; - im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid); + im2 = eina_hash_find(re->generic.ob->gl_context->shared->native_pm_hash, &pmid); if (im2 == im) return im; if (im2) { @@ -2257,7 +1684,7 @@ eng_image_native_set(void *data, void *image, void *native) else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL) { texid = tex; - im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid); + im2 = eina_hash_find(re->generic.ob->gl_context->shared->native_tex_hash, &texid); if (im2 == im) return im; if (im2) { @@ -2271,7 +1698,7 @@ eng_image_native_set(void *data, void *image, void *native) } } - im2 = evas_gl_common_image_new_from_data(re->win->gl_context, + im2 = evas_gl_common_image_new_from_data(re->generic.ob->gl_context, im->w, im->h, NULL, im->alpha, EVAS_COLORSPACE_ARGB8888); evas_gl_common_image_free(im); @@ -2290,7 +1717,7 @@ eng_image_native_set(void *data, void *image, void *native) int num_config, i = 0; int yinvert = 1; - eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); // assume 32bit pixmap! :) config_attrs[i++] = EGL_RED_SIZE; @@ -2311,14 +1738,14 @@ eng_image_native_set(void *data, void *image, void *native) config_attrs[i++] = EGL_PIXMAP_BIT; config_attrs[i++] = EGL_NONE; - if (!eglChooseConfig(re->win->egl_disp, config_attrs, + if (!eglChooseConfig(re->generic.ob->egl_disp, config_attrs, &egl_config, 1, &num_config)) ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config); else { int val; if (extn_have_y_inverted && - eglGetConfigAttrib(re->win->egl_disp, egl_config, + eglGetConfigAttrib(re->generic.ob->egl_disp, egl_config, EGL_Y_INVERTED_NOK, &val)) yinvert = val; } @@ -2327,7 +1754,7 @@ eng_image_native_set(void *data, void *image, void *native) n->pixmap = pm; n->visual = vis; if (glsym_eglCreateImage) - n->egl_surface = glsym_eglCreateImage(re->win->egl_disp, + n->egl_surface = glsym_eglCreateImage(re->generic.ob->egl_disp, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (void *)pm, @@ -2357,7 +1784,7 @@ eng_image_native_set(void *data, void *image, void *native) Window wdummy; // fixme: round trip :( - XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy, + XGetGeometry(re->generic.ob->disp, pm, &wdummy, &dummy, &dummy, &w, &h, &border, &depth); if (depth <= 32) { @@ -2405,8 +1832,8 @@ eng_image_native_set(void *data, void *image, void *native) config_attrs[i++] = 0; - configs = glXChooseFBConfig(re->win->disp, - re->win->screen, + configs = glXChooseFBConfig(re->generic.ob->disp, + re->generic.ob->screen, config_attrs, &num); if (configs) @@ -2420,42 +1847,42 @@ eng_image_native_set(void *data, void *image, void *native) { XVisualInfo *vi; - vi = glXGetVisualFromFBConfig(re->win->disp, configs[j]); + vi = glXGetVisualFromFBConfig(re->generic.ob->disp, configs[j]); if (!vi) continue; if (vi->depth != (int)depth) continue; XFree(vi); - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BUFFER_SIZE, &val); if (val != (int) depth) continue; } - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_DRAWABLE_TYPE, &val); if (!(val & GLX_PIXMAP_BIT)) continue; tex_format = GLX_TEXTURE_FORMAT_RGB_EXT; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_ALPHA_SIZE, &val); if ((depth == 32) && (!val)) continue; if (val > 0) { - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val); if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT; } else { - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val); if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT; } - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_Y_INVERTED_EXT, &val); yinvert = val; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val); tex_target = val; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val); mipmap = val; n->fbc = configs[j]; @@ -2470,7 +1897,7 @@ eng_image_native_set(void *data, void *image, void *native) XFree(configs); } - eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); if ((tex_target & GLX_TEXTURE_2D_BIT_EXT)) target = GLX_TEXTURE_2D_EXT; else if ((tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT)) @@ -2503,7 +1930,7 @@ eng_image_native_set(void *data, void *image, void *native) n->pixmap = pm; n->visual = vis; if (glsym_glXCreatePixmap) - n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp, + n->glx_pixmap = glsym_glXCreatePixmap(re->generic.ob->disp, n->fbc, n->pixmap, pixmap_att); @@ -2517,7 +1944,7 @@ eng_image_native_set(void *data, void *image, void *native) { ERR("no target :("); if (glsym_glXQueryDrawable) - glsym_glXQueryDrawable(re->win->disp, + glsym_glXQueryDrawable(re->generic.ob->disp, n->pixmap, GLX_TEXTURE_TARGET_EXT, &target); @@ -2544,7 +1971,7 @@ eng_image_native_set(void *data, void *image, void *native) else ERR("GLX Pixmap create fail"); im->native.yinvert = yinvert; - im->native.loose = re->win->detected.loose_binding; + im->native.loose = re->generic.ob->detected.loose_binding; im->native.data = n; im->native.func.data = re; im->native.func.bind = _native_bind_cb; @@ -2567,7 +1994,7 @@ eng_image_native_set(void *data, void *image, void *native) { memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface)); - eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_tex_hash, &texid, im); n->pixmap = 0; n->visual = 0; @@ -2622,8 +2049,8 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); - return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error); + eng_window_use(re->generic.ob); + return evas_gl_common_image_load(re->generic.ob->gl_context, file, key, lo, error); } static void * @@ -2633,8 +2060,8 @@ eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); - return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error); + eng_window_use(re->generic.ob); + return evas_gl_common_image_mmap(re->generic.ob->gl_context, f, key, lo, error); } static void * @@ -2643,8 +2070,8 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace); + eng_window_use(re->generic.ob); + return evas_gl_common_image_new_from_data(re->generic.ob->gl_context, w, h, image_data, alpha, cspace); } static void * @@ -2653,8 +2080,8 @@ eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace); + eng_window_use(re->generic.ob); + return evas_gl_common_image_new_from_copied_data(re->generic.ob->gl_context, w, h, image_data, alpha, cspace); } static void @@ -2664,7 +2091,7 @@ eng_image_free(void *data, void *image) re = (Render_Engine *)data; if (!image) return; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_free(image); } @@ -2696,7 +2123,7 @@ eng_image_size_set(void *data, void *image, int w, int h) im->h = h; return image; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt->dyn.img)) { evas_gl_common_texture_free(im->tex, EINA_TRUE); @@ -2727,13 +2154,13 @@ eng_image_size_set(void *data, void *image, int w, int h) return image; if (im_old) { - im = evas_gl_common_image_new(re->win->gl_context, w, h, + im = evas_gl_common_image_new(re->generic.ob->gl_context, w, h, eng_image_alpha_get(data, image), eng_image_colorspace_get(data, image)); evas_gl_common_image_free(im_old); } else - im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); + im = evas_gl_common_image_new(re->generic.ob->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); return im; } @@ -2746,7 +2173,7 @@ eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) re = (Render_Engine *)data; if (!image) return NULL; if (im->native.data) return image; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_dirty(image, x, y, w, h); return image; } @@ -2774,7 +2201,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i } #ifdef GL_GLES - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888)) { @@ -2785,7 +2212,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i if (err) *err = EVAS_LOAD_ERROR_NONE; return im; } - *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, + *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->generic.ob->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC, EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC); @@ -2809,7 +2236,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i return im; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); #endif /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function, @@ -2891,7 +2318,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) if (!image) return NULL; im = image; if (im->native.data) return image; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_alloc_ensure(im); if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data) @@ -2904,7 +2331,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) im->tex->pt->dyn.checked_out--; #ifdef GL_GLES if (im->tex->pt->dyn.checked_out == 0) - glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC); + glsym_eglUnmapImageSEC(re->generic.ob->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC); #endif } @@ -2973,7 +2400,7 @@ eng_image_data_preload_request(void *data, void *image, const Eo *target) #endif evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); if (!gim->tex) - gim->tex = evas_gl_common_texture_new(re->win->gl_context, gim->im); + gim->tex = evas_gl_common_texture_new(re->generic.ob->gl_context, gim->im); evas_gl_preload_target_register(gim->tex, (Eo*) target); } @@ -3014,39 +2441,39 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, { DBG("Rendering Directly to the window: %p", data); - re->win->gl_context->dc = context; + re->generic.ob->gl_context->dc = context; if (re->func.get_pixels) { - if ((re->win->gl_context->master_clip.enabled) && - (re->win->gl_context->master_clip.w > 0) && - (re->win->gl_context->master_clip.h > 0)) + if ((re->generic.ob->gl_context->master_clip.enabled) && + (re->generic.ob->gl_context->master_clip.w > 0) && + (re->generic.ob->gl_context->master_clip.h > 0)) { // Pass the preserve flag info the evas_gl - evgl_direct_partial_info_set(re->win->gl_context->preserve_bit); + evgl_direct_partial_info_set(re->generic.ob->gl_context->preserve_bit); } // Set necessary info for direct rendering - evgl_direct_info_set(re->win->gl_context->w, - re->win->gl_context->h, - re->win->gl_context->rot, + evgl_direct_info_set(re->generic.ob->gl_context->w, + re->generic.ob->gl_context->h, + re->generic.ob->gl_context->rot, dst_x, dst_y, dst_w, dst_h, - re->win->gl_context->dc->clip.x, - re->win->gl_context->dc->clip.y, - re->win->gl_context->dc->clip.w, - re->win->gl_context->dc->clip.h); + re->generic.ob->gl_context->dc->clip.x, + re->generic.ob->gl_context->dc->clip.y, + re->generic.ob->gl_context->dc->clip.w, + re->generic.ob->gl_context->dc->clip.h); // Call pixel get function re->func.get_pixels(re->func.get_pixels_data, re->func.obj); // Call end tile if it's being used - if ((re->win->gl_context->master_clip.enabled) && - (re->win->gl_context->master_clip.w > 0) && - (re->win->gl_context->master_clip.h > 0)) + if ((re->generic.ob->gl_context->master_clip.enabled) && + (re->generic.ob->gl_context->master_clip.w > 0) && + (re->generic.ob->gl_context->master_clip.h > 0)) { evgl_direct_partial_render_end(); evgl_direct_partial_info_clear(); - re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; + re->generic.ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; } // Reset direct rendering info @@ -3055,10 +2482,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, } else { - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_image_draw(re->win->gl_context, image, + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_image_draw(re->generic.ob->gl_context, image, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, smooth); @@ -3089,9 +2516,9 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M re = (Render_Engine *)data; if (!image) return EINA_FALSE; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; if (m->count != 4) { // FIXME: nash - you didn't fix this @@ -3127,7 +2554,7 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M } else { - evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0], + evas_gl_common_image_map_draw(re->generic.ob->gl_context, image, m->count, &m->pts[0], smooth, level); } @@ -3145,8 +2572,8 @@ eng_image_map_surface_new(void *data, int w, int h, int alpha) Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha); + eng_window_use(re->generic.ob); + return evas_gl_common_image_surface_new(re->generic.ob->gl_context, w, h, alpha); } static void @@ -3155,7 +2582,7 @@ eng_image_map_surface_free(void *data, void *surface) Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_free(surface); } @@ -3165,7 +2592,7 @@ eng_image_content_hint_set(void *data, void *image, int hint) Render_Engine *re; re = (Render_Engine *)data; - if (re) eng_window_use(re->win); + if (re) eng_window_use(re->generic.ob); if (image) evas_gl_common_image_content_hint_set(image, hint); } @@ -3185,12 +2612,12 @@ eng_image_cache_flush(void *data) re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); tmp_size = evas_common_image_get_cache(); evas_common_image_set_cache(0); evas_common_rgba_image_scalecache_flush(); - evas_gl_common_image_cache_flush(re->win->gl_context); + evas_gl_common_image_cache_flush(re->generic.ob->gl_context); evas_common_image_set_cache(tmp_size); } @@ -3201,11 +2628,11 @@ eng_image_cache_set(void *data, int bytes) re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_common_image_set_cache(bytes); evas_common_rgba_image_scalecache_size_set(bytes); - evas_gl_common_image_cache_flush(re->win->gl_context); + evas_gl_common_image_cache_flush(re->generic.ob->gl_context); } static int @@ -3255,20 +2682,20 @@ eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; { // FIXME: put im into context so we can free it static RGBA_Image *im = NULL; if (!im) im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - im->cache_entry.w = re->win->gl_context->shared->w; - im->cache_entry.h = re->win->gl_context->shared->h; + im->cache_entry.w = re->generic.ob->gl_context->shared->w; + im->cache_entry.h = re->generic.ob->gl_context->shared->h; evas_common_draw_context_font_ext_set(context, - re->win->gl_context, + re->generic.ob->gl_context, evas_gl_font_texture_new, evas_gl_font_texture_free, evas_gl_font_texture_draw); @@ -3288,7 +2715,7 @@ static Eina_Bool eng_canvas_alpha_get(void *data, void *info EINA_UNUSED) { Render_Engine *re = (Render_Engine *)data; - return re->win->alpha; + return re->generic.ob->alpha; } //--------------------------------// @@ -3339,13 +2766,13 @@ eng_gl_make_current(void *data, void *surface, void *context) EVGLINIT(data, 0); if ((sfc) && (ctx)) { - if ((re->win->gl_context->havestuff) || - (re->win->gl_context->master_clip.used)) + if ((re->generic.ob->gl_context->havestuff) || + (re->generic.ob->gl_context->master_clip.used)) { - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); - if (re->win->gl_context->master_clip.used) - evas_gl_common_context_done(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); + if (re->generic.ob->gl_context->master_clip.used) + evas_gl_common_context_done(re->generic.ob->gl_context); } } @@ -3603,8 +3030,8 @@ static void eng_image_max_size_get(void *data, int *maxw, int *maxh) { Render_Engine *re = (Render_Engine *)data; - if (maxw) *maxw = re->win->gl_context->shared->info.max_texture_size; - if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size; + if (maxw) *maxw = re->generic.ob->gl_context->shared->info.max_texture_size; + if (maxh) *maxh = re->generic.ob->gl_context->shared->info.max_texture_size; } static Eina_Bool @@ -3700,13 +3127,13 @@ eng_context_flush(void *data) Render_Engine *re; re = (Render_Engine *)data; - if ((re->win->gl_context->havestuff) || - (re->win->gl_context->master_clip.used)) + if ((re->generic.ob->gl_context->havestuff) || + (re->generic.ob->gl_context->master_clip.used)) { - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); - if (re->win->gl_context->master_clip.used) - evas_gl_common_context_done(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); + if (re->generic.ob->gl_context->master_clip.used) + evas_gl_common_context_done(re->generic.ob->gl_context); } } @@ -3716,7 +3143,7 @@ eng_context_3d_use(void *data) Render_Engine *re = (Render_Engine *)data; if (!re->context_3d) - re->context_3d = eng_gl_context_new(re->win); + re->context_3d = eng_gl_context_new(re->generic.ob); if (re->context_3d) eng_gl_context_use(re->context_3d); } @@ -3781,8 +3208,8 @@ eng_drawable_scene_render(void *data, void *drawable, void *scene_data) Render_Engine *re = (Render_Engine *)data; E3D_Renderer *renderer = NULL; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); renderer = eng_renderer_3d_get(data); @@ -3806,8 +3233,8 @@ eng_texture_data_set(void *data, void *texture, Evas_3D_Color_Format color_forma Evas_3D_Pixel_Format pixel_format, int w, int h, const void *pixels) { Render_Engine *re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); e3d_texture_data_set((E3D_Texture *)texture, color_format, pixel_format, w, h, pixels); @@ -3817,8 +3244,8 @@ static void eng_texture_file_set(void *data, void *texture, const char *file, const char *key) { Render_Engine *re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); e3d_texture_file_set((E3D_Texture *)texture, file, key); @@ -3894,6 +3321,12 @@ module_open(Evas_Module *em) return 0; } + if (partial_render_debug == -1) + { + if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1; + else partial_render_debug = 0; + } + /* store it for later use */ func = pfunc; /* now to override methods */ @@ -3903,17 +3336,6 @@ module_open(Evas_Module *em) ORD(setup); ORD(canvas_alpha_get); ORD(output_free); - ORD(output_resize); - ORD(output_tile_size_set); - ORD(output_redraws_rect_add); - ORD(output_redraws_rect_del); - ORD(output_redraws_clear); - ORD(output_redraws_next_update_get); - ORD(output_redraws_next_update_push); - ORD(context_cutout_add); - ORD(context_cutout_clear); - ORD(output_flush); - ORD(output_idle_flush); ORD(output_dump); ORD(rectangle_draw); ORD(line_draw); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.h b/src/modules/evas/engines/gl_x11/evas_engine.h index 42d346aedb..603c715866 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.h +++ b/src/modules/evas/engines/gl_x11/evas_engine.h @@ -31,6 +31,8 @@ # include <GL/glx.h> #endif +#include "../software_generic/Evas_Engine_Software_Generic.h" + extern int _evas_engine_GL_X11_log_dom ; #ifdef ERR # undef ERR @@ -62,20 +64,6 @@ typedef struct _Evas_GL_X11_Context Evas_GL_X11_Context; struct _Outbuf { - Display *disp; - Window win; - int w, h; - int screen; - XVisualInfo *visualinfo; - Visual *visual; - Colormap colormap; - int depth; - int alpha; - int rot; - Evas_Engine_GL_Context *gl_context; - struct { - int drew : 1; - } draw; #ifdef GL_GLES EGLContext egl_context[1]; EGLSurface egl_surface[1]; @@ -89,7 +77,32 @@ struct _Outbuf unsigned int loose_binding : 1; } detected; #endif - int surf : 1; + + Evas *evas; + Display *disp; + XVisualInfo *visualinfo; + Visual *visual; + Evas_Engine_GL_Context *gl_context; + Evas_Engine_Info_GL_X11 *info; + + Render_Engine_Swap_Mode swap_mode; + Colormap colormap; + Window win; + int w, h; + int screen; + int depth; + int alpha; + int rot; + int prev_age; + int frame_cnt; + int vsync; + + unsigned char lost_back : 1; + unsigned char surf : 1; + + struct { + unsigned char drew : 1; + } draw; }; struct _Evas_GL_X11_Context @@ -106,10 +119,24 @@ struct _Evas_GL_X11_Context #endif }; -Outbuf *eng_window_new(Display *disp, Window win, int screen, - Visual *vis, Colormap cmap, - int depth, int w, int h, int indirect, - int alpha, int rot); +extern int extn_have_buffer_age; +extern int partial_render_debug; +extern int swap_buffer_debug_mode; +extern int swap_buffer_debug; +extern const char *debug_dir; + +extern void (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d); +extern void (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c); +extern int (*glsym_glXSwapIntervalSGI) (int a); +extern int (*glsym_glXGetVideoSync) (unsigned int *a); +extern int (*glsym_glXWaitVideoSync) (int a, int b, unsigned int *c); + +Outbuf *eng_window_new(Evas_Engine_Info_GL_X11 *info, Evas *e, + Display *disp, Window win, int screen, + Visual *vis, Colormap cmap, + int depth, int w, int h, int indirect, + int alpha, int rot, + Render_Engine_Swap_Mode swap_mode); void eng_window_free(Outbuf *gw); void eng_window_use(Outbuf *gw); void eng_window_unsurf(Outbuf *gw); @@ -123,4 +150,31 @@ Evas_GL_X11_Context *eng_gl_context_new(Outbuf *win); void eng_gl_context_free(Evas_GL_X11_Context *context); void eng_gl_context_use(Evas_GL_X11_Context *context); +void eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); +int eng_outbuf_get_rot(Outbuf *ob); +Render_Engine_Swap_Mode eng_outbuf_swap_mode(Outbuf *ob); +Eina_Bool eng_outbuf_region_first_rect(Outbuf *ob); +void *eng_outbuf_new_region_for_update(Outbuf *ob, + int x, int y, int w, int h, + int *cx, int *cy, int *cw, int *ch); +void eng_outbuf_push_free_region_for_update(Outbuf *ob, RGBA_Image *update); +void eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, + int x, int y, int w, int h); +void eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); + +Eina_Bool eng_preload_make_current(void *data, void *doit); + +static inline int +_re_wincheck(Outbuf *ob) +{ + if (ob->surf) return 1; + eng_window_resurf(ob); + ob->lost_back = 1; + if (!ob->surf) + { + ERR("GL engine can't re-create window surface!"); + } + return 0; +} + #endif diff --git a/src/modules/evas/engines/gl_x11/evas_x_main.c b/src/modules/evas/engines/gl_x11/evas_x_main.c index b3dc5f5537..f4ba440b89 100644 --- a/src/modules/evas/engines/gl_x11/evas_x_main.c +++ b/src/modules/evas/engines/gl_x11/evas_x_main.c @@ -23,7 +23,9 @@ static Colormap _evas_gl_x11_rgba_cmap = 0; static int win_count = 0; Outbuf * -eng_window_new(Display *disp, +eng_window_new(Evas_Engine_Info_GL_X11 *info, + Evas *e, + Display *disp, Window win, int screen, Visual *vis, @@ -33,7 +35,8 @@ eng_window_new(Display *disp, int h, int indirect, int alpha, - int rot) + int rot, + Render_Engine_Swap_Mode swap_mode) { Outbuf *gw; #ifdef GL_GLES @@ -62,6 +65,9 @@ eng_window_new(Display *disp, gw->w = w; gw->h = h; gw->rot = rot; + gw->swap_mode = swap_mode; + gw->info = info; + gw->evas = e; vi_use = _evas_gl_x11_vi; if (gw->alpha) @@ -939,3 +945,305 @@ eng_gl_context_use(Evas_GL_X11_Context *ctx) } #endif } + +void +eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED) +{ + ob->w = w; + ob->h = h; + ob->rot = rot; + eng_window_use(ob); + evas_gl_common_context_resize(ob->gl_context, w, h, rot); +} + +int +eng_outbuf_get_rot(Outbuf *ob) +{ + return ob->rot; +} + +Render_Engine_Swap_Mode +eng_outbuf_swap_mode(Outbuf *ob) +{ + if (ob->swap_mode == MODE_AUTO && extn_have_buffer_age) + { + Render_Engine_Swap_Mode swap_mode; +#ifdef GL_GLES + EGLint age = 0; + + if (!eglQuerySurface(ob->egl_disp, + ob->egl_surface[0], + EGL_BUFFER_AGE_EXT, &age)) + age = 0; +#else + unsigned int age = 0; + + if (glsym_glXQueryDrawable) + { + if (ob->glxwin) + glsym_glXQueryDrawable(ob->disp, + ob->glxwin, + GLX_BACK_BUFFER_AGE_EXT, + &age); + else + glsym_glXQueryDrawable(ob->disp, + ob->win, + GLX_BACK_BUFFER_AGE_EXT, + &age); + } +#endif + if (age == 1) swap_mode = MODE_COPY; + else if (age == 2) swap_mode = MODE_DOUBLE; + else if (age == 3) swap_mode = MODE_TRIPLE; + else if (age == 4) swap_mode = MODE_QUADRUPLE; + else swap_mode = MODE_FULL; + if ((int)age != ob->prev_age) swap_mode = MODE_FULL; + ob->prev_age = age; + + return swap_mode; + } + + return ob->swap_mode; +} + +Eina_Bool +eng_outbuf_region_first_rect(Outbuf *ob) +{ + ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; + + evas_gl_preload_render_lock(eng_preload_make_current, ob); +#ifdef GL_GLES + // dont need to for egl - eng_window_use() can check for other ctxt's +#else + eng_window_use(NULL); +#endif + eng_window_use(ob); + if (!_re_wincheck(ob)) return EINA_TRUE; + + evas_gl_common_context_flush(ob->gl_context); + evas_gl_common_context_newframe(ob->gl_context); + if (partial_render_debug == 1) + { + glClearColor(0.2, 0.5, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + } + + return EINA_FALSE; +} + +void* +eng_outbuf_new_region_for_update(Outbuf *ob, + int x, int y, int w, int h, + int *cx EINA_UNUSED, int *cy EINA_UNUSED, + int *cw EINA_UNUSED, int *ch EINA_UNUSED) +{ + if (w == ob->w && h == ob->h) + { + ob->gl_context->master_clip.enabled = EINA_FALSE; + } + else + { + ob->gl_context->master_clip.enabled = EINA_TRUE; + ob->gl_context->master_clip.x = x; + ob->gl_context->master_clip.y = y; + ob->gl_context->master_clip.w = w; + ob->gl_context->master_clip.h = h; + } + return ob->gl_context->def_surface; +} + +void +eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + /* Is it really necessary to flush per region ? Shouldn't we be able to + still do that for the full canvas when doing partial update */ + if (!_re_wincheck(ob)) return; + ob->draw.drew = 1; + evas_gl_common_context_flush(ob->gl_context); +#ifdef GL_GLES + // this is needed to make sure all previous rendering is flushed to + // buffers/surfaces + // previous rendering should be done and swapped +//xx if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE); +// if (eglGetError() != EGL_SUCCESS) +// { +// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n"); +// } +#else + // previous rendering should be done and swapped +//xx if (!safe_native) glXWaitX(); +#endif +} + +void +eng_outbuf_push_free_region_for_update(Outbuf *ob EINA_UNUSED, + RGBA_Image *update EINA_UNUSED) +{ + /* Nothing to do here as we don't really create an image per area */ +} + +void +eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode) +{ + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; + + if (!_re_wincheck(ob)) goto end; + if (!ob->draw.drew) goto end; + + ob->draw.drew = 0; + eng_window_use(ob); + evas_gl_common_context_done(ob->gl_context); + + // Save contents of the framebuffer to a file + if (swap_buffer_debug_mode == 1) + { + if (swap_buffer_debug) + { + char fname[100]; + int ret = 0; + snprintf(fname, sizeof(fname), "%p", (void*)ob); + + ret = evas_gl_common_buffer_dump(ob->gl_context, + (const char*)debug_dir, + (const char*)fname, + ob->frame_cnt, + NULL); + if (!ret) swap_buffer_debug_mode = 0; + } + } + +#ifdef GL_GLES + if (!ob->vsync) + { + if (ob->info->vsync) eglSwapInterval(ob->egl_disp, 1); + else eglSwapInterval(ob->egl_disp, 0); + ob->vsync = 1; + } + if (ob->info->callback.pre_swap) + { + ob->info->callback.pre_swap(ob->info->callback.data, re->evas); + } + if ((glsym_eglSwapBuffersWithDamage) && (re->swap_mode != MODE_FULL)) + { + EGLint num = 0, *result = NULL, i = 0; + Tilebuf_Rect *r; + + // if partial swaps can be done use re->rects + num = eina_inlist_count(EINA_INLIST_GET(rects)); + if (num > 0) + { + result = alloca(sizeof(EGLint) * 4 * num); + EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) + { + int gw, gh; + + gw = ob->gl_context->w; + gh = ob->gl_context->h; + switch (ob->rot) + { + case 0: + result[i + 0] = r->x; + result[i + 1] = gh - (r->y + r->h); + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + case 90: + result[i + 0] = r->y; + result[i + 1] = r->x; + result[i + 2] = r->h; + result[i + 3] = r->w; + break; + case 180: + result[i + 0] = gw - (r->x + r->w); + result[i + 1] = r->y; + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + case 270: + result[i + 0] = gh - (r->y + r->h); + result[i + 1] = gw - (r->x + r->w); + result[i + 2] = r->h; + result[i + 3] = r->w; + break; + default: + result[i + 0] = r->x; + result[i + 1] = gh - (r->y + r->h); + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + } + i += 4; + } + glsym_eglSwapBuffersWithDamage(ob->egl_disp, + ob->egl_surface[0], + rects, num); + } + } + else + eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]); + +//xx if (!safe_native) eglWaitGL(); + if (ob->info->callback.post_swap) + { + ob->info->callback.post_swap(ob->info->callback.data, ob->evas); + } +// if (eglGetError() != EGL_SUCCESS) +// { +// printf("Error: eglSwapBuffers() fail.\n"); +// } +#else + (void)rects; +#ifdef VSYNC_TO_SCREEN + if (ob->info->vsync) + { + if (glsym_glXSwapIntervalEXT) + { + if (!ob->vsync) + { + if (ob->info->vsync) glsym_glXSwapIntervalEXT(ob->disp, ob->win, 1); + else glsym_glXSwapIntervalEXT(ob->disp, ob->win, 0); + ob->vsync = 1; + } + } + else if (glsym_glXSwapIntervalSGI) + { + if (!ob->vsync) + { + if (ob->info->vsync) glsym_glXSwapIntervalSGI(1); + else glsym_glXSwapIntervalSGI(0); + ob->vsync = 1; + } + } + else + { + if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync)) + { + unsigned int rc; + + glsym_glXGetVideoSync(&rc); + glsym_glXWaitVideoSync(1, 0, &rc); + } + } + } +#endif + if (ob->info->callback.pre_swap) + { + ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); + } + // XXX: if partial swaps can be done use re->rects +// measure(0, "swap"); + glXSwapBuffers(ob->disp, ob->win); +// measure(1, "swap"); + if (ob->info->callback.post_swap) + { + ob->info->callback.post_swap(ob->info->callback.data, ob->evas); + } +#endif + // clear out rects after swap as we may use them during swap + + ob->frame_cnt++; + + end: + evas_gl_preload_render_unlock(eng_preload_make_current, ob); +} |