summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <c.bail@partner.samsung.com>2014-07-04 13:51:32 +0200
committerCedric BAIL <c.bail@partner.samsung.com>2014-07-04 15:11:22 +0200
commit14d22c5a080bebf16a3698ce3358c46c0bc9029a (patch)
tree02c2987f9f15e7a984bbde5390df7560f9dc2a28
parent289b3691b049c20441e5f10606461e9e2a7aad6a (diff)
downloadefl-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.c1374
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.h92
-rw-r--r--src/modules/evas/engines/gl_x11/evas_x_main.c312
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);
+}