Cedric Bail On Jun 24, 2013 3:14 PM, "Chris Michael" <devilho...@comcast.net> wrote: > > Hmmm, you did not port this change to wayland_egl ??
Not yet, mostly because I have an nvidia hardware for the moment. But I tested it should not break stuff if you don't initialize the gl preload. Cedric > > dh > > On 06/24/13 04:04, Cedric Bail - Enlightenment Git wrote: > > cedric pushed a commit to branch master. > > > > commit d06a0982ef3d156059b2264d4494e036cbe409ee > > Author: Cedric Bail <cedric.b...@samsung.com> > > Date: Mon Jun 24 11:41:32 2013 +0900 > > > > evas: add support for asynchronously uploading GL texture. > > > > NOTE: when using Evas_Object image preload infrastructure the GL texture > > upload was uploaded from the main loop during the rendering stage. This > > could lead to some frame drop during fast animation due to the time needed > > to upload that texture. > > > > This patch fix this problem by uploading a small texture quickly (16x16) > > and waiting for going back to the main loop to be able to use the same GL > > context from another thread to do the texture upload asynchronously without > > blocking the main loop. > > --- > > ChangeLog | 4 + > > NEWS | 1 + > > src/Makefile_Evas.am | 1 + > > src/lib/evas/cache/evas_cache_image.c | 1 + > > src/lib/evas/include/evas_common_private.h | 2 + > > .../evas/engines/gl_common/evas_gl_common.h | 40 +- > > .../evas/engines/gl_common/evas_gl_context.c | 54 ++- > > src/modules/evas/engines/gl_common/evas_gl_core.c | 1 - > > src/modules/evas/engines/gl_common/evas_gl_image.c | 5 +- > > .../evas/engines/gl_common/evas_gl_preload.c | 441 +++++++++++++++++++++ > > .../evas/engines/gl_common/evas_gl_texture.c | 111 +++++- > > src/modules/evas/engines/gl_x11/evas_engine.c | 72 +++- > > src/modules/evas/engines/gl_x11/evas_x_main.c | 46 +++ > > 13 files changed, 741 insertions(+), 38 deletions(-) > > > > diff --git a/ChangeLog b/ChangeLog > > index 783c42e..d2abf99 100644 > > --- a/ChangeLog > > +++ b/ChangeLog > > @@ -1,3 +1,7 @@ > > +2013-06-24 Cedric Bail > > + > > + * Evas: add support for asynchronously uploading GL texture. > > + > > 2013-06-22 Thiep Ha > > > > * Edje: Move cursor to correct position when selection handlers are pressed. > > diff --git a/NEWS b/NEWS > > index 9da4640..cd6dda8 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -48,6 +48,7 @@ Additions: > > - Add multiple font draws support to engines > > - Add Cserve2 scalecache support > > - Add evas_object_image_source_clip_set()/get() > > + - Asynchronous preload of GL texture. > > * ecore_x: > > - Add window profile support. > > ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED > > diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am > > index 7cc9433..d4fe9aa 100644 > > --- a/src/Makefile_Evas.am > > +++ b/src/Makefile_Evas.am > > @@ -438,6 +438,7 @@ modules/evas/engines/gl_common/evas_gl_file_cache.c \ > > modules/evas/engines/gl_common/evas_gl_shader.c \ > > modules/evas/engines/gl_common/evas_gl_rectangle.c \ > > modules/evas/engines/gl_common/evas_gl_texture.c \ > > +modules/evas/engines/gl_common/evas_gl_preload.c \ > > modules/evas/engines/gl_common/evas_gl_image.c \ > > modules/evas/engines/gl_common/evas_gl_font.c \ > > modules/evas/engines/gl_common/evas_gl_polygon.c \ > > diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c > > index fe779a5..06d74de 100644 > > --- a/src/lib/evas/cache/evas_cache_image.c > > +++ b/src/lib/evas/cache/evas_cache_image.c > > @@ -396,6 +396,7 @@ _evas_cache_image_async_end(void *data) > > ie->cache->pending = eina_list_remove(ie->cache->pending, ie); > > ie->preload = NULL; > > ie->flags.preload_done = ie->flags.loaded; > > + ie->flags.updated_data = 1; > > while ((tmp = ie->targets)) > > { > > evas_object_inform_call_image_preloaded((Evas_Object*) tmp->target); > > diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h > > index 1a3c10c..f051a72 100644 > > --- a/src/lib/evas/include/evas_common_private.h > > +++ b/src/lib/evas/include/evas_common_private.h > > @@ -519,6 +519,8 @@ struct _Image_Entry_Flags > > Eina_Bool rotated : 1; > > Eina_Bool unload_cancel : 1; > > Eina_Bool given_mmap : 1; > > + > > + Eina_Bool updated_data : 1; > > }; > > > > struct _Image_Entry_Frame > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h > > index 8dc08ae..f0f3bd1 100644 > > --- a/src/modules/evas/engines/gl_common/evas_gl_common.h > > +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h > > @@ -162,6 +162,8 @@ > > #define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 > > #endif > > > > +#define EVAS_GL_TILE_SIZE 16 > > + > > #define SHAD_VERTEX 0 > > #define SHAD_COLOR 1 > > #define SHAD_TEXUV 2 > > @@ -181,6 +183,9 @@ typedef struct _Evas_GL_Image Evas_GL_Image; > > typedef struct _Evas_GL_Font_Texture Evas_GL_Font_Texture; > > typedef struct _Evas_GL_Polygon Evas_GL_Polygon; > > typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point; > > +typedef struct _Evas_GL_Texture_Async_Preload Evas_GL_Texture_Async_Preload; > > + > > +typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit); > > > > typedef enum { > > SHADER_RECT, > > @@ -494,6 +499,7 @@ struct _Evas_GL_Texture > > Evas_GL_Texture_Alloca *apt, *aptt; > > RGBA_Font_Glyph *fglyph; > > int x, y, w, h; > > + int tx, ty; > > double sx1, sy1, sx2, sy2; > > int references; > > > > @@ -503,8 +509,12 @@ struct _Evas_GL_Texture > > int source; > > } double_buffer; > > > > + Eina_List *targets; > > + > > Eina_Bool alpha : 1; > > Eina_Bool dyn : 1; > > + Eina_Bool uploaded : 1; > > + Eina_Bool was_preloaded : 1; > > }; > > > > struct _Evas_GL_Image > > @@ -540,6 +550,7 @@ struct _Evas_GL_Image > > int csize; > > > > Eina_List *filtered; > > + Eina_List *targets; > > > > unsigned char dirty : 1; > > unsigned char cached : 1; > > @@ -563,6 +574,14 @@ struct _Evas_GL_Polygon_Point > > int x, y; > > }; > > > > +struct _Evas_GL_Texture_Async_Preload > > +{ > > + Evas_GL_Texture *tex; > > + RGBA_Image *im; > > + > > + Eina_Bool unpack_row_length; > > +}; > > + > > #if 0 > > extern Evas_GL_Program_Source shader_rect_frag_src; > > extern Evas_GL_Program_Source shader_rect_vert_src; > > @@ -748,7 +767,19 @@ extern unsigned int (*secsym_eglUnmapImageSEC) (void *a, void *b, > > extern unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d); > > #endif > > > > -//#define GL_ERRORS 1 > > +Eina_Bool evas_gl_preload_push(Evas_GL_Texture_Async_Preload *async); > > +void evas_gl_preload_pop(Evas_GL_Texture *tex); > > +int evas_gl_preload_init(void); > > +int evas_gl_preload_shutdown(void); > > +void evas_gl_preload_render_lock(evas_gl_make_current_cb make_current, void *engine_data); > > +void evas_gl_preload_render_unlock(evas_gl_make_current_cb make_current, void *engine_data); > > +void evas_gl_preload_render_relax(evas_gl_make_current_cb make_current, void *engine_data); > > +void evas_gl_preload_target_register(Evas_GL_Texture *tex, Eo *target); > > +void evas_gl_preload_target_unregister(Evas_GL_Texture *tex, Eo *target); > > + > > +void pt_unref(Evas_GL_Texture_Pool *pt); > > + > > +#define GL_ERRORS 1 > > > > #ifdef GL_ERRORS > > # define GLERR(fn, fl, ln, op) \ > > @@ -763,4 +794,11 @@ extern unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, > > Eina_Bool evas_gl_common_module_open(void); > > void evas_gl_common_module_close(void); > > > > +static inline void > > +_tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix) > > +{ > > + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > +} > > + > > #endif > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c > > index f99be54..1bdfac3 100644 > > --- a/src/modules/evas/engines/gl_common/evas_gl_context.c > > +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c > > @@ -1261,8 +1261,15 @@ _evas_gl_common_context_push(int rtype, > > Eina_Bool clip, > > int cx, int cy, int cw, int ch) > > { > > + GLuint current_tex = 0; > > + GLuint current_texm = 0; > > int pn = 0; > > > > + if (tex) > > + current_tex = tex->ptt ? tex->ptt->texture : tex->pt->texture; > > + if (texm) > > + current_texm = texm->ptt ? texm->ptt->texture : tex->pt->texture; > > + > > #ifdef GLPIPES > > again: > > #endif > > @@ -1277,8 +1284,8 @@ _evas_gl_common_context_push(int rtype, > > for (i = pn; i >= 0; i--) > > { > > if ((gc->pipe[i].region.type == rtype) > > - && (!tex || gc->pipe[i].shader.cur_tex == tex->pt->texture) > > - && (!texm || gc->pipe[i].shader.cur_texm == texm->pt->texture) > > + && (!tex || gc->pipe[i].shader.cur_tex == current_tex) > > + && (!texm || gc->pipe[i].shader.cur_texm == current_texm) > > && (gc->pipe[i].shader.cur_prog == prog) > > && (gc->pipe[i].shader.smooth == smooth) > > && (gc->pipe[i].shader.blend == blend) > > @@ -1318,8 +1325,8 @@ _evas_gl_common_context_push(int rtype, > > } > > #else > > if (!((gc->pipe[pn].region.type == rtype) > > - && (!tex || gc->pipe[pn].shader.cur_tex == tex->pt->texture) > > - && (!texm || gc->pipe[pn].shader.cur_texm == texm->pt->texture) > > + && (!tex || gc->pipe[pn].shader.cur_tex == current_tex) > > + && (!texm || gc->pipe[pn].shader.cur_texm == current_texm) > > && (gc->pipe[pn].shader.cur_prog == prog) > > && (gc->pipe[pn].shader.smooth == smooth) > > && (gc->pipe[pn].shader.blend == blend) > > @@ -1553,8 +1560,10 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, > > int r, int g, int b, int a, > > Eina_Bool smooth, Eina_Bool tex_only) > > { > > + Evas_GL_Texture_Pool *pt; > > int pnum, nv, nc, nu, ns, i; > > GLfloat tx1, tx2, ty1, ty2; > > + GLfloat offsetx, offsety; > > Eina_Bool blend = EINA_FALSE; > > GLuint prog = gc->shared->shader[SHADER_IMG].prog; > > int pn = 0, sam = 0; > > @@ -1693,6 +1702,25 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, > > } > > } > > > > + if (tex->ptt) > > + { > > + pt = tex->ptt; > > + offsetx = tex->tx; > > + offsety = tex->ty; > > + > > + // Adjusting sx, sy, sw and sh to real size of tiny texture > > + sx = sx * (EVAS_GL_TILE_SIZE - 2) / tex->w; > > + sw = sw * (EVAS_GL_TILE_SIZE - 2) / tex->w; > > + sy = sy * (EVAS_GL_TILE_SIZE - 1) / tex->h; > > + sh = sh * (EVAS_GL_TILE_SIZE - 1) / tex->h; > > + } > > + else > > + { > > + pt = tex->pt; > > + offsetx = tex->x; > > + offsety = tex->y; > > + } > > + > > pn = _evas_gl_common_context_push(RTYPE_IMAGE, > > gc, tex, NULL, > > prog, > > @@ -1702,7 +1730,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, > > 0, 0, 0, 0, 0); > > > > gc->pipe[pn].region.type = RTYPE_IMAGE; > > - gc->pipe[pn].shader.cur_tex = tex->pt->texture; > > + gc->pipe[pn].shader.cur_tex = pt->texture; > > gc->pipe[pn].shader.cur_prog = prog; > > gc->pipe[pn].shader.smooth = smooth; > > gc->pipe[pn].shader.blend = blend; > > @@ -1731,17 +1759,17 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, > > > > if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert)) > > { > > - tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; > > - ty1 = 1.0 - ((double)(tex->y) + sy) / (double)tex->pt->h; > > - tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; > > - ty2 = 1.0 - ((double)(tex->y) + sy + sh) / (double)tex->pt->h; > > + tx1 = ((double)(offsetx) + sx) / (double)pt->w; > > + ty1 = 1.0 - ((double)(offsety) + sy) / (double)pt->h; > > + tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w; > > + ty2 = 1.0 - ((double)(offsety) + sy + sh) / (double)pt->h; > > } > > else > > { > > - tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; > > - ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h; > > - tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; > > - ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h; > > + tx1 = ((double)(offsetx) + sx) / (double)pt->w; > > + ty1 = ((double)(offsety) + sy) / (double)pt->h; > > + tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w; > > + ty2 = ((double)(offsety) + sy + sh) / (double)pt->h; > > } > > > > PUSH_VERTEX(pn, x , y , 0); > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c > > index 5145e0d..8fadc27 100644 > > --- a/src/modules/evas/engines/gl_common/evas_gl_core.c > > +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c > > @@ -117,7 +117,6 @@ _internal_resource_make_current(void *eng_data, EVGL_Context *ctx) > > } > > } > > > > - > > // Set context from input or from resource > > if (ctx) > > context = ctx->context; > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c > > index f8cdd11..8e721f8 100644 > > --- a/src/modules/evas/engines/gl_common/evas_gl_image.c > > +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c > > @@ -13,7 +13,7 @@ evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc) > > { > > if (!im->tex->pt->dyn.img) > > { > > - evas_gl_common_texture_free(im->tex, EINA_TRUE); > > + evas_gl_common_texture_free(im->tex, EINA_TRUE); > > im->tex = NULL; > > } > > } > > @@ -574,11 +574,12 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) > > { > > case EVAS_COLORSPACE_ARGB8888: > > if ((im->tex) && > > - ((im->dirty) || (ie->animated.animated))) > > + ((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data))) > > { > > evas_cache_image_load_data(&im->im->cache_entry); > > evas_gl_common_texture_update(im->tex, im->im); > > evas_cache_image_unload_data(&im->im->cache_entry); > > + ie->flags.updated_data = 0; > > } > > if (!im->tex) > > { > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_preload.c b/src/modules/evas/engines/gl_common/evas_gl_preload.c > > new file mode 100644 > > index 0000000..ffdb909 > > --- /dev/null > > +++ b/src/modules/evas/engines/gl_common/evas_gl_preload.c > > @@ -0,0 +1,441 @@ > > +#include "evas_gl_private.h" > > + > > +static Eina_Thread async_loader_thread; > > +static Eina_Condition async_loader_cond; > > +static Eina_Lock async_loader_lock; > > + > > +static Evas_GL_Texture_Async_Preload *async_current = NULL; > > +static Eina_List *async_loader_tex = NULL; > > +static Eina_List *async_loader_todie = NULL; > > +static Eina_Bool async_loader_exit = EINA_FALSE; > > +static Eina_Bool async_loader_running = EINA_FALSE; > > +static Eina_Bool async_loader_standby = EINA_FALSE; > > +static Eina_Bool async_current_cancel = EINA_FALSE; > > +static int async_loader_init = 0; > > + > > +static void *async_engine_data = NULL; > > +static evas_gl_make_current_cb async_gl_make_current = NULL; > > + > > +Eina_Bool > > +evas_gl_preload_push(Evas_GL_Texture_Async_Preload *async) > > +{ > > + if (!async_loader_init) return EINA_FALSE; > > + > > + eina_lock_take(&async_loader_lock); > > + async_loader_tex = eina_list_append(async_loader_tex, async); > > + eina_lock_release(&async_loader_lock); > > + > > + return EINA_TRUE; > > +} > > + > > +void > > +evas_gl_preload_pop(Evas_GL_Texture *tex) > > +{ > > + Evas_GL_Texture_Async_Preload *async; > > + Eina_List *l; > > + > > + if (!async_loader_init) return ; > > + > > + eina_lock_take(&async_loader_lock); > > + > > + if (async_gl_make_current && async_current && async_current->tex == tex) > > + { > > + Eina_Bool running = async_loader_running; > > + evas_gl_make_current_cb tmp_cb = async_gl_make_current; > > + void *tmp_data = async_engine_data; > > + > > + async_current_cancel = EINA_TRUE; > > + eina_lock_release(&async_loader_lock); > > + > > + if (running) evas_gl_preload_render_lock(tmp_cb, tmp_data); > > + > > + evas_gl_common_texture_free(async_current->tex, EINA_FALSE); > > + evas_cache_image_drop(&async_current->im->cache_entry); > > + free(async_current); > > + > > + async_current = NULL; > > + > > + if (running) evas_gl_preload_render_unlock(tmp_cb, tmp_data); > > + > > + return ; > > + } > > + > > + EINA_LIST_FOREACH(async_loader_tex, l, async) > > + if (async->tex == tex) > > + { > > + async_loader_tex = eina_list_remove_list(async_loader_tex, l); > > + > > + evas_gl_common_texture_free(async->tex, EINA_FALSE); > > + evas_cache_image_drop(&async->im->cache_entry); > > + free(async); > > + > > + break; > > + } > > + > > + eina_lock_release(&async_loader_lock); > > +} > > + > > +static void > > +_evas_gl_preload_main_loop_wakeup(void) > > +{ > > + Evas_GL_Texture_Async_Preload *async; > > + evas_gl_make_current_cb cb = async_gl_make_current; > > + void *data = async_engine_data; > > + Eina_Bool running = async_loader_running; > > + > > + if (running) evas_gl_preload_render_lock(cb, data); > > + EINA_LIST_FREE(async_loader_todie, async) > > + { > > + Eo *target; > > + > > + EINA_LIST_FREE(async->tex->targets, target) > > + eo_do(target, evas_obj_image_pixels_dirty_set(EINA_TRUE)); > > + async->im->cache_entry.flags.preload_done = 0; > > + async->tex->was_preloaded = EINA_TRUE; > > + > > + async->tex->ptt->allocations = eina_list_remove(async->tex->ptt->allocations, async->tex->aptt); > > + pt_unref(async->tex->ptt); > > + async->tex->ptt = NULL; > > + free(async->tex->aptt); > > + async->tex->aptt = NULL; > > + > > + evas_gl_common_texture_free(async->tex, EINA_FALSE); > > + evas_cache_image_drop(&async->im->cache_entry); > > + free(async); > > + } > > + if (running) evas_gl_preload_render_unlock(cb, data); > > +} > > + > > +static void > > +_evas_gl_preload_main_loop_wakeup_cb(void *target EINA_UNUSED, > > + Evas_Callback_Type type EINA_UNUSED, > > + void *event_info EINA_UNUSED) > > +{ > > + _evas_gl_preload_main_loop_wakeup(); > > +} > > + > > +static Eina_Bool > > +_evas_gl_preload_lock(void) > > +{ > > + eina_lock_take(&async_loader_lock); > > + if (async_loader_standby) > > + { > > + async_gl_make_current(async_engine_data, NULL); > > + > > + async_loader_running = EINA_FALSE; > > + > > + eina_condition_signal(&async_loader_cond); > > + > > + eina_condition_wait(&async_loader_cond); > > + if (async_loader_exit) return EINA_FALSE; > > + > > + async_gl_make_current(async_engine_data, async_engine_data); > > + } > > + async_loader_running = EINA_TRUE; > > + eina_lock_release(&async_loader_lock); > > + > > + return EINA_TRUE; > > +} > > + > > +static void * > > +_evas_gl_preload_tile_async(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED) > > +{ > > + eina_lock_take(&async_loader_lock); > > + while (!async_loader_exit) > > + { > > + Evas_GL_Texture_Async_Preload *async; > > + GLuint fmt; > > + > > + if (!async_loader_standby && async_loader_tex) > > + goto get_next; > > + > > + retry: > > + eina_condition_wait(&async_loader_cond); > > + if (async_loader_exit) break ; > > + > > + get_next: > > + // Get a texture to upload > > + async = eina_list_data_get(async_loader_tex); > > + async_loader_tex = eina_list_remove_list(async_loader_tex, async_loader_tex); > > + if (!async) continue; > > + > > + async_loader_running = EINA_TRUE; > > + async_current = async; > > + > > + eina_lock_release(&async_loader_lock); > > + > > + // Switch context to this thread > > + if (!async_gl_make_current(async_engine_data, async_engine_data)) > > + { > > + eina_lock_take(&async_loader_lock); > > + async_loader_tex = eina_list_append(async_loader_tex, async_current); > > + async_loader_running = EINA_FALSE; > > + async_current = NULL; > > + > > + if (async_loader_standby) > > + eina_condition_signal(&async_loader_cond); > > + > > + goto retry; > > + } > > + > > + // FIXME: loop until all subtile are uploaded or the image is about to be deleted > > + > > + // TEMPORARY CODE JUST TO SEE IF IT WORK > > + fmt = async->tex->pt->format; > > + glBindTexture(GL_TEXTURE_2D, async->tex->pt->texture); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + if (async->unpack_row_length) > > + { > > + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + } > > + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + > > + // +-+ > > + // +-+ > > + // > > + _tex_sub_2d(async->tex->x, async->tex->y, > > + async->im->cache_entry.w, async->im->cache_entry.h, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data); > > + // xxx > > + // xxx > > + // --- > > + _tex_sub_2d(async->tex->x, async->tex->y + async->im->cache_entry.h, > > + async->im->cache_entry.w, 1, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w)); > > + // xxx > > + // xxx > > + // o > > + _tex_sub_2d(async->tex->x - 1, async->tex->y + async->im->cache_entry.h, > > + 1, 1, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w)); > > + // xxx > > + // xxx > > + // o > > + _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y + async->im->cache_entry.h, > > + 1, 1, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w) + (async->im->cache_entry.w - 1)); > > + if (async->unpack_row_length) > > + { > > + glPixelStorei(GL_UNPACK_ROW_LENGTH, async->im->cache_entry.w); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + // |xxx > > + // |xxx > > + // > > + _tex_sub_2d(async->tex->x - 1, async->tex->y, > > + 1, async->im->cache_entry.h, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data); > > + // xxx| > > + // xxx| > > + // > > + _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y, > > + 1, async->im->cache_entry.h, > > + fmt, async->tex->pt->dataformat, > > + async->im->image.data + (async->im->cache_entry.w - 1)); > > + } > > + else > > + { > > + DATA32 *tpix, *ps, *pd; > > + int i; > > + > > + tpix = alloca(async->im->cache_entry.h * sizeof(DATA32)); > > + pd = tpix; > > + ps = async->im->image.data; > > + for (i = 0; i < (int)async->im->cache_entry.h; i++) > > + { > > + *pd = *ps; > > + pd++; > > + ps += async->im->cache_entry.w; > > + } > > + // |xxx > > + // |xxx > > + // > > + _tex_sub_2d(async->tex->x - 1, async->tex->y, > > + 1, async->im->cache_entry.h, > > + fmt, async->tex->pt->dataformat, > > + tpix); > > + pd = tpix; > > + ps = async->im->image.data + (async->im->cache_entry.w - 1); > > + for (i = 0; i < (int)async->im->cache_entry.h; i++) > > + { > > + *pd = *ps; > > + pd++; > > + ps += async->im->cache_entry.w; > > + } > > + // xxx| > > + // xxx| > > + // > > + _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y, > > + 1, async->im->cache_entry.h, > > + fmt, async->tex->pt->dataformat, > > + tpix); > > + } > > + > > + // Switch back to current texture > > + if (async->tex->ptt->texture != async->tex->gc->pipe[0].shader.cur_tex) > > + { > > + glBindTexture(GL_TEXTURE_2D, async->tex->gc->pipe[0].shader.cur_tex); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + } > > + > > + // Shall we block now ? > > + if (!_evas_gl_preload_lock()) > > + break; > > + > > + // Release context > > + async_gl_make_current(async_engine_data, NULL); > > + > > + evas_async_events_put(NULL, 0, NULL, _evas_gl_preload_main_loop_wakeup_cb); > > + > > + eina_lock_take(&async_loader_lock); > > + async_current = NULL; > > + async_loader_todie = eina_list_append(async_loader_todie, async); > > + async_loader_running = EINA_FALSE; > > + > > + if (async_loader_standby) > > + eina_condition_signal(&async_loader_cond); > > + } > > + eina_lock_release(&async_loader_lock); > > + > > + return NULL; > > +} > > + > > +// In the main loop > > +// Push stuff on the todo queue > > +// Upload the mini texture > > +// Use the mini texture > > +// Once download of the big texture, destroy mini texture and image data > > + > > + > > +// Put the async preloader on standby > > +void > > +evas_gl_preload_render_lock(evas_gl_make_current_cb make_current, void *engine_data) > > +{ > > + if (!async_loader_init) return ; > > + eina_lock_take(&async_loader_lock); > > + if (async_loader_running) > > + { > > + async_loader_standby = EINA_TRUE; > > + eina_condition_wait(&async_loader_cond); > > + > > + make_current(engine_data, engine_data); > > + > > + async_engine_data = NULL; > > + async_gl_make_current = NULL; > > + } > > + > > + eina_lock_release(&async_loader_lock); > > +} > > + > > +// Let the async preloader run ! > > +void > > +evas_gl_preload_render_unlock(evas_gl_make_current_cb make_current, void *engine_data) > > +{ > > + if (!async_loader_init) return ; > > + if (!make_current) return ; > > + > > + eina_lock_take(&async_loader_lock); > > + if (!async_loader_running && (async_loader_tex || async_current)) > > + { > > + make_current(engine_data, NULL); > > + > > + async_gl_make_current = make_current; > > + async_engine_data = engine_data; > > + > > + async_loader_standby = EINA_FALSE; > > + eina_condition_signal(&async_loader_cond); > > + } > > + eina_lock_release(&async_loader_lock); > > +} > > + > > +// add a way to destroy surface and temporarily stop the rendering of the image > > +void > > +evas_gl_preload_render_relax(evas_gl_make_current_cb make_current, void *engine_data) > > +{ > > + if (engine_data != async_engine_data) return ; > > + > > + evas_gl_preload_render_lock(make_current, engine_data); > > +} > > + > > +static Eina_Bool > > +_evas_gl_preload_target_die(void *data, Eo *obj, > > + const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) > > +{ > > + Evas_GL_Texture *tex = data; > > + > > + evas_gl_preload_target_unregister(tex, obj); > > + > > + return EO_CALLBACK_CONTINUE; > > +} > > + > > +void > > +evas_gl_preload_target_register(Evas_GL_Texture *tex, Eo *target) > > +{ > > + eo_do(target, > > + eo_event_callback_add(EO_EV_DEL, _evas_gl_preload_target_die, tex)); > > + tex->targets = eina_list_append(tex->targets, target); > > + tex->references++; > > +} > > + > > +void > > +evas_gl_preload_target_unregister(Evas_GL_Texture *tex, Eo *target) > > +{ > > + Eina_List *l; > > + const Eo *o; > > + > > + eo_do(target, > > + eo_event_callback_del(EO_EV_DEL, _evas_gl_preload_target_die, tex)); > > + > > + EINA_LIST_FOREACH(tex->targets, l, o) > > + if (o == target) > > + { > > + void *data = async_engine_data; > > + evas_gl_make_current_cb cb = async_gl_make_current; > > + Eina_Bool running = async_loader_running; > > + > > + if (running) evas_gl_preload_render_lock(cb, data); > > + tex->targets = eina_list_remove_list(tex->targets, l); > > + evas_gl_common_texture_free(tex, EINA_FALSE); > > + if (running) evas_gl_preload_render_unlock(cb, data); > > + > > + break; > > + } > > +} > > + > > +int > > +evas_gl_preload_init(void) > > +{ > > + if (async_loader_init++) return async_loader_init; > > + > > + eina_lock_new(&async_loader_lock); > > + eina_condition_new(&async_loader_cond, &async_loader_lock); > > + > > + if (!eina_thread_create(&async_loader_thread, EINA_THREAD_BACKGROUND, 0, _evas_gl_preload_tile_async, NULL)) > > + { > > + // FIXME: handle error case > > + } > > + > > + return async_loader_init; > > +} > > + > > +int > > +evas_gl_preload_shutdown(void) > > +{ > > + if (--async_loader_init) return async_loader_init; > > + > > + async_loader_exit = EINA_TRUE; > > + eina_condition_signal(&async_loader_cond); > > + > > + eina_thread_join(async_loader_thread); > > + > > + eina_condition_free(&async_loader_cond); > > + eina_lock_free(&async_loader_lock); > > + > > + return async_loader_init; > > +} > > diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c > > index 0c07ffa..426549c 100644 > > --- a/src/modules/evas/engines/gl_common/evas_gl_texture.c > > +++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c > > @@ -194,13 +194,6 @@ evas_gl_common_texture_light_free(Evas_GL_Texture *tex) > > free(tex); > > } > > > > -static void > > -_tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix) > > -{ > > - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix); > > - GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > -} > > - > > static Evas_GL_Texture_Pool * > > _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format) > > { > > @@ -711,7 +704,7 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt) > > pt->h = 0; > > } > > > > -static void > > +void > > pt_unref(Evas_GL_Texture_Pool *pt) > > { > > if (!pt) return; > > @@ -814,7 +807,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im) > > { > > GLuint fmt; > > > > - if (!im->image.data) return; > > + if (!im->cache_entry.flags.loaded) return; > > > > if (tex->alpha != im->cache_entry.flags.alpha) > > { > > @@ -830,8 +823,101 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im) > > *matching_format[lformat].intformat, > > *matching_format[lformat].format); > > } > > + // If image was preloaded then we need a ptt > > if (!tex->pt) return; > > > > + // if preloaded, then async push it in after uploading a miniature of it > > + if (im->cache_entry.flags.preload_done && tex->w > 2 * EVAS_GL_TILE_SIZE && tex->h > 2 * EVAS_GL_TILE_SIZE) > > + { > > + Evas_GL_Texture_Async_Preload *async; > > + int *in; > > + int out[EVAS_GL_TILE_SIZE * EVAS_GL_TILE_SIZE]; > > + float xstep, ystep; > > + float x, y; > > + int i, j; > > + int lformat; > > + int u, v; > > + > > + if (tex->ptt) return ; > > + > > + xstep = (float)tex->w / (EVAS_GL_TILE_SIZE - 2); > > + ystep = (float)tex->h / (EVAS_GL_TILE_SIZE - 1); > > + in = (int*) im->image.data; > > + > > + for (y = 0, j = 0; j < EVAS_GL_TILE_SIZE - 1; y += ystep, j++) > > + { > > + out[j * EVAS_GL_TILE_SIZE] = in[(int)y * im->cache_entry.w]; > > + for (x = 0, i = 1; i < EVAS_GL_TILE_SIZE - 1; x += xstep, i++) > > + out[j * EVAS_GL_TILE_SIZE + i] = in[(int)y * im->cache_entry.w + (int)x]; > > + out[j * EVAS_GL_TILE_SIZE + i] = in[(int)y * im->cache_entry.w + (int)(x - xstep)]; > > + } > > + > > + memcpy(&out[j * EVAS_GL_TILE_SIZE], &out[(j - 1) * EVAS_GL_TILE_SIZE], EVAS_GL_TILE_SIZE * sizeof (int)); > > + > > + // out is a miniature of the texture, upload that now and schedule the data for later. > > + > > + // Creating the mini picture texture > > + lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra); > > + tex->ptt = _pool_tex_find(tex->gc, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE, > > + *matching_format[lformat].intformat, > > + *matching_format[lformat].format, > > + &u, &v, &tex->aptt, > > + tex->gc->shared->info.tune.atlas.max_alloc_size); > > + if (!tex->ptt) > > + goto upload; > > + tex->aptt->tex = tex; > > + > > + tex->tx = u + 1; > > + tex->ty = v; > > + tex->ptt->references++; > > + > > + // Bind and upload ! Vooom ! > > + fmt = tex->ptt->format; > > + glBindTexture(GL_TEXTURE_2D, tex->ptt->texture); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + if (tex->gc->shared->info.unpack_row_length) > > + { > > + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + } > > + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + > > + _tex_sub_2d(u, tex->ty, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE, fmt, tex->ptt->dataformat, out); > > + > > + // Switch back to current texture > > + if (tex->ptt->texture != tex->gc->pipe[0].shader.cur_tex) > > + { > > + glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + } > > + > > + // Now prepare uploading the main texture before returning; > > + async = malloc(sizeof (Evas_GL_Texture_Async_Preload)); > > + if (!async) > > + { > > + goto upload; > > + } > > + > > + async->tex = tex; > > + async->tex->references++; > > + async->im = im; > > + evas_cache_image_ref(&async->im->cache_entry); > > + async->unpack_row_length = tex->gc->shared->info.unpack_row_length; > > + > > + if (evas_gl_preload_push(async)) > > + return ; > > + > > + // Failed to start asynchronous upload, likely due to preload not being supported by the backend > > + async->tex->references--; > > + evas_cache_image_drop(&async->im->cache_entry); > > + free(async); > > + > > + upload: > > + pt_unref(tex->ptt); > > + tex->ptt = NULL; > > + } > > + > > fmt = tex->pt->format; > > glBindTexture(GL_TEXTURE_2D, tex->pt->texture); > > GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > @@ -939,6 +1025,13 @@ void > > evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED) > > { > > if (!tex) return; > > + if (force) > > + { > > + evas_gl_preload_pop(tex); > > + > > + while (tex->targets) > > + evas_gl_preload_target_unregister(tex, eina_list_data_get(tex->targets)); > > + } > > tex->references--; > > if (tex->references != 0) return; > > if (tex->fglyph) > > diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c > > index 7f408fd..9441d6d 100644 > > --- a/src/modules/evas/engines/gl_x11/evas_engine.c > > +++ b/src/modules/evas/engines/gl_x11/evas_engine.c > > @@ -73,6 +73,8 @@ typedef int (*glsym_func_int) (); > > typedef unsigned int (*glsym_func_uint) (); > > typedef const char *(*glsym_func_const_char_ptr) (); > > > > +static Eina_Bool eng_preload_make_current(void *data, void *doit); > > + > > #ifdef GL_GLES > > > > #ifndef EGL_NATIVE_PIXMAP_KHR > > @@ -702,10 +704,6 @@ gl_extn_veto(Render_Engine *re) > > { > > extn_have_buffer_age = 0; > > } > > - if (!strstr(str, "swap_buffers_with_damage")) > > - { > > - glsym_eglSwapBuffersWithDamage = NULL; > > - } > > } > > else > > { > > @@ -808,6 +806,7 @@ static void > > _re_winfree(Render_Engine *re) > > { > > if (!re->win->surf) return; > > + evas_gl_preload_render_relax(eng_preload_make_current, re); > > eng_window_unsurf(re->win); > > } > > > > @@ -877,6 +876,7 @@ eng_setup(Evas *eo_e, void *in) > > evas_common_font_init(); > > evas_common_draw_init(); > > evas_common_tilebuf_init(); > > + evas_gl_preload_init(); > > gl_extn_veto(re); > > // evgl_engine_init(re, &evgl_funcs); > > initted = 1; > > @@ -1033,6 +1033,8 @@ eng_output_free(void *data) > > > > if (re) > > { > > + evas_gl_preload_render_relax(eng_preload_make_current, re); > > + > > #if 0 > > #ifdef GL_GLES > > // Destroy the resource surface > > @@ -1070,6 +1072,7 @@ eng_output_free(void *data) > > } > > if ((initted == 1) && (gl_wins == 0)) > > { > > + evas_gl_preload_shutdown(); > > evas_common_image_shutdown(); > > evas_common_font_shutdown(); > > initted = 0; > > @@ -1213,6 +1216,42 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) > > /* vsync games - not for now though */ > > #define VSYNC_TO_SCREEN 1 > > > > +static Eina_Bool > > +eng_preload_make_current(void *data, void *doit) > > +{ > > + Render_Engine *re = data; > > + > > + if (doit) > > + { > > +#ifdef GL_GLES > > + if (!eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0])) > > + return EINA_FALSE; > > +#else > > + if (!glXMakeCurrent(re->info->info.display, re->win->win, re->win->context)) > > + { > > + ERR("glXMakeCurrent(%p, 0x%x, %p) failed", re->info->info.display, (unsigned int)re->win->win, (void *)re->win->context); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + return EINA_FALSE; > > + } > > +#endif > > + } > > + else > > + { > > +#ifdef GL_GLES > > + if (!eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) > > + return EINA_FALSE; > > +#else > > + if (!glXMakeCurrent(re->info->info.display, None, NULL)) > > + { > > + ERR("glXMakeCurrent(%p, None, NULL) failed", re->info->info.display); > > + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); > > + return EINA_FALSE; > > + } > > +#endif > > + } > > + return EINA_TRUE; > > +} > > + > > static void * > > eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) > > { > > @@ -1353,6 +1392,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i > > } > > if (first_rect) > > { > > + evas_gl_preload_render_lock(eng_preload_make_current, re); > > #ifdef GL_GLES > > // dont need to for egl - eng_window_use() can check for other ctxt's > > #else > > @@ -1433,11 +1473,11 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) > > { > > Render_Engine *re; > > > > - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; > > + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; > > > > re = (Render_Engine *)data; > > - if (!_re_wincheck(re)) return; > > - if (!re->win->draw.drew) return; > > + if (!_re_wincheck(re)) goto end; > > + if (!re->win->draw.drew) goto end; > > > > re->win->draw.drew = 0; > > eng_window_use(re->win); > > @@ -1454,7 +1494,7 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) > > { > > re->info->callback.pre_swap(re->info->callback.data, re->evas); > > } > > - if ((glsym_eglSwapBuffersWithDamage) && (re->mode != MODE_FULL)) > > + if ((glsym_eglSwapBuffersRegion) && (re->mode != MODE_FULL)) > > { > > EGLint num = 0, *rects = NULL, i = 0; > > Tilebuf_Rect *r; > > @@ -1505,9 +1545,9 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) > > } > > i += 4; > > } > > - glsym_eglSwapBuffersWithDamage(re->win->egl_disp, > > - re->win->egl_surface[0], > > - rects, num); > > + glsym_eglSwapBuffersRegion(re->win->egl_disp, > > + re->win->egl_surface[0], > > + num, rects); > > } > > } > > else > > @@ -1574,6 +1614,9 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) > > evas_common_tilebuf_free_render_rects(re->rects); > > re->rects = NULL; > > } > > + > > + end: > > + evas_gl_preload_render_unlock(eng_preload_make_current, re); > > } > > > > static void > > @@ -2771,9 +2814,10 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) > > } > > > > static void > > -eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *target) > > +eng_image_data_preload_request(void *data, void *image, const Eo *target) > > { > > Evas_GL_Image *gim = image; > > + Render_Engine *re = data; > > RGBA_Image *im; > > > > if (!gim) return; > > @@ -2781,6 +2825,9 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *ta > > im = (RGBA_Image *)gim->im; > > if (!im) return; > > evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); > > + if (!gim->tex) > > + gim->tex = evas_gl_common_texture_new(re->win->gl_context, gim->im); > > + evas_gl_preload_target_register(gim->tex, (Eo*) target); > > } > > > > static void > > @@ -2794,6 +2841,7 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *tar > > im = (RGBA_Image *)gim->im; > > if (!im) return; > > evas_cache_image_preload_cancel(&im->cache_entry, target); > > + evas_gl_preload_target_unregister(gim->tex, (Eo*) target); > > } > > > > static Eina_Bool > > diff --git a/src/modules/evas/engines/gl_x11/evas_x_main.c b/src/modules/evas/engines/gl_x11/evas_x_main.c > > index d0de1df..91015dc 100644 > > --- a/src/modules/evas/engines/gl_x11/evas_x_main.c > > +++ b/src/modules/evas/engines/gl_x11/evas_x_main.c > > @@ -454,11 +454,57 @@ eng_window_free(Evas_GL_X11_Window *gw) > > free(gw); > > } > > > > +static Eina_Bool > > +eng_window_make_current(void *data, void *doit) > > +{ > > + Evas_GL_X11_Window *gw = data; > > + > > +#ifdef GL_GLES > > + if (doit) > > + { > > + if (!eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0], gw->egl_context[0])) > > + return EINA_FALSE; > > + } > > + else > > + { > > + if (!eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) > > + return EINA_FALSE; > > + } > > +#else > > + if (doit) > > + { > > + if (gw->glxwin) > > + { > > + if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin, gw->context)) > > + { > > + ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context); > > + return EINA_FALSE; > > + } > > + } > > + else > > + { > > + if (!glXMakeCurrent(gw->disp, gw->win, gw->context)) > > + { > > + ERR("glXMakeCurrent(%p, 0x%x, %p) failed", gw->disp, (unsigned int)gw->win, (void *)gw->context); > > + return EINA_FALSE; > > + } > > + } > > + } > > + else > > + { > > + if (!glXMakeCurrent(gw->disp, None, NULL)) > > + return EINA_FALSE; > > + } > > +#endif > > + return EINA_TRUE; > > +} > > + > > void > > eng_window_use(Evas_GL_X11_Window *gw) > > { > > Eina_Bool force_use = EINA_FALSE; > > > > + evas_gl_preload_render_lock(eng_window_make_current, gw); > > #ifdef GL_GLES > > if (_evas_gl_x11_window) > > { > > > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Windows: > > Build for Windows Store. > > http://p.sf.net/sfu/windows-dev2dev > _______________________________________________ > enlightenment-devel mailing list > enlightenment-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > ------------------------------------------------------------------------------ This SF.net email is sponsored by Windows: Build for Windows Store. http://p.sf.net/sfu/windows-dev2dev _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel