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%
This commit is contained in:
parent
c70ba9e13b
commit
c55c7c0a0d
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue