forked from organicmaps/organicmaps
Merge pull request #4891 from rokuz/traffic-opt
Traffic rendering optimizations
This commit is contained in:
commit
2944c4b013
11 changed files with 83 additions and 17 deletions
|
@ -84,6 +84,18 @@ void AttributeProvider::InitStream(uint8_t streamIndex,
|
|||
INIT_STREAM(streamIndex);
|
||||
}
|
||||
|
||||
void AttributeProvider::Reset(uint32_t vertexCount)
|
||||
{
|
||||
m_vertexCount = vertexCount;
|
||||
}
|
||||
|
||||
void AttributeProvider::UpdateStream(uint8_t streamIndex, ref_ptr<void> data)
|
||||
{
|
||||
ASSERT_LESS(streamIndex, GetStreamCount(), ());
|
||||
m_streams[streamIndex].m_data = data;
|
||||
INIT_STREAM(streamIndex);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void AttributeProvider::CheckStreams() const
|
||||
{
|
||||
|
|
|
@ -27,6 +27,9 @@ public:
|
|||
BindingInfo const & bindingInfo,
|
||||
ref_ptr<void> data);
|
||||
|
||||
void Reset(uint32_t vertexCount);
|
||||
void UpdateStream(uint8_t streamIndex, ref_ptr<void> data);
|
||||
|
||||
private:
|
||||
int32_t m_vertexCount;
|
||||
|
||||
|
|
|
@ -37,7 +37,9 @@ void EngineContext::FlushOverlays(TMapShapes && shapes)
|
|||
|
||||
void EngineContext::FlushTrafficGeometry(TrafficSegmentsGeometry && geometry)
|
||||
{
|
||||
PostMessage(make_unique_dp<FlushTrafficGeometryMessage>(m_tileKey, move(geometry)));
|
||||
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<FlushTrafficGeometryMessage>(m_tileKey, move(geometry)),
|
||||
MessagePriority::Low);
|
||||
}
|
||||
|
||||
void EngineContext::EndReadTile()
|
||||
|
|
|
@ -85,7 +85,8 @@ enum class MessagePriority
|
|||
{
|
||||
Normal,
|
||||
High,
|
||||
UberHighSingleton
|
||||
UberHighSingleton,
|
||||
Low
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -22,18 +22,25 @@ MessageQueue::~MessageQueue()
|
|||
drape_ptr<Message> MessageQueue::PopMessage(bool waitForMessage)
|
||||
{
|
||||
unique_lock<mutex> lock(m_mutex);
|
||||
if (waitForMessage && m_messages.empty())
|
||||
if (waitForMessage && m_messages.empty() && m_lowPriorityMessages.empty())
|
||||
{
|
||||
m_isWaiting = true;
|
||||
m_condition.wait(lock, [this]() { return !m_isWaiting; });
|
||||
m_isWaiting = false;
|
||||
}
|
||||
|
||||
if (m_messages.empty())
|
||||
if (m_messages.empty() && m_lowPriorityMessages.empty())
|
||||
return nullptr;
|
||||
|
||||
drape_ptr<Message> msg = move(m_messages.front().first);
|
||||
m_messages.pop_front();
|
||||
if (!m_messages.empty())
|
||||
{
|
||||
drape_ptr<Message> msg = move(m_messages.front().first);
|
||||
m_messages.pop_front();
|
||||
return msg;
|
||||
}
|
||||
|
||||
drape_ptr<Message> msg = move(m_lowPriorityMessages.front());
|
||||
m_lowPriorityMessages.pop_front();
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -73,6 +80,11 @@ void MessageQueue::PushMessage(drape_ptr<Message> && message, MessagePriority pr
|
|||
m_messages.emplace_front(move(message), priority);
|
||||
break;
|
||||
}
|
||||
case MessagePriority::Low:
|
||||
{
|
||||
m_lowPriorityMessages.emplace_back(move(message));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERT(false, ("Unknown message priority type"));
|
||||
}
|
||||
|
@ -92,6 +104,14 @@ void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn)
|
|||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for (auto it = m_lowPriorityMessages.begin(); it != m_lowPriorityMessages.end(); )
|
||||
{
|
||||
if (needFilterMessageFn(make_ref(*it)))
|
||||
it = m_lowPriorityMessages.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MESSAGE_QUEUE
|
||||
|
@ -99,13 +119,13 @@ void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn)
|
|||
bool MessageQueue::IsEmpty() const
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
return m_messages.empty();
|
||||
return m_messages.empty() && m_lowPriorityMessages.empty();
|
||||
}
|
||||
|
||||
size_t MessageQueue::GetSize() const
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
return m_messages.size();
|
||||
return m_messages.size() + m_lowPriorityMessages.size();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -128,6 +148,7 @@ void MessageQueue::CancelWaitImpl()
|
|||
void MessageQueue::ClearQuery()
|
||||
{
|
||||
m_messages.clear();
|
||||
m_lowPriorityMessages.clear();
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -43,6 +43,7 @@ private:
|
|||
bool m_isWaiting;
|
||||
using TMessageNode = pair<drape_ptr<Message>, MessagePriority>;
|
||||
deque<TMessageNode> m_messages;
|
||||
deque<drape_ptr<Message>> m_lowPriorityMessages;
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -30,6 +30,11 @@ namespace
|
|||
{
|
||||
int constexpr kOutlineMinZoomLevel = 16;
|
||||
|
||||
// The first zoom level in kAverageSegmentsCount.
|
||||
int constexpr kFirstZoomInAverageSegments = 10;
|
||||
// 10 11 12 13 14 15 16 17 18 19
|
||||
vector<size_t> const kAverageSegmentsCount = { 10000, 5000, 10000, 5000, 2500, 5000, 2000, 1000, 500, 500 };
|
||||
|
||||
df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType const & f)
|
||||
{
|
||||
df::BaseApplyFeature::HotelData result;
|
||||
|
@ -65,7 +70,12 @@ void ExtractTrafficGeometry(FeatureType const & f, df::RoadClass const & roadCla
|
|||
static vector<uint8_t> directions = {traffic::TrafficInfo::RoadSegmentId::kForwardDirection,
|
||||
traffic::TrafficInfo::RoadSegmentId::kReverseDirection};
|
||||
auto & segments = geometry[f.GetID().m_mwmId];
|
||||
segments.reserve(segments.size() + directions.size() * (polyline.GetSize() - 1));
|
||||
|
||||
int const index = zoomLevel - kFirstZoomInAverageSegments;
|
||||
ASSERT_GREATER_OR_EQUAL(index, 0, ());
|
||||
ASSERT_LESS(index, kAverageSegmentsCount.size(), ());
|
||||
segments.reserve(kAverageSegmentsCount[index]);
|
||||
|
||||
for (uint16_t segIndex = 0; segIndex + 1 < static_cast<uint16_t>(polyline.GetSize()); ++segIndex)
|
||||
{
|
||||
for (size_t dirIndex = 0; dirIndex < directions.size(); ++dirIndex)
|
||||
|
|
|
@ -187,6 +187,12 @@ void TrafficGenerator::Init()
|
|||
m_batchersPool = make_unique_dp<BatchersPool<TrafficBatcherKey, TrafficBatcherKeyComparator>>(
|
||||
kBatchersCount, bind(&TrafficGenerator::FlushGeometry, this, _1, _2, _3),
|
||||
kBatchSize, kBatchSize);
|
||||
|
||||
m_providerLines.InitStream(0 /* stream index */, GetTrafficLineStaticBindingInfo(), nullptr);
|
||||
m_providerLines.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), nullptr);
|
||||
|
||||
m_providerTriangles.InitStream(0 /* stream index */, GetTrafficStaticBindingInfo(), nullptr);
|
||||
m_providerTriangles.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), nullptr);
|
||||
}
|
||||
|
||||
void TrafficGenerator::ClearGLDependentResources()
|
||||
|
@ -268,13 +274,13 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg
|
|||
|
||||
drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv,
|
||||
staticGeometry.size());
|
||||
dp::AttributeProvider provider(2 /* stream count */, staticGeometry.size());
|
||||
provider.InitStream(0 /* stream index */, GetTrafficLineStaticBindingInfo(), make_ref(staticGeometry.data()));
|
||||
provider.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), make_ref(dynamicGeometry.data()));
|
||||
m_providerLines.Reset(staticGeometry.size());
|
||||
m_providerLines.UpdateStream(0 /* stream index */, make_ref(staticGeometry.data()));
|
||||
m_providerLines.UpdateStream(1 /* stream index */, make_ref(dynamicGeometry.data()));
|
||||
|
||||
dp::GLState curLineState = lineState;
|
||||
curLineState.SetLineWidth(w * df::VisualParams::Instance().GetVisualScale());
|
||||
batcher->InsertLineStrip(curLineState, make_ref(&provider), move(handle));
|
||||
batcher->InsertLineStrip(curLineState, make_ref(&m_providerLines), move(handle));
|
||||
generatedAsLine = true;
|
||||
}
|
||||
}
|
||||
|
@ -293,10 +299,10 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg
|
|||
|
||||
drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv,
|
||||
staticGeometry.size());
|
||||
dp::AttributeProvider provider(2 /* stream count */, staticGeometry.size());
|
||||
provider.InitStream(0 /* stream index */, GetTrafficStaticBindingInfo(), make_ref(staticGeometry.data()));
|
||||
provider.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), make_ref(dynamicGeometry.data()));
|
||||
batcher->InsertTriangleList(state, make_ref(&provider), move(handle));
|
||||
m_providerTriangles.Reset(staticGeometry.size());
|
||||
m_providerTriangles.UpdateStream(0 /* stream index */, make_ref(staticGeometry.data()));
|
||||
m_providerTriangles.UpdateStream(1 /* stream index */, make_ref(dynamicGeometry.data()));
|
||||
batcher->InsertTriangleList(state, make_ref(&m_providerTriangles), move(handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,8 @@ public:
|
|||
|
||||
explicit TrafficGenerator(TFlushRenderDataFn flushFn)
|
||||
: m_flushRenderDataFn(flushFn)
|
||||
, m_providerTriangles(2 /* stream count */, 0 /* vertices count*/)
|
||||
, m_providerLines(2 /* stream count */, 0 /* vertices count*/)
|
||||
{}
|
||||
|
||||
void Init();
|
||||
|
@ -237,6 +239,9 @@ private:
|
|||
|
||||
drape_ptr<BatchersPool<TrafficBatcherKey, TrafficBatcherKeyComparator>> m_batchersPool;
|
||||
TFlushRenderDataFn m_flushRenderDataFn;
|
||||
|
||||
dp::AttributeProvider m_providerTriangles;
|
||||
dp::AttributeProvider m_providerLines;
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -101,6 +101,7 @@ void TrafficManager::SetEnabled(bool enabled)
|
|||
void TrafficManager::Clear()
|
||||
{
|
||||
m_mwmCache.clear();
|
||||
m_lastMwmsByRect.clear();
|
||||
m_activeMwms.clear();
|
||||
m_requestedMwms.clear();
|
||||
}
|
||||
|
@ -147,6 +148,9 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen)
|
|||
|
||||
// Request traffic.
|
||||
auto mwms = m_getMwmsByRectFn(screen.ClipRect());
|
||||
if (m_lastMwmsByRect == mwms)
|
||||
return;
|
||||
m_lastMwmsByRect = mwms;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
|
|
|
@ -133,6 +133,7 @@ private:
|
|||
bool m_isRunning;
|
||||
condition_variable m_condition;
|
||||
|
||||
vector<MwmSet::MwmId> m_lastMwmsByRect;
|
||||
set<MwmSet::MwmId> m_activeMwms;
|
||||
|
||||
vector<MwmSet::MwmId> m_requestedMwms;
|
||||
|
|
Loading…
Add table
Reference in a new issue