forked from enlightenment/efl
evas: make Evas_GL work with multi output.
This commit is contained in:
parent
7f8bbe4972
commit
545c1a70f4
|
@ -1647,10 +1647,10 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
if (!o->direct_render)
|
||||
{
|
||||
if (ENFN->gl_get_pixels_pre)
|
||||
ENFN->gl_get_pixels_pre(output);
|
||||
ENFN->gl_get_pixels_pre(engine, output);
|
||||
o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
|
||||
if (ENFN->gl_get_pixels_post)
|
||||
ENFN->gl_get_pixels_post(output);
|
||||
ENFN->gl_get_pixels_post(engine, output);
|
||||
}
|
||||
|
||||
if (!(obj->cur->geometry.x == x &&
|
||||
|
@ -1674,6 +1674,8 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
{
|
||||
Evas_Native_Surface *ns;
|
||||
ns = ENFN->image_native_get(engine, o->engine_data);
|
||||
fprintf(stderr, "direct render\n");
|
||||
|
||||
if (ENFN->gl_direct_override_get)
|
||||
ENFN->gl_direct_override_get(engine, &direct_override, &direct_force_off);
|
||||
if (ENFN->gl_surface_direct_renderable_get)
|
||||
|
@ -1691,10 +1693,10 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
{
|
||||
// Auto-fallback to FBO rendering (for perf & power consumption)
|
||||
if (ENFN->gl_get_pixels_pre)
|
||||
ENFN->gl_get_pixels_pre(engine);
|
||||
ENFN->gl_get_pixels_pre(engine, output);
|
||||
o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, obj->object);
|
||||
if (ENFN->gl_get_pixels_post)
|
||||
ENFN->gl_get_pixels_post(engine);
|
||||
ENFN->gl_get_pixels_post(engine, output);
|
||||
o->direct_render = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3331,6 +3331,10 @@ evas_render_updates_internal(Evas *eo_e,
|
|||
}
|
||||
eina_evlog("-render_phase5", eo_e, 0.0, NULL);
|
||||
|
||||
/* Define the output for Evas_GL operation */
|
||||
if (ENFN->gl_output_set)
|
||||
ENFN->gl_output_set(ENC, ENDT);
|
||||
|
||||
/* phase 6. check if video surface should be inlined or stay in their hardware plane */
|
||||
eina_evlog("+render_phase6", eo_e, 0.0, NULL);
|
||||
alpha = ENFN->canvas_alpha_get(ENDT);
|
||||
|
@ -3571,6 +3575,7 @@ evas_render_updates_internal(Evas *eo_e,
|
|||
else if (obj->delete_me != 0) obj->delete_me++;
|
||||
*/
|
||||
}
|
||||
|
||||
for (i = 0; i < e->snapshot_objects.count; i++)
|
||||
{
|
||||
Evas_Object_Protected_Data *snap;
|
||||
|
@ -3582,6 +3587,10 @@ evas_render_updates_internal(Evas *eo_e,
|
|||
eina_evlog("-render_post", eo_e, 0.0, NULL);
|
||||
IFRD(e->active_objects.len, 0, " ---]\n");
|
||||
|
||||
/* Set back Evas_GL output to NULL */
|
||||
/* if (ENFN->gl_output_set) */
|
||||
/* ENFN->gl_output_set(ENC, NULL); */
|
||||
|
||||
/* free our obscuring object list */
|
||||
OBJS_ARRAY_CLEAN(&e->obscuring_objects);
|
||||
|
||||
|
|
|
@ -1539,6 +1539,7 @@ struct _Evas_Func
|
|||
int (*font_right_inset_get) (void *engine, Evas_Font_Set *font, const Evas_Text_Props *text_props);
|
||||
|
||||
/* EFL-GL Glue Layer */
|
||||
void *(*gl_output_set) (void *engine, void *output);
|
||||
void *(*gl_surface_create) (void *engine, void *config, int w, int h);
|
||||
void *(*gl_pbuffer_surface_create) (void *engine, void *config, int w, int h, int const *attrib_list);
|
||||
int (*gl_surface_destroy) (void *engine, void *surface);
|
||||
|
@ -1562,8 +1563,8 @@ struct _Evas_Func
|
|||
Eina_Bool (*gl_surface_direct_renderable_get) (void *engine, void *output, Evas_Native_Surface *ns, Eina_Bool *override, void *surface);
|
||||
void (*gl_image_direct_set) (void *engine, void *image, Eina_Bool direct);
|
||||
int (*gl_image_direct_get) (void *engine, void *image);
|
||||
void (*gl_get_pixels_pre) (void *engine);
|
||||
void (*gl_get_pixels_post) (void *engine);
|
||||
void (*gl_get_pixels_pre) (void *engine, void *output);
|
||||
void (*gl_get_pixels_post) (void *engine, void *output);
|
||||
|
||||
int (*image_load_error_get) (void *engine, void *image);
|
||||
int (*font_run_end_get) (void *engine, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
|
||||
|
|
|
@ -22,11 +22,15 @@ struct _Render_Engine_GL_Generic
|
|||
{
|
||||
Render_Engine_Software_Generic software;
|
||||
|
||||
Render_Output_GL_Generic *current;
|
||||
|
||||
struct {
|
||||
Evas_Object_Image_Pixels_Get_Cb get_pixels;
|
||||
void *get_pixels_data;
|
||||
Evas_Object *obj;
|
||||
} func;
|
||||
|
||||
Eina_Bool evgl_initted : 1;
|
||||
};
|
||||
|
||||
struct _Render_Output_GL_Generic
|
||||
|
@ -42,8 +46,6 @@ struct _Render_Output_GL_Generic
|
|||
Context_3D *context_3d;
|
||||
E3D_Renderer *renderer_3d;
|
||||
const EVGL_Interface *evgl_funcs;
|
||||
|
||||
Eina_Bool evgl_initted : 1;
|
||||
};
|
||||
|
||||
static inline Eina_Bool
|
||||
|
@ -96,8 +98,6 @@ evas_render_engine_gl_generic_init(Render_Engine_Software_Generic *engine,
|
|||
re->renderer_3d = NULL;
|
||||
re->evgl_funcs = evgl_funcs;
|
||||
|
||||
re->evgl_initted = EINA_FALSE;
|
||||
|
||||
evas_render_engine_software_generic_tile_strict_set(&re->software, EINA_TRUE);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -57,6 +57,37 @@ static Eina_Bool eng_gl_surface_read_pixels(void *data, void *surface, int x, in
|
|||
|
||||
Eina_Bool _need_context_restore = EINA_FALSE;
|
||||
|
||||
static Render_Output_GL_Generic *
|
||||
_evgl_output_find(Render_Engine_GL_Generic *engine)
|
||||
{
|
||||
Render_Output_GL_Generic *output = NULL;
|
||||
EVGL_Resource *rsc;
|
||||
Eina_List *l;
|
||||
|
||||
if (engine->current)
|
||||
{
|
||||
output = engine->current;
|
||||
goto picked;
|
||||
}
|
||||
|
||||
rsc = _evgl_tls_resource_get();
|
||||
if (rsc &&
|
||||
rsc->stored.data)
|
||||
{
|
||||
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
||||
if (output == rsc->stored.data) goto picked;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
||||
{
|
||||
if (output->software.ob) goto picked;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
picked:
|
||||
return output;
|
||||
}
|
||||
|
||||
static Evas_Func func, pfunc;
|
||||
|
||||
void
|
||||
|
@ -1434,24 +1465,65 @@ eng_font_draw(void *engine EINA_UNUSED, void *data, void *context, void *surface
|
|||
|
||||
//--------------------------------//
|
||||
// Evas GL Related Code
|
||||
static int
|
||||
evgl_init(Render_Output_GL_Generic *re)
|
||||
static inline Eina_Bool
|
||||
evgl_init_do(Render_Engine_GL_Generic *engine,
|
||||
Render_Output_GL_Generic *output)
|
||||
{
|
||||
if (re->evgl_initted) return 1;
|
||||
if (!evgl_engine_init(re, re->evgl_funcs)) return 0;
|
||||
re->evgl_initted = EINA_TRUE;
|
||||
return 1;
|
||||
if (engine->evgl_initted) return EINA_TRUE;
|
||||
if (!evgl_engine_init(output, output->evgl_funcs))
|
||||
return EINA_FALSE;
|
||||
engine->current = output;
|
||||
engine->evgl_initted = EINA_TRUE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#define EVGLINIT(_re, _ret) if (!evgl_init(_re)) return _ret
|
||||
static Render_Output_GL_Generic *
|
||||
evgl_init(Render_Engine_GL_Generic *engine)
|
||||
{
|
||||
Render_Output_GL_Generic *output = NULL;
|
||||
Eina_List *l;
|
||||
|
||||
if (engine->evgl_initted)
|
||||
{
|
||||
if (engine->current) return engine->current;
|
||||
|
||||
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
||||
if (output->software.ob) return output;
|
||||
|
||||
ERR("Evas_GL backend initializeod, but no window found !");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(engine->software.outputs, l, output)
|
||||
{
|
||||
if (!output->software.ob) continue;
|
||||
if (evgl_init_do(engine, output))
|
||||
return output;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define EVGLINIT(_ret) Render_Output_GL_Generic *re; if ((re = evgl_init(engine)) == NULL) return _ret
|
||||
|
||||
static void *
|
||||
eng_gl_output_set(void *eng, void *output)
|
||||
{
|
||||
Render_Engine_GL_Generic *engine = eng;
|
||||
Render_Output_GL_Generic *previous = engine->current;
|
||||
|
||||
engine->current = output;
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_surface_create(void *engine, void *config, int w, int h)
|
||||
{
|
||||
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
||||
|
||||
EVGLINIT(engine, NULL);
|
||||
return evgl_surface_create(engine, cfg, w, h);
|
||||
EVGLINIT(NULL);
|
||||
return evgl_surface_create(re, cfg, w, h);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -1459,18 +1531,20 @@ eng_gl_pbuffer_surface_create(void *engine, void *config, int w, int h, const in
|
|||
{
|
||||
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
||||
|
||||
EVGLINIT(engine, NULL);
|
||||
return evgl_pbuffer_surface_create(engine, cfg, w, h, attrib_list);
|
||||
EVGLINIT(NULL);
|
||||
return evgl_pbuffer_surface_create(re, cfg, w, h, attrib_list);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_surface_destroy(void *engine, void *surface)
|
||||
{
|
||||
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
||||
Render_Engine_GL_Generic *e;
|
||||
|
||||
EVGLINIT(engine, 0);
|
||||
CONTEXT_STORED_RESET(engine, surface);
|
||||
return evgl_surface_destroy(engine, sfc);
|
||||
EVGLINIT(0);
|
||||
if (e->current == re) e->current = NULL;
|
||||
CONTEXT_STORED_RESET(re, surface);
|
||||
return evgl_surface_destroy(re, sfc);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -1480,8 +1554,8 @@ eng_gl_context_create(void *engine, void *share_context, int version,
|
|||
{
|
||||
EVGL_Context *sctx = (EVGL_Context *)share_context;
|
||||
|
||||
EVGLINIT(engine, NULL);
|
||||
return evgl_context_create(engine, sctx, version, native_context_get, engine_data_get);
|
||||
EVGLINIT(NULL);
|
||||
return evgl_context_create(re, sctx, version, native_context_get, engine_data_get);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1489,15 +1563,17 @@ eng_gl_context_destroy(void *engine, void *context)
|
|||
{
|
||||
EVGL_Context *ctx = (EVGL_Context *)context;
|
||||
|
||||
EVGLINIT(engine, 0);
|
||||
return evgl_context_destroy(engine, ctx);
|
||||
EVGLINIT(0);
|
||||
return evgl_context_destroy(re, ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_make_current(void *engine, void *surface, void *context)
|
||||
eng_gl_make_current(void *eng, void *surface, void *context)
|
||||
{
|
||||
Render_Engine_GL_Generic *engine = eng;
|
||||
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
||||
EVGL_Context *ctx = (EVGL_Context *)context;
|
||||
Render_Output_GL_Generic *output;
|
||||
int ret = 0;
|
||||
|
||||
// TODO: Add check for main thread before flush
|
||||
|
@ -1516,8 +1592,11 @@ eng_gl_make_current(void *engine, void *surface, void *context)
|
|||
}
|
||||
}
|
||||
|
||||
ret = evgl_make_current(engine, sfc, ctx);
|
||||
CONTEXT_STORE(engine, surface, context);
|
||||
output = _evgl_output_find(engine);
|
||||
if (!output) return ret;
|
||||
|
||||
ret = evgl_make_current(output, sfc, ctx);
|
||||
CONTEXT_STORE(output, surface, context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1537,25 +1616,32 @@ eng_gl_current_surface_get(void *engine EINA_UNUSED)
|
|||
}
|
||||
|
||||
static int
|
||||
eng_gl_rotation_angle_get(void *engine)
|
||||
eng_gl_rotation_angle_get(void *eng)
|
||||
{
|
||||
Render_Engine_GL_Generic *engine = eng;
|
||||
Render_Output_GL_Generic *output;
|
||||
|
||||
if (!evgl_engine->funcs->rotation_angle_get) return 0;
|
||||
if (!_evgl_direct_enabled()) return 0;
|
||||
return evgl_engine->funcs->rotation_angle_get(engine);
|
||||
|
||||
// It would be better if that this API was called Evas Output
|
||||
output = _evgl_output_find(engine);
|
||||
if (!output) return 0;
|
||||
|
||||
return evgl_engine->funcs->rotation_angle_get(output);
|
||||
}
|
||||
|
||||
static const char *
|
||||
eng_gl_string_query(void *engine, int name)
|
||||
{
|
||||
EVGLINIT(engine, NULL);
|
||||
EVGLINIT(NULL);
|
||||
return evgl_string_query(name);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_proc_address_get(void *engine, const char *name)
|
||||
{
|
||||
Render_Output_GL_Generic *re = engine;
|
||||
EVGLINIT(engine, NULL);
|
||||
EVGLINIT(NULL);
|
||||
void *fun = NULL;
|
||||
|
||||
if (!evgl_safe_extension_get(name, &fun))
|
||||
|
@ -1586,9 +1672,10 @@ eng_gl_native_surface_get(void *engine EINA_UNUSED, void *surface, void *native_
|
|||
static void *
|
||||
eng_gl_api_get(void *engine, int version)
|
||||
{
|
||||
void *ret;
|
||||
Render_Output_GL_Generic *output;
|
||||
Evas_Engine_GL_Context *gl_context;
|
||||
EVGLINIT(engine, NULL);
|
||||
void *ret;
|
||||
EVGLINIT(NULL);
|
||||
|
||||
gl_context = gl_generic_context_find(engine);
|
||||
if (!gl_context)
|
||||
|
@ -1601,7 +1688,9 @@ eng_gl_api_get(void *engine, int version)
|
|||
ERR("Version not supported!");
|
||||
return NULL;
|
||||
}
|
||||
ret = evgl_api_get(engine, version, EINA_TRUE);
|
||||
|
||||
output = _evgl_output_find(engine);
|
||||
ret = evgl_api_get(output, version, EINA_TRUE);
|
||||
|
||||
//Disable GLES3 support if symbols not present
|
||||
if ((!ret) && (version == EVAS_GL_GLES_3_X))
|
||||
|
@ -1614,20 +1703,22 @@ eng_gl_api_get(void *engine, int version)
|
|||
static void
|
||||
eng_gl_direct_override_get(void *engine, Eina_Bool *override, Eina_Bool *force_off)
|
||||
{
|
||||
EVGLINIT(engine, );
|
||||
EVGLINIT();
|
||||
evgl_direct_override_get(override, force_off);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_direct_renderable_get(void *engine, void *output, Evas_Native_Surface *ns, Eina_Bool *override, void *surface)
|
||||
eng_gl_surface_direct_renderable_get(void *eng, void *output, Evas_Native_Surface *ns, Eina_Bool *override, void *surface)
|
||||
{
|
||||
Render_Engine_GL_Generic *engine = eng;
|
||||
Render_Output_GL_Generic *re = output;
|
||||
Eina_Bool direct_render, client_side_rotation;
|
||||
Evas_Engine_GL_Context *gl_context;
|
||||
Evas_GL_Image *sfc = surface;
|
||||
|
||||
if (!re) return EINA_FALSE;
|
||||
EVGLINIT(engine, EINA_FALSE);
|
||||
if (!evgl_init_do(engine, re))
|
||||
return EINA_FALSE;
|
||||
if (!ns) return EINA_FALSE;
|
||||
if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation, override))
|
||||
return EINA_FALSE;
|
||||
|
@ -1656,14 +1747,18 @@ eng_gl_get_pixels_set(void *eng, void *get_pixels, void *get_pixels_data, void *
|
|||
}
|
||||
|
||||
static void
|
||||
eng_gl_get_pixels_pre(void *engine)
|
||||
eng_gl_get_pixels_pre(void *e, void *o)
|
||||
{
|
||||
EVGLINIT(engine, );
|
||||
Render_Engine_GL_Generic *engine = e;
|
||||
Render_Output_GL_Generic *output = o;
|
||||
|
||||
if (!evgl_init_do(engine, output))
|
||||
return ;
|
||||
evgl_get_pixels_pre();
|
||||
}
|
||||
|
||||
static void
|
||||
eng_gl_get_pixels_post(void *engine EINA_UNUSED)
|
||||
eng_gl_get_pixels_post(void *e EINA_UNUSED, void *o EINA_UNUSED)
|
||||
{
|
||||
evgl_get_pixels_post();
|
||||
}
|
||||
|
@ -1759,11 +1854,15 @@ eng_gl_surface_read_pixels(void *engine EINA_UNUSED, void *surface,
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_query(void *engine, void *surface, int attr, void *value)
|
||||
eng_gl_surface_query(void *eng, void *surface, int attr, void *value)
|
||||
{
|
||||
Render_Output_GL_Generic *re = engine;
|
||||
Render_Engine_GL_Generic *engine = eng;
|
||||
Render_Output_GL_Generic *re;
|
||||
EVGL_Surface *sfc = surface;
|
||||
|
||||
re = _evgl_output_find(engine);
|
||||
if (!re) return EINA_FALSE;
|
||||
|
||||
#ifdef GL_GLES
|
||||
if (sfc->pbuffer.is_pbuffer)
|
||||
{
|
||||
|
@ -3112,6 +3211,7 @@ module_open(Evas_Module *em)
|
|||
ORD(font_cache_set);
|
||||
ORD(font_cache_get);
|
||||
|
||||
ORD(gl_output_set);
|
||||
ORD(gl_surface_create);
|
||||
ORD(gl_pbuffer_surface_create);
|
||||
ORD(gl_surface_destroy);
|
||||
|
|
|
@ -4799,6 +4799,7 @@ static Evas_Func func =
|
|||
eng_font_pen_coords_get,
|
||||
eng_font_text_props_info_create,
|
||||
eng_font_right_inset_get,
|
||||
NULL, // No need to set output for software engine
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_create
|
||||
NULL, // need software mesa for gl rendering <- gl_pbuffer_surface_create
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_destroy
|
||||
|
|
Loading…
Reference in New Issue