[Bf-blender-cvs] [bbfd0b9] wiggly-widgets: Use GHash for widget update-draw routine
Julian Eisel
noreply at git.blender.org
Wed Nov 25 13:01:43 CET 2015
Commit: bbfd0b9c179ea04cd73f56c82fa63f1d9e019886
Author: Julian Eisel
Date: Wed Nov 25 12:33:41 2015 +0100
Branches: wiggly-widgets
https://developer.blender.org/rBbbfd0b9c179ea04cd73f56c82fa63f1d9e019886
Use GHash for widget update-draw routine
Helps to avoid some unnecessary loop-in-loops and calling wmWidgetGroupType->poll multiple times without changed context. Did some benchmarks but didn't measure a reliable difference in a scene with Franck rig, subsurf level 2 and 6 face-maps. It should help with some really big scenes though (we have to expect rigs with hundreds of face maps).
===================================================================
M source/blender/editors/space_graph/space_graph.c
M source/blender/editors/space_node/node_draw.c
M source/blender/editors/space_sequencer/sequencer_draw.c
M source/blender/editors/space_sequencer/space_sequencer.c
M source/blender/editors/space_view3d/view3d_draw.c
M source/blender/windowmanager/WM_api.h
M source/blender/windowmanager/intern/wm_widgets.c
===================================================================
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 5c83dbc..0340935 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -361,7 +361,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
/* finally draw any widgets here */
WM_widgets_update(C, ar->widgetmaps.first);
- WM_widgets_draw(C, ar->widgetmaps.first, false);
+ WM_widgets_draw(C, ar->widgetmaps.first, false, true);
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index deb2803..e6e545f 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -1367,7 +1367,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
wmOrtho2_pixelspace(ar->winx, ar->winy);
WM_widgets_update(C, ar->widgetmaps.first);
- WM_widgets_draw(C, ar->widgetmaps.first, false);
+ WM_widgets_draw(C, ar->widgetmaps.first, false, true);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 17d2208..6378f9d 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1651,7 +1651,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* finally draw any widgets here */
WM_widgets_update(C, ar->widgetmaps.first);
- WM_widgets_draw(C, ar->widgetmaps.first, false);
+ WM_widgets_draw(C, ar->widgetmaps.first, false, true);
/* scrollers */
unit = (sseq->flag & SEQ_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDS;
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 05078e3..7af6f77 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -606,7 +606,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
}
WM_widgets_update(C, ar->widgetmaps.first);
- WM_widgets_draw(C, ar->widgetmaps.first, false);
+ WM_widgets_draw(C, ar->widgetmaps.first, false, true);
}
static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index ee3bdec..6554022 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3893,7 +3893,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
* it might be better to have 2 update calls, too */
WM_widgets_update(C, ar->widgetmaps.first);
/* draw depth culled widgets */
- WM_widgets_draw(C, ar->widgetmaps.first, true);
+ WM_widgets_draw(C, ar->widgetmaps.first, true, false);
/* post process */
if (do_compositing) {
@@ -4068,7 +4068,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
if (update_widgets) {
WM_widgets_update(C, ar->widgetmaps.first);
}
- WM_widgets_draw(C, ar->widgetmaps.first, false);
+ WM_widgets_draw(C, ar->widgetmaps.first, false, true);
ED_region_pixelspace(ar);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 969bd6d..e893673 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -511,7 +511,8 @@ struct wmWidget *WM_widget_new(void (*draw)(const struct bContext *, struct wmWi
int (*handler)(struct bContext *, const struct wmEvent *, struct wmWidget *));
void WM_widgets_update(const struct bContext *C, struct wmWidgetMap *wmap);
-void WM_widgets_draw(const struct bContext *C, const struct wmWidgetMap *wmap, const bool in_scene);
+void WM_widgets_draw(const struct bContext *C, const struct wmWidgetMap *wmap,
+ const bool in_scene, const bool free_drawwidgets);
void WM_event_add_area_widgetmap_handlers(struct ARegion *ar);
void WM_modal_handler_attach_widgetgroup(struct bContext *C, struct wmEventHandler *handler,
struct wmWidgetGroupType *wgrouptype, struct wmOperator *op);
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index 0ffd4f1..4cf0dd6 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -98,6 +98,12 @@ typedef struct wmWidgetMapType {
* area type can query the widgetbox to do so */
static ListBase widgetmaptypes = {NULL, NULL};
+/**
+ * Hash table of all visible widgets to avoid unnecessary loops and wmWidgetGroupType->poll checks.
+ * Collected in WM_widgets_update, freed in WM_widgets_draw.
+ */
+static GHash *draw_widgets = NULL;
+
wmWidgetGroupType *WM_widgetgrouptype_new(
int (*poll)(const bContext *C, wmWidgetGroupType *),
@@ -215,10 +221,16 @@ static void wm_widget_data_free(wmWidget *widget)
MEM_freeN(widget->ptr);
}
+/**
+ * Free and NULL \a widget.
+ * \a widgetlist is allowed to be NULL.
+ */
static void wm_widget_delete(ListBase *widgetlist, wmWidget *widget)
{
wm_widget_data_free(widget);
- BLI_freelinkN(widgetlist, widget);
+ if (widgetlist)
+ BLI_remlink(widgetlist, widget);
+ MEM_SAFE_FREE(widget);
}
@@ -276,18 +288,21 @@ void WM_widgets_update(const bContext *C, wmWidgetMap *wmap)
if (!wmap)
return;
+ if (!draw_widgets) {
+ draw_widgets = BLI_ghash_str_new(__func__);
+ }
+
if (widget) {
if ((widget->flag & WM_WIDGET_HIDDEN) == 0) {
widget_calculate_scale(widget, C);
+ BLI_ghash_reinsert(draw_widgets, widget->idname, widget, NULL, NULL);
}
}
else if (wmap->widgetgroups.first) {
- GHash *hash = BLI_ghash_str_new(__func__);
+ wmWidget *highlighted = NULL;
for (wmWidgetGroup *wgroup = wmap->widgetgroups.first; wgroup; wgroup = wgroup->next) {
if (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type)) {
- wmWidget *highlighted = NULL;
-
/* first delete and recreate the widgets */
for (widget = wgroup->widgets.first; widget;) {
wmWidget *widget_next = widget->next;
@@ -313,38 +328,38 @@ void WM_widgets_update(const bContext *C, wmWidgetMap *wmap)
wgroup->type->create(C, wgroup);
}
- if (highlighted) {
- for (widget = wgroup->widgets.first; widget; widget = widget->next) {
- if (widgets_compare(widget, highlighted)) {
- widget_highlight_update(wmap, highlighted, widget);
- wm_widget_delete(&wgroup->widgets, highlighted);
- highlighted = NULL;
- break;
- }
- }
- }
-
- /* if we don't find a highlighted widget, delete the old one here */
- if (highlighted) {
- MEM_freeN(highlighted);
- highlighted = NULL;
- wmap->wmap_context.highlighted_widget = NULL;
- }
-
for (widget = wgroup->widgets.first; widget; widget = widget->next) {
if (widget->flag & WM_WIDGET_HIDDEN)
continue;
+
widget_calculate_scale(widget, C);
/* insert newly created widget into hash table */
- BLI_ghash_insert(hash, widget->idname, widget);
+ BLI_ghash_reinsert(draw_widgets, widget->idname, widget, NULL, NULL);
}
+
+ /* *** From now on, draw_widgets hash table can be used! *** */
+
+ }
+ }
+
+ if (highlighted) {
+ wmWidget *highlighted_new = BLI_ghash_lookup(draw_widgets, highlighted->idname);
+ if (highlighted_new) {
+ BLI_assert(widgets_compare(highlighted, highlighted_new));
+ widget_highlight_update(wmap, highlighted, highlighted_new);
+ wm_widget_delete(NULL, highlighted);
+ }
+ /* if we didn't find a highlighted widget, delete the old one here */
+ else {
+ MEM_SAFE_FREE(highlighted);
+ wmap->wmap_context.highlighted_widget = NULL;
}
}
if (wmap->wmap_context.selected_widgets) {
for (int i = 0; i < wmap->wmap_context.tot_selected; i++) {
wmWidget *sel_old = wmap->wmap_context.selected_widgets[i];
- wmWidget *sel_new = BLI_ghash_lookup(hash, sel_old->idname);
+ wmWidget *sel_new = BLI_ghash_lookup(draw_widgets, sel_old->idname);
/* fails if wgtype->poll state changed */
if (!sel_new)
@@ -363,8 +378,6 @@ void WM_widgets_update(const bContext *C, wmWidgetMap *wmap)
wmap->wmap_context.selected_widgets[i] = sel_new;
}
}
-
- BLI_ghash_free(hash, NULL, NULL);
}
}
@@ -373,7 +386,16 @@ BLI_INLINE bool widgetgroup_poll_check(const bContext *C, const wmWidgetGroup *w
return (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type));
}
-void WM_widgets_draw(const bContext *C, const wmWidgetMap *wmap, const bool in_scene)
+/**
+ * Draw all visible widgets in \a wmap.
+ * Uses global draw_widgets hash table.
+ *
+ * \param in_scene draw depth-culled widgets (wmWidget->flag WM_WIDGET_SCENE_DEPTH) - TODO
+ * \param free_drawwidgets free global draw_widgets hash table (always enable for last draw call in region!).
+ */
+void WM_widgets_draw(
+ const bContext *C, const wmWidgetMap *wmap,
+ const bool in_scene, const bool free_drawwidgets)
{
const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
const bool use_lighting = (U.tw_flag & V3D_SHADED_WIDGETS) != 0;
@@ -406,11 +428,7 @@ void WM_widgets_draw(const bContext *C, const wmWidgetMap *wmap, const bool in_s
wmWidget *widget = wmap->wmap_context.active_widget;
-#define WIDGET_DRAW_POLL(widget_) \
- (in_scene == ((widget_->flag & WM_WIDGET_SCENE_DEPTH) != 0)) && \
- ((widget_->flag & WM_WIDGET_HIDDEN) == 0)
-
- if (widget && WIDGET_DRAW_POLL(widget)) {
+ if (widget && in_scene == (widget->flag & WM_WIDGET_SCENE_DEPTH)) {
if (widget->flag & WM_WIDGET_DRAW_ACTIVE) {
/* notice that we don't update the widgetgroup, widget is now on
* its own, it should have all relevant data to update itself */
@@ -418,16 +436,15 @@ void WM_widgets_draw(const bContext *C, const wmWidgetMap *wmap, const bool in_s
}
}
e
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list