Commit: d1efaadb524b23bd13b1bdd1db8143da9a6bda54
Author: Julian Eisel
Date:   Wed May 18 17:44:44 2016 +0200
Branches: wiggly-widgets
https://developer.blender.org/rBd1efaadb524b23bd13b1bdd1db8143da9a6bda54

Rewrite Widget Update->Draw Routine (Massive Performance Boost)

This commit merges work done in temp_widgets_update_tagging branch into 
wiggly-widgets branch. It gives a speedup of up to ~500x (yes, 50,000%!) for 
simple view navigation in my benchmarks (more detailed results below).

Instead of re-creating all widgets on each redraw (like we do it for buttons), 
we now keep widgets and do some more advanced updating instead.
The widget-map update routine is now split into three steps:
* init - Initialize widget groups, only done once.
* refresh - Refresh data of widget groups, only if widget-map has been 
explicitly tagged for update by calling WM_widgetmap_tag_refresh.
* draw_prepare - Stuff that needs to be done on every redraw (currently used by 
3D transform manipulator).

Also contains some unrelated cleanup.

Benchmark results:
The numbers below are average results, I repeated all tests multiple times 
while tying to keep conditions as similar as possible. I measured the time 
needed update and draw the widget map.
We have to distinguish between a simple redraw which leaves widget data mostly 
untouched and a data refresh. To trigger a simple redraw I rotated the view, 
for triggering data refreshes I continuously toggled selection.

1. Default .blend, 3 objects, transform manipulator
-- Simple redraw: ~4.5x speedup (0.00009 vs. 0.000020 sec.)
-- Data refresh: ~1.6x speedup (0.000033 vs. 0.000021 sec.)

2. Frank pose mode, 9 face map widgets + transform manipulator
-- Simple redraw: ~420x speedup (0.0231 vs. 0.000055 sec.)
-- Data refresh: ~2x speedup (0.014834 vs. 0.007417 sec.)

3. Caminandes island mesh, 197,151 verts, transform manipulator
-- Simple redraw: ~500x speedup (0.011596 vs. 0.000023 sec.)
-- Data refresh: Only ~1.05x speedup (0.009376 vs. 0.008970 sec.)

===================================================================

M       source/blender/blenkernel/intern/facemap.c
M       source/blender/editors/armature/pose_select.c
M       source/blender/editors/include/ED_transform.h
M       source/blender/editors/include/ED_view3d.h
M       source/blender/editors/object/object_edit.c
M       source/blender/editors/space_graph/graph_edit.c
M       source/blender/editors/space_image/space_image.c
M       source/blender/editors/space_node/space_node.c
M       source/blender/editors/space_sequencer/sequencer_view.c
M       source/blender/editors/space_view3d/space_view3d.c
M       source/blender/editors/space_view3d/view3d_intern.h
M       source/blender/editors/space_view3d/view3d_widgets.c
M       source/blender/editors/transform/transform_manipulator.c
M       source/blender/editors/transform/transform_manipulator2d.c
M       source/blender/makesdna/DNA_view3d_types.h
M       source/blender/makesdna/DNA_widget_types.h
M       source/blender/makesrna/intern/rna_pose.c
M       source/blender/makesrna/intern/rna_wm.c
M       source/blender/windowmanager/widgets/WM_widget_api.h
M       source/blender/windowmanager/widgets/WM_widget_library.h
M       source/blender/windowmanager/widgets/WM_widget_types.h
M       
source/blender/windowmanager/widgets/intern/widget_library/arrow_widget.c
M       source/blender/windowmanager/widgets/intern/widget_library/cage_widget.c
M       
source/blender/windowmanager/widgets/intern/widget_library/widget_library_intern.h
M       
source/blender/windowmanager/widgets/intern/widget_library/widget_library_utils.c
M       source/blender/windowmanager/widgets/intern/wm_widget.c
M       source/blender/windowmanager/widgets/intern/wm_widget_intern.h
M       source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
M       source/blender/windowmanager/widgets/intern/wm_widgetmap.c
M       source/blender/windowmanager/widgets/wm_widget_wmapi.h
M       source/blenderplayer/bad_level_call_stubs/stubs.c

===================================================================

diff --git a/source/blender/blenkernel/intern/facemap.c 
b/source/blender/blenkernel/intern/facemap.c
index fb97b7f..c6be004 100644
--- a/source/blender/blenkernel/intern/facemap.c
+++ b/source/blender/blenkernel/intern/facemap.c
@@ -214,12 +214,17 @@ static void object_fmap_remove_object_mode(Object *ob, 
bFaceMap *fmap, bool purg
        }
 }
 
-void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
+static void fmap_remove_exec(Object *ob, bFaceMap *fmap, const bool 
is_edit_mode, const bool purge)
 {
-       if (BKE_object_is_in_editmode(ob))
-               object_fmap_remove_edit_mode(ob, fmap, false, true);
+       if (is_edit_mode)
+               object_fmap_remove_edit_mode(ob, fmap, false, purge);
        else
-               object_fmap_remove_object_mode(ob, fmap, true);
+               object_fmap_remove_object_mode(ob, fmap, purge);
+}
+
+void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
+{
+       fmap_remove_exec(ob, fmap, BKE_object_is_in_editmode(ob), true);
 }
 
 void BKE_object_fmap_remove_all(Object *ob)
@@ -231,12 +236,7 @@ void BKE_object_fmap_remove_all(Object *ob)
 
                while (fmap) {
                        bFaceMap *next_fmap = fmap->next;
-
-                       if (edit_mode)
-                               object_fmap_remove_edit_mode(ob, fmap, false, 
false);
-                       else
-                               object_fmap_remove_object_mode(ob, fmap, false);
-
+                       fmap_remove_exec(ob, fmap, edit_mode, false);
                        fmap = next_fmap;
                }
        }
diff --git a/source/blender/editors/armature/pose_select.c 
b/source/blender/editors/armature/pose_select.c
index e12fb3a..21d13c1 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -357,6 +357,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator 
*op)
        Object *ob = ED_object_context(C);
        bArmature *arm = ob->data;
        int multipaint = scene->toolsettings->multipaint;
+       bool has_facemap = false;
 
        if (action == SEL_TOGGLE) {
                action = CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT 
: SEL_SELECT;
@@ -366,11 +367,15 @@ static int pose_de_select_all_exec(bContext *C, 
wmOperator *op)
        CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones)
        {
                pose_do_bone_select(pchan, action);
+               if (pchan->fmap)
+                       has_facemap = true;
        }
        CTX_DATA_END;
 
-       /* handle widget selection */
-       WM_widgetmap_select_all(C, (wmWidgetMap *)ar->widgetmaps.first, action);
+       /* handle facemap widget selection */
+       if ((ob->mode & OB_MODE_POSE) && has_facemap) {
+               WM_widgetmap_select_all(C, (wmWidgetMap *)ar->widgetmaps.first, 
action);
+       }
 
        WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL);
        
diff --git a/source/blender/editors/include/ED_transform.h 
b/source/blender/editors/include/ED_transform.h
index 8fcd6b7..4f3617c 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -163,13 +163,17 @@ void Transform_Properties(struct wmOperatorType *ot, int 
flags);
 /* transform manipulators */
 
 int WIDGETGROUP_manipulator_poll(const struct bContext *C, struct 
wmWidgetGroupType *wgrouptype);
-void WIDGETGROUP_manipulator_create(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_manipulator_init(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_manipulator_refresh(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_manipulator_draw_prepare(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
 
-void WIDGETGROUP_object_manipulator_create(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_object_manipulator_init(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
 int WIDGETGROUP_object_manipulator_poll(const struct bContext *C, struct 
wmWidgetGroupType *wgrouptype);
 
-void WIDGETGROUP_manipulator2d_create(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
 int WIDGETGROUP_manipulator2d_poll(const struct bContext *C, struct 
wmWidgetGroupType *wgrouptype);
+void WIDGETGROUP_manipulator2d_init(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_manipulator2d_refresh(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
+void WIDGETGROUP_manipulator2d_draw_prepare(const struct bContext *C, struct 
wmWidgetGroup *wgroup);
 
 
 /* Snapping */
diff --git a/source/blender/editors/include/ED_view3d.h 
b/source/blender/editors/include/ED_view3d.h
index 3510617..69a7bb2 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -402,7 +402,8 @@ void ED_view3d_operator_properties_viewmat_get(struct 
wmOperator *op, int *winx,
 #endif
 
 int WIDGETGROUP_lamp_poll(const struct bContext *C, struct wmWidgetGroupType 
*wgrouptype);
-void WIDGETGROUP_lamp_create(const struct bContext *C, struct wmWidgetGroup 
*wgroup);
+void WIDGETGROUP_lamp_init(const struct bContext *C, struct wmWidgetGroup 
*wgroup);
+void WIDGETGROUP_lamp_refresh(const struct bContext *C, struct wmWidgetGroup 
*wgroup);
 
 /* render */
 void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion 
*ar);
diff --git a/source/blender/editors/object/object_edit.c 
b/source/blender/editors/object/object_edit.c
index 75d29c1..4767847 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -2205,13 +2205,17 @@ static int object_widget_add_exec(bContext *C, 
wmOperator *UNUSED(op))
                CTX_data_main(C),
                &(const struct wmWidgetMapType_Params) {"View3D", SPACE_VIEW3D, 
RGN_TYPE_WINDOW, WM_WIDGETMAPTYPE_3D},
                WIDGETGROUP_object_manipulator_poll,
-               WIDGETGROUP_object_manipulator_create,
+               WIDGETGROUP_object_manipulator_init,
+               WIDGETGROUP_manipulator_refresh,
+               WIDGETGROUP_manipulator_draw_prepare,
                WM_widgetgroup_keymap_common,
                "Object Widgets");
 
        /* assign the objects id name to the widget */
        strcpy(wgrouptype->idname, ob->id.name);
 
+       WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+
        return OPERATOR_FINISHED;
 }
 
diff --git a/source/blender/editors/space_graph/graph_edit.c 
b/source/blender/editors/space_graph/graph_edit.c
index f521362..d090c4c 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -2762,26 +2762,35 @@ static int 
graph_widget_backdrop_transform_poll(bContext *C)
                (sipo->backdrop_camera));
 }
 
-static void widgetgroup_backdrop_create(const struct bContext *C, struct 
wmWidgetGroup *wgroup)
+static void widgetgroup_backdrop_init(const bContext *UNUSED(C), wmWidgetGroup 
*wgroup)
 {
-       ARegion *ar = CTX_wm_region(C);
-       wmOperator *op = wgroup->type->op;
-       Scene *scene = CTX_data_scene(C);
-       int width = (scene->r.size * scene->r.xsch) / 150.0f;
-       int height = (scene->r.size * scene->r.ysch) / 150.0f;
-       float origin[3];
+       wmWidgetWrapper *wwrapper = MEM_mallocN(sizeof(wmWidgetWrapper), 
__func__);
+       wgroup->customdata = wwrapper;
 
-       wmWidget *cage = WIDGET_rect_transform_new(
+       wwrapper->widget = WIDGET_rect_transform_new(
                             wgroup, "backdrop_cage",
-                            WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM | 
WIDGET_RECT_TRANSFORM_STYLE_TRANSLATE,
-                            width, height);
-       WM_widget_set_property(cage, RECT_TRANSFORM_SLOT_OFFSET, op->ptr, 
"offset");
-       WM_widget_set_property(cage, RECT_TRANSFORM_SLOT_SCALE, op->ptr, 
"scale");
+                            WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM | 
WIDGET_RECT_TRANSFORM_STYLE_TRANSLATE);
+}
+
+static void widgetgroup_backdrop_refresh(const struct bContext *C, 
wmWidgetGroup *wgroup)
+{
+       wmWidget *cage = ((wmWidgetWrapper *)wgroup->customdata)->widget;
+       ARegion *ar = CTX_wm_region(C);
+       const Scene *scene = CTX_data_scene(C);
+       const int width = (scene->r.size * scene->r.xsch) / 150.0f;
+       const int height = (scene->r.size * scene->r.ysch) / 150.0f;
+       float origin[3];
 
        origin[0] = BLI_rcti_size_x(&ar->winrct) / 2.0f;
        origin[1] = BLI_rcti_size_y(&ar->winrct) / 2.0f;
 
        WM_widget_set_origin(cage, origin);
+       WIDGET_rect_transform_set_dimensions(cage, width, height);
+
+       /* XXX hmmm, can't we do this in _init somehow? Issue is op->ptr is 
freed after OP is done. */
+       wmOperator *op = wgroup->type->op;
+       WM_widget_set_property(cage, RECT_TRANSFORM_SLOT_OFFSET, op->ptr, 
"offset");
+       WM_widget_set_property(cage, RECT_TRANSFORM_SLOT_SCALE, op->ptr, 
"scale");
 }
 
 static wmWidgetGroupType *graph_widget_backdrop_transform_widgets(void)
@@ -2790,7 +2799,10 @@ static wmWidgetGroupType 
*graph_widget_backdrop_transform_widgets(void)
        return WM_widgetgrouptype_register(
                    NULL,
                    &(const struct wmWidgetMapType_Params) {"Graph_Canvas", 
SPACE_IPO, RGN_TYPE_WINDOW, 0},
-                   NULL, widgetgroup_backdrop_create,
+                   NULL,
+                   widgetgroup_backdrop_init,
+                   widgetgroup_backdrop_refresh,
+                   NULL,
                    WM_widgetgroup_keymap_common,
                    "Backdrop Transform Widgets");
 }
@@ -2831,6 +2843,8 @@ static void graph_widget_backdrop_transform_cancel(struct 
bContext *C, struct wm
 
 static int graph_widget_backdrop_transform_modal(bContext *C, wmOperator *op, 
const wmEvent *event)
 {
+       ARegion *ar = CTX_wm_region(C);
+       wmWidgetMap *wmap = ar->widgetmaps.first;
        BackDropTransformData *data = op->customdata;
 
        if (event->type == data->event_type && event->val == KM_PRESS) {
@@ -2849,7 +2863,6 @@ static int graph_widget_backdrop_transform_modal(bContext 
*C, wmOperator *op, co
                case RKEY:
                {
                        SpaceIpo *sipo = CTX_wm_space_graph(C);
-                       ARegion *ar = CTX_wm_region(C);
                        float zero[2] = {0.0f};
                        RNA_float_set_array(op->ptr, "offset", zero);
                        RNA_float_set(op->ptr, "scale", 1.0f);
@@ -2870,8 +2883,6 @@ static int graph_widget_backdrop_transform_modal(bContext 
*C, wmOperator *op, co
                case ESCKEY:
                case RIGHTMOUSE:
                {
-                       ARegion *ar = CTX_wm_region(C);
-                       wmWidgetMap *wmap = ar->widgetmaps.first;
                        SpaceIpo *sipo = CTX_wm_space_graph(C);
 
                        /* only end modal if we're not dragging a widget */
@@ -2884,6 +2895,7 @@ static int graph_widget_backdrop_transform_modal(bContext 
*C, wmOperator *op, co
                        }
                }
        }
+       WM_widgetmap_tag_refresh(wmap);
 
        return OPERATOR_RUNNING_MODAL;
 }
diff --git a/source/blender/editors/space_image/space_image.c 
b/source/blender/editors/space_image/space_image.c
index 62de073..90ab2a9

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to