From: Boram Park Date: Thu, 7 Jan 2016 10:40:36 +0000 (+0900) Subject: resize e_comp_object to the viewport size of a client X-Git-Tag: submit/tizen/20160121.104248~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94350fbb9f2a8dcafdebb95ee4f91a2562806e1d;p=platform%2Fupstream%2Fenlightenment.git resize e_comp_object to the viewport size of a client Change-Id: I22818b165368b8c9ee94a4d10038ff9bf98e2f9d --- diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 13f42bf136..12a8eea6b9 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -1076,6 +1076,9 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h) { E_Comp_Object *cw = data; int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y; +#ifdef HAVE_WAYLAND_ONLY + E_Comp_Wl_Client_Data *cd; +#endif if ((!e_util_strcmp("wl_pointer-cursor", cw->ec->icccm.window_role)) || (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))) @@ -1184,6 +1187,21 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h) EC_CHANGED(cw->ec); return; } + +#ifdef HAVE_WAYLAND_ONLY + cd = (E_Comp_Wl_Client_Data *)cw->ec->comp_data; + if (cd && cd->sub.data && (cd->width_from_viewport < cd->width_from_buffer)) + { + /* resize to the viewport size of a client. + * When the buffer size is bigger than the viewport size, the object is + * clipped by evas rendering mechanism even if we scale down the object + * with evas_map. + */ + pw = cd->width_from_viewport; + ph = cd->height_from_viewport; + } +#endif + prev_w = cw->w, prev_h = cw->h; e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh); /* check shading and clamp to pixmap size for regular clients */ @@ -3749,6 +3767,9 @@ e_comp_object_dirty(Evas_Object *obj) Evas_Object *o; int w, h; Eina_Bool dirty, visible; +#ifdef HAVE_WAYLAND_ONLY + E_Comp_Wl_Client_Data *cd; +#endif API_ENTRY; /* only actually dirty if pixmap is available */ @@ -3783,6 +3804,16 @@ e_comp_object_dirty(Evas_Object *obj) it = eina_tiler_iterator_new(cw->updates); EINA_ITERATOR_FOREACH(it, rect) { +#ifdef HAVE_WAYLAND_ONLY + cd = (E_Comp_Wl_Client_Data *)cw->ec->comp_data; + if (cd && cd->sub.data && (cd->width_from_viewport < cd->width_from_buffer)) + { + Eina_Rectangle tr; + /* change to the buffer cordinate if subsurface */ + e_comp_wl_surface_to_buffer_rect(cw->ec, rect, &tr); + rect = &tr; + } +#endif RENDER_DEBUG("UPDATE ADD [%p]: %d %d %dx%d", cw->ec, rect->x, rect->y, rect->w, rect->h); evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h); EINA_LIST_FOREACH(cw->obj_mirror, ll, o) @@ -3817,6 +3848,9 @@ e_comp_object_render(Evas_Object *obj) int stride, pw, ph; unsigned int *pix, *srcpix; Eina_Bool ret = EINA_FALSE; +#ifdef HAVE_WAYLAND_ONLY + E_Comp_Wl_Client_Data *cd; +#endif API_ENTRY EINA_FALSE; @@ -3886,6 +3920,16 @@ e_comp_object_render(Evas_Object *obj) srcpix = e_pixmap_image_data_get(cw->ec->pixmap); EINA_ITERATOR_FOREACH(it, r) { +#ifdef HAVE_WAYLAND_ONLY + cd = (E_Comp_Wl_Client_Data *)cw->ec->comp_data; + if (cd && cd->sub.data && (cd->width_from_viewport < cd->width_from_buffer)) + { + Eina_Rectangle tr; + /* change to the buffer cordinate if subsurface */ + e_comp_wl_surface_to_buffer_rect(cw->ec, r, &tr); + r = &tr; + } +#endif E_RECTS_CLIP_TO_RECT(r->x, r->y, r->w, r->h, 0, 0, pw, ph); ret = e_pixmap_image_draw(cw->ec->pixmap, r); if (!ret) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 3e98974605..31bf9dfa0a 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -470,6 +470,93 @@ _e_comp_wl_map_transform(int width, int height, uint32_t transform, int32_t scal *dy *= scale; } +static void +_e_comp_wl_map_transform_rect(int width, int height, + uint32_t transform, int32_t scale, + Eina_Rectangle *srect, Eina_Rectangle *drect) +{ + int x1, x2, y1, y2; + + x1 = srect->x; + y1 = srect->y; + x2 = srect->x + srect->w; + y2 = srect->y + srect->h; + + _e_comp_wl_map_transform(width, height, transform, scale, x1, y1, &x1, &y1); + _e_comp_wl_map_transform(width, height, transform, scale, x2, y2, &x2, &y2); + + drect->x = MIN(x1, x2); + drect->y = MIN(y1, y2); + drect->w = MAX(x1, x2) - drect->x; + drect->h = MAX(y1, y2) - drect->y; +} + +static void +_e_comp_wl_map_scaler_surface_to_buffer(E_Client *ec, int sx, int sy, int *bx, int *by) +{ + E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport; + double src_width, src_height; + double src_x, src_y; + + if (vp->buffer.src_width == wl_fixed_from_int(-1)) + { + if (vp->surface.width == -1) + { + *bx = sx; + *by = sy; + return; + } + + src_x = 0.0; + src_y = 0.0; + src_width = ec->comp_data->width_from_buffer; + src_height = ec->comp_data->height_from_buffer; + } + else + { + src_x = wl_fixed_to_double(vp->buffer.src_x); + src_y = wl_fixed_to_double(vp->buffer.src_y); + src_width = wl_fixed_to_double(vp->buffer.src_width); + src_height = wl_fixed_to_double(vp->buffer.src_height); + } + + *bx = sx * src_width / ec->comp_data->width_from_viewport + src_x; + *by = sy * src_height / ec->comp_data->height_from_viewport + src_y; +} + +EAPI void +e_comp_wl_surface_to_buffer_rect(E_Client *ec, Eina_Rectangle *srect, Eina_Rectangle *drect) +{ + E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport; + int xf1, yf1, xf2, yf2; + + if (!ec->comp_data->sub.data) + { + *drect = *srect; + return; + } + + /* first transform box coordinates if the scaler is set */ + + xf1 = srect->x; + yf1 = srect->y; + xf2 = srect->x + srect->w; + yf2 = srect->y + srect->h; + + _e_comp_wl_map_scaler_surface_to_buffer(ec, xf1, yf1, &xf1, &yf1); + _e_comp_wl_map_scaler_surface_to_buffer(ec, xf2, yf2, &xf2, &yf2); + + srect->x = MIN(xf1, xf2); + srect->y = MIN(yf1, yf2); + srect->w = MAX(xf1, xf2) - srect->x; + srect->h = MAX(yf1, yf2) - srect->y; + + _e_comp_wl_map_transform_rect(ec->comp_data->width_from_buffer, + ec->comp_data->height_from_buffer, + vp->buffer.transform, vp->buffer.scale, + srect, drect); +} + static void _e_comp_wl_map_apply(E_Client *ec) { @@ -1922,6 +2009,15 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state) if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure)) ec->comp_data->shell.configure(ec->comp_data->shell.surface, x, y, ec->w, ec->h); + else if (ec->comp_data->sub.data && + (ec->comp_data->width_from_viewport < ec->comp_data->width_from_buffer)) + /* resize to the viewport size of a client. + * When the buffer size is bigger than the viewport size, the object is + * clipped by evas rendering mechanism even if we scale down the object + * with evas_map. + */ + e_client_util_move_resize_without_frame(ec, x, y, ec->comp_data->width_from_viewport, + ec->comp_data->height_from_viewport); else { if (ec->netwm.sync.wait) diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 39b26c3d5d..d83018ad88 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -461,6 +461,7 @@ EINTERN Eina_Bool e_comp_wl_surface_commit(E_Client *ec); EINTERN Eina_Bool e_comp_wl_subsurface_commit(E_Client *ec); E_API void e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer); E_API E_Comp_Wl_Buffer *e_comp_wl_buffer_get(struct wl_resource *resource, E_Client *ec); +E_API void e_comp_wl_surface_to_buffer_rect(E_Client *ec, Eina_Rectangle *srect, Eina_Rectangle *drect); E_API struct wl_signal e_comp_wl_surface_create_signal_get(void); E_API double e_comp_wl_idle_time_get(void);