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).
This commit is contained in:
parent
9a0e128f23
commit
c17cfbd13e
|
@ -1815,7 +1815,7 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
||||||
if (sfc->pbuffer.fbo)
|
if (sfc->pbuffer.fbo)
|
||||||
glDeleteFramebuffers(1, &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);
|
LKL(evgl_engine->resource_lock);
|
||||||
evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
|
evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
|
||||||
LKU(evgl_engine->resource_lock);
|
LKU(evgl_engine->resource_lock);
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct _EVGL_Interface
|
||||||
|
|
||||||
// Create a pbuffer surface
|
// Create a pbuffer surface
|
||||||
void *(*pbuffer_surface_create)(void *data, EVGL_Surface *evgl_sfc, const int *attrib_list);
|
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)
|
// 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);
|
void *(*gles1_surface_create)(void *data, EVGL_Surface *evgl_sfc, Evas_GL_Config *cfg, int w, int h);
|
||||||
|
|
|
@ -120,6 +120,7 @@ static const EVGL_Interface evgl_funcs =
|
||||||
evgl_eng_string_get,
|
evgl_eng_string_get,
|
||||||
evgl_eng_rotation_angle_get,
|
evgl_eng_rotation_angle_get,
|
||||||
NULL, // PBuffer
|
NULL, // PBuffer
|
||||||
|
NULL, // PBuffer
|
||||||
NULL, // OpenGL-ES 1
|
NULL, // OpenGL-ES 1
|
||||||
NULL, // OpenGL-ES 1
|
NULL, // OpenGL-ES 1
|
||||||
};
|
};
|
||||||
|
|
|
@ -256,6 +256,7 @@ static const EVGL_Interface evgl_funcs =
|
||||||
evgl_eng_string_get,
|
evgl_eng_string_get,
|
||||||
evgl_eng_rotation_angle_get,
|
evgl_eng_rotation_angle_get,
|
||||||
NULL, // PBuffer
|
NULL, // PBuffer
|
||||||
|
NULL, // PBuffer
|
||||||
NULL, // OpenGL-ES 1
|
NULL, // OpenGL-ES 1
|
||||||
NULL, // OpenGL-ES 1
|
NULL, // OpenGL-ES 1
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 surfaceless pbuffers (EGL_NO_TEXTURE)
|
||||||
// TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them)
|
// 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
|
#ifdef GL_GLES
|
||||||
int config_attrs[20];
|
int config_attrs[20];
|
||||||
int surface_attrs[20];
|
int surface_attrs[20];
|
||||||
|
@ -646,9 +649,6 @@ evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
|
||||||
EGLDisplay disp;
|
EGLDisplay disp;
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
|
|
||||||
if (attrib_list)
|
|
||||||
WRN("This PBuffer implementation does not support extra attributes yet");
|
|
||||||
|
|
||||||
disp = re->window_egl_display_get(re->software.ob);
|
disp = re->window_egl_display_get(re->software.ob);
|
||||||
ctx = re->window_gl_context_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;
|
return egl_sfc;
|
||||||
#else
|
#else
|
||||||
ERR("PBuffer support is not implemented yet!");
|
GLXPbuffer pbuf;
|
||||||
return NULL;
|
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
|
#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
|
// 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;
|
return evgl_sfc;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#warning GLX support is not implemented for GLES 1.x
|
evgl_sfc->gles1_indirect = EINA_TRUE;
|
||||||
CRIT("Not implemented yet! (GLX for GLES 1)");
|
evgl_sfc->xpixmap = EINA_TRUE;
|
||||||
return NULL;
|
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
|
#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);
|
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
|
#endif
|
||||||
|
|
||||||
if (!evgl_sfc->gles1_sfc_native)
|
if (!evgl_sfc->gles1_sfc_native)
|
||||||
|
@ -871,6 +969,7 @@ static const EVGL_Interface evgl_funcs =
|
||||||
evgl_eng_string_get,
|
evgl_eng_string_get,
|
||||||
evgl_eng_rotation_angle_get,
|
evgl_eng_rotation_angle_get,
|
||||||
evgl_eng_pbuffer_surface_create,
|
evgl_eng_pbuffer_surface_create,
|
||||||
|
evgl_eng_pbuffer_surface_destroy,
|
||||||
evgl_eng_gles1_surface_create,
|
evgl_eng_gles1_surface_create,
|
||||||
evgl_eng_gles1_surface_destroy,
|
evgl_eng_gles1_surface_destroy,
|
||||||
};
|
};
|
||||||
|
|
|
@ -471,7 +471,11 @@ static const EVGL_Interface evgl_funcs =
|
||||||
evgl_eng_make_current,
|
evgl_eng_make_current,
|
||||||
evgl_eng_proc_address_get,
|
evgl_eng_proc_address_get,
|
||||||
evgl_eng_string_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 */
|
/* engine functions */
|
||||||
|
|
Loading…
Reference in New Issue