From 4a8055f9f3667d862403d7398c83da1ee93fb8e2 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 7 Sep 2014 20:23:22 +0200 Subject: [PATCH] don't loose a redraw. This more or less obsoletes the DisplaySuspender. While RAII is nice, the DisplaySuspender cannot be used from outside gtk2_ardour eg Mute/Solo signals notifications from libardour (which don't originate from the GUI). The DisplaySuspender is still useful, because it explicitly disables re-display and forces a single expose at the end. Conflicts: gtk2_ardour/editor_routes.cc gtk2_ardour/editor_routes.h --- gtk2_ardour/editor_routes.cc | 146 +++++++++++++++++++---------------- gtk2_ardour/editor_routes.h | 10 ++- 2 files changed, 88 insertions(+), 68 deletions(-) diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index f1260fb258..55385a9607 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -74,6 +74,8 @@ EditorRoutes::EditorRoutes (Editor* e) , _no_redisplay (false) , _adding_routes (false) , _route_deletion_in_progress (false) + , _redisplay_active (0) + , _queue_tv_update (0) , _menu (0) , old_focus (0) , selection_countdown (0) @@ -494,21 +496,18 @@ EditorRoutes::show_menu () } void -EditorRoutes::redisplay () +EditorRoutes::redisplay_real () { - if (_no_redisplay || !_session || _session->deletion_in_progress()) { - return; - } - TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; uint32_t position; /* n will be the count of tracks plus children (updated by TimeAxisView::show_at), - so we will use that to know where to put things. - */ + * so we will use that to know where to put things. + */ int n; - uint32_t number_label = 1; + uint32_t number_label = 1; + for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) { TimeAxisView *tv = (*i)[_columns.tv]; boost::shared_ptr route = (*i)[_columns.route]; @@ -548,25 +547,47 @@ EditorRoutes::redisplay () } /* whenever we go idle, update the track view list to reflect the new order. - we can't do this here, because we could mess up something that is traversing - the track order and has caused a redisplay of the list. - */ + * we can't do this here, because we could mess up something that is traversing + * the track order and has caused a redisplay of the list. + */ Glib::signal_idle().connect (sigc::mem_fun (*_editor, &Editor::sync_track_view_list_and_routes)); - _editor->reset_controls_layout_height (position); - _editor->reset_controls_layout_width (); + _editor->reset_controls_layout_height (position); + _editor->reset_controls_layout_width (); _editor->_full_canvas_height = position; if ((_editor->vertical_adjustment.get_value() + _editor->_visible_canvas_height) > _editor->vertical_adjustment.get_upper()) { /* - We're increasing the size of the canvas while the bottom is visible. - We scroll down to keep in step with the controls layout. - */ + * We're increasing the size of the canvas while the bottom is visible. + * We scroll down to keep in step with the controls layout. + */ _editor->vertical_adjustment.set_value (_editor->_full_canvas_height - _editor->_visible_canvas_height); } ProgressDialog::instance()->add_progress_step (); } +void +EditorRoutes::redisplay () +{ + if (_no_redisplay || !_session || _session->deletion_in_progress()) { + return; + } + + // model deprecated g_atomic_int_exchange_and_add(, 1) + g_atomic_int_inc(&_redisplay_active); + if (!g_atomic_int_compare_and_exchange (&_redisplay_active, 1, 1)) { + printf ("SKIP redisplay\n"); + return; + } + + redisplay_real (); + + while (!g_atomic_int_compare_and_exchange (&_redisplay_active, 1, 0)) { + g_atomic_int_set(&_redisplay_active, 1); + redisplay_real (); + } +} + void EditorRoutes::row_deleted (Gtk::TreeModel::Path const &) { @@ -805,12 +826,8 @@ EditorRoutes::route_property_changed (const PropertyChange& what_changed, boost: void EditorRoutes::update_active_display () { - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator i; - - for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[_columns.route]; - (*i)[_columns.active] = route->active (); + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } @@ -1663,77 +1680,76 @@ EditorRoutes::update_input_active_display () void EditorRoutes::update_rec_display () { - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator i; - - for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[_columns.route]; - - if (boost::dynamic_pointer_cast (route)) { - boost::shared_ptr mt = boost::dynamic_pointer_cast (route); - - if (route->record_enabled()) { - if (_session->record_status() == Session::Recording) { - (*i)[_columns.rec_state] = 1; - } else { - (*i)[_columns.rec_state] = 2; - } - } else if (mt && mt->step_editing()) { - (*i)[_columns.rec_state] = 3; - } else { - (*i)[_columns.rec_state] = 0; - } - - (*i)[_columns.name_editable] = !route->record_enabled (); - } + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } -void -EditorRoutes::update_mute_display () +bool +EditorRoutes::idle_update_mute_rec_solo_etc() { + g_atomic_int_set (&_queue_tv_update, 0); TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; for (i = rows.begin(); i != rows.end(); ++i) { boost::shared_ptr route = (*i)[_columns.route]; (*i)[_columns.mute_state] = RouteUI::mute_active_state (_session, route); + (*i)[_columns.solo_state] = RouteUI::solo_active_state (route); + (*i)[_columns.solo_isolate_state] = RouteUI::solo_isolate_active_state (route) ? 1 : 0; + (*i)[_columns.solo_safe_state] = RouteUI::solo_safe_active_state (route) ? 1 : 0; + (*i)[_columns.active] = route->active (); + { + if (boost::dynamic_pointer_cast (route)) { + boost::shared_ptr mt = boost::dynamic_pointer_cast (route); + + if (route->record_enabled()) { + if (_session->record_status() == Session::Recording) { + (*i)[_columns.rec_state] = 1; + } else { + (*i)[_columns.rec_state] = 2; + } + } else if (mt && mt->step_editing()) { + (*i)[_columns.rec_state] = 3; + } else { + (*i)[_columns.rec_state] = 0; + } + + (*i)[_columns.name_editable] = !route->record_enabled (); + } + } + } +} + +void +EditorRoutes::update_mute_display () +{ + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } void EditorRoutes::update_solo_display (bool /* selfsoloed */) { - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator i; - - for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[_columns.route]; - (*i)[_columns.solo_state] = RouteUI::solo_active_state (route); + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } void EditorRoutes::update_solo_isolate_display () { - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator i; - - for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[_columns.route]; - (*i)[_columns.solo_isolate_state] = RouteUI::solo_isolate_active_state (route) ? 1 : 0; + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } void EditorRoutes::update_solo_safe_display () { - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator i; - - for (i = rows.begin(); i != rows.end(); ++i) { - boost::shared_ptr route = (*i)[_columns.route]; - (*i)[_columns.solo_safe_state] = RouteUI::solo_safe_active_state (route) ? 1 : 0; + if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) { + Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc)); } } diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h index 08928b1e54..7b6d2be703 100644 --- a/gtk2_ardour/editor_routes.h +++ b/gtk2_ardour/editor_routes.h @@ -62,6 +62,7 @@ public: private: void initial_display (); + void redisplay_real (); void on_input_active_changed (std::string const &); void on_tv_rec_enable_changed (std::string const &); void on_tv_mute_enable_toggled (std::string const &); @@ -78,6 +79,7 @@ private: bool button_press (GdkEventButton *); void route_property_changed (const PBD::PropertyChange&, boost::weak_ptr); void handle_gui_changes (std::string const &, void *); + bool idle_update_mute_rec_solo_etc (); void update_rec_display (); void update_mute_display (); void update_solo_display (bool); @@ -159,9 +161,11 @@ private: bool _ignore_reorder; bool _no_redisplay; - bool _adding_routes; - bool _route_deletion_in_progress; - boost::shared_ptr _route_is_being_deleted; + bool _adding_routes; + bool _route_deletion_in_progress; + boost::shared_ptr _route_is_being_deleted; + volatile gint _redisplay_active; + volatile gint _queue_tv_update; Gtk::Menu* _menu; Gtk::Widget* old_focus;