aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS1
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c27
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c105
4 files changed, 110 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index a9e7833e3..47f89f6bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -380,3 +380,8 @@
2013-01-28 Daniel Willmann <d.willmann@samsung.com>
* Use ecore_audio in edje-multisense
+
+2013-01-28 Rafael Antognolli <antognolli@gmail.com>
+
+ * Ecore_Evas wayland-egl only renders now if last frame has
+ been presented.
diff --git a/NEWS b/NEWS
index ee96a2a36..378155683 100644
--- a/NEWS
+++ b/NEWS
@@ -86,6 +86,7 @@ Improvements:
* edje entry: remove ecore_imf_context_reset, cursor update in mouse move event because it's useless.
* edje entry: move ecore_imf_context_cursor_position_set from mouse down event to mouse up event.
* Use ecore_audio in edje-multisense
+ * Ecore_Evas wayland-egl only renders now if last frame has been presented.
Fixes:
* Fix PPC (big endian) image codec bug.
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index c0cc37dd3..72ec92b5f 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -723,33 +723,6 @@ _ecore_evas_wl_common_pre_render(Ecore_Evas *ee)
return rend;
}
-int
-_ecore_evas_wl_common_render_updates(Ecore_Evas *ee)
-{
- int rend = 0;
- Eina_List *updates = NULL;
- Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- if ((updates = evas_render_updates(ee->evas)))
- {
- Eina_List *l = NULL;
- Eina_Rectangle *r;
-
- EINA_LIST_FOREACH(updates, l, r)
- ecore_wl_window_damage(wdata->win,
- r->x, r->y, r->w, r->h);
-
- ecore_wl_flush();
-
- evas_render_updates_free(updates);
- rend = 1;
- }
-
- return rend;
-}
-
void
_ecore_evas_wl_common_post_render(Ecore_Evas *ee)
{
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
index b79766018..df7eeb0c3 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
@@ -10,6 +10,7 @@
/* local function prototypes */
+static int _ecore_evas_wl_render(Ecore_Evas *ee);
static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
static void _ecore_evas_wl_show(Ecore_Evas *ee);
static void _ecore_evas_wl_hide(Ecore_Evas *ee);
@@ -72,7 +73,7 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
NULL, // modal set
NULL, // demand attention set
NULL, // focus skip set
- _ecore_evas_wl_common_render,
+ _ecore_evas_wl_render,
_ecore_evas_wl_common_screen_geometry_get,
_ecore_evas_wl_common_screen_dpi_get
};
@@ -228,6 +229,108 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
return NULL;
}
+static void
+_ecore_evas_wl_frame_complete (void *data, struct wl_callback *callback, uint32_t time EINA_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 EINA_UNUSED)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ wdata->win->frame_callback = NULL;
+ wdata->win->frame_pending = EINA_FALSE;
+ wl_callback_destroy(callback);
+
+ wdata->win->frame_callback =
+ wl_surface_frame(wdata->win->surface);
+
+ wl_callback_add_listener(wdata->win->frame_callback,
+ &frame_listener, ee);
+}
+
+int
+_ecore_evas_wl_render_updates(Ecore_Evas *ee)
+{
+ int rend = 0;
+ Eina_List *updates = NULL;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ /* eglSwapBuffers is ultimately called by evas_render_updates() if
+ * there is some update to make. So we must pre-emptively create a
+ * frame callback handler. We make sure we always have one of these in
+ * available to track if the event is presented.
+ *
+ * This frame callback will be fired when the frame has been presented
+ * and we can safely call eglSwapBuffers without it blocking. Whether
+ * to render or not is handled by the frame_pending boolean which is
+ * reset on the frame callback event.
+ */
+ if (!wdata->win->frame_pending)
+ {
+ /* FIXME - ideally have an evas_changed_get to return the value
+ * of evas->changed to avoid creating this callback and
+ * destroying it again
+ */
+
+ if (!wdata->win->frame_callback)
+ {
+ wdata->win->frame_callback =
+ wl_surface_frame(wdata->win->surface);
+
+ wl_callback_add_listener(wdata->win->frame_callback,
+ &frame_listener, ee);
+ }
+
+ if ((updates = evas_render_updates(ee->evas)))
+ {
+ Eina_List *l = NULL;
+ Eina_Rectangle *r;
+
+ EINA_LIST_FOREACH(updates, l, r)
+ ecore_wl_window_damage(wdata->win,
+ r->x, r->y, r->w, r->h);
+
+ ecore_wl_flush();
+
+ evas_render_updates_free(updates);
+
+ wdata->win->frame_pending = EINA_TRUE;
+
+ rend = 1;
+ }
+ }
+
+ return rend;
+}
+
+static int
+_ecore_evas_wl_render(Ecore_Evas *ee)
+{
+ int rend = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!ee) return 0;
+ if (!ee->visible)
+ {
+ evas_norender(ee->evas);
+ return 0;
+ }
+
+ rend = _ecore_evas_wl_common_pre_render(ee);
+ rend |= _ecore_evas_wl_render_updates(ee);
+ _ecore_evas_wl_common_post_render(ee);
+
+ return rend;
+}
+
static void
_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
{