Removed usage of dynamic geometry from traffic renderer

This commit is contained in:
r.kuznetsov 2016-12-12 16:48:00 +03:00
parent ced9f3bb90
commit 0eb7d455d8
14 changed files with 110 additions and 377 deletions

View file

@ -109,9 +109,11 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
TTilesCollection tiles = m_requestedTiles->GetTiles();
if (!tiles.empty())
{
ScreenBase const screen = m_requestedTiles->GetScreen();
bool const have3dBuildings = m_requestedTiles->Have3dBuildings();
m_readManager->UpdateCoverage(screen, have3dBuildings, tiles, m_texMng);
ScreenBase screen;
bool have3dBuildings;
bool needRegenerateTraffic;
m_requestedTiles->GetParams(screen, have3dBuildings, needRegenerateTraffic);
m_readManager->UpdateCoverage(screen, have3dBuildings, needRegenerateTraffic, tiles, m_texMng);
m_updateCurrentCountryFn(screen.ClipRect().Center(), (*tiles.begin()).m_zoomLevel);
}
break;
@ -355,17 +357,9 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
case Message::UpdateTraffic:
{
ref_ptr<UpdateTrafficMessage> msg = message;
bool const needInvalidate = m_trafficGenerator->UpdateColoring(msg->GetSegmentsColoring());
if (m_trafficGenerator->IsColorsCacheRefreshed())
{
auto texCoords = m_trafficGenerator->ProcessCacheRefreshing();
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<SetTrafficTexCoordsMessage>(move(texCoords)),
MessagePriority::Normal);
}
m_trafficGenerator->UpdateColoring(msg->GetSegmentsColoring());
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<UpdateTrafficMessage>(move(msg->GetSegmentsColoring()),
needInvalidate),
make_unique_dp<RegenerateTrafficMessage>(),
MessagePriority::Normal);
break;
}

View file

@ -557,7 +557,7 @@ void DrapeEngine::UpdateTraffic(traffic::TrafficInfo const & info)
segmentsColoring.emplace(info.GetMwmId(), info.GetColoring());
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateTrafficMessage>(move(segmentsColoring), false),
make_unique_dp<UpdateTrafficMessage>(move(segmentsColoring)),
MessagePriority::Normal);
}

View file

@ -132,7 +132,7 @@ FrontendRenderer::FrontendRenderer(Params const & params)
, m_requestedTiles(params.m_requestedTiles)
, m_maxGeneration(0)
, m_needRestoreSize(false)
, m_trafficStateChanged(false)
, m_needRegenerateTraffic(false)
, m_trafficEnabled(params.m_trafficEnabled)
{
#ifdef DRAW_INFO
@ -748,26 +748,15 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
ref_ptr<EnableTrafficMessage> msg = message;
m_trafficEnabled = msg->IsTrafficEnabled();
if (msg->IsTrafficEnabled())
m_trafficStateChanged = true;
m_needRegenerateTraffic = true;
else
m_trafficRenderer->ClearGLDependentResources();
break;
}
case Message::UpdateTraffic:
case Message::RegenerateTraffic:
{
ref_ptr<UpdateTrafficMessage> msg = message;
if (msg->NeedInvalidate())
InvalidateRect(m_userEventStream.GetCurrentScreen().ClipRect());
else
m_trafficRenderer->UpdateTraffic(msg->GetSegmentsColoring());
break;
}
case Message::SetTrafficTexCoords:
{
ref_ptr<SetTrafficTexCoordsMessage> msg = message;
m_trafficRenderer->SetTexCoords(move(msg->AcceptTexCoords()));
m_needRegenerateTraffic = true;
break;
}
@ -852,7 +841,7 @@ void FrontendRenderer::UpdateGLResources()
// Request new tiles.
ScreenBase screen = m_userEventStream.GetCurrentScreen();
m_lastReadedModelView = screen;
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), ResolveTileKeys(screen));
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), m_needRegenerateTraffic, ResolveTileKeys(screen));
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateReadManagerMessage>(),
MessagePriority::UberHighSingleton);
@ -907,7 +896,8 @@ void FrontendRenderer::InvalidateRect(m2::RectD const & gRect)
// Request new tiles.
m_lastReadedModelView = screen;
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), ResolveTileKeys(screen));
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(),
m_needRegenerateTraffic, ResolveTileKeys(screen));
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateReadManagerMessage>(),
MessagePriority::UberHighSingleton);
@ -1738,7 +1728,7 @@ void FrontendRenderer::Routine::Do()
isActiveFrame |= m_renderer.m_texMng->UpdateDynamicTextures();
m_renderer.RenderScene(modelView);
if (modelViewChanged || m_renderer.m_trafficStateChanged)
if (modelViewChanged || m_renderer.m_needRegenerateTraffic)
m_renderer.UpdateScene(modelView);
isActiveFrame |= InterpolationHolder::Instance().Advance(frameTime);
@ -1887,15 +1877,16 @@ void FrontendRenderer::UpdateScene(ScreenBase const & modelView)
for (RenderLayer & layer : m_layers)
layer.m_isDirty |= RemoveGroups(removePredicate, layer.m_renderGroups, make_ref(m_overlayTree));
if (m_trafficStateChanged || m_lastReadedModelView != modelView)
if (m_needRegenerateTraffic || m_lastReadedModelView != modelView)
{
m_trafficStateChanged = false;
EmitModelViewChanged(modelView);
m_lastReadedModelView = modelView;
m_requestedTiles->Set(modelView, m_isIsometry || modelView.isPerspective(), ResolveTileKeys(modelView));
m_requestedTiles->Set(modelView, m_isIsometry || modelView.isPerspective(), m_needRegenerateTraffic,
ResolveTileKeys(modelView));
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateReadManagerMessage>(),
MessagePriority::UberHighSingleton);
m_needRegenerateTraffic = false;
}
}

View file

@ -343,7 +343,7 @@ private:
bool m_needRestoreSize;
bool m_trafficStateChanged;
bool m_needRegenerateTraffic;
bool m_trafficEnabled;
#ifdef DEBUG

View file

@ -67,7 +67,7 @@ public:
SetVisibleViewport,
EnableTraffic,
FlushTrafficGeometry,
SetTrafficTexCoords,
RegenerateTraffic,
UpdateTraffic,
FlushTrafficData,
ClearTrafficData,

View file

@ -1032,39 +1032,26 @@ private:
TrafficSegmentsGeometry m_segments;
};
class SetTrafficTexCoordsMessage : public Message
class RegenerateTrafficMessage : public Message
{
public:
explicit SetTrafficTexCoordsMessage(TrafficTexCoords && texCoords)
: m_texCoords(move(texCoords))
{}
Type GetType() const override { return Message::SetTrafficTexCoords; }
bool IsGLContextDependent() const override { return true; }
TrafficTexCoords && AcceptTexCoords() { return move(m_texCoords); }
private:
TrafficTexCoords m_texCoords;
Type GetType() const override { return Message::RegenerateTraffic; }
};
class UpdateTrafficMessage : public Message
{
public:
UpdateTrafficMessage(TrafficSegmentsColoring && segmentsColoring, bool needInvalidate)
explicit UpdateTrafficMessage(TrafficSegmentsColoring && segmentsColoring)
: m_segmentsColoring(move(segmentsColoring))
, m_needInvalidate(needInvalidate)
{}
Type GetType() const override { return Message::UpdateTraffic; }
bool IsGLContextDependent() const override { return true; }
TrafficSegmentsColoring & GetSegmentsColoring() { return m_segmentsColoring; }
bool NeedInvalidate() const { return m_needInvalidate; }
private:
TrafficSegmentsColoring m_segmentsColoring;
bool const m_needInvalidate;
};
class FlushTrafficDataMessage : public Message

View file

@ -86,13 +86,13 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task)
myPool.Return(t);
}
void ReadManager::UpdateCoverage(ScreenBase const & screen, bool have3dBuildings,
void ReadManager::UpdateCoverage(ScreenBase const & screen, bool have3dBuildings, bool needRegenerateTraffic,
TTilesCollection const & tiles, ref_ptr<dp::TextureManager> texMng)
{
m_modeChanged |= (m_have3dBuildings != have3dBuildings);
m_have3dBuildings = have3dBuildings;
if (m_modeChanged || MustDropAllTiles(screen))
if (m_modeChanged || needRegenerateTraffic || MustDropAllTiles(screen))
{
m_modeChanged = false;

View file

@ -30,7 +30,7 @@ public:
ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model,
bool allow3dBuildings, bool trafficEnabled);
void UpdateCoverage(ScreenBase const & screen, bool have3dBuildings,
void UpdateCoverage(ScreenBase const & screen, bool have3dBuildings, bool needRegenerateTraffic,
TTilesCollection const & tiles, ref_ptr<dp::TextureManager> texMng);
void Invalidate(TTilesCollection const & keyStorage);
void InvalidateAll();

View file

@ -3,12 +3,14 @@
namespace df
{
void RequestedTiles::Set(ScreenBase const & screen, bool have3dBuildings, TTilesCollection && tiles)
void RequestedTiles::Set(ScreenBase const & screen, bool have3dBuildings,
bool needRegenerateTraffic, TTilesCollection && tiles)
{
lock_guard<mutex> lock(m_mutex);
m_tiles = move(tiles);
m_screen = screen;
m_have3dBuildings = have3dBuildings;
m_needRegenerateTraffic = needRegenerateTraffic;
}
TTilesCollection RequestedTiles::GetTiles()
@ -21,16 +23,13 @@ TTilesCollection RequestedTiles::GetTiles()
return tiles;
}
ScreenBase RequestedTiles::GetScreen()
void RequestedTiles::GetParams(ScreenBase & screen, bool & have3dBuildings,
bool & needRegenerateTraffic)
{
lock_guard<mutex> lock(m_mutex);
return m_screen;
}
bool RequestedTiles::Have3dBuildings()
{
lock_guard<mutex> lock(m_mutex);
return m_have3dBuildings;
screen = m_screen;
have3dBuildings = m_have3dBuildings;
needRegenerateTraffic = m_needRegenerateTraffic;
}
bool RequestedTiles::CheckTileKey(TileKey const & tileKey) const

View file

@ -13,16 +13,18 @@ class RequestedTiles
{
public:
RequestedTiles() = default;
void Set(ScreenBase const & screen, bool have3dBuildings, TTilesCollection && tiles);
void Set(ScreenBase const & screen, bool have3dBuildings,
bool needRegenerateTraffic, TTilesCollection && tiles);
TTilesCollection GetTiles();
ScreenBase GetScreen();
bool Have3dBuildings();
void GetParams(ScreenBase & screen, bool & have3dBuildings,
bool & needRegenerateTraffic);
bool CheckTileKey(TileKey const & tileKey) const;
private:
TTilesCollection m_tiles;
ScreenBase m_screen;
bool m_have3dBuildings = false;
bool m_needRegenerateTraffic = false;
mutable mutex m_mutex;
};

View file

@ -24,16 +24,15 @@ namespace df
namespace
{
uint32_t const kDynamicStreamID = 0x7F;
dp::BindingInfo const & GetTrafficStaticBindingInfo()
{
static unique_ptr<dp::BindingInfo> s_info;
if (s_info == nullptr)
{
dp::BindingFiller<TrafficStaticVertex> filler(2);
dp::BindingFiller<TrafficStaticVertex> filler(3);
filler.FillDecl<TrafficStaticVertex::TPosition>("a_position");
filler.FillDecl<TrafficStaticVertex::TNormal>("a_normal");
filler.FillDecl<TrafficStaticVertex::TTexCoord>("a_colorTexCoord");
s_info.reset(new dp::BindingInfo(filler.m_info));
}
return *s_info;
@ -44,40 +43,24 @@ dp::BindingInfo const & GetTrafficLineStaticBindingInfo()
static unique_ptr<dp::BindingInfo> s_info;
if (s_info == nullptr)
{
dp::BindingFiller<TrafficLineStaticVertex> filler(1);
dp::BindingFiller<TrafficLineStaticVertex> filler(2);
filler.FillDecl<TrafficLineStaticVertex::TPosition>("a_position");
filler.FillDecl<TrafficLineStaticVertex::TTexCoord>("a_colorTexCoord");
s_info.reset(new dp::BindingInfo(filler.m_info));
}
return *s_info;
}
dp::BindingInfo const & GetTrafficDynamicBindingInfo()
{
static unique_ptr<dp::BindingInfo> s_info;
if (s_info == nullptr)
{
dp::BindingFiller<TrafficDynamicVertex> filler(1, kDynamicStreamID);
filler.FillDecl<TrafficDynamicVertex::TTexCoord>("a_colorTexCoord");
s_info.reset(new dp::BindingInfo(filler.m_info));
}
return *s_info;
}
void SubmitStaticVertex(glsl::vec3 const & pivot, glsl::vec2 const & normal, float side, float offsetFromStart,
void SubmitStaticVertex(glsl::vec3 const & pivot, glsl::vec2 const & normal, float side,
float offsetFromStart, glsl::vec2 const & texCoord,
vector<TrafficStaticVertex> & staticGeom)
{
staticGeom.emplace_back(pivot, TrafficStaticVertex::TNormal(normal, side, offsetFromStart));
}
void SubmitDynamicVertex(glsl::vec2 const & texCoord, vector<TrafficDynamicVertex> & dynamicGeom)
{
dynamicGeom.emplace_back(texCoord);
staticGeom.emplace_back(pivot, TrafficStaticVertex::TNormal(normal, side, offsetFromStart), texCoord);
}
void GenerateCapTriangles(glsl::vec3 const & pivot, vector<glsl::vec2> const & normals,
dp::TextureManager::ColorRegion const & colorRegion,
vector<TrafficStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry)
vector<TrafficStaticVertex> & staticGeometry)
{
float const kEps = 1e-5;
glsl::vec2 const uv = glsl::ToVec2(colorRegion.GetTexRect().Center());
@ -85,100 +68,16 @@ void GenerateCapTriangles(glsl::vec3 const & pivot, vector<glsl::vec2> const & n
for (int j = 0; j < trianglesCount; j++)
{
SubmitStaticVertex(pivot, normals[3 * j],
glsl::length(normals[3 * j]) < kEps ? 0.0f : 1.0f, 0.0f, staticGeometry);
glsl::length(normals[3 * j]) < kEps ? 0.0f : 1.0f, 0.0f, uv, staticGeometry);
SubmitStaticVertex(pivot, normals[3 * j + 1],
glsl::length(normals[3 * j + 1]) < kEps ? 0.0f : 1.0f, 0.0f, staticGeometry);
glsl::length(normals[3 * j + 1]) < kEps ? 0.0f : 1.0f, 0.0f, uv, staticGeometry);
SubmitStaticVertex(pivot, normals[3 * j + 2],
glsl::length(normals[3 * j + 2]) < kEps ? 0.0f : 1.0f, 0.0f, staticGeometry);
for (int k = 0; k < 3; k++)
SubmitDynamicVertex(uv, dynamicGeometry);
glsl::length(normals[3 * j + 2]) < kEps ? 0.0f : 1.0f, 0.0f, uv, staticGeometry);
}
}
} // namespace
TrafficHandle::TrafficHandle(traffic::TrafficInfo::RoadSegmentId const & segmentId, RoadClass const & roadClass,
m2::RectD const & boundingBox, glsl::vec2 const & texCoord, size_t verticesCount)
: OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false)
, m_segmentId(segmentId)
, m_roadClass(roadClass)
, m_boundingBox(boundingBox)
, m_needUpdate(false)
{
ASSERT_NOT_EQUAL(verticesCount, 0, ());
m_buffer.resize(verticesCount);
for (size_t i = 0; i < m_buffer.size(); i++)
m_buffer[i] = texCoord;
}
void TrafficHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const
{
if (!m_needUpdate)
return;
TOffsetNode const & node = GetOffsetNode(kDynamicStreamID);
ASSERT(node.first.GetElementSize() == sizeof(TrafficDynamicVertex), ());
ASSERT(node.second.m_count == m_buffer.size(), ());
uint32_t const byteCount = m_buffer.size() * sizeof(TrafficDynamicVertex);
void * buffer = mutator->AllocateMutationBuffer(byteCount);
memcpy(buffer, m_buffer.data(), byteCount);
dp::MutateNode mutateNode;
mutateNode.m_region = node.second;
mutateNode.m_data = make_ref(buffer);
mutator->AddMutation(node.first, mutateNode);
m_needUpdate = false;
}
bool TrafficHandle::Update(ScreenBase const & screen)
{
UNUSED_VALUE(screen);
return true;
}
bool TrafficHandle::IndexesRequired() const
{
return false;
}
m2::RectD TrafficHandle::GetPixelRect(ScreenBase const & screen, bool perspective) const
{
UNUSED_VALUE(screen);
UNUSED_VALUE(perspective);
return m2::RectD();
}
void TrafficHandle::GetPixelShape(ScreenBase const & screen, bool perspective, Rects & rects) const
{
UNUSED_VALUE(screen);
UNUSED_VALUE(perspective);
}
void TrafficHandle::SetTexCoord(glsl::vec2 const & texCoord)
{
for (size_t i = 0; i < m_buffer.size(); i++)
m_buffer[i] = texCoord;
m_needUpdate = true;
}
traffic::TrafficInfo::RoadSegmentId const & TrafficHandle::GetSegmentId() const
{
return m_segmentId;
}
RoadClass const & TrafficHandle::GetRoadClass() const
{
return m_roadClass;
}
m2::RectD const & TrafficHandle::GetBoundingBox() const
{
return m_boundingBox;
}
void TrafficGenerator::Init()
{
int constexpr kBatchersCount = 3;
@ -188,10 +87,7 @@ void TrafficGenerator::Init()
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()
@ -245,48 +141,33 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg
ASSERT(m_colorsCacheValid, ());
dp::TextureManager::ColorRegion const & colorRegion = m_colorsCache[static_cast<size_t>(segmentColoringIt->second)];
glsl::vec2 const uv = glsl::ToVec2(colorRegion.GetTexRect().Center());
int width = 0;
if (TrafficRenderer::CanBeRendereredAsLine(g.m_roadClass, tileKey.m_zoomLevel, width))
{
vector<TrafficLineStaticVertex> staticGeometry;
vector<TrafficDynamicVertex> dynamicGeometry;
GenerateLineSegment(colorRegion, g.m_polyline, tileKey.GetGlobalRect().Center(), depth,
staticGeometry, dynamicGeometry);
ASSERT_EQUAL(staticGeometry.size(), dynamicGeometry.size(), ());
if ((staticGeometry.size() + dynamicGeometry.size()) == 0)
GenerateLineSegment(colorRegion, g.m_polyline, tileKey.GetGlobalRect().Center(), depth, staticGeometry);
if (staticGeometry.empty())
continue;
drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv,
staticGeometry.size());
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(width);
batcher->InsertLineStrip(curLineState, make_ref(&m_providerLines), move(handle));
batcher->InsertLineStrip(curLineState, make_ref(&m_providerLines));
}
else
{
vector<TrafficStaticVertex> staticGeometry;
vector<TrafficDynamicVertex> dynamicGeometry;
bool const generateCaps = (tileKey.m_zoomLevel > kGenerateCapsZoomLevel[static_cast<uint32_t>(g.m_roadClass)]);
GenerateSegment(colorRegion, g.m_polyline, tileKey.GetGlobalRect().Center(), generateCaps, depth,
staticGeometry, dynamicGeometry);
ASSERT_EQUAL(staticGeometry.size(), dynamicGeometry.size(), ());
if ((staticGeometry.size() + dynamicGeometry.size()) == 0)
GenerateSegment(colorRegion, g.m_polyline, tileKey.GetGlobalRect().Center(), generateCaps, depth, staticGeometry);
if (staticGeometry.empty())
continue;
drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv,
staticGeometry.size());
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));
batcher->InsertTriangleList(state, make_ref(&m_providerTriangles));
}
}
}
@ -299,16 +180,10 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg
GLFunctions::glFlush();
}
bool TrafficGenerator::UpdateColoring(TrafficSegmentsColoring const & coloring)
void TrafficGenerator::UpdateColoring(TrafficSegmentsColoring const & coloring)
{
bool hasNew = false;
for (auto it = coloring.begin(); it != coloring.end(); ++it)
{
if (!hasNew && m_coloring.find(it->first) == m_coloring.end())
hasNew = true;
m_coloring[it->first] = it->second;
}
return hasNew;
for (auto const & p : coloring)
m_coloring[p.first] = p.second;
}
void TrafficGenerator::ClearCache()
@ -334,21 +209,20 @@ void TrafficGenerator::FlushGeometry(TrafficBatcherKey const & key, dp::GLState
renderData.m_bucket = move(buffer);
renderData.m_mwmId = key.m_mwmId;
renderData.m_tileKey = key.m_tileKey;
renderData.m_roadClass = key.m_roadClass;
m_flushRenderDataFn(move(renderData));
}
void TrafficGenerator::GenerateSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
bool generateCaps, float depth, vector<TrafficStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry)
bool generateCaps, float depth, vector<TrafficStaticVertex> & staticGeometry)
{
vector<m2::PointD> const & path = polyline.GetPoints();
ASSERT_GREATER(path.size(), 1, ());
size_t const kAverageSize = path.size() * 4;
size_t const kAverageCapSize = 24;
size_t const kAverageCapSize = 12;
staticGeometry.reserve(staticGeometry.size() + kAverageSize + kAverageCapSize * 2);
dynamicGeometry.reserve(dynamicGeometry.size() + kAverageSize + kAverageCapSize * 2);
// Build geometry.
glsl::vec2 firstPoint, firstTangent, firstLeftNormal, firstRightNormal;
@ -383,14 +257,12 @@ void TrafficGenerator::GenerateSegment(dp::TextureManager::ColorRegion const & c
glsl::vec3 const startPivot = glsl::vec3(p1, depth);
glsl::vec3 const endPivot = glsl::vec3(p2, depth);
SubmitStaticVertex(startPivot, rightNormal, -1.0f, 0.0f, staticGeometry);
SubmitStaticVertex(startPivot, leftNormal, 1.0f, 0.0f, staticGeometry);
SubmitStaticVertex(endPivot, rightNormal, -1.0f, maskSize, staticGeometry);
SubmitStaticVertex(endPivot, rightNormal, -1.0f, maskSize, staticGeometry);
SubmitStaticVertex(startPivot, leftNormal, 1.0f, 0.0f, staticGeometry);
SubmitStaticVertex(endPivot, leftNormal, 1.0f, maskSize, staticGeometry);
for (int j = 0; j < 6; j++)
SubmitDynamicVertex(uv, dynamicGeometry);
SubmitStaticVertex(startPivot, rightNormal, -1.0f, 0.0f, uv, staticGeometry);
SubmitStaticVertex(startPivot, leftNormal, 1.0f, 0.0f, uv, staticGeometry);
SubmitStaticVertex(endPivot, rightNormal, -1.0f, maskSize, uv, staticGeometry);
SubmitStaticVertex(endPivot, rightNormal, -1.0f, maskSize, uv, staticGeometry);
SubmitStaticVertex(startPivot, leftNormal, 1.0f, 0.0f, uv, staticGeometry);
SubmitStaticVertex(endPivot, leftNormal, 1.0f, maskSize, uv, staticGeometry);
}
// Generate caps.
@ -401,36 +273,31 @@ void TrafficGenerator::GenerateSegment(dp::TextureManager::ColorRegion const & c
normals.reserve(kAverageCapSize);
GenerateCapNormals(dp::RoundCap, firstLeftNormal, firstRightNormal, -firstTangent,
1.0f, true /* isStart */, normals, kSegmentsCount);
GenerateCapTriangles(glsl::vec3(firstPoint, depth), normals, colorRegion,
staticGeometry, dynamicGeometry);
GenerateCapTriangles(glsl::vec3(firstPoint, depth), normals, colorRegion, staticGeometry);
normals.clear();
GenerateCapNormals(dp::RoundCap, lastLeftNormal, lastRightNormal, lastTangent,
1.0f, false /* isStart */, normals, kSegmentsCount);
GenerateCapTriangles(glsl::vec3(lastPoint, depth), normals, colorRegion,
staticGeometry, dynamicGeometry);
GenerateCapTriangles(glsl::vec3(lastPoint, depth), normals, colorRegion, staticGeometry);
}
}
void TrafficGenerator::GenerateLineSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
float depth, vector<TrafficLineStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry)
float depth, vector<TrafficLineStaticVertex> & staticGeometry)
{
vector<m2::PointD> const & path = polyline.GetPoints();
ASSERT_GREATER(path.size(), 1, ());
size_t const kAverageSize = path.size();
staticGeometry.reserve(staticGeometry.size() + kAverageSize);
dynamicGeometry.reserve(dynamicGeometry.size() + kAverageSize);
// Build geometry.
glsl::vec2 const uv = glsl::ToVec2(colorRegion.GetTexRect().Center());
for (size_t i = 0; i < path.size(); ++i)
{
glsl::vec2 const p = glsl::ToVec2(MapShape::ConvertToLocal(path[i], tileCenter, kShapeCoordScalar));
staticGeometry.emplace_back(glsl::vec3(p, depth));
SubmitDynamicVertex(uv, dynamicGeometry);
staticGeometry.emplace_back(glsl::vec3(p, depth), uv);
}
}
@ -469,18 +336,7 @@ void TrafficGenerator::FillColorsCache(ref_ptr<dp::TextureManager> textures)
m_colorsCache[i] = colorRegion;
}
m_colorsCacheValid = true;
m_colorsCacheRefreshed = true;
}
}
TrafficTexCoords TrafficGenerator::ProcessCacheRefreshing()
{
TrafficTexCoords result;
for (size_t i = 0; i < m_colorsCache.size(); i++)
result[i] = glsl::ToVec2(m_colorsCache[i].GetTexRect().Center());
m_colorsCacheRefreshed = false;
return result;
}
} // namespace df

View file

@ -7,7 +7,6 @@
#include "drape/color.hpp"
#include "drape/glsl_types.hpp"
#include "drape/glstate.hpp"
#include "drape/overlay_handle.hpp"
#include "drape/render_bucket.hpp"
#include "drape/texture_manager.hpp"
@ -79,16 +78,13 @@ using TrafficSegmentsGeometry = map<MwmSet::MwmId, vector<pair<traffic::TrafficI
TrafficSegmentGeometry>>>;
using TrafficSegmentsColoring = map<MwmSet::MwmId, traffic::TrafficInfo::Coloring>;
class TrafficHandle;
struct TrafficRenderData
{
dp::GLState m_state;
drape_ptr<dp::RenderBucket> m_bucket;
TileKey m_tileKey;
MwmSet::MwmId m_mwmId;
m2::RectD m_boundingBox;
vector<TrafficHandle *> m_handles;
RoadClass m_roadClass;
TrafficRenderData(dp::GLState const & state) : m_state(state) {}
};
@ -97,69 +93,36 @@ struct TrafficStaticVertex
{
using TPosition = glsl::vec3;
using TNormal = glsl::vec4;
using TTexCoord = glsl::vec2;
TrafficStaticVertex() = default;
TrafficStaticVertex(TPosition const & position, TNormal const & normal)
TrafficStaticVertex(TPosition const & position, TNormal const & normal,
TTexCoord const & colorTexCoord)
: m_position(position)
, m_normal(normal)
, m_colorTexCoord(colorTexCoord)
{}
TPosition m_position;
TNormal m_normal;
TTexCoord m_colorTexCoord;
};
struct TrafficLineStaticVertex
{
using TPosition = glsl::vec3;
using TTexCoord = glsl::vec2;
TrafficLineStaticVertex() = default;
TrafficLineStaticVertex(TPosition const & position)
TrafficLineStaticVertex(TPosition const & position, TTexCoord const & colorTexCoord)
: m_position(position)
, m_colorTexCoord(colorTexCoord)
{}
TPosition m_position;
};
struct TrafficDynamicVertex
{
using TTexCoord = glsl::vec2;
TrafficDynamicVertex() = default;
TrafficDynamicVertex(TTexCoord const & color)
: m_colorTexCoord(color)
{}
TTexCoord m_colorTexCoord;
};
class TrafficHandle : public dp::OverlayHandle
{
using TBase = dp::OverlayHandle;
public:
TrafficHandle(traffic::TrafficInfo::RoadSegmentId const & segmentId, RoadClass const & roadClass,
m2::RectD const & boundingBox, glsl::vec2 const & texCoord,
size_t verticesCount);
void GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const override;
bool Update(ScreenBase const & screen) override;
bool IndexesRequired() const override;
m2::RectD GetPixelRect(ScreenBase const & screen, bool perspective) const override;
void GetPixelShape(ScreenBase const & screen, bool perspective, Rects & rects) const override;
void SetTexCoord(glsl::vec2 const & texCoord);
traffic::TrafficInfo::RoadSegmentId const & GetSegmentId() const;
RoadClass const & GetRoadClass() const;
m2::RectD const & GetBoundingBox() const;
private:
traffic::TrafficInfo::RoadSegmentId m_segmentId;
RoadClass m_roadClass;
vector<glsl::vec2> m_buffer;
m2::RectD m_boundingBox;
mutable bool m_needUpdate;
};
using TrafficTexCoords = unordered_map<size_t, glsl::vec2>;
class TrafficGenerator final
@ -169,8 +132,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*/)
, m_providerTriangles(1 /* stream count */, 0 /* vertices count*/)
, m_providerLines(1 /* stream count */, 0 /* vertices count*/)
{}
void Init();
@ -178,15 +141,12 @@ public:
void FlushSegmentsGeometry(TileKey const & tileKey, TrafficSegmentsGeometry const & geom,
ref_ptr<dp::TextureManager> textures);
bool UpdateColoring(TrafficSegmentsColoring const & coloring);
void UpdateColoring(TrafficSegmentsColoring const & coloring);
void ClearCache();
void ClearCache(MwmSet::MwmId const & mwmId);
void InvalidateTexturesCache();
bool IsColorsCacheRefreshed() const { return m_colorsCacheRefreshed; }
TrafficTexCoords ProcessCacheRefreshing();
static df::ColorConstant GetColorBySpeedGroup(traffic::SpeedGroup const & speedGroup);
private:
@ -220,12 +180,10 @@ private:
void GenerateSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
bool generateCaps, float depth, vector<TrafficStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry);
bool generateCaps, float depth, vector<TrafficStaticVertex> & staticGeometry);
void GenerateLineSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter, float depth,
vector<TrafficLineStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry);
vector<TrafficLineStaticVertex> & staticGeometry);
void FillColorsCache(ref_ptr<dp::TextureManager> textures);
void FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state,
@ -235,7 +193,6 @@ private:
array<dp::TextureManager::ColorRegion, static_cast<size_t>(traffic::SpeedGroup::Count)> m_colorsCache;
bool m_colorsCacheValid = false;
bool m_colorsCacheRefreshed = false;
drape_ptr<BatchersPool<TrafficBatcherKey, TrafficBatcherKeyComparator>> m_batchersPool;
TFlushRenderDataFn m_flushRenderDataFn;

View file

@ -111,14 +111,6 @@ void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng, TrafficR
ref_ptr<dp::GpuProgram> program = mng->GetProgram(rd.m_state.GetProgramIndex());
program->Bind();
rd.m_bucket->GetBuffer()->Build(program);
rd.m_handles.reserve(rd.m_bucket->GetOverlayHandlesCount());
for (size_t j = 0; j < rd.m_bucket->GetOverlayHandlesCount(); j++)
{
TrafficHandle * handle = static_cast<TrafficHandle *>(rd.m_bucket->GetOverlayHandle(j).get());
rd.m_handles.emplace_back(handle);
rd.m_boundingBox.Add(handle->GetBoundingBox());
}
}
void TrafficRenderer::OnUpdateViewport(CoverageResult const & coverage, int currentZoomLevel,
@ -143,28 +135,6 @@ void TrafficRenderer::OnGeometryReady(int currentZoomLevel)
}), m_renderData.end());
}
void TrafficRenderer::UpdateTraffic(TrafficSegmentsColoring const & trafficColoring)
{
for (TrafficRenderData & renderData : m_renderData)
{
auto coloringIt = trafficColoring.find(renderData.m_mwmId);
if (coloringIt == trafficColoring.end())
continue;
for (size_t i = 0; i < renderData.m_handles.size(); i++)
{
auto it = coloringIt->second.find(renderData.m_handles[i]->GetSegmentId());
if (it != coloringIt->second.end())
{
auto texCoordIt = m_texCoords.find(static_cast<size_t>(it->second));
if (texCoordIt == m_texCoords.end())
continue;
renderData.m_handles[i]->SetTexCoord(texCoordIt->second);
}
}
}
}
void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, float opacity,
ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms)
@ -172,8 +142,6 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, fl
if (m_renderData.empty() || zoomLevel < kRoadClass0ZoomLevel)
return;
m2::RectD const clipRect = screen.ClipRect();
auto const style = GetStyleReader().GetCurrentStyle();
dp::Color const lightArrowColor = df::GetColorConstant(style, df::TrafficArrowLight);
dp::Color const darkArrowColor = df::GetColorConstant(style, df::TrafficArrowDark);
@ -182,9 +150,6 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, fl
GLFunctions::glClearDepth();
for (TrafficRenderData & renderData : m_renderData)
{
if (!clipRect.IsIntersect(renderData.m_boundingBox))
continue;
if (renderData.m_state.GetDrawAsLine())
{
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgramIndex());
@ -208,37 +173,30 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, fl
int minVisibleArrowZoomLevel = kMinVisibleArrowZoomLevel;
float outline = 0.0f;
if (renderData.m_bucket->GetOverlayHandlesCount() > 0)
int visibleZoomLevel = kRoadClass0ZoomLevel;
if (renderData.m_roadClass == RoadClass::Class0)
{
TrafficHandle * handle = static_cast<TrafficHandle *>(renderData.m_bucket->GetOverlayHandle(0).get());
ASSERT(handle != nullptr, ());
int visibleZoomLevel = kRoadClass0ZoomLevel;
if (handle->GetRoadClass() == RoadClass::Class0)
{
outline = (zoomLevel <= kOutlineMinZoomLevel ? 1.0 : 0.0);
}
else if (handle->GetRoadClass() == RoadClass::Class1)
{
outline = (zoomLevel <= kOutlineMinZoomLevel ? 1.0 : 0.0);
visibleZoomLevel = kRoadClass1ZoomLevel;
}
else if (handle->GetRoadClass() == RoadClass::Class2)
{
visibleZoomLevel = kRoadClass2ZoomLevel;
minVisibleArrowZoomLevel = kRoadClass2MinVisibleArrowZoomLevel;
}
if (zoomLevel < visibleZoomLevel)
continue;
leftPixelHalfWidth = CalculateHalfWidth(screen, handle->GetRoadClass(), true /* left */);
invLeftPixelLength = 1.0f / (2.0f * leftPixelHalfWidth * kTrafficArrowAspect);
rightPixelHalfWidth = CalculateHalfWidth(screen, handle->GetRoadClass(), false /* left */);
float const kEps = 1e-5;
if (fabs(leftPixelHalfWidth) < kEps && fabs(rightPixelHalfWidth) < kEps)
continue;
outline = (zoomLevel <= kOutlineMinZoomLevel ? 1.0 : 0.0);
}
else if (renderData.m_roadClass == RoadClass::Class1)
{
outline = (zoomLevel <= kOutlineMinZoomLevel ? 1.0 : 0.0);
visibleZoomLevel = kRoadClass1ZoomLevel;
}
else if (renderData.m_roadClass == RoadClass::Class2)
{
visibleZoomLevel = kRoadClass2ZoomLevel;
minVisibleArrowZoomLevel = kRoadClass2MinVisibleArrowZoomLevel;
}
if (zoomLevel < visibleZoomLevel)
continue;
leftPixelHalfWidth = CalculateHalfWidth(screen, renderData.m_roadClass, true /* left */);
invLeftPixelLength = 1.0f / (2.0f * leftPixelHalfWidth * kTrafficArrowAspect);
rightPixelHalfWidth = CalculateHalfWidth(screen, renderData.m_roadClass, false /* left */);
float const kEps = 1e-5;
if (fabs(leftPixelHalfWidth) < kEps && fabs(rightPixelHalfWidth) < kEps)
continue;
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgramIndex());
program->Bind();
@ -264,15 +222,9 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, fl
}
}
void TrafficRenderer::SetTexCoords(TrafficTexCoords && texCoords)
{
m_texCoords = move(texCoords);
}
void TrafficRenderer::ClearGLDependentResources()
{
m_renderData.clear();
m_texCoords.clear();
}
void TrafficRenderer::Clear(MwmSet::MwmId const & mwmId)

View file

@ -23,10 +23,6 @@ public:
void AddRenderData(ref_ptr<dp::GpuProgramManager> mng,
TrafficRenderData && renderData);
void SetTexCoords(TrafficTexCoords && texCoords);
void UpdateTraffic(TrafficSegmentsColoring const & trafficColoring);
void RenderTraffic(ScreenBase const & screen, int zoomLevel, float opacity,
ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
@ -47,7 +43,6 @@ private:
static float GetPixelWidthInternal(RoadClass const & roadClass, int zoomLevel);
vector<TrafficRenderData> m_renderData;
TrafficTexCoords m_texCoords;
};
} // namespace df