Evas GL: Fix support for GLES 1.1 indirect rendering
This requires a special context that matches the configuration required for GLES 1.1. Otherwise eglMakeCurrent() would fail miserably with EGL_BAD_MATCH in case of indirect rendering (at least on some drivers).
This commit is contained in:
parent
9a0f591314
commit
ae2061dbe2
|
@ -2074,6 +2074,14 @@ evgl_context_destroy(void *eng_data, EVGL_Context *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Destroy GLES1 indirect rendering context
|
||||
if (ctx->gles1_context &&
|
||||
!evgl_engine->funcs->context_destroy(eng_data, ctx->context))
|
||||
{
|
||||
ERR("Error destroying the GLES1 context.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Destroy engine context
|
||||
if (!evgl_engine->funcs->context_destroy(eng_data, ctx->context))
|
||||
{
|
||||
|
@ -2226,22 +2234,59 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (dbg) DBG("ctx %p is GLES 1", ctx);
|
||||
if (_evgl_direct_renderable(rsc, sfc))
|
||||
{
|
||||
// Transition from pixmap surface rendering to direct rendering
|
||||
/*
|
||||
* TODO:
|
||||
if (!rsc->direct.rendered)
|
||||
{
|
||||
// Restore viewport and scissor test to direct rendering mode
|
||||
glViewport(ctx->viewport_direct[0], ctx->viewport_direct[1], ctx->viewport_direct[2], ctx->viewport_direct[3]);
|
||||
if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
*/
|
||||
if (dbg) DBG("sfc %p is direct renderable.", sfc);
|
||||
rsc->direct.rendered = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ctx->gles1_context)
|
||||
{
|
||||
ctx->gles1_context =
|
||||
evgl_engine->funcs->gles1_context_create(eng_data, ctx, sfc);
|
||||
}
|
||||
if (dbg) DBG("Calling make_current(%p, %p)", sfc->gles1_sfc, ctx->context);
|
||||
evgl_engine->funcs->make_current(eng_data, sfc->gles1_sfc,
|
||||
ctx->context, EINA_TRUE);
|
||||
if (!evgl_engine->funcs->make_current(eng_data, sfc->gles1_sfc,
|
||||
ctx->gles1_context, EINA_TRUE))
|
||||
{
|
||||
ERR("Failed to make current with GLES1 indirect surface.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Transition from direct rendering to pixmap surface rendering
|
||||
if (rsc->direct.rendered)
|
||||
{
|
||||
glViewport(ctx->viewport_coord[0], ctx->viewport_coord[1], ctx->viewport_coord[2], ctx->viewport_coord[3]);
|
||||
if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
ctx->current_fbo = 0;
|
||||
rsc->direct.rendered = 0;
|
||||
}
|
||||
|
||||
ctx->current_sfc = sfc;
|
||||
rsc->current_ctx = ctx;
|
||||
rsc->current_eng = eng_data;
|
||||
|
||||
// Update extensions after GLESv1 context is bound
|
||||
evgl_api_gles1_ext_get(gles1_funcs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GLES 2+ below
|
||||
|
||||
// Normal FBO Rendering
|
||||
// Create FBO if it hasn't been created
|
||||
if (!ctx->surface_fbo)
|
||||
|
@ -2343,12 +2388,6 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
rsc->current_ctx = ctx;
|
||||
rsc->current_eng = eng_data;
|
||||
|
||||
// Update GLESv1 extension functions after GLESv1 context is bound
|
||||
if (ctx->version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
evgl_api_gles1_ext_get(gles1_funcs);
|
||||
}
|
||||
|
||||
_surface_context_list_print();
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -74,6 +74,9 @@ struct _EVGL_Interface
|
|||
|
||||
// Destroy 1.x surface (could be pbuffer or xpixmap for instance)
|
||||
int (*gles1_surface_destroy)(void *data, EVGL_Surface *evgl_sfc);
|
||||
|
||||
// Create an indirect rendering context for GLES 1.x
|
||||
void *(*gles1_context_create)(void *data, EVGL_Context *share_ctx, EVGL_Surface *evgl_sfc);
|
||||
};
|
||||
|
||||
struct _EVGL_Surface
|
||||
|
@ -131,6 +134,7 @@ struct _EVGL_Surface
|
|||
EVGLNative_Surface gles1_sfc;
|
||||
void *gles1_sfc_native;
|
||||
void *gles1_sfc_visual;
|
||||
void *gles1_sfc_config;
|
||||
|
||||
//-------------------------//
|
||||
// Related to PBuffer Surface
|
||||
|
@ -169,6 +173,9 @@ struct _EVGL_Context
|
|||
int scissor_coord[4];
|
||||
int viewport_coord[4];
|
||||
|
||||
// For GLES1 with indirect rendering
|
||||
EVGLNative_Context gles1_context;
|
||||
|
||||
// Partial Rendering
|
||||
int partial_render;
|
||||
|
||||
|
|
|
@ -980,7 +980,7 @@ try_again:
|
|||
config_attrs[i++] = EGL_NONE;
|
||||
config_attrs[i++] = 0;
|
||||
|
||||
if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs, configs, 200, &num))
|
||||
if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs, configs, 200, &num) || !num)
|
||||
{
|
||||
int err = eglGetError();
|
||||
ERR("eglChooseConfig() can't find any configs, error: %x", err);
|
||||
|
@ -1075,6 +1075,8 @@ try_again:
|
|||
evgl_sfc->gles1_sfc = egl_sfc;
|
||||
evgl_sfc->gles1_sfc_native = (void *)(intptr_t) px;
|
||||
evgl_sfc->gles1_sfc_visual = visual;
|
||||
evgl_sfc->gles1_sfc_config = egl_cfg;
|
||||
DBG("Successfully created GLES1 surface: Pixmap %lu EGLSurface %p", px, egl_sfc);
|
||||
return evgl_sfc;
|
||||
|
||||
#else
|
||||
|
@ -1127,6 +1129,51 @@ evgl_eng_gles1_surface_destroy(void *data, EVGL_Surface *evgl_sfc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_gles1_context_create(void *data,
|
||||
EVGL_Context *share_ctx, EVGL_Surface *sfc)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
if (!re) return NULL;
|
||||
|
||||
#ifdef GL_GLES
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
int context_attrs[3];
|
||||
EGLConfig config;
|
||||
|
||||
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
context_attrs[1] = 1;
|
||||
context_attrs[2] = EGL_NONE;
|
||||
|
||||
if (!sfc || !sfc->gles1_sfc_config)
|
||||
{
|
||||
ERR("Surface is not set! Creating context anyways but eglMakeCurrent "
|
||||
"might very well fail with EGL_BAD_MATCH (0x3009)");
|
||||
config = eng_get_ob(re)->egl_config;
|
||||
}
|
||||
else config = sfc->gles1_sfc_config;
|
||||
|
||||
context = eglCreateContext(eng_get_ob(re)->egl_disp, config,
|
||||
share_ctx ? share_ctx->context : NULL,
|
||||
context_attrs);
|
||||
if (!context)
|
||||
{
|
||||
int err = eglGetError();
|
||||
ERR("eglCreateContext failed with error 0x%x", err);
|
||||
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG("Successfully created context for GLES1 indirect rendering.");
|
||||
return context;
|
||||
#else
|
||||
CRI("Support for GLES1 indirect rendering contexts is not implemented for GLX");
|
||||
(void) share_ctx; (void) sfc;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static const EVGL_Interface evgl_funcs =
|
||||
{
|
||||
evgl_eng_display_get,
|
||||
|
@ -1145,6 +1192,7 @@ static const EVGL_Interface evgl_funcs =
|
|||
evgl_eng_pbuffer_surface_destroy,
|
||||
evgl_eng_gles1_surface_create,
|
||||
evgl_eng_gles1_surface_destroy,
|
||||
evgl_eng_gles1_context_create,
|
||||
};
|
||||
|
||||
//----------------------------------------------------------//
|
||||
|
|
Loading…
Reference in New Issue