[Bf-blender-cvs] [d1efaad] wiggly-widgets: Rewrite Widget Update->Draw Routine (Massive Performance Boost)

Julian Eisel noreply at git.blender.org
Wed May 18 17:50:51 CEST 2016


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. @@




More information about the Bf-blender-cvs mailing list