From 9038be49d821f89824c83cf505d51366eb2828c6 Mon Sep 17 00:00:00 2001 From: nick_m Date: Tue, 20 Dec 2016 21:31:54 +1100 Subject: improve midi zoom/scroom performance with lots of notes. - mostly due to searching a multiset rather than a list of canvas events. --- gtk2_ardour/midi_region_view.cc | 92 +++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 49 deletions(-) (limited to 'gtk2_ardour') 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 note (*n); - bool visible; + if (!empty_when_starting) { + for (Events::iterator i = _events.begin(); i != _events.end(); ) { + boost::shared_ptr 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::iterator j = ghosts.begin(); j != ghosts.end(); ++j) { + MidiGhostRegion* gr = dynamic_cast (*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::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 note (*n); + bool visible; - for (vector::iterator j = ghosts.begin(); j != ghosts.end(); ++j) { - MidiGhostRegion* gr = dynamic_cast (*j); - if (gr) { - gr->remove_note (*i); + if (note_in_region_range (note, visible)) { + if (visible) { + cne = add_note (note, true); + set::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; } } } -- cgit v1.2.3