[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