forked from enlightenment/efl
Evas GL: Add indirect surface fallback and yinvert callback
Summary: When either FBO or EGL image from texture extension is not supported, we can use pixmap surface as indirect surface fallback. Since native pixmaps have (0,0) in the upper left while FBOs have (0,0) in the lower left, we should invert the y coordinates when native pixmaps are used as the render target. To accomodate run-time y-invert check we add a new callback for EVAS_NATIVE_SURFACE_EVASGL type. Reviewers: cedric, jpeg Subscribers: wonsik, mer.kim, cedric
This commit is contained in:
parent
63e057bff9
commit
b0d2643f93
|
@ -657,9 +657,10 @@ struct _Evas_GL_Image
|
|||
struct {
|
||||
void *data;
|
||||
struct {
|
||||
void (*bind) (void *data, void *image);
|
||||
void (*unbind) (void *data, void *image);
|
||||
void (*free) (void *data, void *image);
|
||||
void (*bind) (void *data, void *image);
|
||||
void (*unbind) (void *data, void *image);
|
||||
void (*free) (void *data, void *image);
|
||||
int (*yinvert) (void *data, void *image);
|
||||
void *data;
|
||||
} func;
|
||||
int yinvert;
|
||||
|
|
|
@ -2029,6 +2029,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
|
|||
Evas_GL_Shader shader = SHADER_IMG;
|
||||
GLuint prog = gc->shared->shader[shader].prog;
|
||||
int pn = 0, sam = 0, render_op = gc->dc->render_op, nomul = 0;
|
||||
int yinvert = 0;
|
||||
|
||||
if (!!mtex)
|
||||
{
|
||||
|
@ -2121,7 +2122,15 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
|
|||
ox4 = sx;
|
||||
oy4 = sy + sh;
|
||||
|
||||
if (tex->im)
|
||||
if ((tex->im) && (tex->im->native.data))
|
||||
{
|
||||
if (tex->im->native.func.yinvert)
|
||||
yinvert = tex->im->native.func.yinvert(tex->im->native.func.data, tex->im);
|
||||
else
|
||||
yinvert = tex->im->native.yinvert;
|
||||
}
|
||||
|
||||
if ((tex->im) && (tex->im->native.data) && (!yinvert))
|
||||
{
|
||||
switch (tex->im->orient)
|
||||
{
|
||||
|
@ -2707,7 +2716,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
|
|||
Eina_Bool use_texa = EINA_FALSE;
|
||||
Shader_Type type;
|
||||
int pn = 0, i;
|
||||
int flat = 0, nomul = 0;
|
||||
int flat = 0, nomul = 0, yinvert = 0;
|
||||
GLuint prog;
|
||||
|
||||
if (!(gc->dc->render_op == EVAS_RENDER_COPY) &&
|
||||
|
@ -2868,7 +2877,15 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
|
|||
pipe_region_expand(gc, pn, x, y, w, h);
|
||||
PIPE_GROW(gc, pn, 6);
|
||||
|
||||
if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
|
||||
if ((tex->im) && (tex->im->native.data))
|
||||
{
|
||||
if (tex->im->native.func.yinvert)
|
||||
yinvert = tex->im->native.func.yinvert(tex->im->native.func.data, tex->im);
|
||||
else
|
||||
yinvert = tex->im->native.yinvert;
|
||||
}
|
||||
|
||||
if ((tex->im) && (tex->im->native.data) && (!yinvert))
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
|
|
|
@ -239,32 +239,36 @@ _texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_
|
|||
}
|
||||
|
||||
static void *
|
||||
_egl_image_create(EVGL_Context *context, GLuint tex)
|
||||
_egl_image_create(EVGL_Context *context, int target, void *buffer)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
EGLContext ctx = EGL_NO_CONTEXT;
|
||||
EVGL_Resource *rsc = NULL;
|
||||
int attribs[10];
|
||||
int n = 0;
|
||||
|
||||
int attribs[] = {
|
||||
EGL_GL_TEXTURE_LEVEL_KHR, 0,
|
||||
EGL_IMAGE_PRESERVED_KHR, 0,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// Retrieve the resource object
|
||||
if (!(rsc = _evgl_tls_resource_get()))
|
||||
{
|
||||
ERR("Error creating resources in tls.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dpy = (EGLDisplay)rsc->display;
|
||||
ctx = (EGLContext)context->context;
|
||||
|
||||
return EXT_FUNC(eglCreateImage)(dpy, ctx, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(uintptr_t)tex, attribs);
|
||||
dpy = (EGLDisplay)rsc->display;
|
||||
if (target == EGL_GL_TEXTURE_2D_KHR)
|
||||
{
|
||||
ctx = (EGLContext)context->context;
|
||||
attribs[n++] = EGL_GL_TEXTURE_LEVEL_KHR;
|
||||
attribs[n++] = 0;
|
||||
}
|
||||
attribs[n++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[n++] = 0;
|
||||
attribs[n++] = EGL_NONE;
|
||||
|
||||
return EXT_FUNC(eglCreateImage)(dpy, ctx, target, (EGLClientBuffer)(uintptr_t)buffer, attribs);
|
||||
#else
|
||||
(void) context; (void) tex;
|
||||
(void) context; (void) target; (void) buffer;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
@ -856,6 +860,10 @@ _surface_cap_init(void *eng_data)
|
|||
static int
|
||||
_context_ext_check(EVGL_Context *ctx)
|
||||
{
|
||||
int fbo_supported = 0;
|
||||
int egl_image_supported = 0;
|
||||
int texture_image_supported = 0;
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
|
@ -863,9 +871,6 @@ _context_ext_check(EVGL_Context *ctx)
|
|||
return 1;
|
||||
|
||||
#ifdef GL_GLES
|
||||
int fbo_supported = 0;
|
||||
int egl_image_supported = 0;
|
||||
|
||||
switch (ctx->version)
|
||||
{
|
||||
case EVAS_GL_GLES_1_X:
|
||||
|
@ -878,21 +883,31 @@ _context_ext_check(EVGL_Context *ctx)
|
|||
fbo_supported = 1;
|
||||
}
|
||||
|
||||
if (EXTENSION_SUPPORT(EGL_KHR_image_base)
|
||||
&& EXTENSION_SUPPORT(EGL_KHR_gl_texture_2D_image))
|
||||
if (EXTENSION_SUPPORT(EGL_KHR_image_base))
|
||||
egl_image_supported = 1;
|
||||
|
||||
if (fbo_supported && egl_image_supported)
|
||||
ctx->fbo_image_supported = 1;
|
||||
if (EXTENSION_SUPPORT(EGL_KHR_gl_texture_2D_image))
|
||||
texture_image_supported = 1;
|
||||
#else
|
||||
ctx->fbo_image_supported = 1;
|
||||
fbo_supported = 1;
|
||||
egl_image_supported = 0;
|
||||
texture_image_supported = 0;
|
||||
#endif
|
||||
|
||||
if (egl_image_supported)
|
||||
{
|
||||
if (fbo_supported && texture_image_supported)
|
||||
ctx->fbo_image_supported = 1;
|
||||
else
|
||||
ctx->pixmap_image_supported = 1;
|
||||
}
|
||||
|
||||
ctx->extension_checked = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
_glenum_string_get(GLenum e)
|
||||
{
|
||||
|
@ -1179,7 +1194,7 @@ _surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int m
|
|||
sfc->egl_image = NULL;
|
||||
}
|
||||
if ((sfc->current_ctx) && (sfc->current_ctx->fbo_image_supported) && (w) && (h))
|
||||
sfc->egl_image = _egl_image_create(sfc->current_ctx, sfc->color_buf);
|
||||
sfc->egl_image = _egl_image_create(sfc->current_ctx, EGL_GL_TEXTURE_2D_KHR, (void *)(uintptr_t)sfc->color_buf);
|
||||
|
||||
sfc->buffer_mem[0] = w * h * 4;
|
||||
}
|
||||
|
@ -1792,6 +1807,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONFIG);
|
||||
goto error;
|
||||
}
|
||||
sfc->cfg = cfg;
|
||||
|
||||
// Keep track of all the created surfaces
|
||||
LKL(evgl_engine->resource_lock);
|
||||
|
@ -1865,6 +1881,7 @@ evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg,
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
sfc->cfg = cfg;
|
||||
|
||||
pbuffer = evgl_engine->funcs->pbuffer_surface_create
|
||||
(eng_data, sfc, attrib_list);
|
||||
|
@ -2320,7 +2337,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
if (!ctx->fbo_image_supported)
|
||||
if (ctx->pixmap_image_supported)
|
||||
{
|
||||
if (dbg) DBG("ctx %p is GLES %d", ctx, ctx->version);
|
||||
if (_evgl_direct_renderable(rsc, sfc))
|
||||
|
@ -2338,12 +2355,17 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!sfc->indirect_sfc)
|
||||
{
|
||||
evgl_engine->funcs->indirect_surface_create(evgl_engine, eng_data, sfc, sfc->cfg, sfc->w, sfc->h);
|
||||
sfc->egl_image = _egl_image_create(NULL, EVAS_GL_NATIVE_PIXMAP, sfc->indirect_sfc_native);
|
||||
}
|
||||
if (!ctx->indirect_context)
|
||||
{
|
||||
ctx->indirect_context =
|
||||
evgl_engine->funcs->gles_context_create(eng_data, ctx, sfc);
|
||||
}
|
||||
if (dbg) DBG("Calling make_current(%p, %p)", sfc->indirect_sfc, ctx->context);
|
||||
if (dbg) DBG("Calling make_current(%p, %p)", sfc->indirect_sfc, ctx->indirect_context);
|
||||
if (!evgl_engine->funcs->make_current(eng_data, sfc->indirect_sfc,
|
||||
ctx->indirect_context, EINA_TRUE))
|
||||
{
|
||||
|
@ -2559,6 +2581,22 @@ evgl_native_surface_buffer_get(EVGL_Surface *sfc)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
evgl_native_surface_yinvert_get(EVGL_Surface *sfc)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!evgl_engine)
|
||||
{
|
||||
ERR("Invalid input data. Engine: %p", evgl_engine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sfc->indirect)
|
||||
ret = sfc->yinvert;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
|
||||
{
|
||||
|
|
|
@ -44,13 +44,12 @@ typedef struct _EVGL_Surface_Cap EVGL_Surface_Cap;
|
|||
typedef struct _EVGL_Surface_Format EVGL_Surface_Format;
|
||||
|
||||
EAPI void evgl_engine_shutdown(void *eng_data);
|
||||
EAPI void *evgl_native_surface_buffer_get(EVGL_Surface *sfc);
|
||||
EAPI int evgl_native_surface_yinvert_get(EVGL_Surface *sfc);
|
||||
|
||||
typedef void (*EVGL_Engine_Call)(void *eng_data);
|
||||
|
||||
EAPI void *evgl_native_surface_buffer_get(EVGL_Surface *sfc);
|
||||
|
||||
typedef void *(*EVGL_Native_Surface_Call)(void *sfc);
|
||||
|
||||
typedef int (*EVGL_Native_Surface_Yinvert_Call)(void *sfc);
|
||||
|
||||
EVGL_Engine *evgl_engine_init(void *eng_data, const EVGL_Interface *efunc);
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ struct _EVGL_Surface
|
|||
|
||||
// Flag indicating this surface is used for indirect rendering
|
||||
unsigned indirect : 1;
|
||||
unsigned yinvert : 1;
|
||||
|
||||
// Moved from evgl_engine
|
||||
unsigned direct_override : 1;
|
||||
|
@ -124,6 +125,7 @@ struct _EVGL_Surface
|
|||
// Init Flag
|
||||
unsigned buffers_allocated : 1;
|
||||
|
||||
void *cfg;
|
||||
int cfg_index;
|
||||
|
||||
|
||||
|
@ -174,6 +176,7 @@ struct _EVGL_Context
|
|||
unsigned viewport_updated : 1;
|
||||
unsigned extension_checked : 1;
|
||||
unsigned fbo_image_supported : 1;
|
||||
unsigned pixmap_image_supported : 1;
|
||||
|
||||
int scissor_coord[4];
|
||||
int viewport_coord[4];
|
||||
|
|
|
@ -60,6 +60,7 @@ Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
|
|||
Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
|
||||
EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
|
||||
EVGL_Native_Surface_Call glsym_evgl_native_surface_buffer_get = NULL;
|
||||
EVGL_Native_Surface_Yinvert_Call glsym_evgl_native_surface_yinvert_get = NULL;
|
||||
Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
|
||||
|
||||
Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
|
||||
|
@ -893,8 +894,7 @@ evgl_eng_indirect_surface_create(EVGL_Engine *evgl EINA_UNUSED, void *data,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (((cfg->gles_version != EVAS_GL_GLES_3_X) && (cfg->gles_version != EVAS_GL_GLES_1_X))
|
||||
|| (w < 1) || (h < 1))
|
||||
if ((w < 1) || (h < 1))
|
||||
{
|
||||
ERR("Inconsistent parameters, not creating any surface!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
||||
|
@ -932,6 +932,7 @@ evgl_eng_indirect_surface_create(EVGL_Engine *evgl EINA_UNUSED, void *data,
|
|||
int msaa = 0, depth = 0, stencil = 0;
|
||||
Visual *visual = NULL;
|
||||
Eina_Bool retried = EINA_FALSE;
|
||||
int val;
|
||||
|
||||
/* Now we need to iterate over all EGL configurations to check the compatible
|
||||
* ones and finally check their visual ID. */
|
||||
|
@ -955,6 +956,8 @@ try_again:
|
|||
config_attrs[i++] = EGL_RENDERABLE_TYPE;
|
||||
if (cfg->gles_version == EVAS_GL_GLES_3_X)
|
||||
config_attrs[i++] = EGL_OPENGL_ES3_BIT;
|
||||
else if (cfg->gles_version == EVAS_GL_GLES_2_X)
|
||||
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
|
||||
else
|
||||
config_attrs[i++] = EGL_OPENGL_ES_BIT;
|
||||
if (alpha)
|
||||
|
@ -1084,6 +1087,13 @@ try_again:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (extn_have_y_inverted &&
|
||||
eglGetConfigAttrib(eng_get_ob(re)->egl_disp, egl_cfg,
|
||||
EGL_Y_INVERTED_NOK, &val))
|
||||
evgl_sfc->yinvert = val;
|
||||
else
|
||||
evgl_sfc->yinvert = 1;
|
||||
|
||||
evgl_sfc->indirect = EINA_TRUE;
|
||||
evgl_sfc->indirect_sfc = egl_sfc;
|
||||
evgl_sfc->indirect_sfc_native = (void *)(intptr_t) px;
|
||||
|
@ -1171,7 +1181,7 @@ evgl_eng_gles_context_create(void *data,
|
|||
else config = sfc->indirect_sfc_config;
|
||||
|
||||
context = eglCreateContext(eng_get_ob(re)->egl_disp, config,
|
||||
share_ctx ? share_ctx->context : NULL,
|
||||
share_ctx->context,
|
||||
context_attrs);
|
||||
if (!context)
|
||||
{
|
||||
|
@ -1269,6 +1279,7 @@ gl_symbols(void)
|
|||
LINK2GENERIC(evas_gl_preload_shutdown);
|
||||
LINK2GENERIC(evgl_engine_shutdown);
|
||||
LINK2GENERIC(evgl_native_surface_buffer_get);
|
||||
LINK2GENERIC(evgl_native_surface_yinvert_get);
|
||||
LINK2GENERIC(evas_gl_symbols);
|
||||
LINK2GENERIC(evas_gl_common_error_get);
|
||||
LINK2GENERIC(evas_gl_common_error_set);
|
||||
|
@ -1961,12 +1972,14 @@ struct _Native
|
|||
Visual *visual;
|
||||
void *buffer;
|
||||
|
||||
void *egl_surface;
|
||||
|
||||
void *config;
|
||||
void *surface;
|
||||
/*
|
||||
#ifndef GL_GLES
|
||||
void *fbc;
|
||||
XID glx_pixmap;
|
||||
#endif
|
||||
*/
|
||||
};
|
||||
|
||||
// FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
|
||||
|
@ -1987,11 +2000,11 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
if (n->surface)
|
||||
{
|
||||
if (glsym_glEGLImageTargetTexture2DOES)
|
||||
{
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->surface);
|
||||
if (eglGetError() != EGL_SUCCESS)
|
||||
ERR("glEGLImageTargetTexture2DOES() failed.");
|
||||
}
|
||||
|
@ -2004,7 +2017,7 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
|
||||
if (glsym_glXBindTexImage)
|
||||
{
|
||||
glsym_glXBindTexImage(eng_get_ob(re)->disp, n->glx_pixmap,
|
||||
glsym_glXBindTexImage(eng_get_ob(re)->disp, (XID)n->surface,
|
||||
GLX_FRONT_LEFT_EXT, NULL);
|
||||
GLERRV("glsym_glXBindTexImage");
|
||||
}
|
||||
|
@ -2020,11 +2033,11 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
if (n->surface)
|
||||
{
|
||||
if (glsym_glEGLImageTargetTexture2DOES)
|
||||
{
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, n->egl_surface);
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, n->surface);
|
||||
if (eglGetError() != EGL_SUCCESS)
|
||||
ERR("glEGLImageTargetTexture2DOES() failed.");
|
||||
}
|
||||
|
@ -2035,10 +2048,10 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
if (n->egl_surface)
|
||||
if (n->surface)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
void *surface = glsym_evgl_native_surface_buffer_get(n->egl_surface);
|
||||
void *surface = glsym_evgl_native_surface_buffer_get(n->surface);
|
||||
if (glsym_glEGLImageTargetTexture2DOES)
|
||||
{
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
|
||||
|
@ -2048,7 +2061,7 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
else
|
||||
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
||||
#else
|
||||
GLuint tex = (GLuint)(uintptr_t)glsym_evgl_native_surface_buffer_get(n->egl_surface);
|
||||
GLuint tex = (GLuint)(uintptr_t)glsym_evgl_native_surface_buffer_get(n->surface);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
#endif
|
||||
}
|
||||
|
@ -2071,7 +2084,7 @@ _native_unbind_cb(void *data EINA_UNUSED, void *image)
|
|||
|
||||
if (glsym_glXReleaseTexImage)
|
||||
{
|
||||
glsym_glXReleaseTexImage(eng_get_ob(re)->disp, n->glx_pixmap,
|
||||
glsym_glXReleaseTexImage(eng_get_ob(re)->disp, (XID)n->surface,
|
||||
GLX_FRONT_LEFT_EXT);
|
||||
}
|
||||
else
|
||||
|
@ -2110,13 +2123,13 @@ _native_free_cb(void *data, void *image)
|
|||
pmid = n->pixmap;
|
||||
eina_hash_del(eng_get_ob(re)->gl_context->shared->native_pm_hash, &pmid, im);
|
||||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
if (n->surface)
|
||||
{
|
||||
int err;
|
||||
if (glsym_eglDestroyImage)
|
||||
{
|
||||
glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
|
||||
n->egl_surface);
|
||||
n->surface);
|
||||
if ((err = eglGetError()) != EGL_SUCCESS)
|
||||
{
|
||||
ERR("eglDestroyImage() failed.");
|
||||
|
@ -2128,13 +2141,13 @@ _native_free_cb(void *data, void *image)
|
|||
}
|
||||
#else
|
||||
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
||||
if (n->glx_pixmap)
|
||||
if (n->surface)
|
||||
{
|
||||
if (im->native.loose)
|
||||
{
|
||||
if (glsym_glXReleaseTexImage)
|
||||
{
|
||||
glsym_glXReleaseTexImage(eng_get_ob(re)->disp, n->glx_pixmap,
|
||||
glsym_glXReleaseTexImage(eng_get_ob(re)->disp, (XID)n->surface,
|
||||
GLX_FRONT_LEFT_EXT);
|
||||
}
|
||||
else
|
||||
|
@ -2142,12 +2155,12 @@ _native_free_cb(void *data, void *image)
|
|||
}
|
||||
if (glsym_glXDestroyPixmap)
|
||||
{
|
||||
glsym_glXDestroyPixmap(eng_get_ob(re)->disp, n->glx_pixmap);
|
||||
glsym_glXDestroyPixmap(eng_get_ob(re)->disp, (XID)n->surface);
|
||||
GLERRV("glsym_glXDestroyPixmap");
|
||||
}
|
||||
else
|
||||
ERR("Try glXDestroyPixmap on GLX with no support");
|
||||
n->glx_pixmap = 0;
|
||||
n->surface = 0;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
@ -2161,13 +2174,13 @@ _native_free_cb(void *data, void *image)
|
|||
{
|
||||
eina_hash_del(eng_get_ob(re)->gl_context->shared->native_tbm_hash, &n->buffer, im);
|
||||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
if (n->surface)
|
||||
{
|
||||
int err;
|
||||
if (glsym_eglDestroyImage)
|
||||
{
|
||||
glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
|
||||
n->egl_surface);
|
||||
n->surface);
|
||||
if ((err = eglGetError()) != EGL_SUCCESS)
|
||||
{
|
||||
ERR("eglDestroyImage() failed.");
|
||||
|
@ -2191,6 +2204,45 @@ _native_free_cb(void *data, void *image)
|
|||
free(n);
|
||||
}
|
||||
|
||||
static int
|
||||
_native_yinvert_cb(void *data, void *image)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
Evas_GL_Image *im = image;
|
||||
Native *n = im->native.data;
|
||||
int yinvert = 0, val;
|
||||
|
||||
// Yinvert callback should only be used for EVAS_NATIVE_SURFACE_EVASGL type now,
|
||||
// as yinvert value is not changed for other types.
|
||||
if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
|
||||
{
|
||||
#if GL_GLES
|
||||
if (extn_have_y_inverted &&
|
||||
eglGetConfigAttrib(eng_get_ob(re)->egl_disp, n->config,
|
||||
EGL_Y_INVERTED_NOK, &val))
|
||||
yinvert = val;
|
||||
#else
|
||||
glXGetFBConfigAttrib(eng_get_ob(re)->disp, n->config,
|
||||
GLX_Y_INVERTED_EXT, &val);
|
||||
yinvert = val;
|
||||
#endif
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
||||
{
|
||||
yinvert = 0;
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
|
||||
{
|
||||
yinvert = 1;
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
yinvert = glsym_evgl_native_surface_yinvert_get(n->surface);
|
||||
}
|
||||
|
||||
return yinvert;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_image_native_set(void *data, void *image, void *native)
|
||||
{
|
||||
|
@ -2406,15 +2458,17 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
n->pixmap = pm;
|
||||
n->visual = vis;
|
||||
if (glsym_eglCreateImage)
|
||||
n->egl_surface = glsym_eglCreateImage(eng_get_ob(re)->egl_disp,
|
||||
n->surface = glsym_eglCreateImage(eng_get_ob(re)->egl_disp,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_PIXMAP_KHR,
|
||||
(void *)pm,
|
||||
NULL);
|
||||
else
|
||||
ERR("Try eglCreateImage on EGL with no support");
|
||||
if (!n->egl_surface)
|
||||
if (!n->surface)
|
||||
ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
|
||||
n->config = (void *)egl_config;
|
||||
|
||||
im->native.yinvert = yinvert;
|
||||
im->native.loose = 0;
|
||||
im->native.data = n;
|
||||
|
@ -2537,7 +2591,7 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
glXGetFBConfigAttrib(eng_get_ob(re)->disp, configs[j],
|
||||
GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
|
||||
mipmap = val;
|
||||
n->fbc = configs[j];
|
||||
n->config = configs[j];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -2582,16 +2636,16 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
n->pixmap = pm;
|
||||
n->visual = vis;
|
||||
if (glsym_glXCreatePixmap)
|
||||
n->glx_pixmap = glsym_glXCreatePixmap(eng_get_ob(re)->disp,
|
||||
n->fbc,
|
||||
n->pixmap,
|
||||
pixmap_att);
|
||||
n->surface = (void *)glsym_glXCreatePixmap(eng_get_ob(re)->disp,
|
||||
n->config,
|
||||
n->pixmap,
|
||||
pixmap_att);
|
||||
else
|
||||
ERR("Try glXCreatePixmap on GLX with no support");
|
||||
if (n->glx_pixmap)
|
||||
if (n->surface)
|
||||
{
|
||||
// printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
|
||||
// n, pm, w, h, depth, n->glx_pixmap);
|
||||
// n, pm, w, h, depth, n->surface);
|
||||
if (!target)
|
||||
{
|
||||
ERR("no target :(");
|
||||
|
@ -2650,12 +2704,8 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
|
||||
n->pixmap = 0;
|
||||
n->visual = 0;
|
||||
#ifdef GL_GLES
|
||||
n->egl_surface = 0;
|
||||
#else
|
||||
n->fbc = 0;
|
||||
n->glx_pixmap = 0;
|
||||
#endif
|
||||
n->config = 0;
|
||||
n->surface = 0;
|
||||
|
||||
im->native.yinvert = 0;
|
||||
im->native.loose = 0;
|
||||
|
@ -2688,14 +2738,14 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
||||
n->buffer = buffer;
|
||||
if (glsym_eglCreateImage)
|
||||
n->egl_surface = glsym_eglCreateImage(eng_get_ob(re)->egl_disp,
|
||||
n->surface = glsym_eglCreateImage(eng_get_ob(re)->egl_disp,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_SURFACE_TIZEN,
|
||||
(void *)buffer,
|
||||
NULL);
|
||||
else
|
||||
ERR("Try eglCreateImage on EGL with no support");
|
||||
if (!n->egl_surface)
|
||||
if (!n->surface)
|
||||
ERR("eglCreateImage() for %p failed", buffer);
|
||||
im->native.yinvert = 1;
|
||||
im->native.loose = 0;
|
||||
|
@ -2725,17 +2775,18 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
n->pixmap = 0;
|
||||
n->visual = 0;
|
||||
|
||||
n->egl_surface = ns->data.evasgl.surface;
|
||||
n->surface = ns->data.evasgl.surface;
|
||||
|
||||
im->native.yinvert = 0;
|
||||
im->native.loose = 0;
|
||||
im->native.data = n;
|
||||
im->native.func.data = re;
|
||||
im->native.func.bind = _native_bind_cb;
|
||||
im->native.func.unbind = _native_unbind_cb;
|
||||
im->native.func.free = _native_free_cb;
|
||||
im->native.target = GL_TEXTURE_2D;
|
||||
im->native.mipmap = 0;
|
||||
im->native.yinvert = 0;
|
||||
im->native.loose = 0;
|
||||
im->native.data = n;
|
||||
im->native.func.data = re;
|
||||
im->native.func.bind = _native_bind_cb;
|
||||
im->native.func.unbind = _native_unbind_cb;
|
||||
im->native.func.free = _native_free_cb;
|
||||
im->native.func.yinvert = _native_yinvert_cb;
|
||||
im->native.target = GL_TEXTURE_2D;
|
||||
im->native.mipmap = 0;
|
||||
|
||||
// FIXME: need to implement mapping sub texture regions
|
||||
// x, y, w, h for possible texture atlasing
|
||||
|
|
Loading…
Reference in New Issue