1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-01 07:33:44 +02:00

Rewrite the quick exit test in OverlayPanel::DrawOverlays

This commit is contained in:
Paul Licameli 2019-01-23 20:41:00 -05:00
parent 4dbe88df26
commit a73970d864

View File

@ -41,7 +41,8 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
{
size_t n_pairs = mOverlays.size();
std::vector< std::pair<wxRect, bool /*out of date?*/> > pairs;
using Pair = std::pair<wxRect, bool /*out of date?*/>;
std::vector< Pair > pairs;
pairs.reserve(n_pairs);
// Find out the rectangles and outdatedness for each overlay
@ -55,13 +56,28 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
// By redrawing only what needs it, we avoid flashing things like
// the cursor that are drawn with invert, and also avoid
// unnecessary work.
bool some_overlays_need_repainting = repaint_all;
// But first, a quick exit test.
bool some_overlays_need_repainting =
repaint_all ||
std::any_of( pairs.begin(), pairs.end(),
[]( const Pair &pair ){ return pair.second; } );
if (!some_overlays_need_repainting) {
// This function (OverlayPanel::DrawOverlays()) is called at
// fairly high frequency through a timer in TrackPanel. In case
// there is nothing to do, we exit early because creating the
// wxClientDC below is expensive, at least on Linux.
return;
}
if (!repaint_all) {
// For each overlay that needs update, any other overlay whose
// rectangle instersects it will also need update.
bool done;
do {
done = true;
for (size_t ii = 0; ii < n_pairs; ++ii) {
some_overlays_need_repainting |= pairs[ii].second;
for (size_t ii = 0; ii < n_pairs - 1; ++ii) {
for (size_t jj = ii + 1; jj < n_pairs; ++jj) {
if (pairs[ii].second != pairs[jj].second &&
pairs[ii].first.Intersects(pairs[jj].first)) {
@ -73,40 +89,27 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
} while (!done);
}
if (!some_overlays_need_repainting) {
// This function (OverlayPanel::DrawOverlays()) is called at
// fairly high frequency through a timer in TrackPanel. In case
// there is nothing to do, we exit early because creating the
// wxClientDC below is expensive, at least on Linux.
return;
}
Maybe<wxClientDC> myDC;
auto &dc = pDC ? *pDC : (myDC.create(this), *myDC);
// Erase
bool done = true;
auto it2 = pairs.begin();
for (auto pOverlay : mOverlays) {
if (repaint_all || it2->second) {
done = false;
if (repaint_all || it2->second)
pOverlay->Erase(dc, GetBackingDC());
}
++it2;
}
// Draw
if (!done) {
it2 = pairs.begin();
for (auto pOverlay : mOverlays) {
if (repaint_all || it2->second) {
// Guarantee a clean state of the dc each pass:
ADCChanger changer{ &dc };
it2 = pairs.begin();
for (auto pOverlay : mOverlays) {
if (repaint_all || it2->second) {
// Guarantee a clean state of the dc each pass:
ADCChanger changer{ &dc };
pOverlay->Draw(*this, dc);
}
++it2;
pOverlay->Draw(*this, dc);
}
++it2;
}
}