mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 10:20:04 +00:00 
			
		
		
		
	Merge pull request #397 from AdenKoperczak/speed_up_geolines
Speed up geolines by avoiding iterative finds
This commit is contained in:
		
						commit
						e641c0b0e5
					
				
					 3 changed files with 55 additions and 52 deletions
				
			
		|  | @ -50,6 +50,7 @@ struct GeoLineDrawItem : types::EventHandler | ||||||
|    units::angle::degrees<float> angle_ {}; |    units::angle::degrees<float> angle_ {}; | ||||||
|    std::string                  hoverText_ {}; |    std::string                  hoverText_ {}; | ||||||
|    GeoLines::HoverCallback      hoverCallback_ {nullptr}; |    GeoLines::HoverCallback      hoverCallback_ {nullptr}; | ||||||
|  |    size_t                       lineIndex_ {0}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class GeoLines::Impl | class GeoLines::Impl | ||||||
|  | @ -87,10 +88,10 @@ public: | ||||||
|    void UpdateBuffers(); |    void UpdateBuffers(); | ||||||
|    void UpdateModifiedLineBuffers(); |    void UpdateModifiedLineBuffers(); | ||||||
|    void UpdateSingleBuffer(const std::shared_ptr<GeoLineDrawItem>& di, |    void UpdateSingleBuffer(const std::shared_ptr<GeoLineDrawItem>& di, | ||||||
|                            std::size_t                             lineIndex, |  | ||||||
|                            std::vector<float>&                     linesBuffer, |                            std::vector<float>&                     linesBuffer, | ||||||
|                            std::vector<GLint>&          integerBuffer, |                            std::vector<GLint>&                 integerBuffer, | ||||||
|                            std::vector<LineHoverEntry>& hoverLines); |                            std::unordered_map<std::shared_ptr<GeoLineDrawItem>, | ||||||
|  |                                               LineHoverEntry>& hoverLines); | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<GlContext> context_; |    std::shared_ptr<GlContext> context_; | ||||||
| 
 | 
 | ||||||
|  | @ -112,8 +113,10 @@ public: | ||||||
|    std::vector<float> newLinesBuffer_ {}; |    std::vector<float> newLinesBuffer_ {}; | ||||||
|    std::vector<GLint> newIntegerBuffer_ {}; |    std::vector<GLint> newIntegerBuffer_ {}; | ||||||
| 
 | 
 | ||||||
|    std::vector<LineHoverEntry> currentHoverLines_ {}; |    std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry> | ||||||
|    std::vector<LineHoverEntry> newHoverLines_ {}; |       currentHoverLines_ {}; | ||||||
|  |    std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry> | ||||||
|  |       newHoverLines_ {}; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<ShaderProgram> shaderProgram_; |    std::shared_ptr<ShaderProgram> shaderProgram_; | ||||||
|    GLint                          uMVPMatrixLocation_; |    GLint                          uMVPMatrixLocation_; | ||||||
|  | @ -323,7 +326,9 @@ void GeoLines::StartLines() | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<GeoLineDrawItem> GeoLines::AddLine() | std::shared_ptr<GeoLineDrawItem> GeoLines::AddLine() | ||||||
| { | { | ||||||
|    return p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>()); |    auto& di = p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>()); | ||||||
|  |    di->lineIndex_ = p->newLineList_.size() - 1; | ||||||
|  |    return di; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GeoLines::SetLineLocation(const std::shared_ptr<GeoLineDrawItem>& di, | void GeoLines::SetLineLocation(const std::shared_ptr<GeoLineDrawItem>& di, | ||||||
|  | @ -470,7 +475,7 @@ void GeoLines::Impl::UpdateBuffers() | ||||||
| 
 | 
 | ||||||
|       // Update line buffer
 |       // Update line buffer
 | ||||||
|       UpdateSingleBuffer( |       UpdateSingleBuffer( | ||||||
|          di, i, newLinesBuffer_, newIntegerBuffer_, newHoverLines_); |          di, newLinesBuffer_, newIntegerBuffer_, newHoverLines_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // All lines have been updated
 |    // All lines have been updated
 | ||||||
|  | @ -488,23 +493,15 @@ void GeoLines::Impl::UpdateModifiedLineBuffers() | ||||||
|    // Update buffers for modified lines
 |    // Update buffers for modified lines
 | ||||||
|    for (auto& di : dirtyLines_) |    for (auto& di : dirtyLines_) | ||||||
|    { |    { | ||||||
|       // Find modified line in the current list
 |       // Check if modified line is in the current list
 | ||||||
|       auto it = |       if (di->lineIndex_ >= currentLineList_.size() || | ||||||
|          std::find(currentLineList_.cbegin(), currentLineList_.cend(), di); |           currentLineList_[di->lineIndex_] != di) | ||||||
| 
 |  | ||||||
|       // Ignore invalid lines
 |  | ||||||
|       if (it == currentLineList_.cend()) |  | ||||||
|       { |       { | ||||||
|          continue; |          continue; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       auto lineIndex = std::distance(currentLineList_.cbegin(), it); |       UpdateSingleBuffer( | ||||||
| 
 |          di, currentLinesBuffer_, currentIntegerBuffer_, currentHoverLines_); | ||||||
|       UpdateSingleBuffer(di, |  | ||||||
|                          lineIndex, |  | ||||||
|                          currentLinesBuffer_, |  | ||||||
|                          currentIntegerBuffer_, |  | ||||||
|                          currentHoverLines_); |  | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    // Clear list of modified lines
 |    // Clear list of modified lines
 | ||||||
|  | @ -517,10 +514,10 @@ void GeoLines::Impl::UpdateModifiedLineBuffers() | ||||||
| 
 | 
 | ||||||
| void GeoLines::Impl::UpdateSingleBuffer( | void GeoLines::Impl::UpdateSingleBuffer( | ||||||
|    const std::shared_ptr<GeoLineDrawItem>& di, |    const std::shared_ptr<GeoLineDrawItem>& di, | ||||||
|    std::size_t                             lineIndex, |  | ||||||
|    std::vector<float>&                     lineBuffer, |    std::vector<float>&                     lineBuffer, | ||||||
|    std::vector<GLint>&                     integerBuffer, |    std::vector<GLint>&                     integerBuffer, | ||||||
|    std::vector<LineHoverEntry>&            hoverLines) |    std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>& | ||||||
|  |       hoverLines) | ||||||
| { | { | ||||||
|    // Threshold value
 |    // Threshold value
 | ||||||
|    units::length::nautical_miles<double> threshold = di->threshold_; |    units::length::nautical_miles<double> threshold = di->threshold_; | ||||||
|  | @ -588,10 +585,10 @@ void GeoLines::Impl::UpdateSingleBuffer( | ||||||
| 
 | 
 | ||||||
|    // Buffer position data
 |    // Buffer position data
 | ||||||
|    auto lineBufferPosition = lineBuffer.end(); |    auto lineBufferPosition = lineBuffer.end(); | ||||||
|    auto lineBufferOffset   = lineIndex * kLineBufferLength_; |    auto lineBufferOffset   = di->lineIndex_ * kLineBufferLength_; | ||||||
| 
 | 
 | ||||||
|    auto integerBufferPosition = integerBuffer.end(); |    auto integerBufferPosition = integerBuffer.end(); | ||||||
|    auto integerBufferOffset   = lineIndex * kIntegerBufferLength_; |    auto integerBufferOffset   = di->lineIndex_ * kIntegerBufferLength_; | ||||||
| 
 | 
 | ||||||
|    if (lineBufferOffset < lineBuffer.size()) |    if (lineBufferOffset < lineBuffer.size()) | ||||||
|    { |    { | ||||||
|  | @ -620,9 +617,7 @@ void GeoLines::Impl::UpdateSingleBuffer( | ||||||
|       std::copy(integerData.begin(), integerData.end(), integerBufferPosition); |       std::copy(integerData.begin(), integerData.end(), integerBufferPosition); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    auto hoverIt = std::find_if(hoverLines.begin(), |    auto hoverIt = hoverLines.find(di); | ||||||
|                                hoverLines.end(), |  | ||||||
|                                [&di](auto& entry) { return entry.di_ == di; }); |  | ||||||
| 
 | 
 | ||||||
|    if (di->visible_ && (!di->hoverText_.empty() || |    if (di->visible_ && (!di->hoverText_.empty() || | ||||||
|                         di->hoverCallback_ != nullptr || di->event_ != nullptr)) |                         di->hoverCallback_ != nullptr || di->event_ != nullptr)) | ||||||
|  | @ -644,17 +639,23 @@ void GeoLines::Impl::UpdateSingleBuffer( | ||||||
| 
 | 
 | ||||||
|       if (hoverIt == hoverLines.end()) |       if (hoverIt == hoverLines.end()) | ||||||
|       { |       { | ||||||
|          hoverLines.emplace_back( |          hoverLines.emplace(di, | ||||||
|             LineHoverEntry {di, sc1, sc2, otl, otr, obl, obr}); |                             LineHoverEntry {.di_  = di, | ||||||
|  |                                             .p1_  = sc1, | ||||||
|  |                                             .p2_  = sc2, | ||||||
|  |                                             .otl_ = otl, | ||||||
|  |                                             .otr_ = otr, | ||||||
|  |                                             .obl_ = obl, | ||||||
|  |                                             .obr_ = obr}); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|          hoverIt->p1_  = sc1; |          hoverIt->second.p1_  = sc1; | ||||||
|          hoverIt->p2_  = sc2; |          hoverIt->second.p2_  = sc2; | ||||||
|          hoverIt->otl_ = otl; |          hoverIt->second.otl_ = otl; | ||||||
|          hoverIt->otr_ = otr; |          hoverIt->second.otr_ = otr; | ||||||
|          hoverIt->obl_ = obl; |          hoverIt->second.obl_ = obl; | ||||||
|          hoverIt->obr_ = obr; |          hoverIt->second.obr_ = obr; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|    else if (hoverIt != hoverLines.end()) |    else if (hoverIt != hoverLines.end()) | ||||||
|  | @ -726,10 +727,12 @@ bool GeoLines::RunMousePicking( | ||||||
|    // For each pickable line
 |    // For each pickable line
 | ||||||
|    auto it = std::find_if( |    auto it = std::find_if( | ||||||
|       std::execution::par_unseq, |       std::execution::par_unseq, | ||||||
|       p->currentHoverLines_.rbegin(), |       p->currentHoverLines_.cbegin(), | ||||||
|       p->currentHoverLines_.rend(), |       p->currentHoverLines_.cend(), | ||||||
|       [&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line) |       [&mapDistance, &selectedTime, &mapMatrix, &mouseCoords]( | ||||||
|  |          const auto& lineIt) | ||||||
|       { |       { | ||||||
|  |          const auto& line = lineIt.second; | ||||||
|          if (( |          if (( | ||||||
|                 // Placefile is thresholded
 |                 // Placefile is thresholded
 | ||||||
|                 mapDistance > units::length::meters<double> {0.0} && |                 mapDistance > units::length::meters<double> {0.0} && | ||||||
|  | @ -785,24 +788,24 @@ bool GeoLines::RunMousePicking( | ||||||
|          return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords); |          return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|    if (it != p->currentHoverLines_.crend()) |    if (it != p->currentHoverLines_.cend()) | ||||||
|    { |    { | ||||||
|       itemPicked = true; |       itemPicked = true; | ||||||
| 
 | 
 | ||||||
|       if (!it->di_->hoverText_.empty()) |       if (!it->second.di_->hoverText_.empty()) | ||||||
|       { |       { | ||||||
|          // Show tooltip
 |          // Show tooltip
 | ||||||
|          util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); |          util::tooltip::Show(it->second.di_->hoverText_, mouseGlobalPos); | ||||||
|       } |       } | ||||||
|       else if (it->di_->hoverCallback_ != nullptr) |       else if (it->second.di_->hoverCallback_ != nullptr) | ||||||
|       { |       { | ||||||
|          it->di_->hoverCallback_(it->di_, mouseGlobalPos); |          it->second.di_->hoverCallback_(it->second.di_, mouseGlobalPos); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (it->di_->event_ != nullptr) |       if (it->second.di_->event_ != nullptr) | ||||||
|       { |       { | ||||||
|          // Register event handler
 |          // Register event handler
 | ||||||
|          eventHandler = it->di_; |          eventHandler = it->second.di_; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,9 +19,8 @@ struct GeoLineDrawItem; | ||||||
| class GeoLines : public DrawItem | class GeoLines : public DrawItem | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    typedef std::function<void(std::shared_ptr<GeoLineDrawItem>&, |    using HoverCallback = std::function<void( | ||||||
|                               const QPointF&)> |       const std::shared_ptr<GeoLineDrawItem>&, const QPointF&)>; | ||||||
|       HoverCallback; |  | ||||||
| 
 | 
 | ||||||
|    explicit GeoLines(std::shared_ptr<GlContext> context); |    explicit GeoLines(std::shared_ptr<GlContext> context); | ||||||
|    ~GeoLines(); |    ~GeoLines(); | ||||||
|  |  | ||||||
|  | @ -159,8 +159,9 @@ public: | ||||||
|    void ConnectSignals(); |    void ConnectSignals(); | ||||||
|    void HandleGeoLinesEvent(std::weak_ptr<gl::draw::GeoLineDrawItem>& di, |    void HandleGeoLinesEvent(std::weak_ptr<gl::draw::GeoLineDrawItem>& di, | ||||||
|                             QEvent*                                   ev); |                             QEvent*                                   ev); | ||||||
|    void HandleGeoLinesHover(std::shared_ptr<gl::draw::GeoLineDrawItem>& di, |    void | ||||||
|                             const QPointF& mouseGlobalPos); |    HandleGeoLinesHover(const std::shared_ptr<gl::draw::GeoLineDrawItem>& di, | ||||||
|  |                        const QPointF& mouseGlobalPos); | ||||||
|    void ScheduleRefresh(); |    void ScheduleRefresh(); | ||||||
| 
 | 
 | ||||||
|    LineData& GetLineData(const std::shared_ptr<const awips::Segment>& segment, |    LineData& GetLineData(const std::shared_ptr<const awips::Segment>& segment, | ||||||
|  | @ -720,8 +721,8 @@ void AlertLayer::Impl::HandleGeoLinesEvent( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AlertLayer::Impl::HandleGeoLinesHover( | void AlertLayer::Impl::HandleGeoLinesHover( | ||||||
|    std::shared_ptr<gl::draw::GeoLineDrawItem>& di, |    const std::shared_ptr<gl::draw::GeoLineDrawItem>& di, | ||||||
|    const QPointF&                              mouseGlobalPos) |    const QPointF&                                    mouseGlobalPos) | ||||||
| { | { | ||||||
|    if (di != lastHoverDi_) |    if (di != lastHoverDi_) | ||||||
|    { |    { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat