Re: [E-devel] [EGIT] [legacy/ecore] ecore-1.7 01/01: Backport 1210067fbeb21bdce34ec710e66749de981a1617.

2013-08-06 Thread Rafael Antognolli
On Sat, Aug 3, 2013 at 12:50 AM, Carsten Haitzler ras...@rasterman.com wrote:
 On Fri, 02 Aug 2013 13:52:46 -0700 Rafael Antognolli - Enlightenment Git
 no-re...@enlightenment.org said:

 let me get this right. if we have rendered and sent a frame off to the
 compositor, we will drop/skip all renders UNTIL the compositor sends back a
 i'm done - frame presented now. right?

Yeah, otherwise calling eglSwapBuffers will block until the compositor
is done with that frame.

It was discussed here: http://trac.enlightenment.org/e/ticket/1280

 antognolli pushed a commit to branch ecore-1.7.

 commit 6a53facca7028a4d8404c83b8ba5630393c5a615
 Author: Rafael Antognolli rafael.antogno...@intel.com
 Date:   Sat Aug 3 16:52:00 2013 -0300

 Backport 1210067fbeb21bdce34ec710e66749de981a1617.

 ecore_evas/wayland_egl: Only render if last frame has been presented.

 This avoids blocking in eglSwapBuffers and has the side effect of
 avoiding doing unnecessary work - painting where a frame won't be
 presented.

 We do this by using the event that the wayland compositor will send us
 to tell us that the frame has been presented. Due to the fact that
 evas_render_updates() could do no work and not cause a eglSwapBuffers we
 must always have a frame callback listener setup.

 Original patch by: Rob Bradford r...@linux.intel.com

 (I just adjusted the patch to the single efl tree)
 ---
  src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 ++
 +-- 1 file changed, 53 insertions(+), 13 deletions(-)

 diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 504b5e2..36695d5 100644
 --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
 NULL,
 NULL,
 NULL,
 -   _ecore_evas_wl_render,
 +   _ecore_evas_wl_render,
 _ecore_evas_wl_screen_geometry_get,
 _ecore_evas_wl_screen_dpi_get
  };
 @@ -828,6 +828,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int
 transparent) }
  }

 +static void
 +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
 uint32_t time __UNUSED__); +
 +static const struct wl_callback_listener frame_listener = {
 +   _ecore_evas_wl_frame_complete,
 +};
 +
 +static void
 +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
 uint32_t time __UNUSED__) +{
 +   Ecore_Evas *ee = data;
 +   Ecore_Wl_Window *win = ee-engine.wl.win;
 +
 +   win-frame_callback = NULL;
 +   win-frame_pending = EINA_FALSE;
 +   wl_callback_destroy(callback);
 +
 +   win-frame_callback =
 +  wl_surface_frame(win-surface);
 +
 +   wl_callback_add_listener(win-frame_callback,
 +frame_listener, ee);
 +}
 +
  static int
  _ecore_evas_wl_render(Ecore_Evas *ee)
  {
 @@ -840,6 +864,7 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
   {
  Eina_List *ll = NULL, *updates = NULL;
  Ecore_Evas *ee2 = NULL;
 +Ecore_Wl_Window *win = NULL;

  if (ee-func.fn_pre_render) ee-func.fn_pre_render(ee);

 @@ -851,25 +876,40 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
   if (ee2-func.fn_post_render) ee2-func.fn_post_render(ee2);
}

 -if ((updates = evas_render_updates(ee-evas)))
 +win = ee-engine.wl.win;
 +
 +if (!win-frame_pending)
{
 - Eina_List *l = NULL;
 - Eina_Rectangle *r;
 + if (!win-frame_callback)
 +   {
 +  win-frame_callback = wl_surface_frame(win-surface);
 +  wl_callback_add_listener(win-frame_callback,
 +   frame_listener, ee);
 +   }
 +
 + if ((updates = evas_render_updates(ee-evas)))
 +   {
 +  Eina_List *l = NULL;
 +  Eina_Rectangle *r;
 +
 +  LOGFN(__FILE__, __LINE__, __FUNCTION__);

 - LOGFN(__FILE__, __LINE__, __FUNCTION__);
 +  EINA_LIST_FOREACH(updates, l, r)
 + ecore_wl_window_damage(win,
 +r-x, r-y, r-w, r-h);

 - EINA_LIST_FOREACH(updates, l, r)
 -   ecore_wl_window_damage(ee-engine.wl.win,
 -  r-x, r-y, r-w, r-h);
 +  ecore_wl_flush();

 - ecore_wl_flush();
 +  evas_render_updates_free(updates);
 +  _ecore_evas_idle_timeout_update(ee);
 +  rend = 1;
 +
 +  win-frame_pending = EINA_TRUE;
 +   }

 - evas_render_updates_free(updates);
 - _ecore_evas_idle_timeout_update(ee);
 - rend = 1;
 + if (ee-func.fn_post_render) ee-func.fn_post_render(ee);
}

 -if (ee-func.fn_post_render) ee-func.fn_post_render(ee);
   }
  

Re: [E-devel] [EGIT] [legacy/ecore] ecore-1.7 01/01: Backport 1210067fbeb21bdce34ec710e66749de981a1617.

2013-08-06 Thread The Rasterman
On Tue, 6 Aug 2013 11:47:37 -0300 Rafael Antognolli antogno...@gmail.com said:

 On Sat, Aug 3, 2013 at 12:50 AM, Carsten Haitzler ras...@rasterman.com
 wrote:
  On Fri, 02 Aug 2013 13:52:46 -0700 Rafael Antognolli - Enlightenment Git
  no-re...@enlightenment.org said:
 
  let me get this right. if we have rendered and sent a frame off to the
  compositor, we will drop/skip all renders UNTIL the compositor sends back a
  i'm done - frame presented now. right?
 
 Yeah, otherwise calling eglSwapBuffers will block until the compositor
 is done with that frame.
 
 It was discussed here: http://trac.enlightenment.org/e/ticket/1280

this is bad when using manual rendering. a manual render may be skipped. if you
do ecore_evas_manual_render() then this has to block until compositor ok's it.

this is also why i think with wl we should take charge of buffer swapping and
actually explicitly do triple buffering so the client can render a frame ahead
without skipping (and sleeping) or blocking. important for performance
especially if your gpu is weak, or you are pushing the limits and now inserting
sleep times dropping performance even more.

if you have plenty of rendering grunt to spare, it makes no real big
difference... but not if you are pushing the boundaries.

also manual control of buffers means we can literally free all buffers (except
current displayed front-buffer) when evas goes idle for long enough (we have an
idle flush engine call already).


  antognolli pushed a commit to branch ecore-1.7.
 
  commit 6a53facca7028a4d8404c83b8ba5630393c5a615
  Author: Rafael Antognolli rafael.antogno...@intel.com
  Date:   Sat Aug 3 16:52:00 2013 -0300
 
  Backport 1210067fbeb21bdce34ec710e66749de981a1617.
 
  ecore_evas/wayland_egl: Only render if last frame has been presented.
 
  This avoids blocking in eglSwapBuffers and has the side effect of
  avoiding doing unnecessary work - painting where a frame won't be
  presented.
 
  We do this by using the event that the wayland compositor will send us
  to tell us that the frame has been presented. Due to the fact that
  evas_render_updates() could do no work and not cause a eglSwapBuffers
  we must always have a frame callback listener setup.
 
  Original patch by: Rob Bradford r...@linux.intel.com
 
  (I just adjusted the patch to the single efl tree)
  ---
   src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 ++
  +-- 1 file changed, 53 insertions(+), 13 deletions(-)
 
  diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 504b5e2..36695d5 100644
  --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
  NULL,
  NULL,
  NULL,
  -   _ecore_evas_wl_render,
  +   _ecore_evas_wl_render,
  _ecore_evas_wl_screen_geometry_get,
  _ecore_evas_wl_screen_dpi_get
   };
  @@ -828,6 +828,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int
  transparent) }
   }
 
  +static void
  +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
  uint32_t time __UNUSED__); +
  +static const struct wl_callback_listener frame_listener = {
  +   _ecore_evas_wl_frame_complete,
  +};
  +
  +static void
  +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
  uint32_t time __UNUSED__) +{
  +   Ecore_Evas *ee = data;
  +   Ecore_Wl_Window *win = ee-engine.wl.win;
  +
  +   win-frame_callback = NULL;
  +   win-frame_pending = EINA_FALSE;
  +   wl_callback_destroy(callback);
  +
  +   win-frame_callback =
  +  wl_surface_frame(win-surface);
  +
  +   wl_callback_add_listener(win-frame_callback,
  +frame_listener, ee);
  +}
  +
   static int
   _ecore_evas_wl_render(Ecore_Evas *ee)
   {
  @@ -840,6 +864,7 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
{
   Eina_List *ll = NULL, *updates = NULL;
   Ecore_Evas *ee2 = NULL;
  +Ecore_Wl_Window *win = NULL;
 
   if (ee-func.fn_pre_render) ee-func.fn_pre_render(ee);
 
  @@ -851,25 +876,40 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
if (ee2-func.fn_post_render) ee2-func.fn_post_render(ee2);
 }
 
  -if ((updates = evas_render_updates(ee-evas)))
  +win = ee-engine.wl.win;
  +
  +if (!win-frame_pending)
 {
  - Eina_List *l = NULL;
  - Eina_Rectangle *r;
  + if (!win-frame_callback)
  +   {
  +  win-frame_callback = wl_surface_frame(win-surface);
  +  wl_callback_add_listener(win-frame_callback,
  +   frame_listener, ee);
  +   }
  +
  + if ((updates = evas_render_updates(ee-evas)))
  +   {
  +  Eina_List *l = NULL;
  +  Eina_Rectangle *r;
  +
  +

Re: [E-devel] [EGIT] [legacy/ecore] ecore-1.7 01/01: Backport 1210067fbeb21bdce34ec710e66749de981a1617.

2013-08-06 Thread Rafael Antognolli
Is it OK if we leave it as it's now for 1.7 branch? I added this
mostly to fix the current issues caused by blocking the mainloop. I
think there are some race conditions triggered by not waiting for the
frame callback, that are making the wayland event queue to starve
waiting for events when we don't wait for the frame callback. One
example is the elementary glview example, I don't know why but it does
not work correctly without this.

Now, for the correct fix on 1.8, see below.

On Tue, Aug 6, 2013 at 9:26 PM, Carsten Haitzler ras...@rasterman.com wrote:
 On Tue, 6 Aug 2013 11:47:37 -0300 Rafael Antognolli antogno...@gmail.com 
 said:

 On Sat, Aug 3, 2013 at 12:50 AM, Carsten Haitzler ras...@rasterman.com
 wrote:
  On Fri, 02 Aug 2013 13:52:46 -0700 Rafael Antognolli - Enlightenment Git
  no-re...@enlightenment.org said:
 
  let me get this right. if we have rendered and sent a frame off to the
  compositor, we will drop/skip all renders UNTIL the compositor sends back a
  i'm done - frame presented now. right?

 Yeah, otherwise calling eglSwapBuffers will block until the compositor
 is done with that frame.

 It was discussed here: http://trac.enlightenment.org/e/ticket/1280

 this is bad when using manual rendering. a manual render may be skipped. if 
 you
 do ecore_evas_manual_render() then this has to block until compositor ok's it.

 this is also why i think with wl we should take charge of buffer swapping and
 actually explicitly do triple buffering so the client can render a frame ahead
 without skipping (and sleeping) or blocking. important for performance
 especially if your gpu is weak, or you are pushing the limits and now 
 inserting
 sleep times dropping performance even more.

I totally agree about the triple buffering and that we should be able
to render as much as we can without blocking because the compositor is
not ready yet. However, what do you mean by we should take charge of
buffer swapping? Aren't we doing this already?

Also, would the triple buffering solution fix the manual render problem too?

 if you have plenty of rendering grunt to spare, it makes no real big
 difference... but not if you are pushing the boundaries.

 also manual control of buffers means we can literally free all buffers (except
 current displayed front-buffer) when evas goes idle for long enough (we have 
 an
 idle flush engine call already).

That would be good, indeed. I'm not sure what we have regarding this,
but I think it can be done.

Devilhorns, any thoughts?


  antognolli pushed a commit to branch ecore-1.7.
 
  commit 6a53facca7028a4d8404c83b8ba5630393c5a615
  Author: Rafael Antognolli rafael.antogno...@intel.com
  Date:   Sat Aug 3 16:52:00 2013 -0300
 
  Backport 1210067fbeb21bdce34ec710e66749de981a1617.
 
  ecore_evas/wayland_egl: Only render if last frame has been presented.
 
  This avoids blocking in eglSwapBuffers and has the side effect of
  avoiding doing unnecessary work - painting where a frame won't be
  presented.
 
  We do this by using the event that the wayland compositor will send us
  to tell us that the frame has been presented. Due to the fact that
  evas_render_updates() could do no work and not cause a eglSwapBuffers
  we must always have a frame callback listener setup.
 
  Original patch by: Rob Bradford r...@linux.intel.com
 
  (I just adjusted the patch to the single efl tree)
  ---
   src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 ++
  +-- 1 file changed, 53 insertions(+), 13 deletions(-)
 
  diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 504b5e2..36695d5 
  100644
  --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
  @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
  NULL,
  NULL,
  NULL,
  -   _ecore_evas_wl_render,
  +   _ecore_evas_wl_render,
  _ecore_evas_wl_screen_geometry_get,
  _ecore_evas_wl_screen_dpi_get
   };
  @@ -828,6 +828,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int
  transparent) }
   }
 
  +static void
  +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
  uint32_t time __UNUSED__); +
  +static const struct wl_callback_listener frame_listener = {
  +   _ecore_evas_wl_frame_complete,
  +};
  +
  +static void
  +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
  uint32_t time __UNUSED__) +{
  +   Ecore_Evas *ee = data;
  +   Ecore_Wl_Window *win = ee-engine.wl.win;
  +
  +   win-frame_callback = NULL;
  +   win-frame_pending = EINA_FALSE;
  +   wl_callback_destroy(callback);
  +
  +   win-frame_callback =
  +  wl_surface_frame(win-surface);
  +
  +   wl_callback_add_listener(win-frame_callback,
  +frame_listener, ee);
  +}
  +
   static int
   _ecore_evas_wl_render(Ecore_Evas *ee)
   {
  @@ -840,6 +864,7 @@ _ecore_evas_wl_render(Ecore_Evas *ee)

Re: [E-devel] [EGIT] [legacy/ecore] ecore-1.7 01/01: Backport 1210067fbeb21bdce34ec710e66749de981a1617.

2013-08-06 Thread The Rasterman
On Tue, 6 Aug 2013 22:31:54 -0300 Rafael Antognolli antogno...@gmail.com said:

 Is it OK if we leave it as it's now for 1.7 branch? I added this
 mostly to fix the current issues caused by blocking the mainloop. I
 think there are some race conditions triggered by not waiting for the
 frame callback, that are making the wayland event queue to starve
 waiting for events when we don't wait for the frame callback. One
 example is the elementary glview example, I don't know why but it does
 not work correctly without this.

well for the manual render.. thats an actual bug now that needs fixing. if an
app does a manual render, it expects it to render. now. not be skipped. with
the code as it is here, the render will skip and your update will never happen.
so this introduces a rendering artifact bug. :)

for performance - that can be a 1.8 thing, but if anything blocking is better
than adding the above bug. :)

 Now, for the correct fix on 1.8, see below.
 
 On Tue, Aug 6, 2013 at 9:26 PM, Carsten Haitzler ras...@rasterman.com wrote:
  On Tue, 6 Aug 2013 11:47:37 -0300 Rafael Antognolli antogno...@gmail.com
  said:
 
  On Sat, Aug 3, 2013 at 12:50 AM, Carsten Haitzler ras...@rasterman.com
  wrote:
   On Fri, 02 Aug 2013 13:52:46 -0700 Rafael Antognolli - Enlightenment Git
   no-re...@enlightenment.org said:
  
   let me get this right. if we have rendered and sent a frame off to the
   compositor, we will drop/skip all renders UNTIL the compositor sends
   back a i'm done - frame presented now. right?
 
  Yeah, otherwise calling eglSwapBuffers will block until the compositor
  is done with that frame.
 
  It was discussed here: http://trac.enlightenment.org/e/ticket/1280
 
  this is bad when using manual rendering. a manual render may be skipped. if
  you do ecore_evas_manual_render() then this has to block until compositor
  ok's it.
 
  this is also why i think with wl we should take charge of buffer swapping
  and actually explicitly do triple buffering so the client can render a
  frame ahead without skipping (and sleeping) or blocking. important for
  performance especially if your gpu is weak, or you are pushing the limits
  and now inserting sleep times dropping performance even more.
 
 I totally agree about the triple buffering and that we should be able
 to render as much as we can without blocking because the compositor is
 not ready yet. However, what do you mean by we should take charge of
 buffer swapping? Aren't we doing this already?
 
 Also, would the triple buffering solution fix the manual render problem too?
 
  if you have plenty of rendering grunt to spare, it makes no real big
  difference... but not if you are pushing the boundaries.
 
  also manual control of buffers means we can literally free all buffers
  (except current displayed front-buffer) when evas goes idle for long enough
  (we have an idle flush engine call already).
 
 That would be good, indeed. I'm not sure what we have regarding this,
 but I think it can be done.
 
 Devilhorns, any thoughts?
 
 
   antognolli pushed a commit to branch ecore-1.7.
  
   commit 6a53facca7028a4d8404c83b8ba5630393c5a615
   Author: Rafael Antognolli rafael.antogno...@intel.com
   Date:   Sat Aug 3 16:52:00 2013 -0300
  
   Backport 1210067fbeb21bdce34ec710e66749de981a1617.
  
   ecore_evas/wayland_egl: Only render if last frame has been
   presented.
  
   This avoids blocking in eglSwapBuffers and has the side effect of
   avoiding doing unnecessary work - painting where a frame won't be
   presented.
  
   We do this by using the event that the wayland compositor will send
   us to tell us that the frame has been presented. Due to the fact that
   evas_render_updates() could do no work and not cause a
   eglSwapBuffers we must always have a frame callback listener setup.
  
   Original patch by: Rob Bradford r...@linux.intel.com
  
   (I just adjusted the patch to the single efl tree)
   ---
src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 ++
   +-- 1 file changed, 53 insertions(+), 13 deletions(-)
  
   diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
   b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 504b5e2..36695d5
   100644
   --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
   +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
   @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func
   = NULL,
   NULL,
   NULL,
   -   _ecore_evas_wl_render,
   +   _ecore_evas_wl_render,
   _ecore_evas_wl_screen_geometry_get,
   _ecore_evas_wl_screen_dpi_get
};
   @@ -828,6 +828,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int
   transparent) }
}
  
   +static void
   +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
   uint32_t time __UNUSED__); +
   +static const struct wl_callback_listener frame_listener = {
   +   _ecore_evas_wl_frame_complete,
   +};
   +
   +static void
   

Re: [E-devel] [EGIT] [legacy/ecore] ecore-1.7 01/01: Backport 1210067fbeb21bdce34ec710e66749de981a1617.

2013-08-02 Thread The Rasterman
On Fri, 02 Aug 2013 13:52:46 -0700 Rafael Antognolli - Enlightenment Git
no-re...@enlightenment.org said:

let me get this right. if we have rendered and sent a frame off to the
compositor, we will drop/skip all renders UNTIL the compositor sends back a
i'm done - frame presented now. right?

 antognolli pushed a commit to branch ecore-1.7.
 
 commit 6a53facca7028a4d8404c83b8ba5630393c5a615
 Author: Rafael Antognolli rafael.antogno...@intel.com
 Date:   Sat Aug 3 16:52:00 2013 -0300
 
 Backport 1210067fbeb21bdce34ec710e66749de981a1617.
 
 ecore_evas/wayland_egl: Only render if last frame has been presented.
 
 This avoids blocking in eglSwapBuffers and has the side effect of
 avoiding doing unnecessary work - painting where a frame won't be
 presented.
 
 We do this by using the event that the wayland compositor will send us
 to tell us that the frame has been presented. Due to the fact that
 evas_render_updates() could do no work and not cause a eglSwapBuffers we
 must always have a frame callback listener setup.
 
 Original patch by: Rob Bradford r...@linux.intel.com
 
 (I just adjusted the patch to the single efl tree)
 ---
  src/lib/ecore_evas/ecore_evas_wayland_egl.c | 66 ++
 +-- 1 file changed, 53 insertions(+), 13 deletions(-)
 
 diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 b/src/lib/ecore_evas/ecore_evas_wayland_egl.c index 504b5e2..36695d5 100644
 --- a/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
 @@ -176,7 +176,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
 NULL,
 NULL,
 NULL,
 -   _ecore_evas_wl_render, 
 +   _ecore_evas_wl_render,
 _ecore_evas_wl_screen_geometry_get,
 _ecore_evas_wl_screen_dpi_get
  };
 @@ -828,6 +828,30 @@ _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int
 transparent) }
  }
  
 +static void
 +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
 uint32_t time __UNUSED__); +
 +static const struct wl_callback_listener frame_listener = {
 +   _ecore_evas_wl_frame_complete,
 +};
 +
 +static void
 +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback,
 uint32_t time __UNUSED__) +{
 +   Ecore_Evas *ee = data;
 +   Ecore_Wl_Window *win = ee-engine.wl.win;
 +
 +   win-frame_callback = NULL;
 +   win-frame_pending = EINA_FALSE;
 +   wl_callback_destroy(callback);
 +
 +   win-frame_callback =
 +  wl_surface_frame(win-surface);
 +
 +   wl_callback_add_listener(win-frame_callback,
 +frame_listener, ee);
 +}
 +
  static int 
  _ecore_evas_wl_render(Ecore_Evas *ee)
  {
 @@ -840,6 +864,7 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
   {
  Eina_List *ll = NULL, *updates = NULL;
  Ecore_Evas *ee2 = NULL;
 +Ecore_Wl_Window *win = NULL;
  
  if (ee-func.fn_pre_render) ee-func.fn_pre_render(ee);
  
 @@ -851,25 +876,40 @@ _ecore_evas_wl_render(Ecore_Evas *ee)
   if (ee2-func.fn_post_render) ee2-func.fn_post_render(ee2);
}
  
 -if ((updates = evas_render_updates(ee-evas))) 
 +win = ee-engine.wl.win;
 +
 +if (!win-frame_pending)
{
 - Eina_List *l = NULL;
 - Eina_Rectangle *r;
 + if (!win-frame_callback)
 +   {
 +  win-frame_callback = wl_surface_frame(win-surface);
 +  wl_callback_add_listener(win-frame_callback,
 +   frame_listener, ee);
 +   }
 +
 + if ((updates = evas_render_updates(ee-evas)))
 +   {
 +  Eina_List *l = NULL;
 +  Eina_Rectangle *r;
 +
 +  LOGFN(__FILE__, __LINE__, __FUNCTION__);
  
 - LOGFN(__FILE__, __LINE__, __FUNCTION__);
 +  EINA_LIST_FOREACH(updates, l, r)
 + ecore_wl_window_damage(win,
 +r-x, r-y, r-w, r-h);
  
 - EINA_LIST_FOREACH(updates, l, r) 
 -   ecore_wl_window_damage(ee-engine.wl.win, 
 -  r-x, r-y, r-w, r-h);
 +  ecore_wl_flush();
  
 - ecore_wl_flush();
 +  evas_render_updates_free(updates);
 +  _ecore_evas_idle_timeout_update(ee);
 +  rend = 1;
 +
 +  win-frame_pending = EINA_TRUE;
 +   }
  
 - evas_render_updates_free(updates);
 - _ecore_evas_idle_timeout_update(ee);
 - rend = 1;
 + if (ee-func.fn_post_render) ee-func.fn_post_render(ee);
}
  
 -if (ee-func.fn_post_render) ee-func.fn_post_render(ee);
   }
 return rend;
  }
 
 -- 
 
 --
 Get your SQL database under version control now!
 Version control is standard for