1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-12-26 14:41:14 +01:00

Merge pull request #148 from RaphaelMarinier/optimize_audacity_idle_loops_no_autoreconf

Reduced CPU usage of Audacity when idle.
This commit is contained in:
James Crook
2016-07-21 23:03:00 +01:00
committed by GitHub
2 changed files with 26 additions and 10 deletions

View File

@@ -37,11 +37,11 @@ void OverlayPanel::ClearOverlays()
mOverlays.clear(); mOverlays.clear();
} }
void OverlayPanel::DrawOverlays(bool repaint, wxDC *pDC) void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
{ {
size_t n_pairs = mOverlays.size(); size_t n_pairs = mOverlays.size();
std::vector< std::pair<wxRect, bool> > pairs; std::vector< std::pair<wxRect, bool /*out of date?*/> > pairs;
pairs.reserve(n_pairs); pairs.reserve(n_pairs);
// Find out the rectangles and outdatedness for each overlay // Find out the rectangles and outdatedness for each overlay
@@ -53,12 +53,15 @@ void OverlayPanel::DrawOverlays(bool repaint, wxDC *pDC)
// If not, then whatever is outdated, and whatever will be damaged by // If not, then whatever is outdated, and whatever will be damaged by
// undrawing. // undrawing.
// By redrawing only what needs it, we avoid flashing things like // By redrawing only what needs it, we avoid flashing things like
// the cursor that are drawn with invert. // the cursor that are drawn with invert, and also avoid
if (!repaint) { // unnecessary work.
bool some_overlays_need_repainting = repaint_all;
if (!repaint_all) {
bool done; bool done;
do { do {
done = true; done = true;
for (size_t ii = 0; ii < n_pairs; ++ii) { for (size_t ii = 0; ii < n_pairs; ++ii) {
some_overlays_need_repainting |= pairs[ii].second;
for (size_t jj = ii + 1; jj < n_pairs; ++jj) { for (size_t jj = ii + 1; jj < n_pairs; ++jj) {
if (pairs[ii].second != pairs[jj].second && if (pairs[ii].second != pairs[jj].second &&
pairs[ii].first.Intersects(pairs[jj].first)) { pairs[ii].first.Intersects(pairs[jj].first)) {
@@ -70,6 +73,14 @@ void OverlayPanel::DrawOverlays(bool repaint, wxDC *pDC)
} while (!done); } 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; Maybe<wxClientDC> myDC;
auto &dc = pDC ? *pDC : (myDC.create(this), *myDC); auto &dc = pDC ? *pDC : (myDC.create(this), *myDC);
@@ -77,7 +88,7 @@ void OverlayPanel::DrawOverlays(bool repaint, wxDC *pDC)
bool done = true; bool done = true;
auto it2 = pairs.begin(); auto it2 = pairs.begin();
for (auto pOverlay : mOverlays) { for (auto pOverlay : mOverlays) {
if (repaint || it2->second) { if (repaint_all || it2->second) {
done = false; done = false;
pOverlay->Erase(dc, GetBackingDC()); pOverlay->Erase(dc, GetBackingDC());
} }
@@ -88,7 +99,7 @@ void OverlayPanel::DrawOverlays(bool repaint, wxDC *pDC)
if (!done) { if (!done) {
it2 = pairs.begin(); it2 = pairs.begin();
for (auto pOverlay : mOverlays) { for (auto pOverlay : mOverlays) {
if (repaint || it2->second) { if (repaint_all || it2->second) {
// Guarantee a clean state of the dc each pass: // Guarantee a clean state of the dc each pass:
ADCChanger changer{ &dc }; ADCChanger changer{ &dc };

View File

@@ -22,7 +22,7 @@ public:
// default as for wxPanel: // default as for wxPanel:
long style = wxTAB_TRAVERSAL | wxNO_BORDER); long style = wxTAB_TRAVERSAL | wxNO_BORDER);
// Register and unregister overlay objects. // Registers and unregisters overlay objects.
// The sequence in which they were registered is the sequence in // The sequence in which they were registered is the sequence in
// which they are painted. // which they are painted.
// OverlayPanel is not responsible for their memory management. // OverlayPanel is not responsible for their memory management.
@@ -31,9 +31,14 @@ public:
bool RemoveOverlay(Overlay *pOverlay); bool RemoveOverlay(Overlay *pOverlay);
void ClearOverlays(); void ClearOverlays();
// Erase and redraw things like the cursor, cheaply and directly to the // Erases and redraws to the client area the overlays that have
// client area, without full refresh. // been previously added with AddOverlay(). If "repaint_all" is
void DrawOverlays(bool repaint, wxDC *pDC = nullptr); // true, all overlays will be erased and re-drawn. Otherwise, only
// the ones that are out-of-date, as well as the intersecting ones,
// will be erased and re-drawn.
// pDC can be null, in which case, DrawOverlays() will create a
// wxClientDC internally when necessary.
void DrawOverlays(bool repaint_all, wxDC *pDC = nullptr);
private: private:
std::vector<Overlay*> mOverlays; std::vector<Overlay*> mOverlays;