Page MenuHomePhabricator

evas_map: draw what map did not draw before.
ClosedPublic

Authored by kimcinoo on Thu, Aug 1, 5:27 AM.

Details

Summary

When a map property is changed, map draws it.
Before drawing, evas_object_map_update updates map->spans which is data for
actual drawing. But if changed_map is false, then evas_object_map_update does
not update map->spans.

Usually mapped object has following step.

(1) change map data (evas_map_point_coord_set)
(2) render_pre
(3) evas_object_map_update updates map->spans if changed_map is true.
(4) render
(5) render_post -> evas_object_cur_prev -> "map->prev = map->cur"

But if mapped object hides at step(1), then step(3),(4) does not happen. But
step(4) map->prev keeps changed map data. After this point, If same map data
comes, then map does not draw it. Because the new data is same with map->prev.

The issue occurs with following step.
(A) point_coord_set with point A.
(B) (2)(3)(4)(5) works.
(C) point_coord_set with point B. And hide.
(D) (2)(5) wokrs.
(E) point_coord_set with point A. still hide, so none of (2)(3)(4)(5) work.
(F) point_coord_set with point B. And show.
(G) (2)(3)(4)(5) works. BUT step(3) does not update map->spans because
changed_map is false. So you can see image of point A.

The changed_map is changed to false after updating map->spans at step(3).
So usually changed_map is false before deciding changed_map of next render.
In case of not rendering (but render_pre/post) after map data is changed, the
changed_map keeps true. So this patch was suppose to make changed_map
false if changed_map is already ture before _evas_map_calc_map_geometry
decides changed_map which occurs step(1). true changed_map indicates that
you need to draw even though new map data is same with previous map data.

Test Plan

Diff Detail

Repository
rEFL core/efl
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
kimcinoo created this revision.Thu, Aug 1, 5:27 AM
kimcinoo requested review of this revision.Thu, Aug 1, 5:27 AM
kimcinoo edited the test plan for this revision. (Show Details)Thu, Aug 1, 5:28 AM

@Hermet
As we discussed at a meeting. I have checked if render_pre is called or not when rect's visibility is changed to hide from show.
The result is that the render_pre is called.
The procedure is following.

(1) hide rect
(2) _phase1_object_process, the is_active is true. 
   Please have a look into evas_object_is_active in this case. One of is_visible or was_visible is ture, then is_active could be true. 
   In case of smart object, there is a condition checking was_visible in _phase1_object_mapped.
(3) _phase1_object_changed_normal, push rect to render_objects
(4) _phase1_direct calls render_pre

You could check using attached example.

You may have following line in your mind.

_evas_render_phase1_object_changed_normal(Phase1_Context *p1ctx,
   ...
        else
          {
             /* It goes to be hidden. Prev caching should be replaced
              by the current (hidden) state. */
             if (evas_object_is_visible(obj) !=
                 evas_object_was_visible(obj))
               evas_object_cur_prev(obj);
             RD(level, "  skip - not smart, not active or clippees or not relevant\n");
          }

This is not called for this case.

Hermet requested changes to this revision.Mon, Aug 5, 2:16 AM

Looks bad to me if _evas_map_calc_geom_change() is called twice.
And what happens if _evas_map_calc_map_geometry() is not called in the next frame?

This revision now requires changes to proceed.Mon, Aug 5, 2:16 AM
kimcinoo updated this revision to Diff 23886.Mon, Aug 5, 4:27 AM

do not use changed_map but add a condition to check spans->pts.

kimcinoo edited the summary of this revision. (Show Details)Mon, Aug 5, 4:35 AM
Hermet requested changes to this revision.Mon, Aug 12, 5:53 AM

I guess this function won't be triggered if user just make it object visible again without any map update,

Does this work properly?

This revision now requires changes to proceed.Mon, Aug 12, 5:53 AM

I guess this function won't be triggered if user just make it object visible again without any map update,

Does this work properly?

Even though it works as you guess it is not a problem. Because this change tries to fix a rendering issue when user makes an object visible with map update at the same time.
The issue is that the changed map does not render at all. If there is not a changed map, then there is not the problem.
But above all this function is triggered if user just make it object visible again without any map update. Please see evas_render_mapped calling this function.
If an object makes condition (_evas_render_has_map(obj) && !_evas_render_can_map(obj)) true, then this function is triggered.

if other properties has been changed such as texture uv, image, point color, smooth option, antialiasing, etc
Does here it needs to check out all the property diff?

if other properties has been changed such as texture uv, image, point color, smooth option, antialiasing, etc
Does here it needs to check out all the property diff?

In case of uv, it seems that it is compared at line 1317.
Others probably should be checked as well here, if those are not working neither.
Or you might mean that these should be checked somewhere else not here.

kimcinoo updated this revision to Diff 24050.Tue, Aug 13, 1:26 AM

Use changed_map.
Remove incorrect(unnecessary) move, resize callback call

kimcinoo edited the summary of this revision. (Show Details)Tue, Aug 13, 1:27 AM
Hermet accepted this revision.Tue, Aug 13, 8:39 PM
This revision is now accepted and ready to land.Tue, Aug 13, 8:39 PM
This revision was automatically updated to reflect the committed changes.