evas: Fixed evas_gl multi-window support design issue.

Evas engine is created per window but evas_gl engine was not properly
updating the engine info for new windows that are created. So, addressed
the design issue by passing engine_data to evas_gl engine apis..
This commit is contained in:
Sung W. Park 2013-05-02 19:06:10 +09:00
parent c8b9e0540b
commit 289a666333
7 changed files with 420 additions and 343 deletions

View File

@ -36,7 +36,7 @@ void _direct_rendering_check(const char *api)
return;
}
if (_evgl_not_in_pixel_get(evgl_engine))
if (_evgl_not_in_pixel_get())
{
CRIT("\e[1;33m%s\e[m: This API is being called outside Pixel Get Callback Function.", api);
}
@ -68,7 +68,7 @@ _evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
// Take care of BindFramebuffer 0 issue
if (framebuffer==0)
{
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
glBindFramebuffer(target, 0);
else
glBindFramebuffer(target, ctx->surface_fbo);
@ -250,19 +250,24 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
static void
_evgl_glClear(GLbitfield mask)
{
EVGL_Engine *ee = evgl_engine;
EVGL_Resource *rsc;
EVGL_Context *ctx;
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get(ee)))
if (!(rsc=_evgl_tls_resource_get()))
{
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
ctx = rsc->current_ctx;
if (!ctx)
{
@ -270,7 +275,7 @@ _evgl_glClear(GLbitfield mask)
return;
}
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
{
if (!(rsc->current_ctx->current_fbo))
{
@ -281,7 +286,7 @@ _evgl_glClear(GLbitfield mask)
}
img = rsc->direct_img_obj;
rot = ee->funcs->rotation_angle_get(ee->engine_data);
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 0, 0, 0, 0, 0, oc, nc);
@ -346,12 +351,11 @@ _evgl_glDisable(GLenum cap)
void
_evgl_glGetIntegerv(GLenum pname, GLint* params)
{
EVGL_Engine *ee = evgl_engine;
EVGL_Resource *rsc;
EVGL_Context *ctx;
Evas_Object_Protected_Data *img;
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
{
if (!params)
{
@ -359,8 +363,18 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params)
return;
}
rsc = _evgl_tls_resource_get(ee);
if (!(rsc=_evgl_tls_resource_get()))
{
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
ctx = rsc->current_ctx;
if (!ctx)
{
ERR("Unable to retrive Current Context");
return;
}
// Only need to handle it if it's directly rendering to the window
if (!(rsc->current_ctx->current_fbo))
@ -403,19 +417,25 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params)
static void
_evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
{
EVGL_Engine *ee = evgl_engine;
EVGL_Resource *rsc;
EVGL_Context *ctx;
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get(ee)))
if (!(rsc=_evgl_tls_resource_get()))
{
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
ctx = rsc->current_ctx;
if (!ctx)
{
@ -423,13 +443,13 @@ _evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum forma
return;
}
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
{
if (!(rsc->current_ctx->current_fbo))
{
img = rsc->direct_img_obj;
rot = ee->funcs->rotation_angle_get(ee->engine_data);
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc);
glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
@ -448,19 +468,24 @@ _evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum forma
static void
_evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVGL_Engine *ee = evgl_engine;
EVGL_Resource *rsc;
EVGL_Context *ctx;
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get(ee)))
if (!(rsc=_evgl_tls_resource_get()))
{
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
ctx = rsc->current_ctx;
if (!ctx)
{
@ -468,7 +493,7 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
return;
}
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
{
if (!(rsc->current_ctx->current_fbo))
{
@ -478,7 +503,7 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
}
img = rsc->direct_img_obj;
rot = ee->funcs->rotation_angle_get(ee->engine_data);
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc);
glScissor(nc[0], nc[1], nc[2], nc[3]);
@ -528,19 +553,24 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
static void
_evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVGL_Engine *ee = evgl_engine;
EVGL_Resource *rsc;
EVGL_Context *ctx;
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get(ee)))
if (!(rsc=_evgl_tls_resource_get()))
{
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
ctx = rsc->current_ctx;
if (!ctx)
{
@ -548,7 +578,7 @@ _evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
return;
}
if (_evgl_direct_enabled(evgl_engine))
if (_evgl_direct_enabled())
{
if (!(rsc->current_ctx->current_fbo))
{
@ -559,7 +589,7 @@ _evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
img = rsc->direct_img_obj;
rot = ee->funcs->rotation_angle_get(ee->engine_data);
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 0, x, y, width, height, oc, nc);

View File

@ -66,12 +66,24 @@ char _gl_ext_string[10240] = { 0 };
static void *
evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
{
EVGL_Engine *ee = evgl_engine;
EGLDisplay dpy = EGL_NO_DISPLAY;
EVGL_Resource *rsc;
if ((ee) && (ee->funcs->display_get))
if (!(rsc=_evgl_tls_resource_get()))
{
dpy = (EGLDisplay)ee->funcs->display_get(ee->engine_data);
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
if ((evgl_engine) && (evgl_engine->funcs->display_get))
{
dpy = (EGLDisplay)evgl_engine->funcs->display_get(rsc->current_eng);
return EXT_FUNC(eglCreateImage)(dpy, EGL_NO_CONTEXT, target, buffer, attrib_list);
}
else
@ -84,12 +96,24 @@ evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
static void
evgl_evasglDestroyImage(EvasGLImage image)
{
EVGL_Engine *ee = evgl_engine;
EGLDisplay dpy = EGL_NO_DISPLAY;
EVGL_Resource *rsc;
if ((ee) && (ee->funcs->display_get))
if (!(rsc=_evgl_tls_resource_get()))
{
dpy = (EGLDisplay)ee->funcs->display_get(ee->engine_data);
ERR("Unable to execute GL command. Error retrieving tls");
return;
}
if (!rsc->current_eng)
{
ERR("Unable to retrive Current Engine");
return;
}
if ((evgl_engine) && (evgl_engine->funcs->display_get))
{
dpy = (EGLDisplay)evgl_engine->funcs->display_get(rsc->current_eng);
EXT_FUNC(eglDestroyImage)(dpy, image);
}
else

File diff suppressed because it is too large Load Diff

View File

@ -18,22 +18,22 @@ typedef struct _EVGL_Surface_Cap EVGL_Surface_Cap;
typedef struct _EVGL_Surface_Format EVGL_Surface_Format;
extern EVGL_Engine *evgl_engine_create(EVGL_Interface *efunc, void *engine_data);
extern int evgl_engine_destroy(EVGL_Engine *ee);
extern EVGL_Engine *evgl_engine_init(void *eng_data, EVGL_Interface *efunc);
extern void evgl_engine_shutdown(void *eng_data);
extern void *evgl_surface_create(EVGL_Engine *ee, Evas_GL_Config *cfg, int w, int h);
extern int evgl_surface_destroy(EVGL_Engine *ee, EVGL_Surface *sfc);
extern void *evgl_context_create(EVGL_Engine *ee, EVGL_Context *share_ctx);
extern int evgl_context_destroy(EVGL_Engine *ee, EVGL_Context *ctx);
extern int evgl_make_current(EVGL_Engine *ee, EVGL_Surface *sfc, EVGL_Context *ctx);
extern const char *evgl_string_query(EVGL_Engine *ee, int name);
extern void *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h);
extern int evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc);
extern void *evgl_context_create(void *eng_data, EVGL_Context *share_ctx);
extern int evgl_context_destroy(void *eng_data, EVGL_Context *ctx);
extern int evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx);
extern const char *evgl_string_query(int name);
extern void *evgl_proc_address_get(const char *name);
extern int evgl_native_surface_get(EVGL_Engine *ee, EVGL_Surface *sfc, Evas_Native_Surface *ns);
extern Evas_GL_API *evgl_api_get(EVGL_Engine *ee);
extern int evgl_direct_rendered(EVGL_Engine *ee);
extern void evgl_direct_img_obj_set(EVGL_Engine *ee, Evas_Object *img);
extern Evas_Object *evgl_direct_img_obj_get(EVGL_Engine *ee);
extern int evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns);
extern Evas_GL_API *evgl_api_get();
extern int evgl_direct_rendered();
extern void evgl_direct_img_obj_set(Evas_Object *img, int alpha, int rot);
extern Evas_Object *evgl_direct_img_obj_get();
#endif //_EVAS_GL_CORE_H

View File

@ -208,6 +208,7 @@ struct _EVGL_Resource
EVGLNative_Surface surface;
EVGL_Context *current_ctx;
void *current_eng;
int direct_rendered;
Evas_Object *direct_img_obj;
@ -242,7 +243,7 @@ struct _EVGL_Engine
Eina_List *surfaces;
Eina_List *contexts;
void *engine_data;
//void *engine_data;
};
@ -252,9 +253,11 @@ extern EVGL_Engine *evgl_engine;
// Internally used functions
extern void _evgl_api_get(Evas_GL_API *api, int debug);
extern EVGL_Resource *_evgl_tls_resource_get(EVGL_Engine *ee);
extern EVGL_Resource *_evgl_tls_resource_get();
extern EVGL_Resource *_evgl_tls_resource_create(void *data);
extern void _evgl_tls_resource_destroy(void *data);
extern EVGL_Context *_evgl_current_context_get();
extern int _evgl_not_in_pixel_get();
extern int _evgl_direct_enabled(EVGL_Engine *ee);
extern int _evgl_direct_enabled();
#endif //_EVAS_GL_CORE_PRIVATE_H

View File

@ -35,11 +35,11 @@ evas_gl_common_file_cache_mkpath_if_not_exists(const char *path)
struct stat st;
if (stat(path, &st) < 0)
return evas_gl_common_file_cache_mkdir(path);
return evas_gl_common_file_cache_mkdir(path);
else if (!S_ISDIR(st.st_mode))
return EINA_FALSE;
return EINA_FALSE;
else
return EINA_TRUE;
return EINA_TRUE;
}
Eina_Bool
@ -57,7 +57,7 @@ evas_gl_common_file_cache_mkpath(const char *path)
{
ss[i] = 0;
if (!evas_gl_common_file_cache_mkpath_if_not_exists(ss))
return EINA_FALSE;
return EINA_FALSE;
}
}
ss[i] = 0;

View File

@ -52,8 +52,6 @@ struct _Render_Engine
int vsync;
int lost_back;
int prev_age;
EVGL_Engine *evgl_engine;
};
static int initted = 0;
@ -255,7 +253,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
if ((!context) && (!surface))
{
ret = glXMakeCurrent(re->info->info.display, None, NULL);
ret = glXMakeCurrent(re->info->info.display, None, NULL);
if (!ret)
{
ERR("glXMakeCurrent() failed!");
@ -858,12 +856,9 @@ eng_setup(Evas *eo_e, void *in)
evas_common_draw_init();
evas_common_tilebuf_init();
gl_extn_veto(re);
evgl_engine_init(re, &evgl_funcs);
initted = 1;
}
re->evgl_engine = evgl_engine_create(&evgl_funcs, (void*)re);
if (!re->evgl_engine)
ERR("Error Creating Evas_GL Engine. Evas GL will not be supported!");
}
else
{
@ -1039,10 +1034,6 @@ eng_output_free(void *data)
glsym_glXReleaseBuffersMESA(disp, win);
#endif
gl_wins--;
// NEW_EVAS_GL
if (gl_wins == 0)
evgl_engine_destroy(re->evgl_engine);
}
evas_common_tilebuf_free(re->tb);
@ -1050,6 +1041,9 @@ eng_output_free(void *data)
if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
if (gl_wins == 0) evgl_engine_shutdown(re);
free(re);
}
if ((initted == 1) && (gl_wins == 0))
@ -2794,10 +2788,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) &&
(n->ns.data.opengl.framebuffer_id == 0) &&
(evgl_direct_rendered(re->evgl_engine)))
(evgl_direct_rendered()))
{
DBG("Rendering Directly to the window");
evas_object_image_pixels_dirty_set(evgl_direct_img_obj_get(re->evgl_engine), EINA_TRUE);
DBG("Rendering Directly to the window: %p", data);
evas_object_image_pixels_dirty_set(evgl_direct_img_obj_get(), EINA_TRUE);
}
else
{
@ -3004,54 +2998,48 @@ eng_canvas_alpha_get(void *data, void *info EINA_UNUSED)
static void *
eng_gl_surface_create(void *data, void *config, int w, int h)
{
Render_Engine *re = (Render_Engine *)data;
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
return evgl_surface_create(re->evgl_engine, cfg, w, h);
return evgl_surface_create(data, cfg, w, h);
}
static int
eng_gl_surface_destroy(void *data, void *surface)
{
Render_Engine *re = (Render_Engine *)data;
EVGL_Surface *sfc = (EVGL_Surface *)surface;
return evgl_surface_destroy(re->evgl_engine, sfc);
return evgl_surface_destroy(data, sfc);
}
static void *
eng_gl_context_create(void *data, void *share_context)
{
Render_Engine *re = (Render_Engine *)data;
EVGL_Context *sctx = (EVGL_Context *)share_context;
return evgl_context_create(re->evgl_engine, sctx);
return evgl_context_create(data, sctx);
}
static int
eng_gl_context_destroy(void *data, void *context)
{
Render_Engine *re = (Render_Engine *)data;
EVGL_Context *ctx = (EVGL_Context *)context;
return evgl_context_destroy(re->evgl_engine, ctx);
return evgl_context_destroy(data, ctx);
}
static int
eng_gl_make_current(void *data, void *surface, void *context)
{
Render_Engine *re = (Render_Engine *)data;
EVGL_Surface *sfc = (EVGL_Surface *)surface;
EVGL_Context *ctx = (EVGL_Context *)context;
return evgl_make_current(re->evgl_engine, sfc, ctx);
return evgl_make_current(data, sfc, ctx);
}
static void *
eng_gl_string_query(void *data, int name)
eng_gl_string_query(void *data EINA_UNUSED, int name)
{
Render_Engine *re = (Render_Engine *)data;
return (void *)evgl_string_query(re->evgl_engine, name);
return (void *)evgl_string_query(name);
}
// Need to deprecate this function..
@ -3062,39 +3050,26 @@ eng_gl_proc_address_get(void *data EINA_UNUSED, const char *name EINA_UNUSED)
}
static int
eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_surface)
{
Render_Engine *re = (Render_Engine *)data;
EVGL_Surface *sfc = (EVGL_Surface *)surface;
Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface;
return evgl_native_surface_get(re->evgl_engine, sfc, ns);
return evgl_native_surface_get(sfc, ns);
}
static void *
eng_gl_api_get(void *data)
eng_gl_api_get(void *data EINA_UNUSED)
{
Render_Engine *re = (Render_Engine *)data;
return evgl_api_get(re->evgl_engine);
return evgl_api_get();
}
static void
eng_gl_img_obj_set(void *data, void *image, int has_alpha)
eng_gl_img_obj_set(void *data EINA_UNUSED, void *image, int has_alpha)
{
Render_Engine *re = (Render_Engine *)data;
// Normally direct rendering isn't allowed if alpha is on and
// rotation is not 0. BUT, if override is on, allow it.
if ((has_alpha) || (re->win->gl_context->rot!=0))
{
if (re->evgl_engine->direct_override)
evgl_direct_img_obj_set(re->evgl_engine, image);
else
evgl_direct_img_obj_set(re->evgl_engine, NULL);
}
else
evgl_direct_img_obj_set(re->evgl_engine, image);
evgl_direct_img_obj_set(image, has_alpha, re->win->gl_context->rot);
}
//--------------------------------//