summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authornick_m <mainsbridge@gmail.com>2016-12-20 21:31:54 +1100
committernick_m <mainsbridge@gmail.com>2016-12-20 21:31:54 +1100
commit9038be49d821f89824c83cf505d51366eb2828c6 (patch)
treead4cf1bef6f04ea66b65166524c12e2f93d17762 /gtk2_ardour
parentba970cc191bf3b2f477bc13c3ffe090f6c2955e7 (diff)
improve midi zoom/scroom performance with lots of notes.
- mostly due to searching a multiset rather than a list of canvas events.
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/midi_region_view.cc92
1 files changed, 43 insertions, 49 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 376ae0197f..ecc39dde6b 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -1186,74 +1186,68 @@ MidiRegionView::redisplay_model()
return;
}
- for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
- (*i)->invalidate ();
- }
-
- MidiModel::ReadLock lock(_model->read_lock());
-
- MidiModel::Notes& notes (_model->notes());
- _optimization_iterator = _events.begin();
-
bool empty_when_starting = _events.empty();
- NoteBase* cne;
-
- for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) {
+ MidiModel::ReadLock lock(_model->read_lock());
+ MidiModel::Notes missing_notes = _model->notes(); // copy
- boost::shared_ptr<NoteType> note (*n);
- bool visible;
+ if (!empty_when_starting) {
+ for (Events::iterator i = _events.begin(); i != _events.end(); ) {
+ boost::shared_ptr<NoteType> note ((*i)->note());
+ /* remove note items that are no longer valid */
+ if (!(*i)->valid () || !_model->find_note (note)) {
- if (note_in_region_range (note, visible)) {
+ for (vector<GhostRegion*>::iterator j = ghosts.begin(); j != ghosts.end(); ++j) {
+ MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*j);
+ if (gr) {
+ gr->remove_note (*i);
+ }
+ }
- if (!empty_when_starting && (cne = find_canvas_note (note)) != 0) {
+ delete *i;
+ i = _events.erase (i);
- if (visible) {
- cne->validate ();
- update_note (cne);
- cne->show ();
+ } else {
+ MidiModel::Notes::iterator f;
+ NoteBase* cne = (*i);
+ bool visible;
+
+ if (note_in_region_range (note, visible)) {
+ if (visible) {
+ update_note (cne);
+ cne->show ();
+ } else {
+ cne->hide ();
+ }
} else {
cne->hide ();
}
- } else {
-
- cne = add_note (note, visible);
- }
-
- set<Evoral::event_id_t>::iterator it;
- for (it = _pending_note_selection.begin(); it != _pending_note_selection.end(); ++it) {
- if ((*it) == note->id()) {
- add_to_selection (cne);
+ if ((f = missing_notes.find (note)) != missing_notes.end()) {
+ missing_notes.erase (f);
}
- }
-
- } else {
- if (!empty_when_starting && (cne = find_canvas_note (note)) != 0) {
- cne->validate ();
- cne->hide ();
+ ++i;
}
+
}
}
- /* remove note items that are no longer valid */
+ NoteBase* cne;
- if (!empty_when_starting) {
- for (Events::iterator i = _events.begin(); i != _events.end(); ) {
- if (!(*i)->valid ()) {
+ for (MidiModel::Notes::iterator n = missing_notes.begin(); n != missing_notes.end(); ++n) {
+ boost::shared_ptr<NoteType> note (*n);
+ bool visible;
- for (vector<GhostRegion*>::iterator j = ghosts.begin(); j != ghosts.end(); ++j) {
- MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*j);
- if (gr) {
- gr->remove_note (*i);
+ if (note_in_region_range (note, visible)) {
+ if (visible) {
+ cne = add_note (note, true);
+ set<Evoral::event_id_t>::iterator it;
+
+ for (it = _pending_note_selection.begin(); it != _pending_note_selection.end(); ++it) {
+ if ((*it) == note->id()) {
+ add_to_selection (cne);
}
}
-
- delete *i;
- i = _events.erase (i);
-
- } else {
- ++i;
}
}
}