Merge pull request #4891 from rokuz/traffic-opt

Traffic rendering optimizations
This commit is contained in:
Daria Volvenkova 2016-12-07 14:06:02 +03:00 committed by GitHub
commit 2944c4b013
11 changed files with 83 additions and 17 deletions

View file

@ -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
{

View file

@ -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;

View file

@ -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()

View file

@ -85,7 +85,8 @@ enum class MessagePriority
{
Normal,
High,
UberHighSingleton
UberHighSingleton,
Low
};
} // namespace df

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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));
}
}
}

View file

@ -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

View file

@ -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);

View file

@ -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;