Improve bbt ruler drawing performance for large time ranges.
- when the timeline displays many bars, zoom/autoscroll speed is improved by calculating the bbt ruler scale first then requesting a suitably scaled grid.
This commit is contained in:
parent
208cb967e5
commit
715b178130
@ -2239,10 +2239,8 @@ Editor::set_snap_to (SnapType st)
|
||||
case SnapToBeatDiv4:
|
||||
case SnapToBeatDiv3:
|
||||
case SnapToBeatDiv2: {
|
||||
std::vector<TempoMap::BBTPoint> grid;
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
update_tempo_based_rulers (grid);
|
||||
compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples());
|
||||
update_tempo_based_rulers ();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4614,10 +4612,8 @@ Editor::visual_changer (const VisualChange& vc)
|
||||
|
||||
compute_fixed_ruler_scale ();
|
||||
|
||||
std::vector<TempoMap::BBTPoint> grid;
|
||||
compute_current_bbt_points (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
|
||||
compute_bbt_ruler_scale (grid, vc.time_origin, pending_visual_change.time_origin + current_page_samples());
|
||||
update_tempo_based_rulers (grid);
|
||||
compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples());
|
||||
update_tempo_based_rulers ();
|
||||
|
||||
update_video_timeline();
|
||||
}
|
||||
|
@ -890,7 +890,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
void update_just_timecode ();
|
||||
void compute_fixed_ruler_scale (); //calculates the RulerScale of the fixed rulers
|
||||
void update_fixed_rulers ();
|
||||
void update_tempo_based_rulers (std::vector<ARDOUR::TempoMap::BBTPoint>& grid);
|
||||
void update_tempo_based_rulers ();
|
||||
void popup_ruler_menu (framepos_t where = 0, ItemType type = RegionItem);
|
||||
void update_ruler_visibility ();
|
||||
void set_ruler_visible (RulerType, bool);
|
||||
@ -953,7 +953,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
gint bbt_nmarks;
|
||||
uint32_t bbt_bar_helper_on;
|
||||
uint32_t bbt_accent_modulo;
|
||||
void compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid, framepos_t lower, framepos_t upper);
|
||||
void compute_bbt_ruler_scale (framepos_t lower, framepos_t upper);
|
||||
|
||||
ArdourCanvas::Ruler* timecode_ruler;
|
||||
ArdourCanvas::Ruler* bbt_ruler;
|
||||
|
@ -710,14 +710,12 @@ Editor::update_fixed_rulers ()
|
||||
}
|
||||
|
||||
void
|
||||
Editor::update_tempo_based_rulers (std::vector<TempoMap::BBTPoint>& grid)
|
||||
Editor::update_tempo_based_rulers ()
|
||||
{
|
||||
if (_session == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
compute_bbt_ruler_scale (grid, leftmost_frame, leftmost_frame+current_page_samples());
|
||||
|
||||
_bbt_metric->units_per_pixel = samples_per_pixel;
|
||||
|
||||
if (ruler_bbt_action->get_active()) {
|
||||
@ -1009,7 +1007,7 @@ Editor::metric_get_timecode (std::vector<ArdourCanvas::Ruler::Mark>& marks, gdou
|
||||
}
|
||||
|
||||
void
|
||||
Editor::compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid, framepos_t lower, framepos_t upper)
|
||||
Editor::compute_bbt_ruler_scale (framepos_t lower, framepos_t upper)
|
||||
{
|
||||
if (_session == 0) {
|
||||
return;
|
||||
@ -1107,22 +1105,17 @@ Editor::compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
bbt_beat_subdivision = 4;
|
||||
break;
|
||||
}
|
||||
if (distance (grid.begin(), grid.end()) == 0) {
|
||||
|
||||
const double ceil_upper_beat = floor (max (0.0, _session->tempo_map().beat_at_frame (upper))) + 1.0;
|
||||
if (ceil_upper_beat == floor_lower_beat) {
|
||||
return;
|
||||
}
|
||||
|
||||
i = grid.end();
|
||||
i--;
|
||||
bbt_bars = _session->tempo_map().bbt_at_beat (ceil_upper_beat).bars - _session->tempo_map().bbt_at_beat (floor_lower_beat).bars;
|
||||
|
||||
/* XX ?? */
|
||||
if ((*i).beat >= (*grid.begin()).beat) {
|
||||
bbt_bars = (*i).bar - (*grid.begin()).bar;
|
||||
} else {
|
||||
bbt_bars = (*i).bar - (*grid.begin()).bar;
|
||||
}
|
||||
beats = (ceil_upper_beat - floor_lower_beat) - bbt_bars;
|
||||
double beat_density = ((beats + 1) * ((double) (upper - lower) / (double) (1 + beat_after_upper_pos - beat_before_lower_pos))) / 5.0;
|
||||
|
||||
beats = distance (grid.begin(), grid.end()) - bbt_bars;
|
||||
double beat_density = ((distance (grid.begin(), grid.end()) + 1) * ((double) (upper - lower) / (double) (1 + grid.back().frame - grid.front().frame))) / 5.0;
|
||||
/* Only show the bar helper if there aren't many bars on the screen */
|
||||
if ((bbt_bars < 2) || (beats < 5)) {
|
||||
bbt_bar_helper_on = true;
|
||||
|
@ -166,11 +166,14 @@ Editor::tempo_map_changed (const PropertyChange& /*ignored*/)
|
||||
tempo_lines->tempo_map_changed();
|
||||
}
|
||||
|
||||
compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples());
|
||||
std::vector<TempoMap::BBTPoint> grid;
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
if (bbt_ruler_scale != bbt_show_many) {
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
}
|
||||
_session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers
|
||||
draw_measures (grid);
|
||||
update_tempo_based_rulers (grid);
|
||||
update_tempo_based_rulers ();
|
||||
}
|
||||
|
||||
struct CurveComparator {
|
||||
@ -249,10 +252,15 @@ Editor::marker_position_changed ()
|
||||
}
|
||||
}
|
||||
|
||||
compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples());
|
||||
std::vector<TempoMap::BBTPoint> grid;
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
|
||||
if (bbt_ruler_scale != bbt_show_many) {
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
}
|
||||
|
||||
draw_measures (grid);
|
||||
update_tempo_based_rulers (grid);
|
||||
update_tempo_based_rulers ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -263,11 +271,15 @@ Editor::redisplay_tempo (bool immediate_redraw)
|
||||
}
|
||||
|
||||
if (immediate_redraw) {
|
||||
compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples());
|
||||
std::vector<TempoMap::BBTPoint> grid;
|
||||
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
if (bbt_ruler_scale != bbt_show_many) {
|
||||
compute_current_bbt_points (grid, leftmost_frame, leftmost_frame + current_page_samples());
|
||||
}
|
||||
|
||||
draw_measures (grid);
|
||||
update_tempo_based_rulers (grid); // redraw rulers and measure lines
|
||||
update_tempo_based_rulers (); // redraw rulers and measure lines
|
||||
|
||||
} else {
|
||||
Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::mem_fun (*this, &Editor::redisplay_tempo), true), false));
|
||||
@ -285,7 +297,36 @@ Editor::compute_current_bbt_points (std::vector<TempoMap::BBTPoint>& grid, frame
|
||||
/* prevent negative values of leftmost from creeping into tempomap
|
||||
*/
|
||||
const double lower_beat = floor (max (0.0, _session->tempo_map().beat_at_frame (leftmost))) - 1.0;
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost);
|
||||
switch (bbt_ruler_scale) {
|
||||
|
||||
case bbt_show_beats:
|
||||
case bbt_show_ticks:
|
||||
case bbt_show_ticks_detail:
|
||||
case bbt_show_ticks_super_detail:
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost);
|
||||
break;
|
||||
|
||||
case bbt_show_1:
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost, 1);
|
||||
break;
|
||||
|
||||
case bbt_show_4:
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost, 4);
|
||||
break;
|
||||
|
||||
case bbt_show_16:
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost, 16);
|
||||
break;
|
||||
|
||||
case bbt_show_64:
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost, 64);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* bbt_show_many */
|
||||
_session->tempo_map().get_grid (grid, max (_session->tempo_map().frame_at_beat (lower_beat), (framepos_t) 0), rightmost, 128);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -110,9 +110,22 @@ TempoLines::draw (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
i = grid.end();
|
||||
i--;
|
||||
bars = (*i).bar - (*grid.begin()).bar;
|
||||
beats = distance (grid.begin(), grid.end()) - bars;
|
||||
|
||||
beat_density = (beats * 10.0f) / lines.canvas()->width();
|
||||
if (bars < distance (grid.begin(), grid.end()) - 1) {
|
||||
/* grid contains beats and bars */
|
||||
beats = distance (grid.begin(), grid.end()) - bars;
|
||||
} else {
|
||||
/* grid contains only bars */
|
||||
beats = distance (grid.begin(), grid.end());
|
||||
}
|
||||
|
||||
double canvas_width_used = 1.0;
|
||||
if (leftmost_frame < grid.front().frame) {
|
||||
const framecnt_t frame_distance = max ((framecnt_t) 1, grid.back().frame - grid.front().frame);
|
||||
canvas_width_used = 1.0 - ((grid.front().frame - leftmost_frame) / (double) (frame_distance + grid.front().frame));
|
||||
}
|
||||
|
||||
beat_density = (beats * 10.0f) / (lines.canvas()->width() * canvas_width_used);
|
||||
|
||||
if (beat_density > 2.0f) {
|
||||
/* if the lines are too close together, they become useless */
|
||||
|
@ -324,7 +324,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||
}
|
||||
|
||||
void get_grid (std::vector<BBTPoint>&,
|
||||
framepos_t start, framepos_t end);
|
||||
framepos_t start, framepos_t end, uint32_t bar_mod = 0);
|
||||
|
||||
static const Tempo& default_tempo() { return _default_tempo; }
|
||||
static const Meter& default_meter() { return _default_meter; }
|
||||
|
@ -3500,7 +3500,7 @@ TempoMap::round_to_type (framepos_t frame, RoundMode dir, BBTPointType type)
|
||||
|
||||
void
|
||||
TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
|
||||
framepos_t lower, framepos_t upper)
|
||||
framepos_t lower, framepos_t upper, uint32_t bar_mod)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
int32_t cnt = ceil (beat_at_frame_locked (_metrics, lower));
|
||||
@ -3513,14 +3513,32 @@ TempoMap::get_grid (vector<TempoMap::BBTPoint>& points,
|
||||
if (frame_at_beat_locked (_metrics, cnt) >= upper) {
|
||||
return;
|
||||
}
|
||||
if (bar_mod == 0) {
|
||||
while (pos >= 0 && pos < upper) {
|
||||
pos = frame_at_beat_locked (_metrics, cnt);
|
||||
const TempoSection tempo = tempo_section_at_frame_locked (_metrics, pos);
|
||||
const MeterSection meter = meter_section_at_frame_locked (_metrics, pos);
|
||||
const BBT_Time bbt = bbt_at_beat_locked (_metrics, cnt);
|
||||
points.push_back (BBTPoint (meter, tempo_at_frame_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func()));
|
||||
++cnt;
|
||||
}
|
||||
} else {
|
||||
BBT_Time bbt = bbt_at_frame_locked (_metrics, lower);
|
||||
bbt.beats = 1;
|
||||
bbt.ticks = 0;
|
||||
|
||||
while (pos >= 0 && pos < upper) {
|
||||
pos = frame_at_beat_locked (_metrics, cnt);
|
||||
const TempoSection tempo = tempo_section_at_frame_locked (_metrics, pos);
|
||||
const MeterSection meter = meter_section_at_frame_locked (_metrics, pos);
|
||||
const BBT_Time bbt = bbt_at_beat_locked (_metrics, cnt);
|
||||
points.push_back (BBTPoint (meter, tempo_at_frame_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func()));
|
||||
++cnt;
|
||||
if (bar_mod != 1) {
|
||||
bbt.bars -= bbt.bars % bar_mod;
|
||||
++bbt.bars;
|
||||
}
|
||||
|
||||
while (pos >= 0 && pos < upper) {
|
||||
pos = frame_at_bbt_locked (_metrics, bbt);
|
||||
const TempoSection tempo = tempo_section_at_frame_locked (_metrics, pos);
|
||||
const MeterSection meter = meter_section_at_frame_locked (_metrics, pos);
|
||||
points.push_back (BBTPoint (meter, tempo_at_frame_locked (_metrics, pos), pos, bbt.bars, bbt.beats, tempo.c_func()));
|
||||
bbt.bars += bar_mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user