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

Reply via email to