forked from enlightenment/efl
Evas GL: Use EGL image to share between Evas GL and GL backend
Summary: When the context version between Evas GL and GL backend differs, we cannot share texture between them. So, when the driver has support for KHR_gl_texture_2D_image extension, use EGL image to share between Evas GL and GL backend Test Plan: Local Evas GL tests for 1.1, 2.0 and 3.0 Reviewers: jpeg Subscribers: mythri, mer.kim, wonsik, cedric Differential Revision: https://phab.enlightenment.org/D2115
This commit is contained in:
parent
eae786917c
commit
d8fc60e0e6
|
@ -461,7 +461,7 @@ struct _Evas_Pixel_Import_Source
|
|||
* Magic version number to know what the native surface struct looks like
|
||||
*/
|
||||
|
||||
#define EVAS_NATIVE_SURFACE_VERSION 3
|
||||
#define EVAS_NATIVE_SURFACE_VERSION 4
|
||||
|
||||
/**
|
||||
* Native surface types that image object supports
|
||||
|
@ -476,6 +476,7 @@ typedef enum _Evas_Native_Surface_Type
|
|||
EVAS_NATIVE_SURFACE_OPENGL, /**< OpenGL system based type. texture or framebuffer id*/
|
||||
EVAS_NATIVE_SURFACE_WL, /**< Wayland system based type. buffer of surface */
|
||||
EVAS_NATIVE_SURFACE_TBM, /**< Tizen system based type. tbm surface */
|
||||
EVAS_NATIVE_SURFACE_EVASGL, /**< Evas GL based type. evas gl surface */
|
||||
} Evas_Native_Surface_Type;
|
||||
|
||||
/**
|
||||
|
@ -532,6 +533,10 @@ struct _Evas_Native_Surface
|
|||
{
|
||||
void *buffer; /**< tbm surface buffer to use */
|
||||
} tbm; /**< Set this struct fields if surface data is Tizen based. */
|
||||
struct
|
||||
{
|
||||
void *surface; /**< evas gl surface to use */
|
||||
} evasgl; /**< Set this struct fields if surface data is Evas GL based. */
|
||||
} data; /**< Choose one union data according to your surface. */
|
||||
};
|
||||
|
||||
|
|
|
@ -50,14 +50,18 @@
|
|||
#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define EXT_FUNC(fname) gl_ext_sym_##fname
|
||||
|
||||
#define EXT_FUNC_GLES1(fname) gles1_ext_sym_##fname
|
||||
#define EXT_FUNC_GLES3(fname) gles3_ext_sym_##fname
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Extension HEADER
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define _EVASGL_EXT_CHECK_SUPPORT(name)
|
||||
#define _EVASGL_EXT_DISCARD_SUPPORT()
|
||||
#define _EVASGL_EXT_BEGIN(name) extern int _gl_ext_support_##name;
|
||||
#define _EVASGL_EXT_BEGIN(name) \
|
||||
extern int _gl_ext_support_##name; \
|
||||
extern int _gles1_ext_support_##name; \
|
||||
extern int _gles3_ext_support_##name;
|
||||
#define _EVASGL_EXT_END()
|
||||
#define _EVASGL_EXT_DRVNAME(name)
|
||||
#define _EVASGL_EXT_DRVNAME_PRIVATE(name)
|
||||
|
@ -86,6 +90,8 @@
|
|||
#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define EXTENSION_SUPPORT(name) (_gl_ext_support_##name == 1)
|
||||
#define EXTENSION_SUPPORT_GLES1(name) (_gles1_ext_support_##name == 1)
|
||||
#define EXTENSION_SUPPORT_GLES3(name) (_gles3_ext_support_##name == 1)
|
||||
|
||||
extern Eina_Bool evgl_api_ext_init(void *getproc, const char *glueexts);
|
||||
extern void evgl_api_ext_get(Evas_GL_API *gl_funcs);
|
||||
|
|
|
@ -390,6 +390,7 @@ struct _Evas_GL_Shared
|
|||
Eina_Hash *native_tex_hash;
|
||||
Eina_Hash *native_wl_hash;
|
||||
Eina_Hash *native_tbm_hash;
|
||||
Eina_Hash *native_evasgl_hash;
|
||||
|
||||
#ifdef GL_GLES
|
||||
// FIXME: hack.
|
||||
|
|
|
@ -965,6 +965,7 @@ evas_gl_common_context_new(void)
|
|||
shared->native_tex_hash = eina_hash_int32_new(NULL);
|
||||
shared->native_wl_hash = eina_hash_pointer_new(NULL);
|
||||
shared->native_tbm_hash = eina_hash_pointer_new(NULL);
|
||||
shared->native_evasgl_hash = eina_hash_pointer_new(NULL);
|
||||
}
|
||||
gc->shared = shared;
|
||||
gc->shared->references++;
|
||||
|
@ -1040,6 +1041,7 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
|
|||
eina_hash_free(gc->shared->native_tex_hash);
|
||||
eina_hash_free(gc->shared->native_wl_hash);
|
||||
eina_hash_free(gc->shared->native_tbm_hash);
|
||||
eina_hash_free(gc->shared->native_evasgl_hash);
|
||||
free(gc->shared);
|
||||
shared = NULL;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,14 @@ _internal_resources_create(void *eng_data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Get display
|
||||
rsc->display = evgl_engine->funcs->display_get(eng_data);
|
||||
if (!rsc->display)
|
||||
{
|
||||
ERR("Error getting display");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Create resource surface
|
||||
rsc->window = evgl_engine->funcs->native_window_create(eng_data);
|
||||
if (!rsc->window)
|
||||
|
@ -75,7 +83,7 @@ _internal_resources_create(void *eng_data)
|
|||
rsc->context = evgl_engine->funcs->context_create(eng_data, NULL, EVAS_GL_GLES_2_X);
|
||||
if (!rsc->context)
|
||||
{
|
||||
ERR("Internal resource context creations failed.");
|
||||
ERR("Internal resource context creation failed.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -168,7 +176,7 @@ _texture_allocate_2d(GLuint tex, GLint ifmt, GLenum fmt, GLenum type, int w, int
|
|||
{
|
||||
//if (!(*tex))
|
||||
// glGenTextures(1, tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex );
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -191,8 +199,11 @@ _texture_destroy(GLuint *tex)
|
|||
// Attach 2D texture with the given format to already bound FBO
|
||||
// *NOTE: attach2 here is used for depth_stencil attachment in GLES env.
|
||||
void
|
||||
_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples)
|
||||
_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_Bool use_ext)
|
||||
{
|
||||
#define FBO_FUNC(name, param) \
|
||||
(use_ext)?(gles1_funcs->name##OES param):((name) param)
|
||||
|
||||
if (samples)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
|
@ -213,12 +224,38 @@ _texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples)
|
|||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
|
||||
FBO_FUNC(glFramebufferTexture2D, (GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0));
|
||||
|
||||
if (attach2)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0);
|
||||
FBO_FUNC(glFramebufferTexture2D, (GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0));
|
||||
|
||||
}
|
||||
#undef FBO_FUNC
|
||||
}
|
||||
|
||||
void
|
||||
_egl_image_attach_texture(EVGL_Context *context, EvasGLImage *image, GLuint tex)
|
||||
{
|
||||
EVGLNative_Display dpy = EGL_NO_DISPLAY;
|
||||
EVGLNative_Context ctx = EGL_NO_CONTEXT;
|
||||
EVGL_Resource *rsc = NULL;
|
||||
int attribs[] = {
|
||||
EVAS_GL_TEXTURE_LEVEL, 0,
|
||||
EVAS_GL_IMAGE_PRESERVED, 0,
|
||||
EVAS_GL_NONE
|
||||
};
|
||||
|
||||
// Retrieve the resource object
|
||||
if (!(rsc = _evgl_tls_resource_get()))
|
||||
{
|
||||
ERR("Error creating resources in tls.");
|
||||
return;
|
||||
}
|
||||
|
||||
dpy = (EVGLNative_Display)rsc->display;
|
||||
ctx = context->context;
|
||||
|
||||
*image = EXT_FUNC(eglCreateImage)(dpy, ctx, EVAS_GL_TEXTURE_2D, (EGLClientBuffer)tex, attribs);
|
||||
}
|
||||
|
||||
// Gen Renderbuffer
|
||||
|
@ -260,9 +297,13 @@ _renderbuffer_destroy(GLuint *buf)
|
|||
|
||||
// Attach a renderbuffer with the given format to already bound FBO
|
||||
void
|
||||
_renderbuffer_attach(GLuint buf, GLenum attach)
|
||||
_renderbuffer_attach(GLuint buf, GLenum attach, Eina_Bool use_ext)
|
||||
{
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
|
||||
#define FBO_FUNC(name, param) \
|
||||
(use_ext)?(gles1_funcs->name##OES param):((name) param)
|
||||
|
||||
FBO_FUNC(glFramebufferRenderbuffer, (GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf));
|
||||
#undef FBO_FUNC
|
||||
}
|
||||
|
||||
// Check whether the given FBO surface config is supported by the driver
|
||||
|
@ -288,7 +329,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
|||
{
|
||||
_texture_create(&color_buf);
|
||||
_texture_allocate_2d(color_buf, color_ifmt, color_fmt, GL_UNSIGNED_BYTE, w, h);
|
||||
_texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples);
|
||||
_texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples, EINA_FALSE);
|
||||
}
|
||||
|
||||
// Check Depth_Stencil Format First
|
||||
|
@ -299,7 +340,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
|||
_texture_allocate_2d(depth_stencil_buf, depth_fmt,
|
||||
depth_fmt, GL_UNSIGNED_INT_24_8_OES, w, h);
|
||||
_texture_attach_2d(depth_stencil_buf, GL_DEPTH_ATTACHMENT,
|
||||
GL_STENCIL_ATTACHMENT, mult_samples);
|
||||
GL_STENCIL_ATTACHMENT, mult_samples, EINA_FALSE);
|
||||
depth_stencil = 1;
|
||||
}
|
||||
#else
|
||||
|
@ -307,7 +348,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
|||
{
|
||||
_renderbuffer_create(&depth_stencil_buf);
|
||||
_renderbuffer_allocate(depth_stencil_buf, depth_fmt, w, h, mult_samples);
|
||||
_renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
_renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, EINA_FALSE);
|
||||
depth_stencil = 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -317,7 +358,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
|||
{
|
||||
_renderbuffer_create(&depth_buf);
|
||||
_renderbuffer_allocate(depth_buf, depth_fmt, w, h, mult_samples);
|
||||
_renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT);
|
||||
_renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT, EINA_FALSE);
|
||||
}
|
||||
|
||||
// Stencil Attachment
|
||||
|
@ -325,7 +366,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
|||
{
|
||||
_renderbuffer_create(&stencil_buf);
|
||||
_renderbuffer_allocate(stencil_buf, stencil_fmt, w, h, mult_samples);
|
||||
_renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT);
|
||||
_renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT, EINA_FALSE);
|
||||
}
|
||||
|
||||
// Check FBO for completeness
|
||||
|
@ -730,6 +771,42 @@ _surface_cap_init(void *eng_data)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_context_ext_check(EVGL_Context *ctx)
|
||||
{
|
||||
int fbo_supported = 0;
|
||||
int egl_image_supported = 0;
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
if (ctx->extension_checked)
|
||||
return 1;
|
||||
|
||||
switch (ctx->version)
|
||||
{
|
||||
case EVAS_GL_GLES_1_X:
|
||||
if (EXTENSION_SUPPORT_GLES1(framebuffer_object))
|
||||
fbo_supported = 1;
|
||||
break;
|
||||
case EVAS_GL_GLES_3_X:
|
||||
case EVAS_GL_GLES_2_X:
|
||||
default:
|
||||
fbo_supported = 1;
|
||||
}
|
||||
|
||||
if (EXTENSION_SUPPORT(EGL_KHR_image_base)
|
||||
&& EXTENSION_SUPPORT(EGL_KHR_gl_texture_2D_image))
|
||||
egl_image_supported = 1;
|
||||
|
||||
if (fbo_supported && egl_image_supported)
|
||||
ctx->extension_supported = 1;
|
||||
|
||||
ctx->extension_checked = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_glenum_string_get(GLenum e)
|
||||
{
|
||||
|
@ -909,54 +986,58 @@ _surface_context_list_print()
|
|||
// Start from here.....
|
||||
//--------------------------------------------------------//
|
||||
static int
|
||||
_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo)
|
||||
_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo, Eina_Bool use_ext)
|
||||
{
|
||||
int status;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
#define FBO_FUNC(name, param) \
|
||||
(use_ext)?(gles1_funcs->name##OES param):((name) param)
|
||||
|
||||
FBO_FUNC(glBindFramebuffer, (GL_FRAMEBUFFER, fbo));
|
||||
|
||||
// Detach any previously attached buffers
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
FBO_FUNC(glFramebufferTexture2D, (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0));
|
||||
FBO_FUNC(glFramebufferRenderbuffer, (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0));
|
||||
FBO_FUNC(glFramebufferRenderbuffer, (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0));
|
||||
#ifdef GL_GLES
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
FBO_FUNC(glFramebufferTexture2D, (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0));
|
||||
FBO_FUNC(glFramebufferTexture2D, (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0));
|
||||
#else
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
FBO_FUNC(glFramebufferRenderbuffer, (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0));
|
||||
#endif
|
||||
|
||||
// Render Target Texture
|
||||
if (sfc->color_buf)
|
||||
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples);
|
||||
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, use_ext);
|
||||
|
||||
// Depth Stencil RenderBuffer - Attach it to FBO
|
||||
if (sfc->depth_stencil_buf)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
_texture_attach_2d(sfc->depth_stencil_buf, GL_DEPTH_ATTACHMENT,
|
||||
GL_STENCIL_ATTACHMENT, sfc->msaa_samples);
|
||||
GL_STENCIL_ATTACHMENT, sfc->msaa_samples, use_ext);
|
||||
#else
|
||||
_renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT);
|
||||
_renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, use_ext);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Depth RenderBuffer - Attach it to FBO
|
||||
if (sfc->depth_buf)
|
||||
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT);
|
||||
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT, use_ext);
|
||||
|
||||
// Stencil RenderBuffer - Attach it to FBO
|
||||
if (sfc->stencil_buf)
|
||||
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT);
|
||||
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT, use_ext);
|
||||
|
||||
// Check FBO for completeness
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
status = FBO_FUNC(glCheckFramebufferStatus, (GL_FRAMEBUFFER));
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
ERR("FBO not complete. Error Code: %x!", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef FBO_FUNC
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1011,6 +1092,8 @@ _surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int m
|
|||
{
|
||||
_texture_allocate_2d(sfc->color_buf, sfc->color_ifmt, sfc->color_fmt,
|
||||
GL_UNSIGNED_BYTE, w, h);
|
||||
if ((sfc->current_ctx) && (sfc->current_ctx->extension_supported))
|
||||
_egl_image_attach_texture(sfc->current_ctx, &sfc->egl_image, sfc->color_buf);
|
||||
sfc->buffer_mem[0] = w * h * 4;
|
||||
}
|
||||
|
||||
|
@ -1616,56 +1699,6 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
goto error;
|
||||
}
|
||||
|
||||
// Set the context current with resource context/surface
|
||||
if (!_internal_resource_make_current(eng_data, NULL))
|
||||
{
|
||||
ERR("Error doing an internal resource make current");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Allocate indirect surface for fallback rendering
|
||||
if ((cfg->gles_version == EVAS_GL_GLES_1_X) ||
|
||||
(cfg->gles_version == EVAS_GL_GLES_3_X))
|
||||
{
|
||||
if (!evgl_engine->funcs->indirect_surface_create)
|
||||
{
|
||||
ERR("Cannot create indirect surface");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
|
||||
goto error;
|
||||
}
|
||||
|
||||
INF("Creating indirect surface for fallback rendering");
|
||||
evgl_engine->funcs->indirect_surface_create(evgl_engine, eng_data, sfc, cfg, w, h);
|
||||
}
|
||||
|
||||
// Create internal buffers
|
||||
if (!_surface_buffers_create(sfc))
|
||||
{
|
||||
ERR("Unable Create Specificed Surfaces.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
};
|
||||
|
||||
// Allocate resources for fallback unless the flag is on
|
||||
if (!sfc->direct_mem_opt)
|
||||
{
|
||||
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
|
||||
{
|
||||
ERR("Unable Create Allocate Memory for Surface.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbg) DBG("Calling make_current(NULL, NULL)");
|
||||
if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
|
||||
{
|
||||
ERR("Error doing make_current(NULL, NULL).");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Keep track of all the created surfaces
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
|
||||
|
@ -1819,7 +1852,6 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
{
|
||||
EVGL_Resource *rsc;
|
||||
Eina_Bool dbg;
|
||||
GLuint texid;
|
||||
|
||||
// FIXME: This does some make_current(0,0) which may have side effects
|
||||
|
||||
|
@ -1889,7 +1921,6 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
|
||||
|
||||
// Destroy created buffers
|
||||
texid = sfc->color_buf;
|
||||
if (!_surface_buffers_destroy(sfc))
|
||||
{
|
||||
ERR("Error deleting surface resources.");
|
||||
|
@ -1925,8 +1956,16 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
|
||||
if (sfc->direct_fb_opt)
|
||||
{
|
||||
eina_hash_del(evgl_engine->direct_surfaces, &texid, sfc);
|
||||
DBG("Removed tex %d from the direct surface: %p", texid, sfc);
|
||||
if (!sfc->indirect)
|
||||
{
|
||||
eina_hash_del(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
|
||||
DBG("Removed tex %d as direct surface: %p", sfc->color_buf, sfc);
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_hash_del(evgl_engine->direct_surfaces, &sfc->indirect_sfc_native, sfc);
|
||||
DBG("Removed native %p as direct surface: %p", sfc->indirect_sfc_native, sfc);
|
||||
}
|
||||
}
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
|
@ -1944,6 +1983,7 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
|
|||
Evas_GL_Context_Version version)
|
||||
{
|
||||
EVGL_Context *ctx = NULL;
|
||||
EVGL_Resource *rsc = NULL;
|
||||
|
||||
// Check the input
|
||||
if (!evgl_engine)
|
||||
|
@ -1963,6 +2003,12 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
|
|||
if (evgl_engine->api_debug_mode)
|
||||
DBG("Creating context GLESv%d (eng = %p, shctx = %p)", version, eng_data, share_ctx);
|
||||
|
||||
if (!(rsc = _evgl_tls_resource_get()))
|
||||
{
|
||||
ERR("Error creating resources in tls.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate context object
|
||||
ctx = calloc(1, sizeof(EVGL_Context));
|
||||
if (!ctx)
|
||||
|
@ -2096,7 +2142,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
|
||||
if (!rsc)
|
||||
{
|
||||
DBG("Creating new TLS for this thread: %lu", eina_thread_self());
|
||||
DBG("Creating new TLS for this thread: %x", eina_thread_self());
|
||||
rsc = _evgl_tls_resource_create(eng_data);
|
||||
if (!rsc) return 0;
|
||||
}
|
||||
|
@ -2144,6 +2190,42 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
rsc->current_ctx->partial_render = 0;
|
||||
}
|
||||
|
||||
// Do a make current
|
||||
if (!_internal_resource_make_current(eng_data, ctx))
|
||||
{
|
||||
ERR("Error doing a make current with internal surface. Context: %p", ctx);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
sfc->current_ctx = ctx;
|
||||
rsc->current_ctx = ctx;
|
||||
rsc->current_eng = eng_data;
|
||||
|
||||
// Check whether extensions are supported for the current context version
|
||||
// to use fbo & egl image passing to evas
|
||||
if (!ctx->extension_checked)
|
||||
{
|
||||
if (!evgl_api_get(ctx->version))
|
||||
{
|
||||
ERR("Unable to get the list of GL APIs for version %d", ctx->version);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
if (!_context_ext_check(ctx))
|
||||
{
|
||||
ERR("Unable to check required extension for the current context");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sfc->color_buf && !_surface_buffers_create(sfc))
|
||||
{
|
||||
ERR("Unable to create specified surfaces.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Allocate or free resources depending on what mode (direct of fbo) it's
|
||||
// running only if the env var EVAS_GL_DIRECT_MEM_OPT is set.
|
||||
if (evgl_engine->direct_mem_opt)
|
||||
|
@ -2187,17 +2269,21 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do a make current
|
||||
if (!_internal_resource_make_current(eng_data, ctx))
|
||||
else
|
||||
{
|
||||
ERR("Error doing a make current with internal surface. Context: %p", ctx);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
if (!sfc->buffers_allocated)
|
||||
{
|
||||
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
|
||||
{
|
||||
ERR("Unable Create Allocate Memory for Surface.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
return 0;
|
||||
}
|
||||
sfc->buffers_allocated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// GLES 1.x and 3.x
|
||||
if ((ctx->version == EVAS_GL_GLES_1_X) || (ctx->version == EVAS_GL_GLES_3_X))
|
||||
if (!ctx->extension_supported)
|
||||
{
|
||||
if (dbg) DBG("ctx %p is GLES %d", ctx, ctx->version);
|
||||
if (_evgl_direct_renderable(rsc, sfc))
|
||||
|
@ -2239,26 +2325,16 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
ctx->current_fbo = 0;
|
||||
rsc->direct.rendered = 0;
|
||||
}
|
||||
|
||||
// Update GLESv1 extension functions after GLESv1 context is bound
|
||||
if (ctx->version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
evgl_api_gles1_ext_get(gles1_funcs);
|
||||
}
|
||||
else if (ctx->version == EVAS_GL_GLES_3_X)
|
||||
{
|
||||
evgl_api_gles3_ext_get(gles3_funcs);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// GLES 2+ below
|
||||
#define FBO_FUNC(name, param) \
|
||||
((ctx->version == EVAS_GL_GLES_1_X) && (ctx->extension_supported))?(gles1_funcs->name##OES param):((name) param)
|
||||
|
||||
// Normal FBO Rendering
|
||||
// Create FBO if it hasn't been created
|
||||
if (!ctx->surface_fbo)
|
||||
glGenFramebuffers(1, &ctx->surface_fbo);
|
||||
FBO_FUNC(glGenFramebuffers, (1, &ctx->surface_fbo));
|
||||
|
||||
// Direct Rendering
|
||||
if (_evgl_direct_renderable(rsc, sfc))
|
||||
|
@ -2269,13 +2345,13 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
|
||||
if (ctx->surface_fbo == (GLuint)curr_fbo)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
FBO_FUNC(glBindFramebuffer, (GL_FRAMEBUFFER, 0));
|
||||
ctx->current_fbo = 0;
|
||||
}
|
||||
else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
|
||||
{
|
||||
// Using the same context, we were rendering on a pbuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
FBO_FUNC(glBindFramebuffer, (GL_FRAMEBUFFER, 0));
|
||||
ctx->current_fbo = 0;
|
||||
}
|
||||
|
||||
|
@ -2304,7 +2380,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
|
||||
if (sfc->color_buf)
|
||||
{
|
||||
if (!_surface_buffers_fbo_set(sfc, sfc->color_buf))
|
||||
if (!_surface_buffers_fbo_set(sfc, sfc->color_buf, EINA_FALSE))
|
||||
ERR("Could not detach current FBO");
|
||||
}
|
||||
|
||||
|
@ -2314,7 +2390,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
|
||||
// Bind to the previously bound buffer (may be 0)
|
||||
if (ctx->current_fbo)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
|
||||
FBO_FUNC(glBindFramebuffer, (GL_FRAMEBUFFER, ctx->current_fbo));
|
||||
|
||||
rsc->direct.rendered = 0;
|
||||
}
|
||||
|
@ -2337,7 +2413,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (rsc->direct.partial.enabled)
|
||||
evgl_direct_partial_render_end();
|
||||
|
||||
if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo))
|
||||
if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, EINA_FALSE))
|
||||
{
|
||||
ERR("Attaching buffers to context fbo failed. Engine: %p Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
|
@ -2347,10 +2423,11 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
|
||||
// Bind to the previously bound buffer
|
||||
if (ctx->current_fbo)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
|
||||
FBO_FUNC(glBindFramebuffer, (GL_FRAMEBUFFER, ctx->current_fbo));
|
||||
}
|
||||
rsc->direct.rendered = 0;
|
||||
}
|
||||
#undef FBO_FUNC
|
||||
}
|
||||
|
||||
ctx->current_sfc = sfc;
|
||||
|
@ -2428,6 +2505,18 @@ evgl_safe_extension_get(const char *name, void **pfuncptr)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void *
|
||||
evgl_native_surface_egl_image_get(EVGL_Surface *sfc)
|
||||
{
|
||||
if (!evgl_engine)
|
||||
{
|
||||
ERR("Invalid input data. Engine: %p", evgl_engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sfc->egl_image;
|
||||
}
|
||||
|
||||
int
|
||||
evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
|
||||
{
|
||||
|
@ -2440,14 +2529,9 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
|
|||
|
||||
if (!sfc->indirect)
|
||||
{
|
||||
ns->type = EVAS_NATIVE_SURFACE_OPENGL;
|
||||
ns->type = EVAS_NATIVE_SURFACE_EVASGL;
|
||||
ns->version = EVAS_NATIVE_SURFACE_VERSION;
|
||||
ns->data.opengl.texture_id = sfc->color_buf;
|
||||
ns->data.opengl.framebuffer_id = sfc->color_buf;
|
||||
ns->data.opengl.x = 0;
|
||||
ns->data.opengl.y = 0;
|
||||
ns->data.opengl.w = sfc->w;
|
||||
ns->data.opengl.h = sfc->h;
|
||||
ns->data.evasgl.surface = sfc;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2456,7 +2540,6 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
|
|||
ns->data.x11.pixmap = (unsigned long)(intptr_t)sfc->indirect_sfc_native;
|
||||
ns->data.x11.visual = sfc->indirect_sfc_visual;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2514,6 +2597,11 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL &&
|
||||
ns->data.evasgl.surface)
|
||||
{
|
||||
sfc = ns->data.evasgl.surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Only EVAS_NATIVE_SURFACE_OPENGL or EVAS_NATIVE_SURFACE_X11 can be used for direct rendering");
|
||||
|
@ -2537,10 +2625,10 @@ void
|
|||
evgl_direct_info_set(int win_w, int win_h, int rot,
|
||||
int img_x, int img_y, int img_w, int img_h,
|
||||
int clip_x, int clip_y, int clip_w, int clip_h,
|
||||
unsigned int texid)
|
||||
void *surface)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
EVGL_Surface *sfc;
|
||||
EVGL_Surface *sfc = surface;
|
||||
|
||||
if (!(rsc = _evgl_tls_resource_get()))
|
||||
return;
|
||||
|
@ -2555,8 +2643,6 @@ evgl_direct_info_set(int win_w, int win_h, int rot,
|
|||
* If the surface is not found, we assume indirect rendering.
|
||||
*/
|
||||
|
||||
sfc = eina_hash_find(evgl_engine->direct_surfaces, &texid);
|
||||
|
||||
if (sfc &&
|
||||
((rot == 0) || sfc->client_side_rotation || sfc->direct_override))
|
||||
{
|
||||
|
|
|
@ -21,6 +21,11 @@ EAPI void evgl_engine_shutdown(void *eng_data);
|
|||
|
||||
typedef void (*EVGL_Engine_Call)(void *eng_data);
|
||||
|
||||
EAPI void *evgl_native_surface_egl_image_get(EVGL_Surface *sfc);
|
||||
|
||||
typedef void *(*EVGL_Native_Surface_Call)(void *sfc);
|
||||
|
||||
|
||||
EVGL_Engine *evgl_engine_init(void *eng_data, const EVGL_Interface *efunc);
|
||||
|
||||
void *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h);
|
||||
|
@ -41,7 +46,7 @@ void evgl_direct_override_get(Eina_Bool *override, Eina_Bool *force_off)
|
|||
void evgl_direct_info_set(int win_w, int win_h, int rot,
|
||||
int img_x, int img_y, int img_w, int img_h,
|
||||
int clip_x, int clip_y, int clip_w, int clip_h,
|
||||
unsigned int texid);
|
||||
void *hash_key);
|
||||
void evgl_direct_info_clear(void);
|
||||
void evgl_get_pixels_pre(void);
|
||||
void evgl_get_pixels_post(void);
|
||||
|
|
|
@ -137,6 +137,7 @@ struct _EVGL_Surface
|
|||
void *indirect_sfc_native;
|
||||
void *indirect_sfc_visual;
|
||||
void *indirect_sfc_config;
|
||||
void *egl_image;
|
||||
|
||||
//-------------------------//
|
||||
// Related to PBuffer Surface
|
||||
|
@ -171,6 +172,8 @@ struct _EVGL_Context
|
|||
int scissor_updated : 1;
|
||||
int direct_scissor : 1;
|
||||
int viewport_updated : 1;
|
||||
int extension_checked : 1;
|
||||
int extension_supported : 1;
|
||||
|
||||
int scissor_coord[4];
|
||||
int viewport_coord[4];
|
||||
|
|
|
@ -821,7 +821,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
|
|||
|
||||
if (eng_gl_image_direct_get(data, image))
|
||||
{
|
||||
unsigned int texid;
|
||||
void *surface;
|
||||
|
||||
gl_context->dc = context;
|
||||
if ((gl_context->master_clip.enabled) &&
|
||||
|
@ -833,9 +833,11 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
|
|||
}
|
||||
|
||||
if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
|
||||
texid = n->data.opengl.texture_id;
|
||||
surface = eina_hash_find(evgl_engine->direct_surfaces, &n->data.opengl.texture_id);
|
||||
else if (n->type == EVAS_NATIVE_SURFACE_X11)
|
||||
texid = n->data.x11.pixmap;
|
||||
surface = eina_hash_find(evgl_engine->direct_surfaces, &n->data.x11.pixmap);
|
||||
else if (n->type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
surface = n->data.evasgl.surface;
|
||||
else
|
||||
{
|
||||
ERR("This native surface type is not supported for direct rendering");
|
||||
|
@ -851,7 +853,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
|
|||
gl_context->dc->clip.y,
|
||||
gl_context->dc->clip.w,
|
||||
gl_context->dc->clip.h,
|
||||
texid);
|
||||
surface);
|
||||
|
||||
// Call pixel get function
|
||||
evgl_get_pixels_pre();
|
||||
|
|
|
@ -59,6 +59,7 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
|
|||
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_egl_image_get = NULL;
|
||||
Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
|
||||
|
||||
Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
|
||||
|
@ -1274,6 +1275,7 @@ gl_symbols(void)
|
|||
LINK2GENERIC(evas_gl_preload_init);
|
||||
LINK2GENERIC(evas_gl_preload_shutdown);
|
||||
LINK2GENERIC(evgl_engine_shutdown);
|
||||
LINK2GENERIC(evgl_native_surface_egl_image_get);
|
||||
LINK2GENERIC(evas_gl_symbols);
|
||||
LINK2GENERIC(evas_gl_common_error_get);
|
||||
LINK2GENERIC(evas_gl_common_error_set);
|
||||
|
@ -2003,6 +2005,25 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
|
|||
else
|
||||
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
{
|
||||
void *surface = glsym_evgl_native_surface_egl_image_get(n->egl_surface);
|
||||
if (glsym_glEGLImageTargetTexture2DOES)
|
||||
{
|
||||
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
|
||||
if (eglGetError() != EGL_SUCCESS)
|
||||
ERR("glEGLImageTargetTexture2DOES() failed.");
|
||||
}
|
||||
else
|
||||
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
||||
}
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -2039,6 +2060,10 @@ _native_unbind_cb(void *data EINA_UNUSED, void *image)
|
|||
{
|
||||
// nothing
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2123,6 +2148,10 @@ _native_free_cb(void *data, void *image)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
eina_hash_del(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
|
||||
}
|
||||
im->native.data = NULL;
|
||||
im->native.func.data = NULL;
|
||||
im->native.func.bind = NULL;
|
||||
|
@ -2195,6 +2224,16 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
return im;
|
||||
}
|
||||
}
|
||||
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
buffer = ns->data.evasgl.surface;
|
||||
if (im->native.data)
|
||||
{
|
||||
Evas_Native_Surface *ens = im->native.data;
|
||||
if (ens->data.evasgl.surface == buffer)
|
||||
return im;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((!ns) && (!im->native.data)) return im;
|
||||
|
||||
|
@ -2257,6 +2296,21 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer);
|
||||
if (im2 == im) return im;
|
||||
if (im2)
|
||||
{
|
||||
n = im2->native.data;
|
||||
if (n)
|
||||
{
|
||||
glsym_evas_gl_common_image_ref(im2);
|
||||
glsym_evas_gl_common_image_free(im);
|
||||
return im2;
|
||||
}
|
||||
}
|
||||
}
|
||||
im2 = glsym_evas_gl_common_image_new_from_data(eng_get_ob(re)->gl_context,
|
||||
im->w, im->h, NULL, im->alpha,
|
||||
EVAS_COLORSPACE_ARGB8888);
|
||||
|
@ -2625,6 +2679,44 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
|
||||
{
|
||||
if (native)
|
||||
{
|
||||
n = calloc(1, sizeof(Native));
|
||||
if (n)
|
||||
{
|
||||
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
||||
|
||||
eina_hash_add(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer, im);
|
||||
|
||||
n->pixmap = 0;
|
||||
n->visual = 0;
|
||||
#ifdef GL_GLES
|
||||
n->egl_surface = ns->data.evasgl.surface;
|
||||
#else
|
||||
n->fbc = 0;
|
||||
n->glx_pixmap = 0;
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
// FIXME: need to implement mapping sub texture regions
|
||||
// x, y, w, h for possible texture atlasing
|
||||
|
||||
glsym_evas_gl_common_image_native_enable(im);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue