summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2014-11-10 11:55:18 -0500
committerChris Michael <cp.michael@samsung.com>2014-11-10 11:55:18 -0500
commit4dfdfe2428d04c3838f2985e744b93ee620e05e8 (patch)
treefa1eb0993415b525ea1d77851d37284f56ec622e
parent2e0168359ef92035dabcffcef004f7cd8adfe180 (diff)
downloadenlightenment-4dfdfe2428d04c3838f2985e744b93ee620e05e8.tar.gz
Implement caching of pixmap resources for wayland clients.
Move sending of frame completion to the image_draw function. Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/bin/e_pixmap.c113
1 files changed, 94 insertions, 19 deletions
diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c
index 1f0c5ca26f..9382b58852 100644
--- a/src/bin/e_pixmap.c
+++ b/src/bin/e_pixmap.c
@@ -33,6 +33,7 @@ struct _E_Pixmap
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
struct wl_resource *resource;
+ Eina_List *resource_cache;
#endif
Eina_Bool usable : 1;
@@ -40,6 +41,14 @@ struct _E_Pixmap
Eina_Bool image_argb : 1;
};
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+static void
+_e_pixmap_resource_free(struct wl_resource *pixres)
+{
+ if (pixres) wl_buffer_send_release(pixres);
+}
+#endif
+
static void
_e_pixmap_clear(E_Pixmap *cp, Eina_Bool cache)
{
@@ -60,7 +69,12 @@ _e_pixmap_clear(E_Pixmap *cp, Eina_Bool cache)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- e_pixmap_image_clear(cp, cache);
+ if (cp->resource)
+ {
+ _e_pixmap_resource_free(cp->resource);
+ cp->resource = NULL;
+ e_pixmap_image_clear(cp, cache);
+ }
#endif
break;
default: break;
@@ -97,7 +111,15 @@ _e_pixmap_free(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- /* NB: No-Op. Nothing to free. image data no longer memcpy'd */
+ if (!cp->resource_cache) break;
+ if (!cp->client)
+ {
+ void *i;
+
+ EINA_LIST_FREE(cp->resource_cache, i)
+ _e_pixmap_resource_free(i);
+ }
+ cp->resource_cache = NULL;
#endif
break;
default:
@@ -350,7 +372,6 @@ e_pixmap_clear(E_Pixmap *cp)
cp->dirty = EINA_TRUE;
}
-
EAPI void
e_pixmap_dirty(E_Pixmap *cp)
{
@@ -364,6 +385,7 @@ e_pixmap_refresh(E_Pixmap *cp)
Eina_Bool success = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(cp, EINA_FALSE);
+
if (!cp->usable)
{
cp->failures++;
@@ -415,8 +437,43 @@ e_pixmap_refresh(E_Pixmap *cp)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- _e_pixmap_update_wl(cp);
- success = ((cp->w > 0) && (cp->h > 0));
+ {
+ E_Comp_Wl_Client_Data *cd = NULL;
+ struct wl_resource *res = NULL;
+ int pw = 0, ph = 0;
+
+ if (cp->client)
+ {
+ cd = (E_Comp_Wl_Client_Data *)cp->client->comp_data;
+ e_comp_object_native_surface_set(cp->client->frame, 0);
+ res = cd->pending.buffer;
+ /* pw = cp->client->client.w; */
+ /* ph = cp->client->client.h; */
+ }
+
+ success = (res != NULL);
+ if (!success) break;
+
+ if ((cd) && (cd->pending.w) && (cd->pending.h))
+ {
+ pw = cd->pending.w;
+ ph = cd->pending.h;
+ }
+
+ success = ((pw > 0) && (ph > 0));
+ if (success)
+ {
+ /* if (cp->resource) _e_pixmap_resource_free(cp->resource); */
+ e_pixmap_image_clear(cp, EINA_TRUE);
+ cp->resource = res;
+ _e_pixmap_update_wl(cp);
+ e_pixmap_image_clear(cp, EINA_FALSE);
+ }
+ else
+ {
+ if (res) _e_pixmap_resource_free(res);
+ }
+ }
#endif
break;
default:
@@ -586,6 +643,9 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache)
#ifndef HAVE_WAYLAND_ONLY
if (!cp->image) return;
#endif
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ if (!cp->resource) return;
+#endif
}
cp->failures = 0;
@@ -609,23 +669,21 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache)
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ if (cache)
{
- E_Comp_Wl_Client_Data *cd;
- struct wl_resource *cb;
+ void *i;
- if ((!cp->client) || (!cp->client->comp_data)) return;
- cd = (E_Comp_Wl_Client_Data*)cp->client->comp_data;
- EINA_LIST_FREE(cd->frames, cb)
- {
- wl_callback_send_done(cb, (ecore_loop_time_get() * 1000));
- wl_resource_destroy(cb);
- }
+ EINA_LIST_FREE(cp->resource_cache, i)
+ _e_pixmap_resource_free(i);
}
-
- if (cache)
+ else
{
- if (cp->resource) wl_buffer_send_release(cp->resource);
- cp->resource = NULL;
+ if (eina_list_data_find(cp->resource_cache, cp->resource) !=
+ cp->resource)
+ {
+ cp->resource_cache =
+ eina_list_append(cp->resource_cache, cp->resource);
+ }
}
#endif
break;
@@ -642,6 +700,7 @@ e_pixmap_image_refresh(E_Pixmap *cp)
#ifndef HAVE_WAYLAND_ONLY
if (cp->image) return EINA_TRUE;
#endif
+
if (cp->dirty)
{
CRI("BUG! PIXMAP %p IS DIRTY!", cp);
@@ -817,8 +876,24 @@ e_pixmap_image_draw(E_Pixmap *cp, const Eina_Rectangle *r)
#endif
break;
case E_PIXMAP_TYPE_WL:
+#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
+ {
+ E_Comp_Wl_Client_Data *cd;
+ struct wl_resource *cb;
+
+ if ((!cp->client) || (!cp->client->comp_data))
+ return EINA_FALSE;
+
+ cd = (E_Comp_Wl_Client_Data*)cp->client->comp_data;
+ EINA_LIST_FREE(cd->frames, cb)
+ {
+ wl_callback_send_done(cb, (ecore_loop_time_get() * 1000));
+ wl_resource_destroy(cb);
+ }
+ }
+#endif
(void) r;
- return EINA_TRUE; //this call is a NOP
+ return EINA_TRUE;
default:
break;
}