From 0d87dc5d6af056bb6b70631f852ec3f9f9f78be1 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Sat, 1 Jul 2023 10:56:05 +0100 Subject: [PATCH] perf: predetermine history trail draw function On every render, we were checking the fields to determine the type of dot we are rendering. However, we don't need to do this, as the dot type can only change as part of an ASR load or configuration menu change. This change saves the draw function as a lambda when something changes, allowing us to reduce the render time by approximately 25% - went from 12ms to 8ms in testing. --- .../historytrail/HistoryTrailRenderer.cpp | 115 +++++++++++------- .../historytrail/HistoryTrailRenderer.h | 13 +- 2 files changed, 77 insertions(+), 51 deletions(-) diff --git a/src/plugin/historytrail/HistoryTrailRenderer.cpp b/src/plugin/historytrail/HistoryTrailRenderer.cpp index 8ab341ca3..f6be8f641 100644 --- a/src/plugin/historytrail/HistoryTrailRenderer.cpp +++ b/src/plugin/historytrail/HistoryTrailRenderer.cpp @@ -57,6 +57,9 @@ namespace UKControllerPlugin { userSetting.GetIntegerEntry(this->maxAltitudeFilterUserSettingKey, this->defaultMaxAltitude); this->filledDots = userSetting.GetBooleanEntry(this->dotFillUserSettingKey, false); this->rotatedDots = userSetting.GetBooleanEntry(this->dotRotateUserSettingKey, false); + + // Load the dot drawing function + this->drawDot = this->GetDrawDotFunction(); } /* @@ -136,51 +139,6 @@ namespace UKControllerPlugin { return this->antialiasedTrails; } - /* - Draws a single dot to the screen. - */ - void - HistoryTrailRenderer::DrawDot(GdiGraphicsInterface& graphics, Gdiplus::Pen& pen, const Gdiplus::RectF& area) - { - if (this->historyTrailType == this->trailTypeDiamond) { - graphics.DrawDiamond(area, pen); - } else if (this->historyTrailType == this->trailTypeCircle) { - graphics.DrawCircle(area, pen); - } else if (this->historyTrailType == this->trailTypeLine) { - graphics.DrawLine( - pen, - Gdiplus::PointF{area.GetLeft(), area.GetBottom()}, - Gdiplus::PointF{area.GetRight(), area.GetTop()}); - } else { - graphics.DrawRect(area, pen); - } - } - - /* - Fills a single dot to the screen. - */ - void - HistoryTrailRenderer::FillDot(GdiGraphicsInterface& graphics, Gdiplus::Brush& brush, const Gdiplus::RectF& area) - { - if (this->historyTrailType == this->trailTypeDiamond) { - graphics.FillDiamond(area, brush); - } else if (this->historyTrailType == this->trailTypeCircle) { - graphics.FillCircle(area, brush); - } else { - graphics.FillRect(area, brush); - } - } - - void HistoryTrailRenderer::DoDot(GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) - { - // Draw the dot - if (this->filledDots && this->historyTrailType != this->trailTypeLine) { - this->FillDot(graphics, *this->brush, area); - } else { - this->DrawDot(graphics, *this->pen, area); - } - } - /* Returns the configuration menu item. */ @@ -372,9 +330,9 @@ namespace UKControllerPlugin { if (this->rotatedDots) { graphics.Rotated( static_cast(position->heading), - [&graphics, &dot, this]() { this->DoDot(graphics, dot); }); + [&graphics, &dot, this]() { this->drawDot(graphics, dot); }); } else { - this->DoDot(graphics, dot); + this->drawDot(graphics, dot); } }); @@ -405,5 +363,68 @@ namespace UKControllerPlugin { void HistoryTrailRenderer::ResetPosition(void) { } + + auto HistoryTrailRenderer::GetDoDotFunction() const + -> std::function + { + return this->filledDots && this->historyTrailType != this->trailTypeLine ? this->GetFillDotFunction() + : this->GetDrawDotFunction(); + } + + auto HistoryTrailRenderer::GetDrawDotFunction() const + -> std::function + { + // Diamonds + if (this->historyTrailType == this->trailTypeDiamond) { + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.DrawDiamond(area, *this->pen); + }; + } + + // Circles + if (this->historyTrailType == this->trailTypeCircle) { + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.DrawCircle(area, *this->pen); + }; + } + + // Lines + if (this->historyTrailType == this->trailTypeLine) { + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.DrawLine( + *this->pen, + Gdiplus::PointF{area.GetLeft(), area.GetBottom()}, + Gdiplus::PointF{area.GetRight(), area.GetTop()}); + }; + } + + // Rectangles + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.DrawRect(area, *this->pen); + }; + } + + auto HistoryTrailRenderer::GetFillDotFunction() const + -> std::function + { + // Diamonds + if (this->historyTrailType == this->trailTypeDiamond) { + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.FillDiamond(area, *this->brush); + }; + } + + // Circles + if (this->historyTrailType == this->trailTypeCircle) { + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.FillCircle(area, *this->brush); + }; + } + + // Rects + return [this](Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area) { + graphics.FillRect(area, *this->brush); + }; + } } // namespace HistoryTrail } // namespace UKControllerPlugin diff --git a/src/plugin/historytrail/HistoryTrailRenderer.h b/src/plugin/historytrail/HistoryTrailRenderer.h index 39152b083..ec7ce2142 100644 --- a/src/plugin/historytrail/HistoryTrailRenderer.h +++ b/src/plugin/historytrail/HistoryTrailRenderer.h @@ -158,10 +158,12 @@ namespace UKControllerPlugin { const int defaultMaxAltitude = 99999; private: - void DrawDot(Windows::GdiGraphicsInterface& graphics, Gdiplus::Pen& pen, const Gdiplus::RectF& area); - - void FillDot(Windows::GdiGraphicsInterface& graphics, Gdiplus::Brush& brush, const Gdiplus::RectF& area); - void DoDot(Windows::GdiGraphicsInterface& graphics, const Gdiplus::RectF& area); + [[nodiscard]] auto GetDoDotFunction() const + -> std::function; + [[nodiscard]] auto GetFillDotFunction() const + -> std::function; + [[nodiscard]] auto GetDrawDotFunction() const + -> std::function; // Handles dialogs const Dialog::DialogManager& dialogManager; @@ -222,6 +224,9 @@ namespace UKControllerPlugin { // The dot command for opening the configuration modal. const std::string dotCommand = ".ukcp h"; + + // Function for drawing the dot - saved as a lambda so we dont have to keep checking the trail type + std::function drawDot; }; } // namespace HistoryTrail } // namespace UKControllerPlugin