discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=cdf6650a11b3e09828312e3e383a82128d4539bc
commit cdf6650a11b3e09828312e3e383a82128d4539bc Author: Mike Blumenkrantz <zm...@osg.samsung.com> Date: Tue Sep 29 18:53:15 2015 -0400 redo wayland client buffer referencing the previous methodology was effectively: attach -> ref(new buffer) x2 / unref(old buffer) x2 ... ... attach -> ref(new buffer) x2 / unref(old buffer) x2 this resulted in buffer management failures and crashing. now the buffer gets 1x ref before render and 1x unref after render, ensuring that the lifetime is accurate (assuming evas doesn't lie to us) now we still have random crashing during resize, but not as much as before --- src/bin/e_comp_wl.c | 6 +-- src/bin/e_pixmap.c | 131 ++++++++++++++++++++++++++++------------------------ 2 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index bd17dc3..ddc44ee 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -2205,8 +2205,6 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec) _e_comp_wl_surface_state_finish(&ec->comp_data->pending); - e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, NULL); - EINA_LIST_FREE(ec->comp_data->frames, cb) wl_resource_destroy(cb); @@ -2771,11 +2769,11 @@ e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id) EINTERN void e_comp_wl_surface_attach(E_Client *ec, E_Comp_Wl_Buffer *buffer) { - e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, buffer); - /* set usable early because shell module checks this */ e_pixmap_usable_set(ec->pixmap, (buffer != NULL)); e_pixmap_resource_set(ec->pixmap, buffer); + e_pixmap_dirty(ec->pixmap); + e_pixmap_refresh(ec->pixmap); _e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending); } diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c index 8d09e0b..178c00c 100644 --- a/src/bin/e_pixmap.c +++ b/src/bin/e_pixmap.c @@ -35,6 +35,7 @@ struct _E_Pixmap #endif #ifdef HAVE_WAYLAND + E_Comp_Wl_Buffer *buffer; E_Comp_Wl_Buffer_Ref buffer_ref; struct wl_listener buffer_destroy_listener; void *data; @@ -79,15 +80,7 @@ _e_pixmap_clear(E_Pixmap *cp, Eina_Bool cache) break; case E_PIXMAP_TYPE_WL: #ifdef HAVE_WAYLAND - if (cp->buffer_destroy_listener.notify) - { - wl_list_remove(&cp->buffer_destroy_listener.link); - cp->buffer_destroy_listener.notify = NULL; - } - - e_comp_wl_buffer_reference(&cp->buffer_ref, NULL); - - (void)cache; + e_pixmap_image_clear(cp, cache); #endif break; default: @@ -408,7 +401,37 @@ e_pixmap_refresh(E_Pixmap *cp) break; case E_PIXMAP_TYPE_WL: #ifdef HAVE_WAYLAND - success = ((cp->w > 0) && (cp->h > 0)); + { + E_Comp_Wl_Buffer *buffer = cp->buffer; + struct wl_shm_buffer *shm_buffer; + + cp->w = cp->h = 0; + cp->image_argb = EINA_FALSE; + + if (!buffer) return EINA_FALSE; + + shm_buffer = wl_shm_buffer_get(buffer->resource); + if (!shm_buffer) + { + WRN("Cannot get shm buffer from buffer resource"); + return EINA_FALSE; + } + + cp->w = buffer->w; + cp->h = buffer->h; + + switch (wl_shm_buffer_get_format(shm_buffer)) + { + case WL_SHM_FORMAT_ARGB8888: + cp->image_argb = EINA_TRUE; + break; + default: + cp->image_argb = EINA_FALSE; + break; + } + + success = ((cp->w > 0) && (cp->h > 0)); + } #endif break; default: @@ -507,7 +530,7 @@ e_pixmap_resource_get(E_Pixmap *cp) return NULL; } #ifdef HAVE_WAYLAND - return cp->buffer_ref.buffer; + return cp->buffer; #endif return NULL; } @@ -517,52 +540,7 @@ e_pixmap_resource_set(E_Pixmap *cp, void *resource) { if ((!cp) || (cp->type != E_PIXMAP_TYPE_WL)) return; #ifdef HAVE_WAYLAND - { - E_Comp_Wl_Buffer *buffer; - struct wl_shm_buffer *shm_buffer; - - buffer = (E_Comp_Wl_Buffer *)resource; - e_comp_wl_buffer_reference(&cp->buffer_ref, buffer); - - if (cp->buffer_destroy_listener.notify) - { - wl_list_remove(&cp->buffer_destroy_listener.link); - cp->buffer_destroy_listener.notify = NULL; - } - - cp->w = cp->h = 0; - cp->image_argb = EINA_FALSE; - - if (!buffer) return; - - if (!(shm_buffer = wl_shm_buffer_get(buffer->resource))) - { - WRN("Cannot get shm buffer from buffer resource"); - e_comp_wl_buffer_reference(&cp->buffer_ref, NULL); - return; - } - - buffer->shm_buffer = shm_buffer; - cp->w = buffer->w; - cp->h = buffer->h; - /* buffer->w = cp->w = wl_shm_buffer_get_width(shm_buffer); */ - /* buffer->h = cp->h = wl_shm_buffer_get_height(shm_buffer); */ - - switch (wl_shm_buffer_get_format(shm_buffer)) - { - case WL_SHM_FORMAT_ARGB8888: - cp->image_argb = EINA_TRUE; - break; - default: - cp->image_argb = EINA_FALSE; - break; - } - - cp->data = wl_shm_buffer_get_data(shm_buffer); - - cp->buffer_destroy_listener.notify = _e_pixmap_cb_buffer_destroy; - wl_signal_add(&buffer->destroy_signal, &cp->buffer_destroy_listener); - } + cp->buffer = resource; #else (void)resource; #endif @@ -665,6 +643,13 @@ e_pixmap_image_clear(E_Pixmap *cp, Eina_Bool cache) wl_resource_destroy(cb); } } + if (cp->buffer_destroy_listener.notify) + { + wl_list_remove(&cp->buffer_destroy_listener.link); + cp->buffer_destroy_listener.notify = NULL; + } + e_comp_wl_buffer_reference(&cp->buffer_ref, NULL); + cp->data = NULL; #endif break; default: @@ -701,8 +686,34 @@ e_pixmap_image_refresh(E_Pixmap *cp) break; case E_PIXMAP_TYPE_WL: #ifdef HAVE_WAYLAND - /* FIXME */ - return EINA_TRUE; + { + E_Comp_Wl_Buffer *buffer = cp->buffer; + struct wl_shm_buffer *shm_buffer; + + shm_buffer = wl_shm_buffer_get(buffer->resource); + if (!shm_buffer) + { + WRN("Cannot get shm buffer from buffer resource"); + return EINA_FALSE; + } + if (cp->buffer_ref.buffer && (cp->buffer_ref.buffer != buffer)) + { + /* FIXME: wtf? */ + } + else if (cp->buffer_ref.buffer) return EINA_TRUE; + e_comp_wl_buffer_reference(&cp->buffer_ref, buffer); + + if (cp->buffer_destroy_listener.notify) + { + wl_list_remove(&cp->buffer_destroy_listener.link); + cp->buffer_destroy_listener.notify = NULL; + } + + cp->buffer_destroy_listener.notify = _e_pixmap_cb_buffer_destroy; + wl_signal_add(&buffer->destroy_signal, &cp->buffer_destroy_listener); + cp->data = wl_shm_buffer_get_data(shm_buffer); + return EINA_TRUE; + } #endif break; default: @@ -722,7 +733,7 @@ e_pixmap_image_exists(const E_Pixmap *cp) return !!cp->image; #endif #ifdef HAVE_WAYLAND - return (cp->buffer_ref.buffer != NULL); + return !!cp->data; /* FIXME: egl */ #endif return EINA_FALSE; --