User marks generator fixes.

This commit is contained in:
Daria Volvenkova 2017-06-23 18:45:16 +03:00 committed by Roman Kuznetsov
parent 85a5f9996e
commit 891bcaa629
14 changed files with 287 additions and 339 deletions

View file

@ -32,6 +32,7 @@ BackendRenderer::BackendRenderer(Params && params)
, m_readManager(make_unique_dp<ReadManager>(params.m_commutator, m_model,
params.m_allow3dBuildings, params.m_trafficEnabled))
, m_trafficGenerator(make_unique_dp<TrafficGenerator>(bind(&BackendRenderer::FlushTrafficRenderData, this, _1)))
, m_userMarkGenerator(make_unique_dp<UserMarkGenerator>(bind(&BackendRenderer::FlushUserMarksRenderData, this, _1, _2)))
, m_requestedTiles(params.m_requestedTiles)
, m_updateCurrentCountryFn(params.m_updateCurrentCountryFn)
, m_metalineManager(make_unique_dp<MetalineManager>(params.m_commutator, m_model))
@ -167,6 +168,7 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
{
ref_ptr<TileReadEndMessage> msg = message;
m_batchersPool->ReleaseBatcher(msg->GetKey());
m_userMarkGenerator->GenerateUserMarksGeometry(msg->GetKey(), m_texMng);
break;
}
@ -251,21 +253,11 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
case Message::UpdateUserMarkLayer:
{
ref_ptr<UpdateUserMarkLayerMessage> msg = message;
UserMarksProvider const * marksProvider = msg->StartProcess();
if (marksProvider->IsDirty())
{
size_t const layerId = msg->GetLayerId();
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<ClearUserMarkLayerMessage>(layerId),
MessagePriority::Normal);
TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng);
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FlushUserMarksMessage>(layerId, move(shapes)),
MessagePriority::Normal);
}
msg->EndProcess();
size_t const layerId = msg->GetLayerId();
m_userMarkGenerator->SetUserMarks(static_cast<GroupID>(layerId), msg->AcceptRenderParams());
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<InvalidateUserMarksMessage>(layerId),
MessagePriority::Normal);
break;
}
@ -579,6 +571,13 @@ void BackendRenderer::FlushTrafficRenderData(TrafficRenderData && renderData)
MessagePriority::Normal);
}
void BackendRenderer::FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData)
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FlushUserMarksMessage>(groupId, std::move(renderData)),
MessagePriority::Normal);
}
void BackendRenderer::CleanupOverlays(TileKey const & tileKey)
{
auto const functor = [&tileKey](OverlayRenderData const & data)

View file

@ -9,6 +9,7 @@
#include "drape_frontend/overlay_batcher.hpp"
#include "drape_frontend/requested_tiles.hpp"
#include "drape_frontend/traffic_generator.hpp"
#include "drape_frontend/user_mark_generator.hpp"
#include "drape/pointers.hpp"
#include "drape/viewport.hpp"
@ -95,6 +96,7 @@ private:
void FlushGeometry(TileKey const & key, dp::GLState const & state, drape_ptr<dp::RenderBucket> && buffer);
void FlushTrafficRenderData(TrafficRenderData && renderData);
void FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData);
void CleanupOverlays(TileKey const & tileKey);
@ -103,6 +105,7 @@ private:
drape_ptr<ReadManager> m_readManager;
drape_ptr<RouteBuilder> m_routeBuilder;
drape_ptr<TrafficGenerator> m_trafficGenerator;
drape_ptr<UserMarkGenerator> m_userMarkGenerator;
drape_ptr<DrapeApiBuilder> m_drapeApiBuilder;
gui::LayerCacher m_guiCacher;

View file

@ -209,8 +209,23 @@ void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible)
void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider)
{
auto renderCollection = make_unique_dp<UserMarksRenderCollection>();
renderCollection->reserve(provider->GetUserPointCount());
for (size_t i = 0, sz = provider->GetUserPointCount(); i < sz; ++i)
{
UserPointMark const * mark = provider->GetUserPointMark(i);
UserMarkRenderParams renderInfo;
renderInfo.m_anchor = mark->GetAnchor();
renderInfo.m_depth = mark->GetDepth();
renderInfo.m_isVisible = mark->IsVisible();
renderInfo.m_pivot = mark->GetPivot();
renderInfo.m_pixelOffset = mark->GetPixelOffset();
renderInfo.m_runCreationAnim = mark->RunCreationAnim();
renderInfo.m_symbolName = mark->GetSymbolName();
renderCollection->emplace_back(std::move(renderInfo));
}
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<UpdateUserMarkLayerMessage>(layerId, provider),
make_unique_dp<UpdateUserMarkLayerMessage>(layerId, std::move(renderCollection)),
MessagePriority::Normal);
}

View file

@ -114,7 +114,6 @@ SOURCES += \
watch/geometry_processors.cpp \
watch/feature_processor.cpp \
watch/default_font.cpp \
user_mark_builder.cpp \
user_mark_generator.cpp
HEADERS += \
@ -237,7 +236,6 @@ HEADERS += \
watch/brush_info.hpp \
watch/geometry_processors.hpp \
watch/feature_processor.hpp \
user_mark_builder.hpp \
user_mark_generator.hpp
OTHER_FILES += \

View file

@ -298,13 +298,14 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
{
ref_ptr<FlushUserMarksMessage> msg = message;
size_t const layerId = msg->GetLayerId();
for (UserMarkShape & shape : msg->GetShapes())
TUserMarksRenderData marksRenderData = msg->AcceptRenderData();
for (UserMarkRenderData & renderData : marksRenderData)
{
PrepareBucket(shape.m_state, shape.m_bucket);
auto program = m_gpuProgramManager->GetProgram(shape.m_state.GetProgramIndex());
auto program3d = m_gpuProgramManager->GetProgram(shape.m_state.GetProgram3dIndex());
auto group = make_unique_dp<UserMarkRenderGroup>(layerId, shape.m_state, shape.m_tileKey,
std::move(shape.m_bucket));
PrepareBucket(renderData.m_state, renderData.m_bucket);
auto program = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgramIndex());
auto program3d = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgram3dIndex());
auto group = make_unique_dp<UserMarkRenderGroup>(layerId, renderData.m_state, renderData.m_tileKey,
std::move(renderData.m_bucket));
m_userMarkRenderGroups.push_back(std::move(group));
m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms));
}
@ -1302,7 +1303,7 @@ void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView)
for (auto const & group : m_userMarkRenderGroups)
{
ASSERT(group.get() != nullptr, ());
if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end())
//if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end())
{
if (!group->CanBeClipped() || screenRect.IsIntersect(group->GetTileKey().GetGlobalRect()))
RenderSingleGroup(modelView, make_ref(group));

View file

@ -23,6 +23,7 @@ public:
ClearUserMarkLayer,
ChangeUserMarkLayerVisibility,
UpdateUserMarkLayer,
InvalidateUserMarks,
FlushUserMarks,
GuiLayerRecached,
GuiRecache,

View file

@ -16,6 +16,7 @@
#include "drape_frontend/selection_shape.hpp"
#include "drape_frontend/tile_utils.hpp"
#include "drape_frontend/traffic_generator.hpp"
#include "drape_frontend/user_mark_generator.hpp"
#include "drape_frontend/user_mark_shapes.hpp"
#include "drape_frontend/user_marks_provider.hpp"
@ -237,62 +238,47 @@ private:
class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage
{
public:
UpdateUserMarkLayerMessage(size_t layerId, UserMarksProvider * provider)
UpdateUserMarkLayerMessage(size_t layerId, drape_ptr<UserMarksRenderCollection> && renderParams)
: BaseUserMarkLayerMessage(layerId)
, m_provider(provider)
{
m_provider->IncrementCounter();
}
, m_renderParams(std::move(renderParams))
{}
~UpdateUserMarkLayerMessage() override
{
ASSERT(m_inProcess == false, ());
m_provider->DecrementCounter();
if (m_provider->IsPendingOnDelete() && m_provider->CanBeDeleted())
delete m_provider;
}
{}
Type GetType() const override { return Message::UpdateUserMarkLayer; }
UserMarksProvider const * StartProcess()
{
m_provider->BeginRead();
#ifdef DEBUG
m_inProcess = true;
#endif
return m_provider;
}
void EndProcess()
{
#ifdef DEBUG
m_inProcess = false;
#endif
m_provider->EndRead();
}
drape_ptr<UserMarksRenderCollection> && AcceptRenderParams() { return std::move(m_renderParams); }
private:
UserMarksProvider * m_provider;
#ifdef DEBUG
bool m_inProcess;
#endif
drape_ptr<UserMarksRenderCollection> m_renderParams;
};
class FlushUserMarksMessage : public BaseUserMarkLayerMessage
{
public:
FlushUserMarksMessage(size_t layerId, TUserMarkShapes && shapes)
FlushUserMarksMessage(size_t layerId, TUserMarksRenderData && renderData)
: BaseUserMarkLayerMessage(layerId)
, m_shapes(move(shapes))
, m_renderData(move(renderData))
{}
Type GetType() const override { return Message::FlushUserMarks; }
bool IsGLContextDependent() const override { return true; }
TUserMarkShapes & GetShapes() { return m_shapes; }
TUserMarksRenderData && AcceptRenderData() { return std::move(m_renderData); }
private:
TUserMarkShapes m_shapes;
TUserMarksRenderData m_renderData;
};
class InvalidateUserMarksMessage : public BaseUserMarkLayerMessage
{
public:
InvalidateUserMarksMessage(size_t layerId)
: BaseUserMarkLayerMessage(layerId)
{}
Type GetType() const override { return Message::InvalidateUserMarks; }
};
class GuiLayerRecachedMessage : public Message

View file

@ -1,16 +0,0 @@
#include "drape_frontend/user_mark_builder.hpp"
namespace df
{
UserMarkBuilder::UserMarkBuilder(TFlushFn const & flushFn)
: m_flushFn(flushFn)
{
}
void UserMarkBuilder::BuildUserMarks(UserMarksRenderCollection const & marks, MarkIndexesCollection && indexes,
ref_ptr<dp::TextureManager> textures)
{
}
} // namespace df

View file

@ -1,20 +0,0 @@
#pragma once
#include "drape_frontend/user_mark_shapes.hpp"
#include "drape_frontend/user_mark_generator.hpp"
namespace df
{
class UserMarkBuilder
{
public:
using TFlushFn = function<void(TUserMarkShapes && shapes)>;
UserMarkBuilder(TFlushFn const & flushFn);
void BuildUserMarks(MarkGroups const & marks, MarkIndexesGroups && indexes,
ref_ptr<dp::TextureManager> textures);
private:
TFlushFn m_flushFn;
};
}

View file

@ -1,8 +1,14 @@
#include "drape_frontend/user_mark_generator.hpp"
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/shader_def.hpp"
#include "drape_frontend/shape_view_params.hpp"
#include "drape/utils/vertex_decl.hpp"
namespace df
{
UserMarkGenerator::UserMarkGenerator()
UserMarkGenerator::UserMarkGenerator(TFlushFn const & flushFn)
: m_flushFn(flushFn)
{
}
@ -24,46 +30,91 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId)
{
auto itGroupIndexes = tileGroups.second->find(groupId);
if (itGroupIndexes != tileGroups.second->end())
itGroupIndexes->second->clear();
{
itGroupIndexes->second->m_markIndexes.clear();
}
}
UserMarksRenderCollection & marks = *m_marks[groupId];
for (size_t markIndex = 0; markIndex < marks.size(); ++markIndex)
{
for (size_t zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
{
TileKey const tileKey = GetTileKeyByPoint(marks[markIndex].m_pivot, zoomLevel);
ref_ptr<MarkIndexesGroups> tileGroups;
auto itTileGroups = m_marksIndex.find(tileKey);
if (itTileGroups == m_marksIndex.end())
{
auto tileIndexesGroups = make_unique_dp<MarkIndexesGroups>();
tileGroups = make_ref(tileIndexesGroups);
m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups)));
}
else
{
tileGroups = make_ref(itTileGroups->second);
}
ref_ptr<MarkIndexesCollection> groupIndexes;
auto itGroupIndexes = tileGroups->find(groupId);
if (itGroupIndexes == tileGroups->end())
{
auto groupMarkIndexes = make_unique_dp<MarkIndexesCollection>();
groupIndexes = make_ref(groupMarkIndexes);
tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes)));
}
else
{
groupIndexes = make_ref(itGroupIndexes->second);
}
groupIndexes->push_back(static_cast<uint32_t>(markIndex));
ref_ptr<IndexesCollection> groupIndexes = GetIndexesCollection(tileKey, groupId);
groupIndexes->m_markIndexes.push_back(static_cast<uint32_t>(markIndex));
}
}
CleanIndex();
}
void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId)
{
for (auto & tileGroups : m_marksIndex)
{
auto itGroupIndexes = tileGroups.second->find(groupId);
if (itGroupIndexes != tileGroups.second->end())
{
itGroupIndexes->second->m_lineIndexes.clear();
}
}
UserLinesRenderCollection & lines = *m_lines[groupId];
for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex)
{
for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel)
{
// TODO: Calculate tiles for the line.
std::set<TileKey> tiles;
for (size_t i = 0, sz = lines[lineIndex].m_points.size(); i < sz; ++i)
{
tiles.insert(GetTileKeyByPoint(lines[lineIndex].m_points[i], zoomLevel));
}
for (auto const & tileKey : tiles)
{
ref_ptr<IndexesCollection> groupIndexes = GetIndexesCollection(tileKey, groupId);
groupIndexes->m_lineIndexes.push_back(static_cast<uint32_t>(lineIndex));
}
}
}
CleanIndex();
}
ref_ptr<IndexesCollection> UserMarkGenerator::GetIndexesCollection(TileKey const & tileKey, GroupID groupId)
{
ref_ptr<MarkIndexesGroups> tileGroups;
auto itTileGroups = m_marksIndex.find(tileKey);
if (itTileGroups == m_marksIndex.end())
{
auto tileIndexesGroups = make_unique_dp<MarkIndexesGroups>();
tileGroups = make_ref(tileIndexesGroups);
m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups)));
}
else
{
tileGroups = make_ref(itTileGroups->second);
}
ref_ptr<IndexesCollection> groupIndexes;
auto itGroupIndexes = tileGroups->find(groupId);
if (itGroupIndexes == tileGroups->end())
{
auto groupMarkIndexes = make_unique_dp<IndexesCollection>();
groupIndexes = make_ref(groupMarkIndexes);
tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes)));
}
else
{
groupIndexes = make_ref(itGroupIndexes->second);
}
return groupIndexes;
}
void UserMarkGenerator::CleanIndex()
{
for (auto tileIt = m_marksIndex.begin(); tileIt != m_marksIndex.end();)
{
if (tileIt->second->empty())
@ -73,11 +124,6 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId)
}
}
void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId)
{
}
void UserMarkGenerator::SetGroupVisibility(GroupID groupId, bool isVisible)
{
m_groupsVisibility[groupId] = isVisible;
@ -93,63 +139,18 @@ void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_p
for (auto & groupPair : indexesGroups)
{
GroupID groupId = groupPair.first;
MarkIndexesCollection & indexes = *groupPair.second;
UserMarksRenderCollection const & renderParams = *m_marks[groupId];
MarkIndexesCollection const & indexes = groupPair.second->m_markIndexes;
if (!m_groupsVisibility[groupId])
continue;
//if (!m_groupsVisibility[groupId])
// continue;
UserMarkBatcherKey batcherKey(tileKey, groupId);
m_batchersPool->ReserveBatcher(batcherKey);
ref_ptr<dp::Batcher> batcher = m_batchersPool->GetBatcher(batcherKey);
TUserMarksRenderData renderData;
UserMarkShape::Draw(tileKey, textures, renderParams, indexes, renderData);
dp::TextureManager::SymbolRegion region;
uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad;
uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad;
buffer_vector<UPV, 128> buffer;
buffer.reserve(vertexCount);
for (auto const markIndex : indexes)
{
UserMarkRenderInfo const & renderInfo = m_marks[markIndex];
if (!renderInfo.m_isVisible)
continue;
textures->GetSymbolRegion(renderInfo.m_symbolName, region);
m2::RectF const & texRect = region.GetTexRect();
m2::PointF const pxSize = region.GetPixelSize();
dp::Anchor const anchor = renderInfo.m_anchor;
m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar);
glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth);
bool const runAnim = renderInfo.m_runCreationAnim;
glsl::vec2 left, right, up, down;
AlignHorizontal(pxSize.x * 0.5f, anchor, left, right);
AlignVertical(pxSize.y * 0.5f, anchor, up, down);
m2::PointD const pixelOffset = pointMark->GetPixelOffset();
glsl::vec2 const offset(pixelOffset.x, pixelOffset.y);
buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim);
buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim);
buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim);
buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim);
}
dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer);
state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM);
state.SetColorTexture(region.GetTexture());
state.SetTextureFilter(gl_const::GLNearest);
uint32_t const kMaxSize = 65000;
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
drape_ptr<dp::RenderBucket> && b)
{
outShapes.emplace_back(UserMarkShape(state, move(b), key));
});
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
m_flushFn(groupId, std::move(renderData));
}
}
} // namespace df

View file

@ -16,47 +16,24 @@
namespace df
{
struct UserMarkRenderInfo
{
m2::PointD m_pivot;
m2::PointD m_pixelOffset;
std::string m_symbolName;
dp::Anchor m_anchor;
float m_depth;
bool m_runCreationAnim;
bool m_isVisible;
};
struct LineLayer
{
dp::Color m_color;
float m_width;
float m_depth;
};
struct UserLineRenderInfo
{
std::vector<LineLayer> m_layers;
std::vector<m2::PointD> m_points;
};
using UserMarksRenderCollection = std::vector<UserMarkRenderInfo>;
using UserLinesRenderCollection = std::vector<UserLineRenderInfo>;
using GroupID = uint32_t;
using MarkGroups = std::map<GroupID, drape_ptr<UserMarksRenderCollection>>;
using LineGroups = std::map<GroupID, drape_ptr<UserLinesRenderCollection>>;
using MarkIndexesCollection = std::vector<uint32_t>;
using MarkIndexesGroups = std::map<GroupID, drape_ptr<MarkIndexesCollection>>;
struct IndexesCollection
{
MarkIndexesCollection m_markIndexes;
LineIndexesCollection m_lineIndexes;
};
using MarkIndexesGroups = std::map<GroupID, drape_ptr<IndexesCollection>>;
using MarksIndex = std::map<TileKey, drape_ptr<MarkIndexesGroups>>;
class UserMarkGenerator
{
public:
using TFlushFn = function<void(TUserMarkShapes && shapes)>;
using TFlushFn = function<void(GroupID, TUserMarksRenderData && renderData)>;
UserMarkGenerator(TFlushFn const & flushFn);
@ -67,38 +44,12 @@ public:
void GenerateUserMarksGeometry(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures);
private:
TFlushFn m_flushFn;
private:
void UpdateMarksIndex(GroupID groupId);
void UpdateLinesIndex(GroupID groupId);
struct UserMarkBatcherKey
{
UserMarkBatcherKey() = default;
UserMarkBatcherKey(TileKey const & tileKey, GroupID groupId)
: m_tileKey(tileKey)
, m_groupId(groupId)
{}
GroupID m_groupId;
TileKey m_tileKey;
};
struct UserMarkBatcherKeyComparator
{
bool operator() (UserMarkBatcherKey const & lhs, UserMarkBatcherKey const & rhs) const
{
if (lhs.m_groupId == rhs.m_groupId)
return lhs.m_tileKey.LessStrict(rhs.m_tileKey);
return lhs.m_groupId < rhs.m_groupId;
}
};
void FlushGeometry(UserMarkBatcherKey const & key, dp::GLState const & state,
drape_ptr<dp::RenderBucket> && buffer);
drape_ptr<BatchersPool<UserMarkBatcherKey, UserMarkBatcherKeyComparator>> m_batchersPool;
TFlushFn m_flushRenderDataFn;
ref_ptr<IndexesCollection> GetIndexesCollection(TileKey const & tileKey, GroupID groupId);
void CleanIndex();
std::map<GroupID, bool> m_groupsVisibility;
@ -106,6 +57,8 @@ private:
LineGroups m_lines;
MarksIndex m_marksIndex;
TFlushFn m_flushFn;
};
} // namespace df

View file

@ -77,84 +77,7 @@ struct UserPointVertex : gpu::BaseVertex
};
using UPV = UserPointVertex;
void CacheUserPoints(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures,
TUserMarkShapes & outShapes)
{
size_t markCount = provider->GetUserPointCount();
if (markCount == 0)
return;
int const kZoomLevel = 10;
map<TileKey, vector<UserPointMark const *>> marks;
for (size_t i = 0; i < markCount; ++i)
{
UserPointMark const * userMark = provider->GetUserPointMark(i);
if (!userMark->IsVisible())
continue;
TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel);
marks[tileKey].push_back(userMark);
}
for (auto it = marks.begin(); it != marks.end(); ++it)
{
TileKey const & key = it->first;
m2::PointD const tileCenter = key.GetGlobalRect().Center();
sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2)
{
return v1->GetPivot().y < v2->GetPivot().y;
});
dp::TextureManager::SymbolRegion region;
uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad;
uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad;
buffer_vector<UPV, 128> buffer;
buffer.reserve(vertexCount);
for (size_t i = 0; i < it->second.size(); ++i)
{
UserPointMark const * pointMark = it->second[i];
textures->GetSymbolRegion(pointMark->GetSymbolName(), region);
m2::RectF const & texRect = region.GetTexRect();
m2::PointF const pxSize = region.GetPixelSize();
dp::Anchor const anchor = pointMark->GetAnchor();
m2::PointD const pt = MapShape::ConvertToLocal(pointMark->GetPivot(), tileCenter, kShapeCoordScalar);
glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), pointMark->GetDepth());
bool const runAnim = pointMark->RunCreationAnim();
glsl::vec2 left, right, up, down;
AlignHorizontal(pxSize.x * 0.5f, anchor, left, right);
AlignVertical(pxSize.y * 0.5f, anchor, up, down);
m2::PointD const pixelOffset = pointMark->GetPixelOffset();
glsl::vec2 const offset(pixelOffset.x, pixelOffset.y);
buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim);
buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim);
buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim);
buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim);
}
dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer);
state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM);
state.SetColorTexture(region.GetTexture());
state.SetTextureFilter(gl_const::GLNearest);
uint32_t const kMaxSize = 65000;
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
drape_ptr<dp::RenderBucket> && b)
{
outShapes.emplace_back(UserMarkShape(state, move(b), key));
});
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
}
}
/*
void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures,
TUserMarkShapes & outShapes)
{
@ -186,7 +109,7 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManag
dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state,
drape_ptr<dp::RenderBucket> && b)
{
outShapes.emplace_back(UserMarkShape(state, move(b), key));
outShapes.emplace_back(UserMarksRenderData(state, move(b), key));
});
for (auto const & lineData : it->second)
{
@ -209,15 +132,77 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManag
}
}
}
*/
} // namespace
TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures)
// static
void UserMarkShape::Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes,
TUserMarksRenderData & renderData)
{
uint32_t const vertexCount = static_cast<uint32_t>(indexes.size()) * dp::Batcher::VertexPerQuad;
uint32_t const indicesCount = static_cast<uint32_t>(indexes.size()) * dp::Batcher::IndexPerQuad;
buffer_vector<UPV, 128> buffer;
buffer.reserve(vertexCount);
// TODO: Sort once on render params receiving.
MarkIndexesCollection sortedIndexes = indexes;
sort(sortedIndexes.begin(), sortedIndexes.end(), [&renderParams](uint32_t ind1, uint32_t ind2)
{
return renderParams[ind1].m_pivot.y > renderParams[ind2].m_pivot.y;
});
dp::TextureManager::SymbolRegion region;
for (auto const markIndex : sortedIndexes)
{
UserMarkRenderParams const & renderInfo = renderParams[markIndex];
if (!renderInfo.m_isVisible)
continue;
textures->GetSymbolRegion(renderInfo.m_symbolName, region);
m2::RectF const & texRect = region.GetTexRect();
m2::PointF const pxSize = region.GetPixelSize();
dp::Anchor const anchor = renderInfo.m_anchor;
m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar);
glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth);
bool const runAnim = renderInfo.m_runCreationAnim;
glsl::vec2 left, right, up, down;
AlignHorizontal(pxSize.x * 0.5f, anchor, left, right);
AlignVertical(pxSize.y * 0.5f, anchor, up, down);
m2::PointD const pixelOffset = renderInfo.m_pixelOffset;
glsl::vec2 const offset(pixelOffset.x, pixelOffset.y);
buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim);
buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim);
buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim);
buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim);
}
dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer);
state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM);
state.SetColorTexture(region.GetTexture());
state.SetTextureFilter(gl_const::GLNearest);
uint32_t const kMaxSize = 65000;
dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize));
dp::SessionGuard guard(batcher, [&tileKey, &renderData](dp::GLState const & state,
drape_ptr<dp::RenderBucket> && b)
{
renderData.emplace_back(UserMarkRenderData(state, move(b), tileKey));
});
dp::AttributeProvider attribProvider(1, static_cast<uint32_t>(buffer.size()));
attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data()));
batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad);
}
// static
void UserLineShape::Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
UserLinesRenderCollection const & renderParams, LineIndexesCollection const & indexes,
TUserMarksRenderData & renderData)
{
TUserMarkShapes shapes;
CacheUserPoints(provider, textures, shapes);
CacheUserLines(provider, textures, shapes);
return shapes;
}
} // namespace df

View file

@ -13,21 +13,64 @@
namespace df
{
struct UserMarkShape
struct UserMarkRenderParams
{
m2::PointD m_pivot;
m2::PointD m_pixelOffset;
std::string m_symbolName;
dp::Anchor m_anchor;
float m_depth;
bool m_runCreationAnim;
bool m_isVisible;
};
struct LineLayer
{
dp::Color m_color;
float m_width;
float m_depth;
};
struct UserLineRenderParams
{
std::vector<LineLayer> m_layers;
std::vector<m2::PointD> m_points;
};
using UserMarksRenderCollection = std::vector<UserMarkRenderParams>;
using UserLinesRenderCollection = std::vector<UserLineRenderParams>;
using MarkIndexesCollection = std::vector<uint32_t>;
using LineIndexesCollection = std::vector<uint32_t>;
struct UserMarkRenderData
{
UserMarkRenderData(dp::GLState const & state,
drape_ptr<dp::RenderBucket> && bucket,
TileKey const & tileKey)
: m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey)
{}
dp::GLState m_state;
drape_ptr<dp::RenderBucket> m_bucket;
TileKey m_tileKey;
UserMarkShape(dp::GLState const & state, drape_ptr<dp::RenderBucket> && bucket,
TileKey const & tileKey)
: m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey)
{}
};
using TUserMarkShapes = vector<UserMarkShape>;
using TUserMarksRenderData = std::vector<UserMarkRenderData>;
TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider,
ref_ptr<dp::TextureManager> textures);
class UserMarkShape
{
public:
static void Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures,
UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes,
TUserMarksRenderData & renderData);
};
class UserLineShape
{
public:
static void Draw(TileKey const & tileKey, ref_ptr<dp::TextureManager> textures, UserLinesRenderCollection const & renderParams,
LineIndexesCollection const & indexes, TUserMarksRenderData & renderData);
};
} // namespace df

View file

@ -3,7 +3,6 @@
#include "drape_frontend/drape_engine.hpp"
#include "drape_frontend/tile_key.hpp"
#include "drape_frontend/user_mark_shapes.hpp"
#include "base/scope_guard.hpp"
#include "base/macros.hpp"