From 6856e562ca4a76ac33a89669bf4cf4932ec7c07d Mon Sep 17 00:00:00 2001 From: Taekyun Kim Date: Tue, 7 Jan 2014 17:39:23 +0900 Subject: [PATCH] Evas: 3D: Refined proxy texture implementation Added new APIs for controlling source object's visibility. Fixed bugs related to updating proxy textures. --- src/examples/evas/evas-3d-cube.c | 2 +- src/examples/evas/evas-3d-cube2.c | 2 +- src/examples/evas/evas-3d-md2.c | 2 +- src/examples/evas/evas-3d-pick.c | 2 +- src/examples/evas/evas-3d-proxy.c | 2 +- src/lib/evas/Evas_3D.h | 6 ++-- src/lib/evas/canvas/evas_3d_texture.c | 58 ++++++++++++++++++++++++++++----- src/lib/evas/canvas/evas_object_image.c | 13 ++++++++ src/lib/evas/canvas/evas_object_main.c | 4 +++ src/lib/evas/canvas/evas_render.c | 19 +++++++++++ src/lib/evas/include/evas_3d_utils.h | 17 +++++----- src/lib/evas/include/evas_inline.x | 4 +++ 12 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/examples/evas/evas-3d-cube.c b/src/examples/evas/evas-3d-cube.c index fddca28..cd9ccf4 100644 --- a/src/examples/evas/evas-3d-cube.c +++ b/src/examples/evas/evas-3d-cube.c @@ -245,7 +245,7 @@ main(void) evas_object_show(image); /* Set the image object as render target for 3D scene. */ - evas_object_image_3d_scene_set(image, data.scene); + evas_object_image_t3d_scene_set(image, data.scene); /* Add animation timer callback. */ ecore_timer_add(0.016, _animate_scene, &data); diff --git a/src/examples/evas/evas-3d-cube2.c b/src/examples/evas/evas-3d-cube2.c index fe4d6a8..80cf160 100644 --- a/src/examples/evas/evas-3d-cube2.c +++ b/src/examples/evas/evas-3d-cube2.c @@ -306,7 +306,7 @@ main(void) evas_object_show(image); /* Set the image object as render target for 3D scene. */ - evas_object_image_3d_scene_set(image, data.scene); + evas_object_image_t3d_scene_set(image, data.scene); /* Add animation timer callback. */ ecore_timer_add(0.01, _animate_scene, &data); diff --git a/src/examples/evas/evas-3d-md2.c b/src/examples/evas/evas-3d-md2.c index 091e4eb..1a8df4e 100644 --- a/src/examples/evas/evas-3d-md2.c +++ b/src/examples/evas/evas-3d-md2.c @@ -148,7 +148,7 @@ main(void) image = evas_object_image_filled_add(evas); evas_object_image_size_set(image, WIDTH, HEIGHT); - evas_object_image_3d_scene_set(image, scene); + evas_object_image_t3d_scene_set(image, scene); evas_object_move(image, 0, 0); evas_object_resize(image, WIDTH, HEIGHT); evas_object_show(image); diff --git a/src/examples/evas/evas-3d-pick.c b/src/examples/evas/evas-3d-pick.c index 02d11d5..2d06363 100644 --- a/src/examples/evas/evas-3d-pick.c +++ b/src/examples/evas/evas-3d-pick.c @@ -378,7 +378,7 @@ main(void) image = evas_object_image_filled_add(evas); evas_object_image_size_set(image, WIDTH, HEIGHT); - evas_object_image_3d_scene_set(image, scene); + evas_object_image_t3d_scene_set(image, scene); evas_object_move(image, 0, 0); evas_object_resize(image, WIDTH, HEIGHT); evas_object_show(image); diff --git a/src/examples/evas/evas-3d-proxy.c b/src/examples/evas/evas-3d-proxy.c index e09af9d..d0a9db4 100644 --- a/src/examples/evas/evas-3d-proxy.c +++ b/src/examples/evas/evas-3d-proxy.c @@ -260,7 +260,7 @@ main(void) _scene_setup(&data); /* Set the image object as render target for 3D scene. */ - evas_object_image_3d_scene_set(image, data.scene); + evas_object_image_t3d_scene_set(image, data.scene); /* Add animation timer callback. */ ecore_timer_add(0.016, _animate_scene, &data); diff --git a/src/lib/evas/Evas_3D.h b/src/lib/evas/Evas_3D.h index 95de2bf..cdd5284 100644 --- a/src/lib/evas/Evas_3D.h +++ b/src/lib/evas/Evas_3D.h @@ -117,8 +117,8 @@ typedef enum _Evas_3D_Pick_Type } Evas_3D_Pick_Type; /* Image object render target */ -EAPI void evas_object_image_3d_scene_set(Evas_Object *obj, Evas_3D_Scene *scene) EINA_ARG_NONNULL(1); -EAPI Evas_3D_Scene *evas_object_image_3d_scene_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +EAPI void evas_object_image_t3d_scene_set(Evas_Object *obj, Evas_3D_Scene *scene) EINA_ARG_NONNULL(1); +EAPI Evas_3D_Scene *evas_object_image_t3d_scene_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); /* Scene */ EAPI Evas_3D_Scene *evas_3d_scene_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); @@ -259,6 +259,8 @@ EAPI Evas *evas_3d_texture_evas_get(const Evas_3D_Texture *texture) EAPI void evas_3d_texture_data_set(Evas_3D_Texture *texture, Evas_3D_Color_Format color_format, Evas_3D_Pixel_Format pixel_format, int w, int h, const void *data); EAPI void evas_3d_texture_file_set(Evas_3D_Texture *texture, const char *file, const char *key) EINA_ARG_NONNULL(1); EAPI void evas_3d_texture_source_set(Evas_3D_Texture *texture, Evas_Object *source) EINA_ARG_NONNULL(1); +EAPI void evas_3d_texture_source_visible_set(Evas_3D_Texture *texture, Eina_Bool visible) EINA_ARG_NONNULL(1); +EAPI Eina_Bool evas_3d_texture_source_visible_get(const Evas_3D_Texture *texture) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); EAPI Evas_3D_Color_Format evas_3d_texture_color_format_get(const Evas_3D_Texture *texture) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); EAPI void evas_3d_texture_size_get(const Evas_3D_Texture *texture, int *w, int *h) EINA_ARG_NONNULL(1); EAPI void evas_3d_texture_wrap_set(Evas_3D_Texture *texture, Evas_3D_Wrap_Mode s, Evas_3D_Wrap_Mode t) EINA_ARG_NONNULL(1); diff --git a/src/lib/evas/canvas/evas_3d_texture.c b/src/lib/evas/canvas/evas_3d_texture.c index 16e3395..3b075e7 100644 --- a/src/lib/evas/canvas/evas_3d_texture.c +++ b/src/lib/evas/canvas/evas_3d_texture.c @@ -28,15 +28,14 @@ _texture_proxy_unset(Evas_3D_Texture *texture) { proxy_src->proxy_textures = eina_list_remove(proxy_src->proxy_textures, texture); - if (eina_list_count(proxy_src->proxy_textures) == 0) + if (eina_list_count(proxy_src->proxy_textures) == 0 && + eina_list_count(proxy_src->proxies) == 0 && + proxy_src->surface != NULL) { - if (eina_list_count(proxy_src->proxies) == 0) - { - Evas_Public_Data *e = src->layer->evas; - e->engine.func->image_map_surface_free(e->engine.data.output, - proxy_src->surface); - proxy_src->surface = NULL; - } + Evas_Public_Data *e = src->layer->evas; + e->engine.func->image_map_surface_free(e->engine.data.output, + proxy_src->surface); + proxy_src->surface = NULL; } if (proxy_src->src_invisible) @@ -134,11 +133,18 @@ _texture_proxy_subrender(Evas_3D_Texture *texture) } else { + Evas_Proxy_Render_Data proxy_render_data = { + .eo_proxy = NULL, + .proxy_obj = NULL, + .eo_src = texture->source, + .source_clip = EINA_FALSE + }; + evas_render_mapped(e, texture->source, source, ctx, proxy_write->surface, -source->cur->geometry.x, -source->cur->geometry.y, 1, 0, 0, e->output.w, e->output.h, - NULL + &proxy_render_data #ifdef REND_DBG , 1 #endif @@ -388,6 +394,40 @@ evas_3d_texture_source_set(Evas_3D_Texture *texture, Evas_Object *source) evas_3d_object_change(&texture->base, EVAS_3D_STATE_TEXTURE_DATA, NULL); } +EAPI void +evas_3d_texture_source_visible_set(Evas_3D_Texture *texture, Eina_Bool visible) +{ + Evas_Object_Protected_Data *src_obj; + + if (texture->source == NULL) + return; + + src_obj = eo_data_scope_get(texture->source, EVAS_OBJ_CLASS); + + if (src_obj->proxy->src_invisible == !visible) + return; + + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src_obj->proxy, Evas_Object_Proxy_Data, proxy_write) + proxy_write->src_invisible = !visible; + EINA_COW_WRITE_END(evas_object_proxy_cow, src_obj->proxy, proxy_write); + + src_obj->changed_src_visible = EINA_TRUE; + evas_object_smart_member_cache_invalidate(texture->source, EINA_FALSE, EINA_FALSE, EINA_TRUE); + evas_object_change(texture->source, src_obj); +} + +EAPI Eina_Bool +evas_3d_texture_source_visible_get(const Evas_3D_Texture *texture) +{ + Evas_Object_Protected_Data *src_obj; + + if (texture->source == NULL) + return EINA_FALSE; + + src_obj = eo_data_scope_get(texture->source, EVAS_OBJ_CLASS); + return !src_obj->proxy->src_invisible; +} + EAPI Evas_3D_Color_Format evas_3d_texture_color_format_get(const Evas_3D_Texture *texture) { diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 67b37d8..b4da8a3 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -3875,7 +3875,20 @@ evas_object_image_is_inside(Evas_Object *eo_obj, (o->cur->source ? eo_data_scope_get(o->cur->source, EVAS_OBJ_CLASS): NULL); +#ifdef EVAS_3D + if (o->cur->scene) + { + _3d_render(obj->layer->evas->evas, eo_obj, obj, o, o->cur->scene); + pixels = obj->data_3d->surface; + imagew = obj->data_3d->w; + imageh = obj->data_3d->h; + uvw = imagew; + uvh = imageh; + } + else if (!o->cur->source) +#else if (!o->cur->source) +#endif { pixels = o->engine_data; imagew = o->cur->image.w; diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index 24aadcd..d6809f7 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -677,6 +677,10 @@ _evas_object_eo_base_destructor(Eo *eo_obj, Evas_Object_Protected_Data *obj) else if (eo_isa(proxy, EVAS_OBJ_TEXT_CLASS)) eo_do(proxy, evas_obj_text_filter_source_set(NULL, eo_obj)); } + + while (obj->proxy->proxy_textures) + evas_3d_texture_source_set(obj->proxy->proxy_textures->data, NULL); + if (obj->cur->clipper) evas_object_clip_unset(eo_obj); evas_object_map_set(eo_obj, NULL); if (obj->is_smart) evas_object_smart_del(eo_obj); diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 5ffe0f4..2db05ff 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -278,6 +278,17 @@ _evas_proxy_redraw_set(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, //Update the proxies recursively. _evas_proxy_redraw_set(e, proxy, render); } + +#ifdef EVAS_3D + if (obj->proxy->proxy_textures) + { + /* Flag need redraw on proxy texture source */ + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, + Evas_Object_Proxy_Data, source) + source->redraw = EINA_TRUE; + EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, source); + } +#endif } static void @@ -298,7 +309,11 @@ _evas_render_phase1_direct(Evas_Public_Data *e, eina_array_data_get(active_objects, i); if (obj->changed) evas_object_clip_recalc(obj); +#ifdef EVAS_3D + if (!obj->proxy->proxies && !obj->proxy->proxy_textures) continue; +#else if (!obj->proxy->proxies) continue; +#endif if (obj->smart.smart) changed = evas_object_smart_changed_get(obj->object); @@ -325,7 +340,11 @@ _evas_render_phase1_direct(Evas_Public_Data *e, obj->func->render_pre(eo_obj, obj, obj->private_data); if (obj->proxy->redraw) _evas_render_prev_cur_clip_cache_add(e, obj); +#ifdef EVAS_3D + if (obj->proxy->proxies || obj->proxy->proxy_textures) +#else if (obj->proxy->proxies) +#endif { if (!obj->smart.smart || evas_object_smart_changed_get(eo_obj)) { diff --git a/src/lib/evas/include/evas_3d_utils.h b/src/lib/evas/include/evas_3d_utils.h index 92ae65a..8933c45 100644 --- a/src/lib/evas/include/evas_3d_utils.h +++ b/src/lib/evas/include/evas_3d_utils.h @@ -1528,13 +1528,12 @@ evas_box3_ray3_intersect(const Evas_Box3 *box EINA_UNUSED, const Evas_Ray3 *ray static inline Evas_Real evas_reciprocal_sqrt(Evas_Real x) { - long i; - float y, r; - - y = x * 0.5f; - i = *(long *)(&x); - i = 0x5f3759df - (i >> 1); - r = *(float *)(&i); - r = r * (1.5f - r * r * y); - return r; + union { + float f; + long i; + } u; + + u.f = x; + u.i = 0x5f3759df - (u.i >> 1); + return u.f * (1.5f - u.f * u.f * x * 0.5f); } diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x index c4e102d..8952c3b 100644 --- a/src/lib/evas/include/evas_inline.x +++ b/src/lib/evas/include/evas_inline.x @@ -110,7 +110,11 @@ evas_object_is_source_invisible(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pro { if (obj->parent_cache.src_invisible_valid) return obj->parent_cache.src_invisible; +#ifdef EVAS_3D + if ((obj->proxy->proxies || obj->proxy->proxy_textures) && obj->proxy->src_invisible) return 1; +#else if (obj->proxy->proxies && obj->proxy->src_invisible) return 1; +#endif if (!obj->smart.parent) return 0; Evas_Object_Protected_Data *smart_parent_pd = eo_data_scope_get(obj->smart.parent, EVAS_OBJ_CLASS); -- 2.7.4