summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-11-06 17:50:22 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-11-06 18:17:29 +0900
commit6d76943c1ef6d379d91230387db45a52c4bb0e1d (patch)
tree7edd8625f4acdfdc81c850cc2ae5c698b2fb99a9
parent1786d5bf4165fa6c2f4ea049b73fd0c6a93064e8 (diff)
downloadefl-6d76943c1ef6d379d91230387db45a52c4bb0e1d.tar.gz
Evas GL: Optimize out calls to eglGetCurrent from the main loop
This is an optimization for EGL only and for the main loop only. eglGetCurrent{Display,Context,Surface} are expensive calls (they shouldn't be, but they are). eglMakeCurrent is also very expensive, so we want as much as possible to avoid calling those functions. Store the pointers for the main loop as static variables. Valgrind stats for a quick scrolling session in elm_test: Before this patch: - eglGetCurrentContext ~ 0.4% - eglGetCurrentDisplay ~ 0.4% After this patch: - evas_eglGetCurrentContext ~ 0.02% - evas_eglGetCurrentDisplay ~ 0.02%
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c88
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.h7
-rw-r--r--src/modules/evas/engines/gl_x11/evas_x_main.c34
3 files changed, 93 insertions, 36 deletions
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c
index 75a389205d..0d12b744cd 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -158,6 +158,65 @@ evgl_eng_evas_surface_get(void *data)
return NULL;
}
+#ifdef GL_GLES
+static EGLDisplay main_dpy = EGL_NO_DISPLAY;
+static EGLSurface main_draw = EGL_NO_SURFACE;
+static EGLSurface main_read = EGL_NO_SURFACE;
+static EGLContext main_ctx = EGL_NO_CONTEXT;
+
+EGLContext
+evas_eglGetCurrentContext(void)
+{
+ if (eina_main_loop_is())
+ return main_ctx;
+ else
+ return eglGetCurrentContext();
+}
+
+EGLSurface
+evas_eglGetCurrentSurface(EGLint readdraw)
+{
+ if (eina_main_loop_is())
+ return (readdraw == EGL_READ) ? main_read : main_draw;
+ else
+ return eglGetCurrentSurface(readdraw);
+}
+
+EGLDisplay
+evas_eglGetCurrentDisplay(void)
+{
+ if (eina_main_loop_is())
+ return main_dpy;
+ else
+ return eglGetCurrentDisplay();
+}
+
+EGLBoolean
+evas_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ if (eina_main_loop_is())
+ {
+ EGLBoolean ret;
+
+ if ((dpy == main_dpy) && (draw == main_draw) &&
+ (read == main_read) && (ctx == main_ctx))
+ return 1;
+
+ ret = eglMakeCurrent(dpy, draw, read, ctx);
+ if (ret)
+ {
+ main_dpy = dpy;
+ main_draw = draw;
+ main_read = read;
+ main_ctx = ctx;
+ }
+ return ret;
+ }
+ else
+ return eglMakeCurrent(dpy, draw, read, ctx);
+}
+#endif
+
static int
evgl_eng_make_current(void *data, void *surface, void *context, int flush)
{
@@ -172,7 +231,6 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
return 0;
}
-
#ifdef GL_GLES
EGLContext ctx = (EGLContext)context;
EGLSurface sfc = (EGLSurface)surface;
@@ -180,25 +238,21 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
if ((!context) && (!surface))
{
- if (!eglGetCurrentContext() &&
- !eglGetCurrentSurface(EGL_READ) &&
- !eglGetCurrentSurface(EGL_DRAW))
- return 1;
- ret = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ret = evas_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!ret)
{
int err = eglGetError();
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
- ERR("eglMakeCurrent() failed! Error Code=%#x", err);
+ ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
return 0;
}
return 1;
}
// FIXME: Check (eglGetCurrentDisplay() != dpy) ?
- if ((eglGetCurrentContext() != ctx) ||
- (eglGetCurrentSurface(EGL_READ) != sfc) ||
- (eglGetCurrentSurface(EGL_DRAW) != sfc) )
+ if ((evas_eglGetCurrentContext() != ctx) ||
+ (evas_eglGetCurrentSurface(EGL_READ) != sfc) ||
+ (evas_eglGetCurrentSurface(EGL_DRAW) != sfc) )
{
//!!!! Does it need to be flushed with it's set to NULL above??
@@ -206,13 +260,13 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
if (flush) eng_window_use(NULL);
// Do a make current
- ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
+ ret = evas_eglMakeCurrent(dpy, sfc, sfc, ctx);
if (!ret)
{
int err = eglGetError();
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
- ERR("eglMakeCurrent() failed! Error Code=%#x", err);
+ ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
return 0;
}
}
@@ -662,7 +716,7 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
config_attrs[i++] = EGL_PBUFFER_BIT;
config_attrs[i++] = EGL_NONE;
#else
- // It looks like eglMakeCurrent might fail if we use a different config from
+ // It looks like evas_eglMakeCurrent might fail if we use a different config from
// the actual display surface. This is weird.
i = 0;
config_attrs[i++] = EGL_CONFIG_ID;
@@ -1121,7 +1175,7 @@ evgl_eng_gles_context_create(void *data,
if (!sfc || !sfc->indirect_sfc_config)
{
- ERR("Surface is not set! Creating context anyways but eglMakeCurrent "
+ ERR("Surface is not set! Creating context anyways but evas_eglMakeCurrent "
"might very well fail with EGL_BAD_MATCH (0x3009)");
config = eng_get_ob(re)->egl_config;
}
@@ -1833,7 +1887,7 @@ eng_preload_make_current(void *data, void *doit)
if (doit)
{
#ifdef GL_GLES
- if (!eglMakeCurrent(ob->egl_disp, ob->egl_surface[0], ob->egl_surface[0], ob->egl_context[0]))
+ if (!evas_eglMakeCurrent(ob->egl_disp, ob->egl_surface[0], ob->egl_surface[0], ob->egl_context[0]))
return EINA_FALSE;
#else
if (!__glXMakeContextCurrent(ob->info->info.display, ob->glxwin, ob->context))
@@ -1848,7 +1902,7 @@ eng_preload_make_current(void *data, void *doit)
else
{
#ifdef GL_GLES
- if (!eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
+ if (!evas_eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
return EINA_FALSE;
#else
if (!__glXMakeContextCurrent(ob->info->info.display, 0, NULL))
@@ -1895,7 +1949,7 @@ eng_gl_current_context_get(void *data EINA_UNUSED)
context = glsym_evgl_current_native_context_get(ctx);
#ifdef GL_GLES
- if (eglGetCurrentContext() == context)
+ if (evas_eglGetCurrentContext() == context)
return ctx;
#else
if (glXGetCurrentContext() == context)
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.h b/src/modules/evas/engines/gl_x11/evas_engine.h
index 3ef4054e10..f84313b16f 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.h
+++ b/src/modules/evas/engines/gl_x11/evas_engine.h
@@ -214,7 +214,12 @@ _re_wincheck(Outbuf *ob)
return 0;
}
-#ifndef GL_GLES
+#ifdef GL_GLES
+EGLBoolean evas_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLContext evas_eglGetCurrentContext(void);
+EGLSurface evas_eglGetCurrentSurface(EGLint readdraw);
+EGLDisplay evas_eglGetCurrentDisplay(void);
+#else
Eina_Bool __glXMakeContextCurrent(Display *disp, GLXDrawable glxwin,
GLXContext context);
#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 d6073aad8e..8ee32d2dde 100644
--- a/src/modules/evas/engines/gl_x11/evas_x_main.c
+++ b/src/modules/evas/engines/gl_x11/evas_x_main.c
@@ -276,12 +276,12 @@ try_gles2:
_tls_context_set(gw->egl_context[0]);
SET_RESTORE_CONTEXT();
- if (eglMakeCurrent(gw->egl_disp,
+ if (evas_eglMakeCurrent(gw->egl_disp,
gw->egl_surface[0],
gw->egl_surface[0],
gw->egl_context[0]) == EGL_FALSE)
{
- ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
+ ERR("evas_eglMakeCurrent() fail. code=%#x", eglGetError());
eng_window_free(gw);
return NULL;
}
@@ -591,7 +591,7 @@ eng_window_free(Outbuf *gw)
}
#ifdef GL_GLES
SET_RESTORE_CONTEXT();
- eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (gw->egl_surface[0] != EGL_NO_SURFACE)
eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
if (gw->egl_surface[1] != EGL_NO_SURFACE)
@@ -632,12 +632,12 @@ eng_window_make_current(void *data, void *doit)
SET_RESTORE_CONTEXT();
if (doit)
{
- if (!eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0], gw->egl_context[0]))
+ if (!evas_eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0], gw->egl_context[0]))
return EINA_FALSE;
}
else
{
- if (!eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
+ if (!evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
return EINA_FALSE;
}
#else
@@ -670,15 +670,13 @@ eng_window_use(Outbuf *gw)
#ifdef GL_GLES
if (xwin)
{
- if ((eglGetCurrentDisplay() !=
- xwin->egl_disp) ||
- (eglGetCurrentContext() !=
- xwin->egl_context[0])
+ if ((evas_eglGetCurrentDisplay() != xwin->egl_disp) ||
+ (evas_eglGetCurrentContext() != xwin->egl_context[0])
#if 0
// FIXME: Figure out what that offscreen thing was about...
- || (eglGetCurrentSurface(EGL_READ) !=
+ || (evas_eglGetCurrentSurface(EGL_READ) !=
xwin->egl_surface[xwin->offscreen])
- || (eglGetCurrentSurface(EGL_DRAW) !=
+ || (evas_eglGetCurrentSurface(EGL_DRAW) !=
xwin->egl_surface[xwin->offscreen])
#endif
)
@@ -706,12 +704,12 @@ eng_window_use(Outbuf *gw)
if (gw->egl_surface[0] != EGL_NO_SURFACE)
{
SET_RESTORE_CONTEXT();
- if (eglMakeCurrent(gw->egl_disp,
+ if (evas_eglMakeCurrent(gw->egl_disp,
gw->egl_surface[0],
gw->egl_surface[0],
gw->egl_context[0]) == EGL_FALSE)
{
- ERR("eglMakeCurrent() failed!");
+ ERR("evas_eglMakeCurrent() failed!");
}
}
// GLX
@@ -742,7 +740,7 @@ eng_window_unsurf(Outbuf *gw)
if (xwin == gw)
{
SET_RESTORE_CONTEXT();
- eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (gw->egl_surface[0] != EGL_NO_SURFACE)
eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
gw->egl_surface[0] = EGL_NO_SURFACE;
@@ -777,12 +775,12 @@ eng_window_resurf(Outbuf *gw)
return;
}
SET_RESTORE_CONTEXT();
- if (eglMakeCurrent(gw->egl_disp,
+ if (evas_eglMakeCurrent(gw->egl_disp,
gw->egl_surface[0],
gw->egl_surface[0],
gw->egl_context[0]) == EGL_FALSE)
{
- ERR("eglMakeCurrent() failed!");
+ ERR("evas_eglMakeCurrent() failed!");
}
#else
Evas_GL_X11_Visual *evis;
@@ -1332,10 +1330,10 @@ eng_gl_context_use(Context_3D *ctx)
{
#if GL_GLES
SET_RESTORE_CONTEXT();
- if (eglMakeCurrent(ctx->display, ctx->surface,
+ if (evas_eglMakeCurrent(ctx->display, ctx->surface,
ctx->surface, ctx->context) == EGL_FALSE)
{
- ERR("eglMakeCurrent() failed.");
+ ERR("evas_eglMakeCurrent() failed.");
}
#else
if (!__glXMakeContextCurrent(ctx->display, ctx->glxwin, ctx->context))