}
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;
+ 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, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(uintptr_t)tex, attribs);
+ 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
}
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;
return 1;
#ifdef GL_GLES
- int fbo_supported = 0;
- int egl_image_supported = 0;
-
switch (ctx->version)
{
case EVAS_GL_GLES_1_X:
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)
{
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;
}
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);
goto error;
}
}
+ sfc->cfg = cfg;
pbuffer = evgl_engine->funcs->pbuffer_surface_create
(eng_data, sfc, attrib_list);
}
}
- 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))
}
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))
{
}
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)
{
// Check the input
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;
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);
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. */
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)
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;
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)
{
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);
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
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.");
}
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");
}
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.");
}
}
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);
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
}
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
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.");
}
#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
}
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
{
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.");
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)
{
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;
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;
}
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 :(");
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;
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;
n->pixmap = 0;
n->visual = 0;
- n->egl_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;
+ 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.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