From: Boram Park Date: Fri, 8 May 2015 08:27:55 +0000 (+0900) Subject: wl_scaler: fix memory corruption X-Git-Tag: accepted/tizen/common/20150511.125739~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F23%2F39123%2F1;p=platform%2Fupstream%2Fenlightenment.git wl_scaler: fix memory corruption Change-Id: I9b1637ac6e6d94e8b0382ad4dccd3499d2bb7dcf --- diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 55e498f..a1b116e 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -110,8 +110,8 @@ _e_comp_wl_map_size_cal_from_buffer(E_Client *ec) if (!ec->comp_data->buffer_ref.buffer) { - vp->width_from_buffer = 0; - vp->height_from_buffer = 0; + ec->comp_data->width_from_buffer = 0; + ec->comp_data->height_from_buffer = 0; return; } @@ -130,8 +130,8 @@ _e_comp_wl_map_size_cal_from_buffer(E_Client *ec) break; } - vp->width_from_buffer = width; - vp->height_from_buffer = height; + ec->comp_data->width_from_buffer = width; + ec->comp_data->height_from_buffer = height; } static void @@ -140,13 +140,13 @@ _e_comp_wl_map_size_cal_from_viewport(E_Client *ec) E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport; int32_t width, height; - width = vp->width_from_buffer; - height = vp->height_from_buffer; + width = ec->comp_data->width_from_buffer; + height = ec->comp_data->height_from_buffer; if (width != 0 && vp->surface.width != -1) { - vp->width_from_viewport = vp->surface.width; - vp->height_from_viewport = vp->surface.height; + ec->comp_data->width_from_viewport = vp->surface.width; + ec->comp_data->height_from_viewport = vp->surface.height; return; } @@ -154,13 +154,13 @@ _e_comp_wl_map_size_cal_from_viewport(E_Client *ec) { int32_t w = wl_fixed_to_int(wl_fixed_from_int(1) - 1 + vp->buffer.src_width); int32_t h = wl_fixed_to_int(wl_fixed_from_int(1) - 1 + vp->buffer.src_height); - vp->width_from_viewport = w ?: 1; - vp->height_from_viewport = h ?: 1; + ec->comp_data->width_from_viewport = w ?: 1; + ec->comp_data->height_from_viewport = h ?: 1; return; } - vp->width_from_viewport = width; - vp->height_from_viewport = height; + ec->comp_data->width_from_viewport = width; + ec->comp_data->height_from_viewport = height; } static void @@ -211,14 +211,14 @@ _e_comp_wl_map_apply(E_Client *ec) evas_map_util_points_populate_from_geometry(map, ec->x, ec->y, - vp->width_from_viewport, vp->height_from_viewport, 0); + ec->comp_data->width_from_viewport, ec->comp_data->height_from_viewport, 0); if (vp->buffer.src_width == wl_fixed_from_int(-1)) { x1 = 0.0; y1 = 0.0; - x2 = vp->width_from_buffer; - y2 = vp->height_from_buffer; + x2 = ec->comp_data->width_from_buffer; + y2 = ec->comp_data->height_from_buffer; } else { @@ -228,22 +228,22 @@ _e_comp_wl_map_apply(E_Client *ec) y2 = wl_fixed_to_int(vp->buffer.src_y + vp->buffer.src_height); } - _e_comp_wl_map_transform(vp->width_from_buffer, vp->height_from_buffer, + _e_comp_wl_map_transform(ec->comp_data->width_from_buffer, ec->comp_data->height_from_buffer, vp->buffer.transform, vp->buffer.scale, x1, y1, &x, &y); evas_map_point_image_uv_set(map, 0, x, y); - _e_comp_wl_map_transform(vp->width_from_buffer, vp->height_from_buffer, + _e_comp_wl_map_transform(ec->comp_data->width_from_buffer, ec->comp_data->height_from_buffer, vp->buffer.transform, vp->buffer.scale, x2, y1, &x, &y); evas_map_point_image_uv_set(map, 1, x, y); - _e_comp_wl_map_transform(vp->width_from_buffer, vp->height_from_buffer, + _e_comp_wl_map_transform(ec->comp_data->width_from_buffer, ec->comp_data->height_from_buffer, vp->buffer.transform, vp->buffer.scale, x2, y2, &x, &y); evas_map_point_image_uv_set(map, 2, x, y); - _e_comp_wl_map_transform(vp->width_from_buffer, vp->height_from_buffer, + _e_comp_wl_map_transform(ec->comp_data->width_from_buffer, ec->comp_data->height_from_buffer, vp->buffer.transform, vp->buffer.scale, x1, y2, &x, &y); evas_map_point_image_uv_set(map, 3, x, y); @@ -2316,11 +2316,9 @@ _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec) /* eina_hash_add(clients_win_hash, &win, ec); */ e_hints_client_list_set(); - E_Comp_Wl_Client_Data *cdata = e_pixmap_cdata_get(ec->pixmap); - struct wl_resource *wl_resource = cdata->wl_surface; - ec->comp_data->scaler = cdata->scaler; e_pixmap_cdata_set(ec->pixmap, ec->comp_data); - _e_comp_wl_surface_cb_commit(NULL, wl_resource); + if (ec->comp_data->wl_surface) + _e_comp_wl_surface_cb_commit(NULL, ec->comp_data->wl_surface); } static void diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 2ce5488..4429ee7 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -89,14 +89,6 @@ struct _E_Comp_Wl_Buffer_Viewport { } surface; int changed; - - /* before applying viewport */ - int width_from_buffer; - int height_from_buffer; - - /* after applying viewport */ - int width_from_viewport; - int height_from_viewport; }; struct _E_Comp_Wl_Surface_State @@ -305,6 +297,14 @@ struct _E_Comp_Wl_Client_Data E_Comp_Wl_Buffer_Viewport buffer_viewport; } scaler; + /* before applying viewport */ + int width_from_buffer; + int height_from_buffer; + + /* after applying viewport */ + int width_from_viewport; + int height_from_viewport; + Eina_Bool keep_buffer : 1; Eina_Bool mapped : 1; Eina_Bool change_icon : 1; diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c index b3228be..800b910 100644 --- a/src/bin/e_pixmap.c +++ b/src/bin/e_pixmap.c @@ -36,9 +36,10 @@ struct _E_Pixmap struct wl_listener buffer_destroy_listener; void *data; Eina_Rectangle opaque; -#endif - E_Comp_Client_Data *cdata; + E_Comp_Wl_Client_Data *cdata; + Eina_Bool own_cdata : 1; +#endif Eina_Bool usable : 1; Eina_Bool dirty : 1; @@ -85,6 +86,12 @@ _e_pixmap_clear(E_Pixmap *cp, Eina_Bool cache) e_comp_wl_buffer_reference(&cp->buffer_ref, NULL); + if (cp->own_cdata) + { + free (cp->cdata); + cp->own_cdata = EINA_FALSE; + } + (void)cache; #endif break; @@ -143,9 +150,13 @@ _e_pixmap_new(E_Pixmap_Type type) cp->refcount = 1; cp->dirty = 1; #if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY) - cp->cdata = calloc(1, sizeof(E_Comp_Wl_Client_Data)); -#else - cp->cdata = calloc(1, sizeof(E_Comp_X_Client_Data)); + cp->own_cdata = EINA_TRUE; + cp->cdata = E_NEW(E_Comp_Wl_Client_Data, 1); + cp->cdata->pending.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL; + cp->cdata->pending.buffer_viewport.buffer.scale = 1; + cp->cdata->pending.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1); + cp->cdata->pending.buffer_viewport.surface.width = -1; + cp->cdata->pending.buffer_viewport.changed = 0; #endif return cp; } @@ -961,14 +972,34 @@ EAPI E_Comp_Client_Data * e_pixmap_cdata_get(E_Pixmap *cp) { EINA_SAFETY_ON_NULL_RETURN_VAL(cp, NULL); + +#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY) return (E_Comp_Client_Data*)cp->cdata; +#else + return NULL; +#endif } EAPI void e_pixmap_cdata_set(E_Pixmap *cp, E_Comp_Client_Data *cdata) { +#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY) + E_Comp_Wl_Client_Data *cd = (E_Comp_Wl_Client_Data*)cdata; + EINA_SAFETY_ON_NULL_RETURN(cp); + EINA_SAFETY_ON_NULL_RETURN(cp->cdata); EINA_SAFETY_ON_NULL_RETURN(cdata); - free (cp->cdata); - cp->cdata = cdata; + + if (cp->own_cdata) + { + cd->wl_surface = cp->cdata->wl_surface; + cd->scaler.viewport = cp->cdata->scaler.viewport; + cd->pending.buffer_viewport = cp->cdata->pending.buffer_viewport; + + free (cp->cdata); + cp->own_cdata = EINA_FALSE; + } + + cp->cdata = cd; +#endif } diff --git a/src/modules/wl_desktop_shell/e_scaler.c b/src/modules/wl_desktop_shell/e_scaler.c index e0aabe9..3c4ae83 100644 --- a/src/modules/wl_desktop_shell/e_scaler.c +++ b/src/modules/wl_desktop_shell/e_scaler.c @@ -6,8 +6,10 @@ static void _e_viewport_destroy(struct wl_resource *resource) { - E_Comp_Client_Data *cdata = wl_resource_get_user_data(resource); + E_Pixmap *ep = wl_resource_get_user_data(resource); + E_Comp_Client_Data *cdata = e_pixmap_cdata_get(ep); + EINA_SAFETY_ON_NULL_RETURN(cdata); EINA_SAFETY_ON_NULL_RETURN(cdata->scaler.viewport); cdata->scaler.viewport = NULL; @@ -32,8 +34,10 @@ _e_viewport_cb_set(struct wl_client *client EINA_UNUSED, int32_t dst_width, int32_t dst_height) { - E_Comp_Client_Data *cdata = wl_resource_get_user_data(resource); + E_Pixmap *ep = wl_resource_get_user_data(resource); + E_Comp_Client_Data *cdata = e_pixmap_cdata_get(ep); + EINA_SAFETY_ON_NULL_RETURN(cdata); EINA_SAFETY_ON_NULL_RETURN(cdata->scaler.viewport); if (wl_fixed_to_double(src_width) < 0 || wl_fixed_to_double(src_height) < 0) @@ -72,8 +76,10 @@ _e_viewport_cb_set_source(struct wl_client *client EINA_UNUSED, wl_fixed_t src_width, wl_fixed_t src_height) { - E_Comp_Client_Data *cdata = wl_resource_get_user_data(resource); + E_Pixmap *ep = wl_resource_get_user_data(resource); + E_Comp_Client_Data *cdata = e_pixmap_cdata_get(ep); + EINA_SAFETY_ON_NULL_RETURN(cdata); EINA_SAFETY_ON_NULL_RETURN(cdata->scaler.viewport); if (src_width == wl_fixed_from_int(-1) && src_height == wl_fixed_from_int(-1)) @@ -107,8 +113,10 @@ _e_viewport_cb_set_destination(struct wl_client *client EINA_UNUSED, int32_t dst_width, int32_t dst_height) { - E_Comp_Client_Data *cdata = wl_resource_get_user_data(resource); + E_Pixmap *ep = wl_resource_get_user_data(resource); + E_Comp_Client_Data *cdata = e_pixmap_cdata_get(ep); + EINA_SAFETY_ON_NULL_RETURN(cdata); EINA_SAFETY_ON_NULL_RETURN(cdata->scaler.viewport); if (dst_width == -1 && dst_height == -1) @@ -173,7 +181,7 @@ _e_scaler_cb_get_viewport(struct wl_client *client EINA_UNUSED, struct wl_resour } cdata->scaler.viewport = res; - wl_resource_set_implementation(res, &_e_viewport_interface, cdata, _e_viewport_destroy); + wl_resource_set_implementation(res, &_e_viewport_interface, ep, _e_viewport_destroy); } static const struct wl_scaler_interface _e_scaler_interface = @@ -185,15 +193,8 @@ static const struct wl_scaler_interface _e_scaler_interface = static void _e_scaler_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - E_Comp_Data *cdata; struct wl_resource *res; - if (!(cdata = data)) - { - wl_client_post_no_memory(client); - return; - } - if (!(res = wl_resource_create(client, &wl_scaler_interface, MIN(version, 2), id))) { ERR("Could not create scaler resource: %m"); @@ -201,7 +202,7 @@ _e_scaler_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32 return; } - wl_resource_set_implementation(res, &_e_scaler_interface, cdata, NULL); + wl_resource_set_implementation(res, &_e_scaler_interface, NULL, NULL); } Eina_Bool