jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=c17cfbd13e44b0cf998288cc11061d3703875b21
commit c17cfbd13e44b0cf998288cc11061d3703875b21 Author: Jean-Philippe Andre <[email protected]> Date: Mon Oct 6 21:26:11 2014 +0900 Evas GL: Add support for PBuffer surfaces with GLX Not fully tested, but allows calling evas_gl_make_current, so it works for dummy surfaces (eg. 1x1 for a render thread). --- src/modules/evas/engines/gl_common/evas_gl_core.c | 2 +- .../evas/engines/gl_common/evas_gl_core_private.h | 1 + src/modules/evas/engines/gl_drm/evas_engine.c | 1 + src/modules/evas/engines/gl_sdl/evas_engine.c | 1 + src/modules/evas/engines/gl_x11/evas_engine.c | 125 ++++++++++++++++++--- src/modules/evas/engines/wayland_egl/evas_engine.c | 6 +- 6 files changed, 121 insertions(+), 15 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index 9782b3a..ed2a089 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -1815,7 +1815,7 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc) if (sfc->pbuffer.fbo) glDeleteFramebuffers(1, &sfc->pbuffer.fbo); - ret = evgl_engine->funcs->surface_destroy(eng_data, sfc->pbuffer.native_surface); + ret = evgl_engine->funcs->pbuffer_surface_destroy(eng_data, sfc->pbuffer.native_surface); LKL(evgl_engine->resource_lock); evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc); LKU(evgl_engine->resource_lock); diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h index 5fe0e76..61c8c6c 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h @@ -67,6 +67,7 @@ struct _EVGL_Interface // Create a pbuffer surface void *(*pbuffer_surface_create)(void *data, EVGL_Surface *evgl_sfc, const int *attrib_list); + int (*pbuffer_surface_destroy)(void *data, void *surface); // Create a surface for 1.x rendering (could be pbuffer or xpixmap for instance) void *(*gles1_surface_create)(void *data, EVGL_Surface *evgl_sfc, Evas_GL_Config *cfg, int w, int h); diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index 1322bae..5c804ad 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -120,6 +120,7 @@ static const EVGL_Interface evgl_funcs = evgl_eng_string_get, evgl_eng_rotation_angle_get, NULL, // PBuffer + NULL, // PBuffer NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 }; diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index d2bba51..0aa9296 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -256,6 +256,7 @@ static const EVGL_Interface evgl_funcs = evgl_eng_string_get, evgl_eng_rotation_angle_get, NULL, // PBuffer + NULL, // PBuffer NULL, // OpenGL-ES 1 NULL, // OpenGL-ES 1 }; diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 94bcc02..527ee33 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -637,6 +637,9 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc, // TODO: Add support for surfaceless pbuffers (EGL_NO_TEXTURE) // TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them) + if (attrib_list) + WRN("This PBuffer implementation does not support extra attributes yet"); + #ifdef GL_GLES int config_attrs[20]; int surface_attrs[20]; @@ -646,9 +649,6 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc, EGLDisplay disp; EGLContext ctx; - if (attrib_list) - WRN("This PBuffer implementation does not support extra attributes yet"); - disp = re->window_egl_display_get(re->software.ob); ctx = re->window_gl_context_get(re->software.ob); @@ -747,9 +747,109 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc, return egl_sfc; #else - ERR("PBuffer support is not implemented yet!"); - return NULL; + GLXPbuffer pbuf; + GLXFBConfig *cfgs; + int config_attrs[20]; + int surface_attrs[20]; + int ncfg = 0, i; + + // TODO: Check all required config attributes + +#ifndef GLX_VISUAL_ID +# define GLX_VISUAL_ID 0x800b +#endif + + i = 0; + if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO) + { + config_attrs[i++] = GLX_BUFFER_SIZE; + if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888) + { + config_attrs[i++] = 32; + //config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT; + //config_attrs[i++] = 1; + } + else + { + config_attrs[i++] = 24; + //config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT; + //config_attrs[i++] = 1; + } + } + if (sfc->depth_fmt) + { + config_attrs[i++] = GLX_DEPTH_SIZE; + config_attrs[i++] = 24; // FIXME: This should depend on the requested bits + } + if (sfc->stencil_fmt) + { + config_attrs[i++] = GLX_STENCIL_SIZE; + config_attrs[i++] = 8; // FIXME: This should depend on the requested bits + } + //config_attrs[i++] = GLX_VISUAL_ID; + //config_attrs[i++] = XVisualIDFromVisual(vis); + config_attrs[i++] = 0; + + cfgs = glXChooseFBConfig(re->software.ob->disp, re->software.ob->screen, + config_attrs, &ncfg); + if (!cfgs || !ncfg) + { + ERR("GLX failed to find a valid config for the pbuffer"); + if (cfgs) XFree(cfgs); + return NULL; + } + + i = 0; + surface_attrs[i++] = GLX_LARGEST_PBUFFER; + surface_attrs[i++] = 0; + surface_attrs[i++] = GLX_PBUFFER_WIDTH; + surface_attrs[i++] = sfc->w; + surface_attrs[i++] = GLX_PBUFFER_HEIGHT; + surface_attrs[i++] = sfc->h; + surface_attrs[i++] = 0; + pbuf = glXCreatePbuffer(re->software.ob->disp, cfgs[0], surface_attrs); + if (cfgs) XFree(cfgs); + + if (!pbuf) + { + ERR("GLX failed to create a pbuffer"); + return NULL; + } + + return (void*)(intptr_t)pbuf; +#endif +} + +static int +evgl_eng_pbuffer_surface_destroy(void *data, void *surface) +{ + /* EVGLINIT(re, 0); */ + if (!data) + { + ERR("Invalid Render Engine Data!"); + glsym_evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED); + return 0; + } + + if (!surface) + { + ERR("Invalid surface."); + glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE); + return 0; + } + +#ifdef GL_GLES + Render_Engine *re = data; + + eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface); +#else + Render_Engine_GL_Generic *re = data; + GLXPbuffer pbuf = (GLXPbuffer)(intptr_t) surface; + + glXDestroyPbuffer(re->software.ob->disp, pbuf); #endif + + return 1; } // This function should create a surface that can be used for offscreen rendering @@ -808,9 +908,12 @@ evgl_eng_gles1_surface_create(void *data, EVGL_Surface *evgl_sfc, return evgl_sfc; #else -#warning GLX support is not implemented for GLES 1.x - CRIT("Not implemented yet! (GLX for GLES 1)"); - return NULL; + evgl_sfc->gles1_indirect = EINA_TRUE; + evgl_sfc->xpixmap = EINA_TRUE; + evgl_sfc->gles1_sfc_native = (void *)(intptr_t) px; + evgl_sfc->gles1_sfc = (void *)(intptr_t) px; + evgl_sfc->gles1_sfc_visual = eng_get_ob(re)->info->info.visual; // FIXME: Check this! + return evgl_sfc; #endif } @@ -837,11 +940,6 @@ evgl_eng_gles1_surface_destroy(void *data, EVGL_Surface *evgl_sfc) } eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)evgl_sfc->gles1_sfc); - -#else -#warning GLX support is not implemented for GLES 1.x - CRIT("Not implemented yet! (GLX for GLES 1)"); - return 0; #endif if (!evgl_sfc->gles1_sfc_native) @@ -871,6 +969,7 @@ static const EVGL_Interface evgl_funcs = evgl_eng_string_get, evgl_eng_rotation_angle_get, evgl_eng_pbuffer_surface_create, + evgl_eng_pbuffer_surface_destroy, evgl_eng_gles1_surface_create, evgl_eng_gles1_surface_destroy, }; diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index bcc5869..853fa25 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -471,7 +471,11 @@ static const EVGL_Interface evgl_funcs = evgl_eng_make_current, evgl_eng_proc_address_get, evgl_eng_string_get, - evgl_eng_rotation_angle_get + evgl_eng_rotation_angle_get, + NULL, // PBuffer + NULL, // PBuffer + NULL, // OpenGL-ES 1 + NULL, // OpenGL-ES 1 }; /* engine functions */ --
