summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--src/Makefile_Evas.am1
-rw-r--r--src/lib/evas/cache/evas_cache_image.c1
-rw-r--r--src/lib/evas/include/evas_common_private.h2
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h40
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c54
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core.c1
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_image.c5
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_preload.c441
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_texture.c111
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c72
-rw-r--r--src/modules/evas/engines/gl_x11/evas_x_main.c46
13 files changed, 741 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index 783c42eea8..d2abf99d25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
12013-06-24 Cedric Bail
2
3 * Evas: add support for asynchronously uploading GL texture.
4
12013-06-22 Thiep Ha 52013-06-22 Thiep Ha
2 6
3 * Edje: Move cursor to correct position when selection handlers are pressed. 7 * Edje: Move cursor to correct position when selection handlers are pressed.
diff --git a/NEWS b/NEWS
index 9da46409a0..cd6dda8868 100644
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,7 @@ Additions:
48 - Add multiple font draws support to engines 48 - Add multiple font draws support to engines
49 - Add Cserve2 scalecache support 49 - Add Cserve2 scalecache support
50 - Add evas_object_image_source_clip_set()/get() 50 - Add evas_object_image_source_clip_set()/get()
51 - Asynchronous preload of GL texture.
51 * ecore_x: 52 * ecore_x:
52 - Add window profile support. 53 - Add window profile support.
53 ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED 54 ECORE_X_ATOM_E_WINDOW_PROFILE_SUPPORTED
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 7cc9433e06..d4fe9aabab 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 \
438modules/evas/engines/gl_common/evas_gl_shader.c \ 438modules/evas/engines/gl_common/evas_gl_shader.c \
439modules/evas/engines/gl_common/evas_gl_rectangle.c \ 439modules/evas/engines/gl_common/evas_gl_rectangle.c \
440modules/evas/engines/gl_common/evas_gl_texture.c \ 440modules/evas/engines/gl_common/evas_gl_texture.c \
441modules/evas/engines/gl_common/evas_gl_preload.c \
441modules/evas/engines/gl_common/evas_gl_image.c \ 442modules/evas/engines/gl_common/evas_gl_image.c \
442modules/evas/engines/gl_common/evas_gl_font.c \ 443modules/evas/engines/gl_common/evas_gl_font.c \
443modules/evas/engines/gl_common/evas_gl_polygon.c \ 444modules/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 fe779a57f1..06d74def49 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)
396 ie->cache->pending = eina_list_remove(ie->cache->pending, ie); 396 ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
397 ie->preload = NULL; 397 ie->preload = NULL;
398 ie->flags.preload_done = ie->flags.loaded; 398 ie->flags.preload_done = ie->flags.loaded;
399 ie->flags.updated_data = 1;
399 while ((tmp = ie->targets)) 400 while ((tmp = ie->targets))
400 { 401 {
401 evas_object_inform_call_image_preloaded((Evas_Object*) tmp->target); 402 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 1a3c10c086..f051a72a0a 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
519 Eina_Bool rotated : 1; 519 Eina_Bool rotated : 1;
520 Eina_Bool unload_cancel : 1; 520 Eina_Bool unload_cancel : 1;
521 Eina_Bool given_mmap : 1; 521 Eina_Bool given_mmap : 1;
522
523 Eina_Bool updated_data : 1;
522}; 524};
523 525
524struct _Image_Entry_Frame 526struct _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 8dc08ae37f..f0f3bd1593 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 @@
162#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 162#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
163#endif 163#endif
164 164
165#define EVAS_GL_TILE_SIZE 16
166
165#define SHAD_VERTEX 0 167#define SHAD_VERTEX 0
166#define SHAD_COLOR 1 168#define SHAD_COLOR 1
167#define SHAD_TEXUV 2 169#define SHAD_TEXUV 2
@@ -181,6 +183,9 @@ typedef struct _Evas_GL_Image Evas_GL_Image;
181typedef struct _Evas_GL_Font_Texture Evas_GL_Font_Texture; 183typedef struct _Evas_GL_Font_Texture Evas_GL_Font_Texture;
182typedef struct _Evas_GL_Polygon Evas_GL_Polygon; 184typedef struct _Evas_GL_Polygon Evas_GL_Polygon;
183typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point; 185typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point;
186typedef struct _Evas_GL_Texture_Async_Preload Evas_GL_Texture_Async_Preload;
187
188typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit);
184 189
185typedef enum { 190typedef enum {
186 SHADER_RECT, 191 SHADER_RECT,
@@ -494,6 +499,7 @@ struct _Evas_GL_Texture
494 Evas_GL_Texture_Alloca *apt, *aptt; 499 Evas_GL_Texture_Alloca *apt, *aptt;
495 RGBA_Font_Glyph *fglyph; 500 RGBA_Font_Glyph *fglyph;
496 int x, y, w, h; 501 int x, y, w, h;
502 int tx, ty;
497 double sx1, sy1, sx2, sy2; 503 double sx1, sy1, sx2, sy2;
498 int references; 504 int references;
499 505
@@ -503,8 +509,12 @@ struct _Evas_GL_Texture
503 int source; 509 int source;
504 } double_buffer; 510 } double_buffer;
505 511
512 Eina_List *targets;
513
506 Eina_Bool alpha : 1; 514 Eina_Bool alpha : 1;
507 Eina_Bool dyn : 1; 515 Eina_Bool dyn : 1;
516 Eina_Bool uploaded : 1;
517 Eina_Bool was_preloaded : 1;
508}; 518};
509 519
510struct _Evas_GL_Image 520struct _Evas_GL_Image
@@ -540,6 +550,7 @@ struct _Evas_GL_Image
540 int csize; 550 int csize;
541 551
542 Eina_List *filtered; 552 Eina_List *filtered;
553 Eina_List *targets;
543 554
544 unsigned char dirty : 1; 555 unsigned char dirty : 1;
545 unsigned char cached : 1; 556 unsigned char cached : 1;
@@ -563,6 +574,14 @@ struct _Evas_GL_Polygon_Point
563 int x, y; 574 int x, y;
564}; 575};
565 576
577struct _Evas_GL_Texture_Async_Preload
578{
579 Evas_GL_Texture *tex;
580 RGBA_Image *im;
581
582 Eina_Bool unpack_row_length;
583};
584
566#if 0 585#if 0
567extern Evas_GL_Program_Source shader_rect_frag_src; 586extern Evas_GL_Program_Source shader_rect_frag_src;
568extern Evas_GL_Program_Source shader_rect_vert_src; 587extern Evas_GL_Program_Source shader_rect_vert_src;
@@ -748,7 +767,19 @@ extern unsigned int (*secsym_eglUnmapImageSEC) (void *a, void *b,
748extern unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d); 767extern unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b, int c, int *d);
749#endif 768#endif
750 769
751//#define GL_ERRORS 1 770Eina_Bool evas_gl_preload_push(Evas_GL_Texture_Async_Preload *async);
771void evas_gl_preload_pop(Evas_GL_Texture *tex);
772int evas_gl_preload_init(void);
773int evas_gl_preload_shutdown(void);
774void evas_gl_preload_render_lock(evas_gl_make_current_cb make_current, void *engine_data);
775void evas_gl_preload_render_unlock(evas_gl_make_current_cb make_current, void *engine_data);
776void evas_gl_preload_render_relax(evas_gl_make_current_cb make_current, void *engine_data);
777void evas_gl_preload_target_register(Evas_GL_Texture *tex, Eo *target);
778void evas_gl_preload_target_unregister(Evas_GL_Texture *tex, Eo *target);
779
780void pt_unref(Evas_GL_Texture_Pool *pt);
781
782#define GL_ERRORS 1
752 783
753#ifdef GL_ERRORS 784#ifdef GL_ERRORS
754# define GLERR(fn, fl, ln, op) \ 785# define GLERR(fn, fl, ln, op) \
@@ -763,4 +794,11 @@ extern unsigned int (*secsym_eglGetImageAttribSEC) (void *a, void *b,
763Eina_Bool evas_gl_common_module_open(void); 794Eina_Bool evas_gl_common_module_open(void);
764void evas_gl_common_module_close(void); 795void evas_gl_common_module_close(void);
765 796
797static inline void
798_tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix)
799{
800 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
801 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
802}
803
766#endif 804#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 f99be54c10..1bdfac37f3 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,
1261 Eina_Bool clip, 1261 Eina_Bool clip,
1262 int cx, int cy, int cw, int ch) 1262 int cx, int cy, int cw, int ch)
1263{ 1263{
1264 GLuint current_tex = 0;
1265 GLuint current_texm = 0;
1264 int pn = 0; 1266 int pn = 0;
1265 1267
1268 if (tex)
1269 current_tex = tex->ptt ? tex->ptt->texture : tex->pt->texture;
1270 if (texm)
1271 current_texm = texm->ptt ? texm->ptt->texture : tex->pt->texture;
1272
1266#ifdef GLPIPES 1273#ifdef GLPIPES
1267 again: 1274 again:
1268#endif 1275#endif
@@ -1277,8 +1284,8 @@ _evas_gl_common_context_push(int rtype,
1277 for (i = pn; i >= 0; i--) 1284 for (i = pn; i >= 0; i--)
1278 { 1285 {
1279 if ((gc->pipe[i].region.type == rtype) 1286 if ((gc->pipe[i].region.type == rtype)
1280 && (!tex || gc->pipe[i].shader.cur_tex == tex->pt->texture) 1287 && (!tex || gc->pipe[i].shader.cur_tex == current_tex)
1281 && (!texm || gc->pipe[i].shader.cur_texm == texm->pt->texture) 1288 && (!texm || gc->pipe[i].shader.cur_texm == current_texm)
1282 && (gc->pipe[i].shader.cur_prog == prog) 1289 && (gc->pipe[i].shader.cur_prog == prog)
1283 && (gc->pipe[i].shader.smooth == smooth) 1290 && (gc->pipe[i].shader.smooth == smooth)
1284 && (gc->pipe[i].shader.blend == blend) 1291 && (gc->pipe[i].shader.blend == blend)
@@ -1318,8 +1325,8 @@ _evas_gl_common_context_push(int rtype,
1318 } 1325 }
1319#else 1326#else
1320 if (!((gc->pipe[pn].region.type == rtype) 1327 if (!((gc->pipe[pn].region.type == rtype)
1321 && (!tex || gc->pipe[pn].shader.cur_tex == tex->pt->texture) 1328 && (!tex || gc->pipe[pn].shader.cur_tex == current_tex)
1322 && (!texm || gc->pipe[pn].shader.cur_texm == texm->pt->texture) 1329 && (!texm || gc->pipe[pn].shader.cur_texm == current_texm)
1323 && (gc->pipe[pn].shader.cur_prog == prog) 1330 && (gc->pipe[pn].shader.cur_prog == prog)
1324 && (gc->pipe[pn].shader.smooth == smooth) 1331 && (gc->pipe[pn].shader.smooth == smooth)
1325 && (gc->pipe[pn].shader.blend == blend) 1332 && (gc->pipe[pn].shader.blend == blend)
@@ -1553,8 +1560,10 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
1553 int r, int g, int b, int a, 1560 int r, int g, int b, int a,
1554 Eina_Bool smooth, Eina_Bool tex_only) 1561 Eina_Bool smooth, Eina_Bool tex_only)
1555{ 1562{
1563 Evas_GL_Texture_Pool *pt;
1556 int pnum, nv, nc, nu, ns, i; 1564 int pnum, nv, nc, nu, ns, i;
1557 GLfloat tx1, tx2, ty1, ty2; 1565 GLfloat tx1, tx2, ty1, ty2;
1566 GLfloat offsetx, offsety;
1558 Eina_Bool blend = EINA_FALSE; 1567 Eina_Bool blend = EINA_FALSE;
1559 GLuint prog = gc->shared->shader[SHADER_IMG].prog; 1568 GLuint prog = gc->shared->shader[SHADER_IMG].prog;
1560 int pn = 0, sam = 0; 1569 int pn = 0, sam = 0;
@@ -1693,6 +1702,25 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
1693 } 1702 }
1694 } 1703 }
1695 1704
1705 if (tex->ptt)
1706 {
1707 pt = tex->ptt;
1708 offsetx = tex->tx;
1709 offsety = tex->ty;
1710
1711 // Adjusting sx, sy, sw and sh to real size of tiny texture
1712 sx = sx * (EVAS_GL_TILE_SIZE - 2) / tex->w;
1713 sw = sw * (EVAS_GL_TILE_SIZE - 2) / tex->w;
1714 sy = sy * (EVAS_GL_TILE_SIZE - 1) / tex->h;
1715 sh = sh * (EVAS_GL_TILE_SIZE - 1) / tex->h;
1716 }
1717 else
1718 {
1719 pt = tex->pt;
1720 offsetx = tex->x;
1721 offsety = tex->y;
1722 }
1723
1696 pn = _evas_gl_common_context_push(RTYPE_IMAGE, 1724 pn = _evas_gl_common_context_push(RTYPE_IMAGE,
1697 gc, tex, NULL, 1725 gc, tex, NULL,
1698 prog, 1726 prog,
@@ -1702,7 +1730,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
1702 0, 0, 0, 0, 0); 1730 0, 0, 0, 0, 0);
1703 1731
1704 gc->pipe[pn].region.type = RTYPE_IMAGE; 1732 gc->pipe[pn].region.type = RTYPE_IMAGE;
1705 gc->pipe[pn].shader.cur_tex = tex->pt->texture; 1733 gc->pipe[pn].shader.cur_tex = pt->texture;
1706 gc->pipe[pn].shader.cur_prog = prog; 1734 gc->pipe[pn].shader.cur_prog = prog;
1707 gc->pipe[pn].shader.smooth = smooth; 1735 gc->pipe[pn].shader.smooth = smooth;
1708 gc->pipe[pn].shader.blend = blend; 1736 gc->pipe[pn].shader.blend = blend;
@@ -1731,17 +1759,17 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
1731 1759
1732 if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert)) 1760 if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1733 { 1761 {
1734 tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; 1762 tx1 = ((double)(offsetx) + sx) / (double)pt->w;
1735 ty1 = 1.0 - ((double)(tex->y) + sy) / (double)tex->pt->h; 1763 ty1 = 1.0 - ((double)(offsety) + sy) / (double)pt->h;
1736 tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; 1764 tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w;
1737 ty2 = 1.0 - ((double)(tex->y) + sy + sh) / (double)tex->pt->h; 1765 ty2 = 1.0 - ((double)(offsety) + sy + sh) / (double)pt->h;
1738 } 1766 }
1739 else 1767 else
1740 { 1768 {
1741 tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; 1769 tx1 = ((double)(offsetx) + sx) / (double)pt->w;
1742 ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h; 1770 ty1 = ((double)(offsety) + sy) / (double)pt->h;
1743 tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; 1771 tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w;
1744 ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h; 1772 ty2 = ((double)(offsety) + sy + sh) / (double)pt->h;
1745 } 1773 }
1746 1774
1747 PUSH_VERTEX(pn, x , y , 0); 1775 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 5145e0dfc8..8fadc27a27 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)
117 } 117 }
118 } 118 }
119 119
120
121 // Set context from input or from resource 120 // Set context from input or from resource
122 if (ctx) 121 if (ctx)
123 context = ctx->context; 122 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 f8cdd111f8..8e721f82bc 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)
13 { 13 {
14 if (!im->tex->pt->dyn.img) 14 if (!im->tex->pt->dyn.img)
15 { 15 {
16 evas_gl_common_texture_free(im->tex, EINA_TRUE); 16 evas_gl_common_texture_free(im->tex, EINA_TRUE);
17 im->tex = NULL; 17 im->tex = NULL;
18 } 18 }
19 } 19 }
@@ -574,11 +574,12 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
574 { 574 {
575 case EVAS_COLORSPACE_ARGB8888: 575 case EVAS_COLORSPACE_ARGB8888:
576 if ((im->tex) && 576 if ((im->tex) &&
577 ((im->dirty) || (ie->animated.animated))) 577 ((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data)))
578 { 578 {
579 evas_cache_image_load_data(&im->im->cache_entry); 579 evas_cache_image_load_data(&im->im->cache_entry);
580 evas_gl_common_texture_update(im->tex, im->im); 580 evas_gl_common_texture_update(im->tex, im->im);
581 evas_cache_image_unload_data(&im->im->cache_entry); 581 evas_cache_image_unload_data(&im->im->cache_entry);
582 ie->flags.updated_data = 0;
582 } 583 }
583 if (!im->tex) 584 if (!im->tex)
584 { 585 {
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 0000000000..ffdb9093e7
--- /dev/null
+++ b/src/modules/evas/engines/gl_common/evas_gl_preload.c
@@ -0,0 +1,441 @@
1#include "evas_gl_private.h"
2
3static Eina_Thread async_loader_thread;
4static Eina_Condition async_loader_cond;
5static Eina_Lock async_loader_lock;
6
7static Evas_GL_Texture_Async_Preload *async_current = NULL;
8static Eina_List *async_loader_tex = NULL;
9static Eina_List *async_loader_todie = NULL;
10static Eina_Bool async_loader_exit = EINA_FALSE;
11static Eina_Bool async_loader_running = EINA_FALSE;
12static Eina_Bool async_loader_standby = EINA_FALSE;
13static Eina_Bool async_current_cancel = EINA_FALSE;
14static int async_loader_init = 0;
15
16static void *async_engine_data = NULL;
17static evas_gl_make_current_cb async_gl_make_current = NULL;
18
19Eina_Bool
20evas_gl_preload_push(Evas_GL_Texture_Async_Preload *async)
21{
22 if (!async_loader_init) return EINA_FALSE;
23
24 eina_lock_take(&async_loader_lock);
25 async_loader_tex = eina_list_append(async_loader_tex, async);
26 eina_lock_release(&async_loader_lock);
27
28 return EINA_TRUE;
29}
30
31void
32evas_gl_preload_pop(Evas_GL_Texture *tex)
33{
34 Evas_GL_Texture_Async_Preload *async;
35 Eina_List *l;
36
37 if (!async_loader_init) return ;
38
39 eina_lock_take(&async_loader_lock);
40
41 if (async_gl_make_current && async_current && async_current->tex == tex)
42 {
43 Eina_Bool running = async_loader_running;
44 evas_gl_make_current_cb tmp_cb = async_gl_make_current;
45 void *tmp_data = async_engine_data;
46
47 async_current_cancel = EINA_TRUE;
48 eina_lock_release(&async_loader_lock);
49
50 if (running) evas_gl_preload_render_lock(tmp_cb, tmp_data);
51
52 evas_gl_common_texture_free(async_current->tex, EINA_FALSE);
53 evas_cache_image_drop(&async_current->im->cache_entry);
54 free(async_current);
55
56 async_current = NULL;
57
58 if (running) evas_gl_preload_render_unlock(tmp_cb, tmp_data);
59
60 return ;
61 }
62
63 EINA_LIST_FOREACH(async_loader_tex, l, async)
64 if (async->tex == tex)
65 {
66 async_loader_tex = eina_list_remove_list(async_loader_tex, l);
67
68 evas_gl_common_texture_free(async->tex, EINA_FALSE);
69 evas_cache_image_drop(&async->im->cache_entry);
70 free(async);
71
72 break;
73 }
74
75 eina_lock_release(&async_loader_lock);
76}
77
78static void
79_evas_gl_preload_main_loop_wakeup(void)
80{
81 Evas_GL_Texture_Async_Preload *async;
82 evas_gl_make_current_cb cb = async_gl_make_current;
83 void *data = async_engine_data;
84 Eina_Bool running = async_loader_running;
85
86 if (running) evas_gl_preload_render_lock(cb, data);
87 EINA_LIST_FREE(async_loader_todie, async)
88 {
89 Eo *target;
90
91 EINA_LIST_FREE(async->tex->targets, target)
92 eo_do(target, evas_obj_image_pixels_dirty_set(EINA_TRUE));
93 async->im->cache_entry.flags.preload_done = 0;
94 async->tex->was_preloaded = EINA_TRUE;
95
96 async->tex->ptt->allocations = eina_list_remove(async->tex->ptt->allocations, async->tex->aptt);
97 pt_unref(async->tex->ptt);
98 async->tex->ptt = NULL;
99 free(async->tex->aptt);
100 async->tex->aptt = NULL;
101
102 evas_gl_common_texture_free(async->tex, EINA_FALSE);
103 evas_cache_image_drop(&async->im->cache_entry);
104 free(async);
105 }
106 if (running) evas_gl_preload_render_unlock(cb, data);
107}
108
109static void
110_evas_gl_preload_main_loop_wakeup_cb(void *target EINA_UNUSED,
111 Evas_Callback_Type type EINA_UNUSED,
112 void *event_info EINA_UNUSED)
113{
114 _evas_gl_preload_main_loop_wakeup();
115}
116
117static Eina_Bool
118_evas_gl_preload_lock(void)
119{
120 eina_lock_take(&async_loader_lock);
121 if (async_loader_standby)
122 {
123 async_gl_make_current(async_engine_data, NULL);
124
125 async_loader_running = EINA_FALSE;
126
127 eina_condition_signal(&async_loader_cond);
128
129 eina_condition_wait(&async_loader_cond);
130 if (async_loader_exit) return EINA_FALSE;
131
132 async_gl_make_current(async_engine_data, async_engine_data);
133 }
134 async_loader_running = EINA_TRUE;
135 eina_lock_release(&async_loader_lock);
136
137 return EINA_TRUE;
138}
139
140static void *
141_evas_gl_preload_tile_async(void *data EINA_UNUSED, Eina_Thread t EINA_UNUSED)
142{
143 eina_lock_take(&async_loader_lock);
144 while (!async_loader_exit)
145 {
146 Evas_GL_Texture_Async_Preload *async;
147 GLuint fmt;
148
149 if (!async_loader_standby && async_loader_tex)
150 goto get_next;
151
152 retry:
153 eina_condition_wait(&async_loader_cond);
154 if (async_loader_exit) break ;
155
156 get_next:
157 // Get a texture to upload
158 async = eina_list_data_get(async_loader_tex);
159 async_loader_tex = eina_list_remove_list(async_loader_tex, async_loader_tex);
160 if (!async) continue;
161
162 async_loader_running = EINA_TRUE;
163 async_current = async;
164
165 eina_lock_release(&async_loader_lock);
166
167 // Switch context to this thread
168 if (!async_gl_make_current(async_engine_data, async_engine_data))
169 {
170 eina_lock_take(&async_loader_lock);
171 async_loader_tex = eina_list_append(async_loader_tex, async_current);
172 async_loader_running = EINA_FALSE;
173 async_current = NULL;
174
175 if (async_loader_standby)
176 eina_condition_signal(&async_loader_cond);
177
178 goto retry;
179 }
180
181 // FIXME: loop until all subtile are uploaded or the image is about to be deleted
182
183 // TEMPORARY CODE JUST TO SEE IF IT WORK
184 fmt = async->tex->pt->format;
185 glBindTexture(GL_TEXTURE_2D, async->tex->pt->texture);
186 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
187 if (async->unpack_row_length)
188 {
189 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
190 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
191 }
192 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
193 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
194
195 // +-+
196 // +-+
197 //
198 _tex_sub_2d(async->tex->x, async->tex->y,
199 async->im->cache_entry.w, async->im->cache_entry.h,
200 fmt, async->tex->pt->dataformat,
201 async->im->image.data);
202 // xxx
203 // xxx
204 // ---
205 _tex_sub_2d(async->tex->x, async->tex->y + async->im->cache_entry.h,
206 async->im->cache_entry.w, 1,
207 fmt, async->tex->pt->dataformat,
208 async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w));
209 // xxx
210 // xxx
211 // o
212 _tex_sub_2d(async->tex->x - 1, async->tex->y + async->im->cache_entry.h,
213 1, 1,
214 fmt, async->tex->pt->dataformat,
215 async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w));
216 // xxx
217 // xxx
218 // o
219 _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y + async->im->cache_entry.h,
220 1, 1,
221 fmt, async->tex->pt->dataformat,
222 async->im->image.data + ((async->im->cache_entry.h - 1) * async->im->cache_entry.w) + (async->im->cache_entry.w - 1));
223 if (async->unpack_row_length)
224 {
225 glPixelStorei(GL_UNPACK_ROW_LENGTH, async->im->cache_entry.w);
226 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
227 // |xxx
228 // |xxx
229 //
230 _tex_sub_2d(async->tex->x - 1, async->tex->y,
231 1, async->im->cache_entry.h,
232 fmt, async->tex->pt->dataformat,
233 async->im->image.data);
234 // xxx|
235 // xxx|
236 //
237 _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y,
238 1, async->im->cache_entry.h,
239 fmt, async->tex->pt->dataformat,
240 async->im->image.data + (async->im->cache_entry.w - 1));
241 }
242 else
243 {
244 DATA32 *tpix, *ps, *pd;
245 int i;
246
247 tpix = alloca(async->im->cache_entry.h * sizeof(DATA32));
248 pd = tpix;
249 ps = async->im->image.data;
250 for (i = 0; i < (int)async->im->cache_entry.h; i++)
251 {
252 *pd = *ps;
253 pd++;
254 ps += async->im->cache_entry.w;
255 }
256 // |xxx
257 // |xxx
258 //
259 _tex_sub_2d(async->tex->x - 1, async->tex->y,
260 1, async->im->cache_entry.h,
261 fmt, async->tex->pt->dataformat,
262 tpix);
263 pd = tpix;
264 ps = async->im->image.data + (async->im->cache_entry.w - 1);
265 for (i = 0; i < (int)async->im->cache_entry.h; i++)
266 {
267 *pd = *ps;
268 pd++;
269 ps += async->im->cache_entry.w;
270 }
271 // xxx|
272 // xxx|
273 //
274 _tex_sub_2d(async->tex->x + async->im->cache_entry.w, async->tex->y,
275 1, async->im->cache_entry.h,
276 fmt, async->tex->pt->dataformat,
277 tpix);
278 }
279
280 // Switch back to current texture
281 if (async->tex->ptt->texture != async->tex->gc->pipe[0].shader.cur_tex)
282 {
283 glBindTexture(GL_TEXTURE_2D, async->tex->gc->pipe[0].shader.cur_tex);
284 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
285 }
286
287 // Shall we block now ?
288 if (!_evas_gl_preload_lock())
289 break;
290
291 // Release context
292 async_gl_make_current(async_engine_data, NULL);
293
294 evas_async_events_put(NULL, 0, NULL, _evas_gl_preload_main_loop_wakeup_cb);
295
296 eina_lock_take(&async_loader_lock);
297 async_current = NULL;
298 async_loader_todie = eina_list_append(async_loader_todie, async);
299 async_loader_running = EINA_FALSE;
300
301 if (async_loader_standby)
302 eina_condition_signal(&async_loader_cond);
303 }
304 eina_lock_release(&async_loader_lock);
305
306 return NULL;
307}
308
309// In the main loop
310// Push stuff on the todo queue
311// Upload the mini texture
312// Use the mini texture
313// Once download of the big texture, destroy mini texture and image data
314
315
316// Put the async preloader on standby
317void
318evas_gl_preload_render_lock(evas_gl_make_current_cb make_current, void *engine_data)
319{
320 if (!async_loader_init) return ;
321 eina_lock_take(&async_loader_lock);
322 if (async_loader_running)
323 {
324 async_loader_standby = EINA_TRUE;
325 eina_condition_wait(&async_loader_cond);
326
327 make_current(engine_data, engine_data);
328
329 async_engine_data = NULL;
330 async_gl_make_current = NULL;
331 }
332
333 eina_lock_release(&async_loader_lock);
334}
335
336// Let the async preloader run !
337void
338evas_gl_preload_render_unlock(evas_gl_make_current_cb make_current, void *engine_data)
339{
340 if (!async_loader_init) return ;
341 if (!make_current) return ;
342
343 eina_lock_take(&async_loader_lock);
344 if (!async_loader_running && (async_loader_tex || async_current))
345 {
346 make_current(engine_data, NULL);
347
348 async_gl_make_current = make_current;
349 async_engine_data = engine_data;
350
351 async_loader_standby = EINA_FALSE;
352 eina_condition_signal(&async_loader_cond);
353 }
354 eina_lock_release(&async_loader_lock);
355}
356
357// add a way to destroy surface and temporarily stop the rendering of the image
358void
359evas_gl_preload_render_relax(evas_gl_make_current_cb make_current, void *engine_data)
360{
361 if (engine_data != async_engine_data) return ;
362
363 evas_gl_preload_render_lock(make_current, engine_data);
364}
365
366static Eina_Bool
367_evas_gl_preload_target_die(void *data, Eo *obj,
368 const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
369{
370 Evas_GL_Texture *tex = data;
371
372 evas_gl_preload_target_unregister(tex, obj);
373
374 return EO_CALLBACK_CONTINUE;
375}
376
377void
378evas_gl_preload_target_register(Evas_GL_Texture *tex, Eo *target)
379{
380 eo_do(target,
381 eo_event_callback_add(EO_EV_DEL, _evas_gl_preload_target_die, tex));
382 tex->targets = eina_list_append(tex->targets, target);
383 tex->references++;
384}
385
386void
387evas_gl_preload_target_unregister(Evas_GL_Texture *tex, Eo *target)
388{
389 Eina_List *l;
390 const Eo *o;
391
392 eo_do(target,
393 eo_event_callback_del(EO_EV_DEL, _evas_gl_preload_target_die, tex));
394
395 EINA_LIST_FOREACH(tex->targets, l, o)
396 if (o == target)
397 {
398 void *data = async_engine_data;
399 evas_gl_make_current_cb cb = async_gl_make_current;
400 Eina_Bool running = async_loader_running;
401
402 if (running) evas_gl_preload_render_lock(cb, data);
403 tex->targets = eina_list_remove_list(tex->targets, l);
404 evas_gl_common_texture_free(tex, EINA_FALSE);
405 if (running) evas_gl_preload_render_unlock(cb, data);
406
407 break;
408 }
409}
410
411int
412evas_gl_preload_init(void)
413{
414 if (async_loader_init++) return async_loader_init;
415
416 eina_lock_new(&async_loader_lock);
417 eina_condition_new(&async_loader_cond, &async_loader_lock);
418
419 if (!eina_thread_create(&async_loader_thread, EINA_THREAD_BACKGROUND, 0, _evas_gl_preload_tile_async, NULL))
420 {
421 // FIXME: handle error case
422 }
423
424 return async_loader_init;
425}
426
427int
428evas_gl_preload_shutdown(void)
429{
430 if (--async_loader_init) return async_loader_init;
431
432 async_loader_exit = EINA_TRUE;
433 eina_condition_signal(&async_loader_cond);
434
435 eina_thread_join(async_loader_thread);
436
437 eina_condition_free(&async_loader_cond);
438 eina_lock_free(&async_loader_lock);
439
440 return async_loader_init;
441}
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 0c07ffa383..426549cc74 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)
194 free(tex); 194 free(tex);
195} 195}
196 196
197static void
198_tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix)
199{
200 glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
201 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
202}
203
204static Evas_GL_Texture_Pool * 197static Evas_GL_Texture_Pool *
205_pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format) 198_pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format)
206{ 199{
@@ -711,7 +704,7 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
711 pt->h = 0; 704 pt->h = 0;
712} 705}
713 706
714static void 707void
715pt_unref(Evas_GL_Texture_Pool *pt) 708pt_unref(Evas_GL_Texture_Pool *pt)
716{ 709{
717 if (!pt) return; 710 if (!pt) return;
@@ -814,7 +807,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
814{ 807{
815 GLuint fmt; 808 GLuint fmt;
816 809
817 if (!im->image.data) return; 810 if (!im->cache_entry.flags.loaded) return;
818 811
819 if (tex->alpha != im->cache_entry.flags.alpha) 812 if (tex->alpha != im->cache_entry.flags.alpha)
820 { 813 {
@@ -830,8 +823,101 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
830 *matching_format[lformat].intformat, 823 *matching_format[lformat].intformat,
831 *matching_format[lformat].format); 824 *matching_format[lformat].format);
832 } 825 }
826 // If image was preloaded then we need a ptt
833 if (!tex->pt) return; 827 if (!tex->pt) return;
834 828
829 // if preloaded, then async push it in after uploading a miniature of it
830 if (im->cache_entry.flags.preload_done && tex->w > 2 * EVAS_GL_TILE_SIZE && tex->h > 2 * EVAS_GL_TILE_SIZE)
831 {
832 Evas_GL_Texture_Async_Preload *async;
833 int *in;
834 int out[EVAS_GL_TILE_SIZE * EVAS_GL_TILE_SIZE];
835 float xstep, ystep;
836 float x, y;
837 int i, j;
838 int lformat;
839 int u, v;
840
841 if (tex->ptt) return ;
842
843 xstep = (float)tex->w / (EVAS_GL_TILE_SIZE - 2);
844 ystep = (float)tex->h / (EVAS_GL_TILE_SIZE - 1);
845 in = (int*) im->image.data;
846
847 for (y = 0, j = 0; j < EVAS_GL_TILE_SIZE - 1; y += ystep, j++)
848 {
849 out[j * EVAS_GL_TILE_SIZE] = in[(int)y * im->cache_entry.w];
850 for (x = 0, i = 1; i < EVAS_GL_TILE_SIZE - 1; x += xstep, i++)
851 out[j * EVAS_GL_TILE_SIZE + i] = in[(int)y * im->cache_entry.w + (int)x];
852 out[j * EVAS_GL_TILE_SIZE + i] = in[(int)y * im->cache_entry.w + (int)(x - xstep)];
853 }
854
855 memcpy(&out[j * EVAS_GL_TILE_SIZE], &out[(j - 1) * EVAS_GL_TILE_SIZE], EVAS_GL_TILE_SIZE * sizeof (int));
856
857 // out is a miniature of the texture, upload that now and schedule the data for later.
858
859 // Creating the mini picture texture
860 lformat = _evas_gl_texture_search_format(tex->alpha, tex->gc->shared->info.bgra);
861 tex->ptt = _pool_tex_find(tex->gc, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE,
862 *matching_format[lformat].intformat,
863 *matching_format[lformat].format,
864 &u, &v, &tex->aptt,
865 tex->gc->shared->info.tune.atlas.max_alloc_size);
866 if (!tex->ptt)
867 goto upload;
868 tex->aptt->tex = tex;
869
870 tex->tx = u + 1;
871 tex->ty = v;
872 tex->ptt->references++;
873
874 // Bind and upload ! Vooom !
875 fmt = tex->ptt->format;
876 glBindTexture(GL_TEXTURE_2D, tex->ptt->texture);
877 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
878 if (tex->gc->shared->info.unpack_row_length)
879 {
880 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
881 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
882 }
883 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
884 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
885
886 _tex_sub_2d(u, tex->ty, EVAS_GL_TILE_SIZE, EVAS_GL_TILE_SIZE, fmt, tex->ptt->dataformat, out);
887
888 // Switch back to current texture
889 if (tex->ptt->texture != tex->gc->pipe[0].shader.cur_tex)
890 {
891 glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
892 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
893 }
894
895 // Now prepare uploading the main texture before returning;
896 async = malloc(sizeof (Evas_GL_Texture_Async_Preload));
897 if (!async)
898 {
899 goto upload;
900 }
901
902 async->tex = tex;
903 async->tex->references++;
904 async->im = im;
905 evas_cache_image_ref(&async->im->cache_entry);
906 async->unpack_row_length = tex->gc->shared->info.unpack_row_length;
907
908 if (evas_gl_preload_push(async))
909 return ;
910
911 // Failed to start asynchronous upload, likely due to preload not being supported by the backend
912 async->tex->references--;
913 evas_cache_image_drop(&async->im->cache_entry);
914 free(async);
915
916 upload:
917 pt_unref(tex->ptt);
918 tex->ptt = NULL;
919 }
920
835 fmt = tex->pt->format; 921 fmt = tex->pt->format;
836 glBindTexture(GL_TEXTURE_2D, tex->pt->texture); 922 glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
837 GLERR(__FUNCTION__, __FILE__, __LINE__, ""); 923 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -939,6 +1025,13 @@ void
939evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED) 1025evas_gl_common_texture_free(Evas_GL_Texture *tex, Eina_Bool force EINA_UNUSED)
940{ 1026{
941 if (!tex) return; 1027 if (!tex) return;
1028 if (force)
1029 {
1030 evas_gl_preload_pop(tex);
1031
1032 while (tex->targets)
1033 evas_gl_preload_target_unregister(tex, eina_list_data_get(tex->targets));
1034 }
942 tex->references--; 1035 tex->references--;
943 if (tex->references != 0) return; 1036 if (tex->references != 0) return;
944 if (tex->fglyph) 1037 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 7f408fdd91..9441d6dccd 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) ();
73typedef unsigned int (*glsym_func_uint) (); 73typedef unsigned int (*glsym_func_uint) ();
74typedef const char *(*glsym_func_const_char_ptr) (); 74typedef const char *(*glsym_func_const_char_ptr) ();
75 75
76static Eina_Bool eng_preload_make_current(void *data, void *doit);
77
76#ifdef GL_GLES 78#ifdef GL_GLES
77 79
78#ifndef EGL_NATIVE_PIXMAP_KHR 80#ifndef EGL_NATIVE_PIXMAP_KHR
@@ -702,10 +704,6 @@ gl_extn_veto(Render_Engine *re)
702 { 704 {
703 extn_have_buffer_age = 0; 705 extn_have_buffer_age = 0;
704 } 706 }
705 if (!strstr(str, "swap_buffers_with_damage"))
706 {
707 glsym_eglSwapBuffersWithDamage = NULL;
708 }
709 } 707 }
710 else 708 else
711 { 709 {
@@ -808,6 +806,7 @@ static void
808_re_winfree(Render_Engine *re) 806_re_winfree(Render_Engine *re)
809{ 807{
810 if (!re->win->surf) return; 808 if (!re->win->surf) return;
809 evas_gl_preload_render_relax(eng_preload_make_current, re);
811 eng_window_unsurf(re->win); 810 eng_window_unsurf(re->win);
812} 811}
813 812
@@ -877,6 +876,7 @@ eng_setup(Evas *eo_e, void *in)
877 evas_common_font_init(); 876 evas_common_font_init();
878 evas_common_draw_init(); 877 evas_common_draw_init();
879 evas_common_tilebuf_init(); 878 evas_common_tilebuf_init();
879 evas_gl_preload_init();
880 gl_extn_veto(re); 880 gl_extn_veto(re);
881// evgl_engine_init(re, &evgl_funcs); 881// evgl_engine_init(re, &evgl_funcs);
882 initted = 1; 882 initted = 1;
@@ -1033,6 +1033,8 @@ eng_output_free(void *data)
1033 1033
1034 if (re) 1034 if (re)
1035 { 1035 {
1036 evas_gl_preload_render_relax(eng_preload_make_current, re);
1037
1036#if 0 1038#if 0
1037#ifdef GL_GLES 1039#ifdef GL_GLES
1038 // Destroy the resource surface 1040 // Destroy the resource surface
@@ -1070,6 +1072,7 @@ eng_output_free(void *data)
1070 } 1072 }
1071 if ((initted == 1) && (gl_wins == 0)) 1073 if ((initted == 1) && (gl_wins == 0))
1072 { 1074 {
1075 evas_gl_preload_shutdown();
1073 evas_common_image_shutdown(); 1076 evas_common_image_shutdown();
1074 evas_common_font_shutdown(); 1077 evas_common_font_shutdown();
1075 initted = 0; 1078 initted = 0;
@@ -1213,6 +1216,42 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3)
1213/* vsync games - not for now though */ 1216/* vsync games - not for now though */
1214#define VSYNC_TO_SCREEN 1 1217#define VSYNC_TO_SCREEN 1
1215 1218
1219static Eina_Bool
1220eng_preload_make_current(void *data, void *doit)
1221{
1222 Render_Engine *re = data;
1223
1224 if (doit)
1225 {
1226#ifdef GL_GLES
1227 if (!eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0]))
1228 return EINA_FALSE;
1229#else
1230 if (!glXMakeCurrent(re->info->info.display, re->win->win, re->win->context))
1231 {
1232 ERR("glXMakeCurrent(%p, 0x%x, %p) failed", re->info->info.display, (unsigned int)re->win->win, (void *)re->win->context);
1233 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1234 return EINA_FALSE;
1235 }
1236#endif
1237 }
1238 else
1239 {
1240#ifdef GL_GLES
1241 if (!eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
1242 return EINA_FALSE;
1243#else
1244 if (!glXMakeCurrent(re->info->info.display, None, NULL))
1245 {
1246 ERR("glXMakeCurrent(%p, None, NULL) failed", re->info->info.display);
1247 GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1248 return EINA_FALSE;
1249 }
1250#endif
1251 }
1252 return EINA_TRUE;
1253}
1254
1216static void * 1255static void *
1217eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) 1256eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
1218{ 1257{
@@ -1353,6 +1392,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
1353 } 1392 }
1354 if (first_rect) 1393 if (first_rect)
1355 { 1394 {
1395 evas_gl_preload_render_lock(eng_preload_make_current, re);
1356#ifdef GL_GLES 1396#ifdef GL_GLES
1357 // dont need to for egl - eng_window_use() can check for other ctxt's 1397 // dont need to for egl - eng_window_use() can check for other ctxt's
1358#else 1398#else
@@ -1433,11 +1473,11 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
1433{ 1473{
1434 Render_Engine *re; 1474 Render_Engine *re;
1435 1475
1436 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; 1476 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
1437 1477
1438 re = (Render_Engine *)data; 1478 re = (Render_Engine *)data;
1439 if (!_re_wincheck(re)) return; 1479 if (!_re_wincheck(re)) goto end;
1440 if (!re->win->draw.drew) return; 1480 if (!re->win->draw.drew) goto end;
1441 1481
1442 re->win->draw.drew = 0; 1482 re->win->draw.drew = 0;
1443 eng_window_use(re->win); 1483 eng_window_use(re->win);
@@ -1454,7 +1494,7 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
1454 { 1494 {
1455 re->info->callback.pre_swap(re->info->callback.data, re->evas); 1495 re->info->callback.pre_swap(re->info->callback.data, re->evas);
1456 } 1496 }
1457 if ((glsym_eglSwapBuffersWithDamage) && (re->mode != MODE_FULL)) 1497 if ((glsym_eglSwapBuffersRegion) && (re->mode != MODE_FULL))
1458 { 1498 {
1459 EGLint num = 0, *rects = NULL, i = 0; 1499 EGLint num = 0, *rects = NULL, i = 0;
1460 Tilebuf_Rect *r; 1500 Tilebuf_Rect *r;
@@ -1505,9 +1545,9 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
1505 } 1545 }
1506 i += 4; 1546 i += 4;
1507 } 1547 }
1508 glsym_eglSwapBuffersWithDamage(re->win->egl_disp, 1548 glsym_eglSwapBuffersRegion(re->win->egl_disp,
1509 re->win->egl_surface[0], 1549 re->win->egl_surface[0],
1510 rects, num); 1550 num, rects);
1511 } 1551 }
1512 } 1552 }
1513 else 1553 else
@@ -1574,6 +1614,9 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
1574 evas_common_tilebuf_free_render_rects(re->rects); 1614 evas_common_tilebuf_free_render_rects(re->rects);
1575 re->rects = NULL; 1615 re->rects = NULL;
1576 } 1616 }
1617
1618 end:
1619 evas_gl_preload_render_unlock(eng_preload_make_current, re);
1577} 1620}
1578 1621
1579static void 1622static void
@@ -2771,9 +2814,10 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
2771} 2814}
2772 2815
2773static void 2816static void
2774eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *target) 2817eng_image_data_preload_request(void *data, void *image, const Eo *target)
2775{ 2818{
2776 Evas_GL_Image *gim = image; 2819 Evas_GL_Image *gim = image;
2820 Render_Engine *re = data;
2777 RGBA_Image *im; 2821 RGBA_Image *im;
2778 2822
2779 if (!gim) return; 2823 if (!gim) return;
@@ -2781,6 +2825,9 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *ta
2781 im = (RGBA_Image *)gim->im; 2825 im = (RGBA_Image *)gim->im;
2782 if (!im) return; 2826 if (!im) return;
2783 evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); 2827 evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
2828 if (!gim->tex)
2829 gim->tex = evas_gl_common_texture_new(re->win->gl_context, gim->im);
2830 evas_gl_preload_target_register(gim->tex, (Eo*) target);
2784} 2831}
2785 2832
2786static void 2833static void
@@ -2794,6 +2841,7 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *tar
2794 im = (RGBA_Image *)gim->im; 2841 im = (RGBA_Image *)gim->im;
2795 if (!im) return; 2842 if (!im) return;
2796 evas_cache_image_preload_cancel(&im->cache_entry, target); 2843 evas_cache_image_preload_cancel(&im->cache_entry, target);
2844 evas_gl_preload_target_unregister(gim->tex, (Eo*) target);
2797} 2845}
2798 2846
2799static Eina_Bool 2847static 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 d0de1df8ae..91015dcb3f 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)
454 free(gw); 454 free(gw);
455} 455}
456 456
457static Eina_Bool
458eng_window_make_current(void *data, void *doit)
459{
460 Evas_GL_X11_Window *gw = data;
461
462#ifdef GL_GLES
463 if (doit)
464 {
465 if (!eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0], gw->egl_context[0]))
466 return EINA_FALSE;
467 }
468 else
469 {
470 if (!eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
471 return EINA_FALSE;
472 }
473#else
474 if (doit)
475 {
476 if (gw->glxwin)
477 {
478 if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin, gw->context))
479 {
480 ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->glxwin, (void *)gw->context);
481 return EINA_FALSE;
482 }
483 }
484 else
485 {
486 if (!glXMakeCurrent(gw->disp, gw->win, gw->context))
487 {
488 ERR("glXMakeCurrent(%p, 0x%x, %p) failed", gw->disp, (unsigned int)gw->win, (void *)gw->context);
489 return EINA_FALSE;
490 }
491 }
492 }
493 else
494 {
495 if (!glXMakeCurrent(gw->disp, None, NULL))
496 return EINA_FALSE;
497 }
498#endif
499 return EINA_TRUE;
500}
501
457void 502void
458eng_window_use(Evas_GL_X11_Window *gw) 503eng_window_use(Evas_GL_X11_Window *gw)
459{ 504{
460 Eina_Bool force_use = EINA_FALSE; 505 Eina_Bool force_use = EINA_FALSE;
461 506
507 evas_gl_preload_render_lock(eng_window_make_current, gw);
462#ifdef GL_GLES 508#ifdef GL_GLES
463 if (_evas_gl_x11_window) 509 if (_evas_gl_x11_window)
464 { 510 {