On 24/06/13 07:07, Cedric BAIL wrote: > Cedric Bail > On Jun 24, 2013 3:14 PM, "Chris Michael" <[email protected]> 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
No worries. Ported it myself to wayland_egl ;) dh >> dh >> >> On 06/24/13 04:04, Cedric Bail - Enlightenment Git wrote: >>> cedric pushed a commit to branch master. >>> >>> commit d06a0982ef3d156059b2264d4494e036cbe409ee >>> Author: Cedric Bail <[email protected]> >>> 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 >> [email protected] >> 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 > [email protected] > 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 [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
