Merge pull request #5286 from darina/graphics_benchmark

Graphics benchmark
This commit is contained in:
Roman Kuznetsov 2017-01-26 18:45:08 +03:00 committed by GitHub
commit df9dcf693e
34 changed files with 1281 additions and 541 deletions

View file

@ -40,6 +40,7 @@ set(
${DRAPE_ROOT}/data_buffer_impl.hpp
${DRAPE_ROOT}/debug_rect_renderer.cpp
${DRAPE_ROOT}/debug_rect_renderer.hpp
${DRAPE_ROOT}/drape_diagnostics.hpp
${DRAPE_ROOT}/drape_global.hpp
${DRAPE_ROOT}/dynamic_texture.hpp
${DRAPE_ROOT}/font_texture.cpp

View file

@ -1,5 +1,7 @@
#pragma once
#include "drape/drape_diagnostics.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/overlay_tree.hpp"
#include "drape/pointers.hpp"
@ -7,8 +9,6 @@
#include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp"
//#define RENDER_DEBUG_RECTS
namespace dp
{
@ -39,3 +39,4 @@ private:
};
} // namespace dp

View file

@ -66,6 +66,7 @@ HEADERS += \
$$DRAPE_DIR/data_buffer.hpp \
$$DRAPE_DIR/data_buffer_impl.hpp \
$$DRAPE_DIR/debug_rect_renderer.hpp \
$$DRAPE_DIR/drape_diagnostics.hpp \
$$DRAPE_DIR/drape_global.hpp \
$$DRAPE_DIR/dynamic_texture.hpp \
$$DRAPE_DIR/font_texture.hpp \

View file

@ -0,0 +1,19 @@
#pragma once
//#define DRAW_TILE_NET
//#define RENDER_DEBUG_RECTS
//#define COLLECT_DISPLACEMENT_INFO
//#define DRAPE_MEASURER
//#define SCENARIO_ENABLE
#ifdef DRAPE_MEASURER
//#define RENDER_STATISTIC
//#define TILES_STATISTIC
//#define GENERATING_STATISTIC
//#define TRACK_GPU_MEM
//#define TRACK_GLYPH_USAGE
#endif

View file

@ -1,5 +1,6 @@
#pragma once
#include "drape/drape_diagnostics.hpp"
#include "drape/overlay_handle.hpp"
#include "geometry/screenbase.hpp"
@ -14,8 +15,6 @@
namespace dp
{
//#define COLLECT_DISPLACEMENT_INFO
namespace detail
{

View file

@ -9,18 +9,10 @@
namespace dp
{
GlyphUsageTracker & GlyphUsageTracker::Instance()
string GlyphUsageTracker::GlyphUsageStatistic::ToString() const
{
static GlyphUsageTracker s_inst;
return s_inst;
}
string GlyphUsageTracker::Report()
{
lock_guard<mutex> lock(m_mutex);
ostringstream ss;
ss << "\n ===== Glyphs Usage Report ===== \n";
ss << " ----- Glyphs usage report ----- \n";
ss << " Current language = " << languages::GetCurrentOrig() << "\n";
ss << " Invalid glyphs count = " << m_invalidGlyphs.size() << "\n";
ss << " Invalid glyphs: { ";
@ -40,11 +32,23 @@ string GlyphUsageTracker::Report()
ss << "}\n";
}
ss << " }\n";
ss << " ===== Glyphs Usage Report ===== \n";
ss << " ----- Glyphs usage report ----- \n";
return ss.str();
}
GlyphUsageTracker & GlyphUsageTracker::Instance()
{
static GlyphUsageTracker s_inst;
return s_inst;
}
GlyphUsageTracker::GlyphUsageStatistic GlyphUsageTracker::Report()
{
lock_guard<mutex> lock(m_mutex);
return m_glyphStat;
}
void GlyphUsageTracker::AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c)
{
lock_guard<mutex> lock(m_mutex);
@ -52,7 +56,7 @@ void GlyphUsageTracker::AddInvalidGlyph(strings::UniString const & str, strings:
if (m_processedStrings.find(strings::ToUtf8(str)) != m_processedStrings.end())
return;
++m_invalidGlyphs[c];
++m_glyphStat.m_invalidGlyphs[c];
m_processedStrings.insert(strings::ToUtf8(str));
}
@ -65,7 +69,7 @@ void GlyphUsageTracker::AddUnexpectedGlyph(strings::UniString const & str, strin
if (m_processedStrings.find(strings::ToUtf8(str)) != m_processedStrings.end())
return;
UnexpectedGlyphData & data = m_unexpectedGlyphs[c];
UnexpectedGlyphData & data = m_glyphStat.m_unexpectedGlyphs[c];
++data.m_counter;
data.m_expectedGroups.emplace(expectedGroup);
data.m_group = group;

View file

@ -1,5 +1,7 @@
#pragma once
#include "drape/drape_diagnostics.hpp"
#include "base/string_utils.hpp"
#include "std/map.hpp"
@ -9,31 +11,12 @@
#include "std/string.hpp"
#include "std/unordered_set.hpp"
//#define TRACK_GLYPH_USAGE
namespace dp
{
class GlyphUsageTracker
{
public:
static GlyphUsageTracker & Instance();
void AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c);
void AddUnexpectedGlyph(strings::UniString const & str, strings::UniChar const & c,
size_t const group, size_t const expectedGroup);
string Report();
private:
GlyphUsageTracker() = default;
GlyphUsageTracker(GlyphUsageTracker const & rhs) = delete;
GlyphUsageTracker(GlyphUsageTracker && rhs) = delete;
private:
using InvalidGlyphs = map<strings::UniChar, size_t>;
InvalidGlyphs m_invalidGlyphs;
struct UnexpectedGlyphData
{
size_t m_counter = 0;
@ -41,8 +24,31 @@ private:
set<size_t> m_expectedGroups;
};
using UnexpectedGlyphs = map<strings::UniChar, UnexpectedGlyphData>;
UnexpectedGlyphs m_unexpectedGlyphs;
using InvalidGlyphs = map<strings::UniChar, size_t>;
struct GlyphUsageStatistic
{
string ToString() const;
InvalidGlyphs m_invalidGlyphs;
UnexpectedGlyphs m_unexpectedGlyphs;
};
static GlyphUsageTracker & Instance();
void AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c);
void AddUnexpectedGlyph(strings::UniString const & str, strings::UniChar const & c,
size_t const group, size_t const expectedGroup);
GlyphUsageStatistic Report();
private:
GlyphUsageTracker() = default;
GlyphUsageTracker(GlyphUsageTracker const & rhs) = delete;
GlyphUsageTracker(GlyphUsageTracker && rhs) = delete;
private:
GlyphUsageStatistic m_glyphStat;
unordered_set<string> m_processedStrings;
mutex m_mutex;

View file

@ -6,50 +6,58 @@
namespace dp
{
string GPUMemTracker::GPUMemorySnapshot::ToString() const
{
ostringstream ss;
ss << " Summary Allocated = " << m_summaryAllocatedInMb << "Mb\n";
ss << " Summary Used = " << m_summaryUsedInMb << "Mb\n";
ss << " Tags registered = " << m_tagStats.size() << "\n";
for (auto const it : m_tagStats)
{
ss << " Tag = " << it.first << " \n";
ss << " Object count = " << it.second.m_objectsCount << "\n";
ss << " Allocated = " << it.second.m_alocatedInMb << "Mb\n";
ss << " Used = " << it.second.m_usedInMb << "Mb\n";
}
return ss.str();
}
GPUMemTracker & GPUMemTracker::Inst()
{
static GPUMemTracker s_inst;
return s_inst;
}
string GPUMemTracker::Report()
GPUMemTracker::GPUMemorySnapshot GPUMemTracker::GetMemorySnapshot()
{
uint32_t summaryUsed = 0;
uint32_t summaryAllocated = 0;
GPUMemorySnapshot memStat;
typedef tuple<size_t, uint32_t, uint32_t> TTagStat;
map<string, TTagStat> tagStats;
for (auto const it : m_memTracker)
{
TTagStat & stat = tagStats[it.first.first];
get<0>(stat)++;
get<1>(stat) += it.second.first;
get<2>(stat) += it.second.second;
threads::MutexGuard g(m_mutex);
for (auto const it : m_memTracker)
{
TagMemorySnapshot & tagStat = memStat.m_tagStats[it.first.first];
tagStat.m_objectsCount++;
tagStat.m_alocatedInMb += it.second.first;
tagStat.m_usedInMb += it.second.second;
summaryAllocated += it.second.first;
summaryUsed += it.second.second;
memStat.m_summaryAllocatedInMb += it.second.first;
memStat.m_summaryUsedInMb += it.second.second;
}
}
float byteToMb = static_cast<float>(1024 * 1024);
ostringstream ss;
ss << " ===== Mem Report ===== \n";
ss << " Summary Allocated = " << summaryAllocated / byteToMb << "\n";
ss << " Summary Used = " << summaryUsed / byteToMb << "\n";
ss << " Tags registered = " << tagStats.size() << "\n";
for (auto const it : tagStats)
for (auto & it : memStat.m_tagStats)
{
ss << " Tag = " << it.first << " \n";
ss << " Object count = " << get<0>(it.second) << "\n";
ss << " Allocated = " << get<1>(it.second) / byteToMb << "\n";
ss << " Used = " << get<2>(it.second) / byteToMb << "\n";
it.second.m_alocatedInMb /= byteToMb;
it.second.m_usedInMb /= byteToMb;
}
memStat.m_summaryAllocatedInMb /= byteToMb;
memStat.m_summaryUsedInMb /= byteToMb;
ss << " ===== Mem Report ===== \n";
return ss.str();
return memStat;
}
void GPUMemTracker::AddAllocated(string const & tag, uint32_t id, uint32_t size)
@ -63,7 +71,7 @@ void GPUMemTracker::SetUsed(string const & tag, uint32_t id, uint32_t size)
threads::MutexGuard g(m_mutex);
TAlocUsedMem & node = m_memTracker[make_pair(tag, id)];
node.second = size;
ASSERT_LESS_OR_EQUAL(node.second, node.first, ("Can't use more then allocated"));
ASSERT_LESS_OR_EQUAL(node.second, node.first, ("Can't use more than allocated"));
}
void GPUMemTracker::RemoveDeallocated(string const & tag, uint32_t id)

View file

@ -1,5 +1,7 @@
#pragma once
#include "drape/drape_diagnostics.hpp"
#include "base/mutex.hpp"
#include "std/map.hpp"
@ -7,18 +9,32 @@
#include "std/string.hpp"
#include "std/utility.hpp"
//#define TRACK_GPU_MEM
namespace dp
{
class GPUMemTracker : private noncopyable
{
public:
struct TagMemorySnapshot
{
uint32_t m_objectsCount = 0;
uint32_t m_alocatedInMb = 0;
uint32_t m_usedInMb = 0;
};
struct GPUMemorySnapshot
{
string ToString() const;
uint32_t m_summaryAllocatedInMb = 0;
uint32_t m_summaryUsedInMb = 0;
map<string, TagMemorySnapshot> m_tagStats;
};
static GPUMemTracker & Inst();
string Report();
GPUMemorySnapshot GetMemorySnapshot();
void AddAllocated(string const & tag, uint32_t id, uint32_t size);
void SetUsed(string const & tag, uint32_t id, uint32_t size);
void RemoveDeallocated(string const & tag, uint32_t id);

View file

@ -69,6 +69,8 @@ set(
drape_api_renderer.hpp
drape_engine.cpp
drape_engine.hpp
drape_measurer.cpp
drape_measurer.hpp
engine_context.cpp
engine_context.hpp
framebuffer.cpp
@ -150,6 +152,8 @@ set(
route_shape.hpp
rule_drawer.cpp
rule_drawer.hpp
scenario_manager.cpp
scenario_manager.hpp
screen_animations.cpp
screen_animations.hpp
screen_operations.cpp

View file

@ -3,6 +3,7 @@
#include "drape_frontend/backend_renderer.hpp"
#include "drape_frontend/batchers_pool.hpp"
#include "drape_frontend/drape_api_builder.hpp"
#include "drape_frontend/drape_measurer.hpp"
#include "drape_frontend/gps_track_shape.hpp"
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/message_subclasses.hpp"
@ -204,11 +205,17 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey))
{
ref_ptr<dp::Batcher> batcher = m_batchersPool->GetBatcher(tileKey);
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().StartShapesGeneration();
#endif
for (drape_ptr<MapShape> const & shape : msg->GetShapes())
{
batcher->SetFeatureMinZoom(shape->GetFeatureMinZoom());
shape->Draw(batcher, m_texMng);
}
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().EndShapesGeneration(static_cast<uint32_t>(msg->GetShapes().size()));
#endif
}
break;
}
@ -221,6 +228,9 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
{
CleanupOverlays(tileKey);
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().StartOverlayShapesGeneration();
#endif
OverlayBatcher batcher(tileKey);
for (drape_ptr<MapShape> const & shape : msg->GetShapes())
batcher.Batch(shape, m_texMng);
@ -232,6 +242,11 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
m_overlays.reserve(m_overlays.size() + renderData.size());
move(renderData.begin(), renderData.end(), back_inserter(m_overlays));
}
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().EndOverlayShapesGeneration(
static_cast<uint32_t>(msg->GetShapes().size()));
#endif
}
break;
}

View file

@ -574,4 +574,13 @@ void DrapeEngine::SetFontScaleFactor(double scaleFactor)
VisualParams::Instance().SetFontScale(scaleFactor);
}
void DrapeEngine::RunScenario(ScenarioManager::ScenarioData && scenarioData,
ScenarioManager::ScenarioCallback const & onStartFn,
ScenarioManager::ScenarioCallback const & onFinishFn)
{
auto const & manager = m_frontend->GetScenarioManager();
if (manager != nullptr)
manager->RunScenario(move(scenarioData), onStartFn, onFinishFn);
}
} // namespace df

View file

@ -4,6 +4,7 @@
#include "drape_frontend/color_constants.hpp"
#include "drape_frontend/frontend_renderer.hpp"
#include "drape_frontend/route_shape.hpp"
#include "drape_frontend/scenario_manager.hpp"
#include "drape_frontend/selection_shape.hpp"
#include "drape_frontend/threads_commutator.hpp"
@ -176,6 +177,10 @@ public:
void SetFontScaleFactor(double scaleFactor);
void RunScenario(ScenarioManager::ScenarioData && scenarioData,
ScenarioManager::ScenarioCallback const & onStartFn,
ScenarioManager::ScenarioCallback const & onFinishFn);
private:
void AddUserEvent(drape_ptr<UserEvent> && e);
void ModelViewChanged(ScreenBase const & screen);
@ -188,7 +193,6 @@ private:
void RecacheGui(bool needResetOldGui);
void RecacheMapShapes();
private:
drape_ptr<FrontendRenderer> m_frontend;
drape_ptr<BackendRenderer> m_backend;
drape_ptr<ThreadsCommutator> m_threadCommutator;

View file

@ -8,7 +8,6 @@ include($$ROOT_DIR/common.pri)
INCLUDEPATH *= $$ROOT_DIR/3party/protobuf/src
INCLUDEPATH *= $$ROOT_DIR/3party/expat/lib
INCLUDEPATH *= $$ROOT_DIR/3party/freetype/include
#DEFINES += DRAW_INFO
SOURCES += \
$$ROOT_DIR/3party/agg/agg_curves.cpp \
@ -50,6 +49,7 @@ SOURCES += \
drape_api_builder.cpp \
drape_api_renderer.cpp \
drape_engine.cpp \
drape_measurer.cpp \
engine_context.cpp \
framebuffer.cpp \
frontend_renderer.cpp \
@ -76,6 +76,7 @@ SOURCES += \
route_renderer.cpp \
route_shape.cpp \
rule_drawer.cpp \
scenario_manager.cpp \
screen_animations.cpp \
screen_operations.cpp \
selection_shape.cpp \
@ -149,6 +150,7 @@ HEADERS += \
drape_api_builder.hpp \
drape_api_renderer.hpp \
drape_engine.hpp \
drape_measurer.hpp \
engine_context.hpp \
framebuffer.hpp \
frontend_renderer.hpp \
@ -180,6 +182,7 @@ HEADERS += \
route_renderer.hpp \
route_shape.hpp \
rule_drawer.hpp \
scenario_manager.hpp \
screen_animations.hpp \
screen_operations.hpp \
selection_shape.hpp \

View file

@ -0,0 +1,417 @@
#include "drape_measurer.hpp"
namespace df
{
DrapeMeasurer & DrapeMeasurer::Instance()
{
static DrapeMeasurer s_inst;
return s_inst;
}
void DrapeMeasurer::StartBenchmark()
{
using namespace std::chrono;
m_isEnabled = true;
auto currentTime = std::chrono::steady_clock::now();
#ifdef GENERATING_STATISTIC
m_startScenePreparingTime = currentTime;
m_maxScenePreparingTime = steady_clock::duration::zero();
m_startShapesGenTime = currentTime;
m_totalShapesGenTime = steady_clock::duration::zero();
m_totalShapesCount = 0;
m_startOverlayShapesGenTime = currentTime;
m_totalOverlayShapesGenTime = steady_clock::duration::zero();
m_totalOverlayShapesCount = 0;
#endif
#ifdef TILES_STATISTIC
{
lock_guard<mutex> lock(m_tilesMutex);
m_tilesReadInfo.clear();
}
#endif
#ifdef RENDER_STATISTIC
m_totalTPF = steady_clock::duration::zero();
m_totalTPFCount = 0;
m_minFPS = std::numeric_limits<uint32_t>::max();
m_totalFPS = 0.0;
m_totalFPSCount = 0;
#endif
#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)
m_startFrameRenderTime = currentTime;
m_totalFrameRenderTime = steady_clock::duration::zero();
m_totalFramesCount = 0;
#endif
#ifdef TRACK_GPU_MEM
m_maxSnapshotValues = dp::GPUMemTracker::GPUMemorySnapshot();
m_summarySnapshotValues = dp::GPUMemTracker::GPUMemorySnapshot();
m_numberOfSnapshots = 0;
#endif
}
void DrapeMeasurer::StopBenchmark()
{
m_isEnabled = false;
}
#ifdef GENERATING_STATISTIC
void DrapeMeasurer::StartScenePreparing()
{
if (!m_isEnabled)
return;
m_startScenePreparingTime = std::chrono::steady_clock::now();
}
void DrapeMeasurer::EndScenePreparing()
{
if (!m_isEnabled)
return;
m_maxScenePreparingTime = max(m_maxScenePreparingTime,
std::chrono::steady_clock::now() - m_startScenePreparingTime);
}
void DrapeMeasurer::StartShapesGeneration()
{
m_startShapesGenTime = std::chrono::steady_clock::now();
}
void DrapeMeasurer::EndShapesGeneration(uint32_t shapesCount)
{
m_totalShapesGenTime += std::chrono::steady_clock::now() - m_startShapesGenTime;
m_totalShapesCount += shapesCount;
}
void DrapeMeasurer::StartOverlayShapesGeneration()
{
m_startOverlayShapesGenTime = std::chrono::steady_clock::now();
}
void DrapeMeasurer::EndOverlayShapesGeneration(uint32_t shapesCount)
{
m_totalOverlayShapesGenTime += std::chrono::steady_clock::now() - m_startOverlayShapesGenTime;
m_totalOverlayShapesCount += shapesCount;
}
std::string DrapeMeasurer::GeneratingStatistic::ToString() const
{
std::ostringstream ss;
ss << " ----- Generation statistic report ----- \n";
ss << " Max scene preparing time, ms = " << m_maxScenePreparingTimeInMs << "\n";
ss << " Shapes total generation time, ms = " << m_shapeGenTimeInMs << "\n";
ss << " Shapes total count = " << m_shapesCount
<< ", (" << static_cast<double>(m_shapeGenTimeInMs) / m_shapesCount << " ms per shape)\n";
ss << " Overlay shapes total generation time, ms = " << m_overlayShapeGenTimeInMs << "\n";
ss << " Overlay shapes total count = " << m_overlayShapesCount
<< ", (" << static_cast<double>(m_overlayShapeGenTimeInMs) / m_overlayShapesCount << " ms per overlay)\n";
ss << " ----- Generation statistic report ----- \n";
return ss.str();
}
DrapeMeasurer::GeneratingStatistic DrapeMeasurer::GetGeneratingStatistic()
{
using namespace std::chrono;
GeneratingStatistic statistic;
statistic.m_shapesCount = m_totalShapesCount;
statistic.m_shapeGenTimeInMs =
static_cast<uint32_t>(duration_cast<milliseconds>(m_totalShapesGenTime).count());
statistic.m_overlayShapesCount = m_totalOverlayShapesCount;
statistic.m_overlayShapeGenTimeInMs =
static_cast<uint32_t>(duration_cast<milliseconds>(m_totalOverlayShapesGenTime).count());
statistic.m_maxScenePreparingTimeInMs =
static_cast<uint32_t>(duration_cast<milliseconds>(m_maxScenePreparingTime).count());
return statistic;
}
#endif
#ifdef RENDER_STATISTIC
std::string DrapeMeasurer::RenderStatistic::ToString() const
{
std::ostringstream ss;
ss << " ----- Render statistic report ----- \n";
ss << " FPS = " << m_FPS << "\n";
ss << " min FPS = " << m_minFPS << "\n";
ss << " Frame render time, ms = " << m_frameRenderTimeInMs << "\n";
ss << " ----- Render statistic report ----- \n";
return ss.str();
}
DrapeMeasurer::RenderStatistic DrapeMeasurer::GetRenderStatistic()
{
using namespace std::chrono;
RenderStatistic statistic;
statistic.m_FPS = m_totalFPS / m_totalFPSCount;
statistic.m_minFPS = m_minFPS;
statistic.m_frameRenderTimeInMs =
static_cast<uint32_t>(duration_cast<milliseconds>(m_totalTPF).count()) / m_totalTPFCount;
return statistic;
}
#endif
#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)
void DrapeMeasurer::BeforeRenderFrame()
{
if (!m_isEnabled)
return;
m_startFrameRenderTime = std::chrono::steady_clock::now();
}
void DrapeMeasurer::AfterRenderFrame()
{
using namespace std::chrono;
if (!m_isEnabled)
return;
++m_totalFramesCount;
m_totalFrameRenderTime += steady_clock::now() - m_startFrameRenderTime;
auto elapsed = duration_cast<milliseconds>(m_totalFrameRenderTime).count();
if (elapsed > 1000)
{
#ifdef RENDER_STATISTIC
double fps = m_totalFramesCount * 1000.0 / elapsed;
m_minFPS = std::min(m_minFPS, static_cast<uint32_t>(fps));
m_totalFPS += fps;
++m_totalFPSCount;
m_totalTPF += m_totalFrameRenderTime / m_totalFramesCount;
++m_totalTPFCount;
#endif
m_totalFramesCount = 0;
m_totalFrameRenderTime = steady_clock::duration::zero();
#ifdef TRACK_GPU_MEM
TakeGPUMemorySnapshot();
#endif
}
}
#endif
#ifdef TILES_STATISTIC
std::string DrapeMeasurer::TileStatistic::ToString() const
{
std::ostringstream ss;
ss << " ----- Tiles read statistic report ----- \n";
ss << " Tile read time, ms = " << m_tileReadTimeInMs << "\n";
ss << " Tiles count = " << m_totalTilesCount << "\n";
ss << " ----- Tiles read statistic report ----- \n";
return ss.str();
}
void DrapeMeasurer::StartTileReading()
{
if (!m_isEnabled)
return;
threads::ThreadID tid = threads::GetCurrentThreadID();
std::shared_ptr<TileReadInfo> tileInfo;
{
lock_guard<mutex> lock(m_tilesMutex);
auto const it = m_tilesReadInfo.find(tid);
if (it != m_tilesReadInfo.end())
{
tileInfo = it->second;
}
else
{
tileInfo = std::make_shared<TileReadInfo>();
m_tilesReadInfo.insert(make_pair(tid, tileInfo));
}
}
auto const currentTime = std::chrono::steady_clock::now();
tileInfo->m_startTileReadTime = currentTime;
}
void DrapeMeasurer::EndTileReading()
{
if (!m_isEnabled)
return;
auto const currentTime = std::chrono::steady_clock::now();
threads::ThreadID tid = threads::GetCurrentThreadID();
std::shared_ptr<TileReadInfo> tileInfo;
{
lock_guard<mutex> lock(m_tilesMutex);
auto const it = m_tilesReadInfo.find(tid);
if (it != m_tilesReadInfo.end())
tileInfo = it->second;
else
return;
}
auto passedTime = currentTime - tileInfo->m_startTileReadTime;
tileInfo->m_totalTileReadTime += passedTime;
++tileInfo->m_totalTilesCount;
}
DrapeMeasurer::TileStatistic DrapeMeasurer::GetTileStatistic()
{
using namespace std::chrono;
TileStatistic statistic;
{
lock_guard<mutex> lock(m_tilesMutex);
for (auto const & it : m_tilesReadInfo)
{
statistic.m_tileReadTimeInMs +=
static_cast<uint32_t>(duration_cast<milliseconds>(it.second->m_totalTileReadTime).count());
statistic.m_totalTilesCount += it.second->m_totalTilesCount;
}
}
if (statistic.m_totalTilesCount > 0)
statistic.m_tileReadTimeInMs /= statistic.m_totalTilesCount;
return statistic;
}
#endif
#ifdef TRACK_GPU_MEM
std::string DrapeMeasurer::GPUMemoryStatistic::ToString() const
{
std::ostringstream ss;
ss << " ----- GPU memory report ----- \n";
ss << " --Max memory values:\n";
ss << m_maxMemoryValues.ToString();
ss << "\n --Average memory values:\n";
ss << m_averageMemoryValues.ToString();
ss << " ----- GPU memory report ----- \n";
return ss.str();
}
void DrapeMeasurer::TakeGPUMemorySnapshot()
{
dp::GPUMemTracker::GPUMemorySnapshot snap = dp::GPUMemTracker::Inst().GetMemorySnapshot();
for (auto const & tagPair : snap.m_tagStats)
{
auto itMax = m_maxSnapshotValues.m_tagStats.find(tagPair.first);
if (itMax != m_maxSnapshotValues.m_tagStats.end())
{
itMax->second.m_objectsCount = std::max(itMax->second.m_objectsCount,
tagPair.second.m_objectsCount);
itMax->second.m_alocatedInMb = std::max(itMax->second.m_alocatedInMb,
tagPair.second.m_alocatedInMb);
itMax->second.m_usedInMb = std::max(itMax->second.m_alocatedInMb,
tagPair.second.m_usedInMb);
}
else
{
m_maxSnapshotValues.m_tagStats.insert(tagPair);
}
auto itSummary = m_summarySnapshotValues.m_tagStats.find(tagPair.first);
if (itSummary != m_summarySnapshotValues.m_tagStats.end())
{
itSummary->second.m_objectsCount += tagPair.second.m_objectsCount;
itSummary->second.m_alocatedInMb += tagPair.second.m_alocatedInMb;
itSummary->second.m_usedInMb += tagPair.second.m_usedInMb;
}
else
{
m_summarySnapshotValues.m_tagStats.insert(tagPair);
}
}
m_maxSnapshotValues.m_summaryAllocatedInMb = std::max(snap.m_summaryAllocatedInMb,
m_maxSnapshotValues.m_summaryAllocatedInMb);
m_maxSnapshotValues.m_summaryUsedInMb = std::max(snap.m_summaryUsedInMb,
m_maxSnapshotValues.m_summaryUsedInMb);
m_summarySnapshotValues.m_summaryAllocatedInMb += snap.m_summaryAllocatedInMb;
m_summarySnapshotValues.m_summaryUsedInMb += snap.m_summaryUsedInMb;
++m_numberOfSnapshots;
}
DrapeMeasurer::GPUMemoryStatistic DrapeMeasurer::GetGPUMemoryStatistic()
{
GPUMemoryStatistic statistic;
statistic.m_maxMemoryValues = m_maxSnapshotValues;
statistic.m_averageMemoryValues = m_summarySnapshotValues;
if (m_numberOfSnapshots > 0)
{
for (auto & tagPair : statistic.m_averageMemoryValues.m_tagStats)
{
tagPair.second.m_objectsCount /= m_numberOfSnapshots;
tagPair.second.m_alocatedInMb /= m_numberOfSnapshots;
tagPair.second.m_usedInMb /= m_numberOfSnapshots;
}
statistic.m_averageMemoryValues.m_summaryAllocatedInMb /= m_numberOfSnapshots;
statistic.m_averageMemoryValues.m_summaryUsedInMb /= m_numberOfSnapshots;
}
return statistic;
}
#endif
std::string DrapeMeasurer::DrapeStatistic::ToString() const
{
std::ostringstream ss;
ss << "\n ===== Drape statistic report ===== \n";
#ifdef RENDER_STATISTIC
ss << "\n" << m_renderStatistic.ToString() << "\n";
#endif
#ifdef TILES_STATISTIC
ss << "\n" << m_tileStatistic.ToString() << "\n";
#endif
#ifdef GENERATING_STATISTIC
ss << "\n" << m_generatingStatistic.ToString() << "\n";
#endif
#ifdef TRACK_GPU_MEM
ss << "\n" << m_gpuMemStatistic.ToString() << "\n";
#endif
#ifdef TRACK_GLYPH_USAGE
ss << "\n" << m_glyphStatistic.ToString() << "\n";
#endif
ss << "\n ===== Drape statistic report ===== \n\n";
return ss.str();
}
DrapeMeasurer::DrapeStatistic DrapeMeasurer::GetDrapeStatistic()
{
DrapeStatistic statistic;
#ifdef RENDER_STATISTIC
statistic.m_renderStatistic = GetRenderStatistic();
#endif
#ifdef TILES_STATISTIC
statistic.m_tileStatistic = GetTileStatistic();
#endif
#ifdef GENERATING_STATISTIC
statistic.m_generatingStatistic = GetGeneratingStatistic();
#endif
#ifdef TRACK_GPU_MEM
statistic.m_gpuMemStatistic = GetGPUMemoryStatistic();
#endif
#ifdef TRACK_GLYPH_USAGE
statistic.m_glyphStatistic = dp::GlyphUsageTracker::Instance().Report();
#endif
return statistic;
}
} // namespace df

View file

@ -0,0 +1,175 @@
#pragma once
#include "drape/drape_diagnostics.hpp"
#include "drape/utils/gpu_mem_tracker.hpp"
#include "drape/utils/glyph_usage_tracker.hpp"
#include "base/thread.hpp"
#include "base/timer.hpp"
#include <chrono>
#include <map>
#include <memory>
#include <mutex>
#include <numeric>
#include <vector>
namespace df
{
class DrapeMeasurer
{
public:
static DrapeMeasurer & Instance();
void StartBenchmark();
void StopBenchmark();
#ifdef RENDER_STATISTIC
struct RenderStatistic
{
std::string ToString() const;
uint32_t m_FPS = 0;
uint32_t m_minFPS = 0;
uint32_t m_frameRenderTimeInMs = 0;
};
RenderStatistic GetRenderStatistic();
#endif
#ifdef TILES_STATISTIC
struct TileStatistic
{
std::string ToString() const;
uint32_t m_totalTilesCount = 0;
uint32_t m_tileReadTimeInMs = 0;
};
void StartTileReading();
void EndTileReading();
TileStatistic GetTileStatistic();
#endif
#ifdef GENERATING_STATISTIC
struct GeneratingStatistic
{
std::string ToString() const;
uint32_t m_maxScenePreparingTimeInMs = 0;
uint32_t m_shapesCount = 0;
uint32_t m_shapeGenTimeInMs = 0;
uint32_t m_overlayShapesCount = 0;
uint32_t m_overlayShapeGenTimeInMs = 0;
};
void StartScenePreparing();
void EndScenePreparing();
void StartShapesGeneration();
void EndShapesGeneration(uint32_t shapesCount);
void StartOverlayShapesGeneration();
void EndOverlayShapesGeneration(uint32_t shapesCount);
GeneratingStatistic GetGeneratingStatistic();
#endif
#ifdef TRACK_GPU_MEM
struct GPUMemoryStatistic
{
std::string ToString() const;
dp::GPUMemTracker::GPUMemorySnapshot m_averageMemoryValues;
dp::GPUMemTracker::GPUMemorySnapshot m_maxMemoryValues;
};
GPUMemoryStatistic GetGPUMemoryStatistic();
#endif
#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)
void BeforeRenderFrame();
void AfterRenderFrame();
#endif
struct DrapeStatistic
{
std::string ToString() const;
#ifdef RENDER_STATISTIC
RenderStatistic m_renderStatistic;
#endif
#ifdef TILES_STATISTIC
TileStatistic m_tileStatistic;
#endif
#ifdef GENERATING_STATISTIC
GeneratingStatistic m_generatingStatistic;
#endif
#ifdef TRACK_GPU_MEM
GPUMemoryStatistic m_gpuMemStatistic;
#endif
#ifdef TRACK_GLYPH_USAGE
dp::GlyphUsageTracker::GlyphUsageStatistic m_glyphStatistic;
#endif
};
DrapeStatistic GetDrapeStatistic();
private:
DrapeMeasurer() = default;
bool m_isEnabled = false;
#ifdef GENERATING_STATISTIC
std::chrono::time_point<std::chrono::steady_clock> m_startScenePreparingTime;
std::chrono::nanoseconds m_maxScenePreparingTime;
std::chrono::time_point<std::chrono::steady_clock> m_startShapesGenTime;
std::chrono::nanoseconds m_totalShapesGenTime;
uint32_t m_totalShapesCount = 0;
std::chrono::time_point<std::chrono::steady_clock> m_startOverlayShapesGenTime;
std::chrono::nanoseconds m_totalOverlayShapesGenTime;
uint32_t m_totalOverlayShapesCount = 0;
#endif
#ifdef TILES_STATISTIC
struct TileReadInfo
{
std::chrono::time_point<std::chrono::steady_clock> m_startTileReadTime;
std::chrono::nanoseconds m_totalTileReadTime;
uint32_t m_totalTilesCount = 0;
};
std::map<threads::ThreadID, std::shared_ptr<TileReadInfo>> m_tilesReadInfo;
std::mutex m_tilesMutex;
#endif
#ifdef RENDER_STATISTIC
std::chrono::nanoseconds m_totalTPF;
uint32_t m_totalTPFCount = 0;
uint32_t m_minFPS = std::numeric_limits<uint32_t>::max();
double m_totalFPS = 0.0;
uint32_t m_totalFPSCount = 0;
#endif
#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)
std::chrono::time_point<std::chrono::steady_clock> m_startFrameRenderTime;
std::chrono::nanoseconds m_totalFrameRenderTime;
uint32_t m_totalFramesCount = 0;
#endif
#ifdef TRACK_GPU_MEM
void TakeGPUMemorySnapshot();
dp::GPUMemTracker::GPUMemorySnapshot m_maxSnapshotValues;
dp::GPUMemTracker::GPUMemorySnapshot m_summarySnapshotValues;
uint32_t m_numberOfSnapshots = 0;
#endif
};
}

View file

@ -2,14 +2,17 @@
#include "drape_frontend/gui/drape_gui.hpp"
#include "drape_frontend/gui/ruler_helper.hpp"
#include "drape_frontend/animation_system.hpp"
#include "drape_frontend/batch_merge_helper.hpp"
#include "drape_frontend/drape_measurer.hpp"
#include "drape_frontend/framebuffer.hpp"
#include "drape_frontend/frontend_renderer.hpp"
#include "drape_frontend/message_subclasses.hpp"
#include "drape_frontend/scenario_manager.hpp"
#include "drape_frontend/screen_operations.hpp"
#include "drape_frontend/transparent_layer.hpp"
#include "drape_frontend/visual_params.hpp"
#include "drape_frontend/user_mark_shapes.hpp"
#include "drape_frontend/batch_merge_helper.hpp"
#include "drape/debug_rect_renderer.hpp"
#include "drape/shader_def.hpp"
@ -135,12 +138,10 @@ FrontendRenderer::FrontendRenderer(Params const & params)
, m_needRestoreSize(false)
, m_needRegenerateTraffic(false)
, m_trafficEnabled(params.m_trafficEnabled)
{
#ifdef DRAW_INFO
m_tpf = 0.0;
m_fps = 0.0;
#ifdef SCENARIO_ENABLE
, m_scenarioManager(new ScenarioManager(this))
#endif
{
#ifdef DEBUG
m_isTeardowned = false;
#endif
@ -163,49 +164,13 @@ FrontendRenderer::~FrontendRenderer()
void FrontendRenderer::Teardown()
{
m_scenarioManager.reset();
StopThread();
#ifdef DEBUG
m_isTeardowned = true;
#endif
}
#ifdef DRAW_INFO
void FrontendRenderer::BeforeDrawFrame()
{
m_frameStartTime = m_timer.ElapsedSeconds();
}
void FrontendRenderer::AfterDrawFrame()
{
m_drawedFrames++;
double elapsed = m_timer.ElapsedSeconds();
m_tpfs.push_back(elapsed - m_frameStartTime);
if (elapsed > 1.0)
{
m_timer.Reset();
m_fps = m_drawedFrames / elapsed;
m_drawedFrames = 0;
m_tpf = accumulate(m_tpfs.begin(), m_tpfs.end(), 0.0) / m_tpfs.size();
LOG(LINFO, ("Average Fps : ", m_fps));
LOG(LINFO, ("Average Tpf : ", m_tpf));
#if defined(TRACK_GPU_MEM)
string report = dp::GPUMemTracker::Inst().Report();
LOG(LINFO, (report));
#endif
#if defined(TRACK_GLYPH_USAGE)
string glyphReport = dp::GlyphUsageTracker::Instance().Report();
LOG(LINFO, (glyphReport));
#endif
}
}
#endif
void FrontendRenderer::UpdateCanBeDeletedStatus()
{
m2::RectD const & screenRect = m_userEventStream.GetCurrentScreen().ClipRect();
@ -297,7 +262,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
UpdateCanBeDeletedStatus();
if (m_notFinishedTiles.empty())
{
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().EndScenePreparing();
#endif
m_trafficRenderer->OnGeometryReady(m_currentZoomLevel);
}
break;
}
@ -429,6 +399,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
case Message::GpsInfo:
{
#ifdef SCENARIO_ENABLE
if (m_scenarioManager->IsRunning())
break;
#endif
ref_ptr<GpsInfoMessage> msg = message;
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(),
m_userEventStream.GetCurrentScreen());
@ -1101,8 +1075,8 @@ void FrontendRenderer::EndUpdateOverlayTree()
void FrontendRenderer::RenderScene(ScreenBase const & modelView)
{
#ifdef DRAW_INFO
BeforeDrawFrame();
#if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM))
DrapeMeasurer::Instance().BeforeRenderFrame();
#endif
GLFunctions::glEnable(gl_const::GLDepthTest);
@ -1165,8 +1139,8 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
dp::DebugRectRenderer::Instance().DrawArrow(modelView, arrow);
#endif
#ifdef DRAW_INFO
AfterDrawFrame();
#if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM))
DrapeMeasurer::Instance().AfterRenderFrame();
#endif
MergeBuckets();
@ -1611,6 +1585,10 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen)
m_trafficRenderer->OnUpdateViewport(result, m_currentZoomLevel, tilesToDelete);
#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC)
DrapeMeasurer::Instance().StartScenePreparing();
#endif
return tiles;
}
@ -1808,6 +1786,10 @@ void FrontendRenderer::ReleaseResources()
void FrontendRenderer::AddUserEvent(drape_ptr<UserEvent> && event)
{
#ifdef SCENARIO_ENABLE
if (m_scenarioManager->IsRunning() && event->GetType() == UserEvent::EventType::Touch)
return;
#endif
m_userEventStream.AddEvent(move(event));
if (IsInInfinityWaiting())
CancelMessageWaiting();
@ -1904,6 +1886,11 @@ void FrontendRenderer::OnCacheRouteArrows(int routeIndex, vector<ArrowBorders> c
MessagePriority::Normal);
}
drape_ptr<ScenarioManager> const & FrontendRenderer::GetScenarioManager() const
{
return m_scenarioManager;
}
FrontendRenderer::RenderLayer::RenderLayerID FrontendRenderer::RenderLayer::GetLayerID(dp::GLState const & state)
{
if (state.GetDepthLayer() == dp::GLState::OverlayLayer)

View file

@ -2,12 +2,6 @@
#include "base/thread.hpp"
#ifdef DRAW_INFO
#include "base/timer.hpp"
#include "std/vector.hpp"
#include "std/numeric.hpp"
#endif
#include "drape_frontend/gui/layer_render.hpp"
#include "drape_frontend/backend_renderer.hpp"
@ -54,6 +48,7 @@ class SelectionShape;
class Framebuffer;
class TransparentLayer;
class SelectObjectMessage;
class ScenarioManager;
struct TapInfo
{
@ -129,19 +124,6 @@ public:
void Teardown();
#ifdef DRAW_INFO
double m_tpf;
double m_fps;
my::Timer m_timer;
double m_frameStartTime;
vector<double> m_tpfs;
int m_drawedFrames;
void BeforeDrawFrame();
void AfterDrawFrame();
#endif
void AddUserEvent(drape_ptr<UserEvent> && event);
/// MyPositionController::Listener
@ -154,6 +136,8 @@ public:
void ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero,
TAnimationCreator const & parallelAnimCreator) override;
drape_ptr<ScenarioManager> const & GetScenarioManager() const;
protected:
void AcceptMessage(ref_ptr<Message> message) override;
unique_ptr<threads::IRoutine> CreateRoutine() override;
@ -346,6 +330,8 @@ private:
bool m_needRegenerateTraffic;
bool m_trafficEnabled;
drape_ptr<ScenarioManager> m_scenarioManager;
#ifdef DEBUG
bool m_isTeardowned;
#endif

View file

@ -6,6 +6,8 @@
#include "drape_frontend/traffic_renderer.hpp"
#include "drape_frontend/visual_params.hpp"
#include "drape/drape_diagnostics.hpp"
#include "indexer/feature.hpp"
#include "indexer/feature_algo.hpp"
#include "indexer/feature_visibility.hpp"
@ -17,8 +19,6 @@
#include "std/bind.hpp"
//#define DRAW_TILE_NET
#ifdef DRAW_TILE_NET
#include "drape_frontend/line_shape.hpp"
#include "drape_frontend/text_shape.hpp"

View file

@ -0,0 +1,144 @@
#include "drape_frontend/scenario_manager.hpp"
#include "drape_frontend/user_event_stream.hpp"
namespace df
{
ScenarioManager::ScenarioManager(FrontendRenderer * frontendRenderer)
: m_frontendRenderer(frontendRenderer)
, m_needInterrupt(false)
, m_isFinished(false)
{
ASSERT(m_frontendRenderer != nullptr, ());
}
ScenarioManager::~ScenarioManager()
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_thread != nullptr)
{
m_thread->join();
m_thread.reset();
}
}
void ScenarioManager::Interrupt()
{
std::lock_guard<std::mutex> lock(m_mutex);
InterruptImpl();
}
bool ScenarioManager::RunScenario(ScenarioData && scenarioData, ScenarioCallback const & onStartFn, ScenarioCallback const & onFinishFn)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_thread != nullptr)
{
if (m_isFinished)
InterruptImpl();
else
return false; // The only scenario can be executed currently.
}
std::swap(m_scenarioData, scenarioData);
m_onStartHandler = onStartFn;
m_onFinishHandler = onFinishFn;
m_thread = my::make_unique<threads::SimpleThread>(&ScenarioManager::ThreadRoutine, this);
#ifdef DEBUG
m_threadId = m_thread->get_id();
#endif
return true;
}
bool ScenarioManager::IsRunning()
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_thread == nullptr)
return false;
if (m_isFinished)
{
InterruptImpl();
return false;
}
return true;
}
void ScenarioManager::ThreadRoutine()
{
string const scenarioName = m_scenarioData.m_name;
if (m_onStartHandler != nullptr)
m_onStartHandler(scenarioName);
for (auto const & action : m_scenarioData.m_scenario)
{
// Interrupt scenario if it's necessary.
{
std::lock_guard<std::mutex> lock(m_mutex);
if (m_needInterrupt)
{
m_needInterrupt = false;
break;
}
}
switch(action->GetType())
{
case ActionType::CenterViewport:
{
CenterViewportAction * centerViewportAction = static_cast<CenterViewportAction *>(action.get());
m_frontendRenderer->AddUserEvent(make_unique_dp<SetCenterEvent>(centerViewportAction->GetCenter(),
centerViewportAction->GetZoomLevel(),
true));
break;
}
case ActionType::WaitForTime:
{
WaitForTimeAction * waitForTimeAction = static_cast<WaitForTimeAction *>(action.get());
std::this_thread::sleep_for(waitForTimeAction->GetDuration());
break;
}
default:
LOG(LINFO, ("Unknown action in scenario"));
}
}
ScenarioCallback handler = nullptr;
{
std::lock_guard<std::mutex> lock(m_mutex);
m_scenarioData.m_scenario.clear();
m_isFinished = true;
if (m_onFinishHandler != nullptr)
{
handler = m_onFinishHandler;
m_onFinishHandler = nullptr;
}
}
if (handler != nullptr)
handler(scenarioName);
}
void ScenarioManager::InterruptImpl()
{
if (m_thread == nullptr)
return;
ASSERT_NOT_EQUAL(m_threadId, std::this_thread::get_id(), ());
if (m_isFinished)
{
m_thread->join();
m_thread.reset();
m_isFinished = false;
m_needInterrupt = false;
}
else
{
m_needInterrupt = true;
}
}
} // namespace df

View file

@ -0,0 +1,102 @@
#pragma once
#include "drape_frontend/frontend_renderer.hpp"
#include "drape/drape_diagnostics.hpp"
#include "geometry/point2d.hpp"
#include "base/stl_add.hpp"
#include "base/thread.hpp"
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <vector>
namespace df
{
class ScenarioManager
{
public:
enum class ActionType
{
CenterViewport,
WaitForTime
};
class Action
{
public:
virtual ~Action() {}
virtual ActionType GetType() = 0;
};
class CenterViewportAction : public Action
{
public:
CenterViewportAction(m2::PointD const & pt, int zoomLevel)
: m_center(pt), m_zoomLevel(zoomLevel) {}
ActionType GetType() override { return ActionType::CenterViewport; }
m2::PointD const & GetCenter() const { return m_center; }
int GetZoomLevel() const { return m_zoomLevel; }
private:
m2::PointD const m_center;
int const m_zoomLevel;
};
class WaitForTimeAction : public Action
{
public:
using Duration = std::chrono::steady_clock::duration;
WaitForTimeAction(Duration const & duration)
: m_duration(duration) {}
ActionType GetType() override { return ActionType::WaitForTime; }
Duration const & GetDuration() const { return m_duration; }
private:
Duration m_duration;
};
using Scenario = std::vector<std::unique_ptr<Action>>;
using ScenarioCallback = std::function<void(std::string const & name)>;
struct ScenarioData
{
std::string m_name;
Scenario m_scenario;
};
ScenarioManager(FrontendRenderer * frontendRenderer);
~ScenarioManager();
bool RunScenario(ScenarioData && scenarioData,
ScenarioCallback const & startHandler, ScenarioCallback const & finishHandler);
void Interrupt();
bool IsRunning();
private:
void ThreadRoutine();
void InterruptImpl();
FrontendRenderer * m_frontendRenderer;
std::mutex m_mutex;
ScenarioData m_scenarioData;
bool m_needInterrupt;
bool m_isFinished;
ScenarioCallback m_onStartHandler;
ScenarioCallback m_onFinishHandler;
#ifdef DEBUG
std::thread::id m_threadId;
#endif
std::unique_ptr<threads::SimpleThread> m_thread;
};
} // namespace df

View file

@ -1,3 +1,4 @@
#include "drape_frontend/drape_measurer.hpp"
#include "drape_frontend/engine_context.hpp"
#include "drape_frontend/map_data_provider.hpp"
#include "drape_frontend/rule_drawer.hpp"
@ -57,6 +58,9 @@ void TileInfo::ReadFeatureIndex(MapDataProvider const & model)
void TileInfo::ReadFeatures(MapDataProvider const & model)
{
#if defined(DRAPE_MEASURER) && defined(TILES_STATISTIC)
DrapeMeasurer::Instance().StartTileReading();
#endif
m_context->BeginReadTile();
// Reading can be interrupted by exception throwing
@ -73,6 +77,9 @@ void TileInfo::ReadFeatures(MapDataProvider const & model)
make_ref(m_context), m_is3dBuildings, m_trafficEnabled);
model.ReadFeatures(bind<void>(ref(drawer), _1), m_featureInfo);
}
#if defined(DRAPE_MEASURER) && defined(TILES_STATISTIC)
DrapeMeasurer::Instance().EndTileReading();
#endif
}
void TileInfo::Cancel()

View file

@ -15,6 +15,8 @@ set(
address_finder.cpp
api_mark_point.cpp
api_mark_point.hpp
benchmark_tools.hpp
benchmark_tools.cpp
bookmark_manager.cpp
bookmark_manager.hpp
bookmark.cpp

View file

@ -1,272 +0,0 @@
#include "map/benchmark_engine.hpp"
#include "map/framework.hpp"
#include "indexer/data_header.hpp"
#include "platform/settings.hpp"
#include "coding/file_container.hpp"
#include "coding/reader_streambuf.hpp"
#include "std/fstream.hpp"
class DoGetBenchmarks
{
set<string> m_processed;
BenchmarkEngine & m_engine;
public:
explicit DoGetBenchmarks(BenchmarkEngine & engine) : m_engine(engine) {}
void operator() (vector<string> const & v)
{
if (v[0][0] == '#')
return;
BenchmarkEngine::Benchmark b;
b.m_name = v[1];
m2::RectD r;
if (m_processed.insert(v[0]).second)
{
try
{
feature::DataHeader header(v[0]);
r = header.GetBounds();
}
catch (RootException const & e)
{
LOG(LINFO, ("Can't add", v[0], "file to benchmark:", e.Msg()));
return;
}
}
int lastScale;
if (v.size() > 3)
{
double lat1, lon1, lat2, lon2;
CHECK(strings::to_double(v[2], lat1), (v[2]));
CHECK(strings::to_double(v[3], lon1), (v[3]));
CHECK(strings::to_double(v[4], lat2), (v[4]));
CHECK(strings::to_double(v[5], lon2), (v[5]));
r = m2::RectD(m2::PointD(MercatorBounds::LonToX(lon1), MercatorBounds::LatToY(lat1)),
m2::PointD(MercatorBounds::LonToX(lon2), MercatorBounds::LatToY(lat2)));
CHECK(strings::to_int(v[6], lastScale), (v[6]));
}
else
CHECK(strings::to_int(v[2], lastScale), (v[2]));
ASSERT ( r != m2::RectD::GetEmptyRect(), (r) );
Navigator & nav = m_engine.m_framework->GetNavigator();
nav.SetFromRect(m2::AnyRectD(r));
r = nav.Screen().GlobalRect().GetGlobalRect();
b.m_provider.reset(new BenchmarkRectProvider(nav.GetDrawScale(), r, lastScale));
m_engine.m_benchmarks.push_back(b);
}
};
template <class ToDo>
void ForEachBenchmarkRecord(ToDo & toDo)
{
try
{
string configPath;
if (!Settings::Get("BenchmarkConfig", configPath))
return;
ReaderStreamBuf buffer(GetPlatform().GetReader(configPath, "w"));
istream stream(&buffer);
string line;
while (stream.good())
{
getline(stream, line);
vector<string> parts;
strings::SimpleTokenizer it(line, " \t");
while (it)
{
parts.push_back(*it);
++it;
}
if (!parts.empty())
toDo(parts);
}
}
catch (RootException const & e)
{
LOG(LERROR, ("Error reading benchmarks:", e.Msg()));
}
}
struct MapsCollector
{
vector<string> m_maps;
void operator() (vector<string> const & v)
{
ASSERT(!v[0].empty(), ());
if (v[0][0] != '#')
m_maps.push_back(v[0]);
}
};
void BenchmarkEngine::PrepareMaps()
{
// Deregister all previously registered maps in framework constructor.
m_framework->DeregisterAllMaps();
// add only maps needed for benchmarks
MapsCollector collector;
ForEachBenchmarkRecord(collector);
for (string const & map : collector.m_maps)
{
LOG(LINFO, ("Looking for:", map));
m_framework->RegisterMap(platform::LocalCountryFile::MakeForTesting(map));
}
}
BenchmarkEngine::BenchmarkEngine(Framework * fw)
: m_paintDuration(0),
m_maxDuration(0),
m_framework(fw)
{
}
void BenchmarkEngine::BenchmarkCommandFinished()
{
double duration = m_paintDuration;
if (duration > m_maxDuration)
{
m_maxDuration = duration;
m_maxDurationRect = m_curBenchmarkRect;
}
BenchmarkResult res;
res.m_name = m_benchmarks[m_curBenchmark].m_name;
res.m_rect = m_curBenchmarkRect;
res.m_time = duration;
m_benchmarkResults.push_back(res);
if (m_benchmarkResults.size() > 100)
SaveBenchmarkResults();
m_paintDuration = 0;
}
void BenchmarkEngine::SaveBenchmarkResults()
{
string resultsPath;
Settings::Get("BenchmarkResults", resultsPath);
ofstream fout(GetPlatform().WritablePathForFile(resultsPath).c_str(), ios::app);
for (size_t i = 0; i < m_benchmarkResults.size(); ++i)
{
/// @todo Place correct version here from bundle (platform).
fout << GetPlatform().DeviceName() << " "
<< "3.0.0" << " "
<< m_startTime << " "
<< m_benchmarkResults[i].m_name << " "
<< m_benchmarkResults[i].m_rect.minX() << " "
<< m_benchmarkResults[i].m_rect.minY() << " "
<< m_benchmarkResults[i].m_rect.maxX() << " "
<< m_benchmarkResults[i].m_rect.maxY() << " "
<< m_benchmarkResults[i].m_time << endl;
}
m_benchmarkResults.clear();
}
void BenchmarkEngine::SendBenchmarkResults()
{
}
void BenchmarkEngine::MarkBenchmarkResultsEnd()
{
string resultsPath;
Settings::Get("BenchmarkResults", resultsPath);
ofstream fout(GetPlatform().WritablePathForFile(resultsPath).c_str(), ios::app);
fout << "END " << m_startTime << endl;
}
void BenchmarkEngine::MarkBenchmarkResultsStart()
{
string resultsPath;
Settings::Get("BenchmarkResults", resultsPath);
ofstream fout(GetPlatform().WritablePathForFile(resultsPath).c_str(), ios::app);
fout << "START " << m_startTime << endl;
}
bool BenchmarkEngine::NextBenchmarkCommand()
{
#ifndef USE_DRAPE
if (m_benchmarks[m_curBenchmark].m_provider->hasRect() || ++m_curBenchmark < m_benchmarks.size())
{
double const s = m_benchmarksTimer.ElapsedSeconds();
int const fenceID = m_framework->GetRenderPolicy()->InsertBenchmarkFence();
m_framework->ShowRect(m_benchmarks[m_curBenchmark].m_provider->nextRect());
m_curBenchmarkRect = m_framework->GetCurrentViewport();
m_framework->GetRenderPolicy()->JoinBenchmarkFence(fenceID);
m_paintDuration += m_benchmarksTimer.ElapsedSeconds() - s;
BenchmarkCommandFinished();
return true;
}
else
{
SaveBenchmarkResults();
MarkBenchmarkResultsEnd();
SendBenchmarkResults();
LOG(LINFO, ("Bechmarks took", m_benchmarksTimer.ElapsedSeconds(), "seconds to complete"));
return false;
}
#else
return false;
#endif // USE_DRAPE
}
void BenchmarkEngine::Start()
{
m_thread.Create(make_unique<Routine>(*this));
}
BenchmarkEngine::Routine::Routine(BenchmarkEngine & engine) : m_engine(engine) {}
void BenchmarkEngine::Routine::Do()
{
m_engine.PrepareMaps();
int benchMarkCount = 1;
(void) Settings::Get("BenchmarkCyclesCount", benchMarkCount);
for (int i = 0; i < benchMarkCount; ++i)
{
DoGetBenchmarks doGet(m_engine);
ForEachBenchmarkRecord(doGet);
m_engine.m_curBenchmark = 0;
m_engine.m_benchmarksTimer.Reset();
m_engine.m_startTime = my::FormatCurrentTime();
m_engine.MarkBenchmarkResultsStart();
while (m_engine.NextBenchmarkCommand()){};
m_engine.m_benchmarks.clear();
}
}

View file

@ -1,81 +0,0 @@
#pragma once
#include "map/benchmark_provider.hpp"
#include "geometry/rect2d.hpp"
#include "base/timer.hpp"
#include "base/thread.hpp"
#include "std/string.hpp"
#include "std/vector.hpp"
#include "std/shared_ptr.hpp"
class Framework;
/// BenchmarkEngine is class which:
/// - Creates it's own thread
/// - Feeds the Framework with the paint tasks he wants to performs
/// - Wait until each tasks completion
/// - Measure the time of each task and save the result
class BenchmarkEngine
{
threads::Thread m_thread;
double m_paintDuration;
double m_maxDuration;
m2::RectD m_maxDurationRect;
m2::RectD m_curBenchmarkRect;
string m_startTime;
struct BenchmarkResult
{
string m_name;
m2::RectD m_rect;
double m_time;
};
vector<BenchmarkResult> m_benchmarkResults;
my::Timer m_benchmarksTimer;
struct Benchmark
{
shared_ptr<BenchmarkRectProvider> m_provider;
string m_name;
};
class Routine : public threads::IRoutine
{
public:
Routine(BenchmarkEngine & engine);
// threads::IRoutine overrides:
void Do() override;
private:
BenchmarkEngine & m_engine;
};
vector<Benchmark> m_benchmarks;
size_t m_curBenchmark;
Framework * m_framework;
void BenchmarkCommandFinished();
bool NextBenchmarkCommand();
void SaveBenchmarkResults();
void SendBenchmarkResults();
void MarkBenchmarkResultsStart();
void MarkBenchmarkResultsEnd();
void PrepareMaps();
friend class DoGetBenchmarks;
public:
BenchmarkEngine(Framework * fw);
void Start();
};

View file

@ -1,33 +0,0 @@
#include "base/SRC_FIRST.hpp"
#include "map/benchmark_provider.hpp"
#include "geometry/mercator.hpp"
BenchmarkRectProvider::BenchmarkRectProvider(int startLevel, m2::RectD const & startRect, int endLevel)
: m_endLevel(endLevel)
{
m_rects.push_back(make_pair(startRect, startLevel));
}
bool BenchmarkRectProvider::hasRect() const
{
return !m_rects.empty();
}
m2::RectD const BenchmarkRectProvider::nextRect()
{
pair<m2::RectD, int> const & f = m_rects.front();
m2::RectD r = f.first;
if (f.second < m_endLevel)
{
int nextLevel = f.second + 1;
m_rects.push_back(make_pair(m2::RectD(r.minX(), r.minY(), r.minX() + r.SizeX() / 2, r.minY() + r.SizeY() / 2), nextLevel));
m_rects.push_back(make_pair(m2::RectD(r.minX() + r.SizeX() / 2, r.minY(), r.maxX(), r.minY() + r.SizeY() / 2), nextLevel));
m_rects.push_back(make_pair(m2::RectD(r.minX(), r.minY() + r.SizeY() / 2, r.minX() + r.SizeX() / 2, r.maxY()), nextLevel));
m_rects.push_back(make_pair(m2::RectD(r.minX() + r.SizeX() / 2, r.minY() + r.SizeY() / 2, r.maxX(), r.maxY()), nextLevel));
}
m_rects.pop_front();
return r;
}

View file

@ -1,15 +0,0 @@
#pragma once
#include "geometry/rect2d.hpp"
#include "std/list.hpp"
struct BenchmarkRectProvider
{
int m_endLevel;
list<pair<m2::RectD, int> > m_rects;
BenchmarkRectProvider(int startLevel, m2::RectD const & startRect, int endLevel);
bool hasRect() const;
m2::RectD const nextRect();
};

190
map/benchmark_tools.cpp Normal file
View file

@ -0,0 +1,190 @@
#include "map/benchmark_tools.hpp"
#include "map/framework.hpp"
#include "drape_frontend/drape_measurer.hpp"
#include "drape_frontend/scenario_manager.hpp"
#include "platform/http_client.hpp"
#include "platform/platform.hpp"
#include "3party/jansson/myjansson.hpp"
#include <algorithm>
#include <atomic>
#include <set>
#include <string>
#include <vector>
namespace
{
struct BenchmarkHandle
{
std::vector<df::ScenarioManager::ScenarioData> m_scenariosToRun;
size_t m_currentScenario = 0;
std::vector<storage::TCountryId> m_regionsToDownload;
size_t m_regionsToDownloadCounter = 0;
#ifdef DRAPE_MEASURER
std::vector<std::pair<string, df::DrapeMeasurer::DrapeStatistic>> m_drapeStatistic;
#endif
};
void RunScenario(Framework * framework, std::shared_ptr<BenchmarkHandle> handle)
{
if (handle->m_currentScenario >= handle->m_scenariosToRun.size())
{
#ifdef DRAPE_MEASURER
for (auto const & it : handle->m_drapeStatistic)
{
LOG(LINFO, ("\n ***** Report for scenario", it.first, "*****\n",
it.second.ToString(),
"\n ***** Report for scenario", it.first, "*****\n"));
}
#endif
return;
}
auto & scenarioData = handle->m_scenariosToRun[handle->m_currentScenario];
framework->GetDrapeEngine()->RunScenario(std::move(scenarioData),
[handle](std::string const & name)
{
#ifdef DRAPE_MEASURER
df::DrapeMeasurer::Instance().StartBenchmark();
#endif
},
[framework, handle](std::string const & name)
{
#ifdef DRAPE_MEASURER
df::DrapeMeasurer::Instance().StopBenchmark();
auto const drapeStatistic = df::DrapeMeasurer::Instance().GetDrapeStatistic();
handle->m_drapeStatistic.push_back(make_pair(name, drapeStatistic));
#endif
GetPlatform().RunOnGuiThread([framework, handle]()
{
handle->m_currentScenario++;
RunScenario(framework, handle);
});
});
}
} // namespace
namespace benchmark
{
void RunGraphicsBenchmark(Framework * framework)
{
#ifdef SCENARIO_ENABLE
using namespace df;
// Request scenarios from the server.
platform::HttpClient request("http://osmz.ru/mwm/graphics_benchmark.json");
if (!request.RunHttpRequest())
return;
std::shared_ptr<BenchmarkHandle> handle = std::make_shared<BenchmarkHandle>();
// Parse scenarios.
std::vector<m2::PointD> points;
string const & result = request.ServerResponse();
try
{
my::Json root(result.c_str());
json_t * scenariosNode = json_object_get(root.get(), "scenarios");
if (scenariosNode == nullptr || !json_is_array(scenariosNode))
return;
size_t const sz = json_array_size(scenariosNode);
handle->m_scenariosToRun.resize(sz);
for (size_t i = 0; i < sz; ++i)
{
auto scenarioElem = json_array_get(scenariosNode, i);
if (scenarioElem == nullptr)
return;
my::FromJSONObject(scenarioElem, "name", handle->m_scenariosToRun[i].m_name);
json_t * stepsNode = json_object_get(scenarioElem, "steps");
if (stepsNode != nullptr && json_is_array(stepsNode))
{
size_t const stepsCount = json_array_size(stepsNode);
auto & scenario = handle->m_scenariosToRun[i].m_scenario;
scenario.reserve(stepsCount);
for (size_t j = 0; j < stepsCount; ++j)
{
auto stepElem = json_array_get(stepsNode, j);
if (stepElem == nullptr)
return;
string actionType;
my::FromJSONObject(stepElem, "actionType", actionType);
if (actionType == "waitForTime")
{
json_int_t timeInSeconds = 0;
my::FromJSONObject(stepElem, "time", timeInSeconds);
scenario.push_back(std::unique_ptr<ScenarioManager::Action>(
new ScenarioManager::WaitForTimeAction(seconds(timeInSeconds))));
}
else if (actionType == "centerViewport")
{
json_t * centerNode = json_object_get(stepElem, "center");
if (centerNode == nullptr)
return;
double x = 0.0, y = 0.0;
my::FromJSONObject(centerNode, "x", x);
my::FromJSONObject(centerNode, "y", y);
json_int_t zoomLevel = -1;
my::FromJSONObject(stepElem, "zoomLevel", zoomLevel);
m2::PointD const pt(x, y);
points.push_back(pt);
scenario.push_back(std::unique_ptr<ScenarioManager::Action>(
new ScenarioManager::CenterViewportAction(pt, static_cast<int>(zoomLevel))));
}
}
}
}
}
catch (my::Json::Exception const & e)
{
return;
}
if (handle->m_scenariosToRun.empty())
return;
// Find out regions to download.
std::set<storage::TCountryId> regions;
for (m2::PointD const & pt : points)
regions.insert(framework->GetCountryInfoGetter().GetRegionCountryId(pt));
for (auto const & countryId : regions)
{
storage::NodeStatuses statuses;
framework->GetStorage().GetNodeStatuses(countryId, statuses);
if (statuses.m_status != storage::NodeStatus::OnDisk)
handle->m_regionsToDownload.push_back(countryId);
}
// Download regions and run scenarios after downloading.
if (!handle->m_regionsToDownload.empty())
{
framework->GetStorage().Subscribe([framework, handle](storage::TCountryId const & countryId)
{
if (std::find(handle->m_regionsToDownload.begin(),
handle->m_regionsToDownload.end(), countryId) != handle->m_regionsToDownload.end())
{
handle->m_regionsToDownloadCounter++;
if (handle->m_regionsToDownloadCounter == handle->m_regionsToDownload.size())
{
handle->m_regionsToDownload.clear();
RunScenario(framework, handle);
}
}
}, [](storage::TCountryId const &, storage::MapFilesDownloader::TProgress const &){});
for (auto const & countryId : handle->m_regionsToDownload)
framework->GetStorage().DownloadNode(countryId);
return;
}
// Run scenarios without downloading.
RunScenario(framework, handle);
#endif
}
} // namespace benchmark

8
map/benchmark_tools.hpp Normal file
View file

@ -0,0 +1,8 @@
#pragma once
class Framework;
namespace benchmark
{
void RunGraphicsBenchmark(Framework * framework);
} // namespace benchmark

View file

@ -1,4 +1,5 @@
#include "map/framework.hpp"
#include "map/benchmark_tools.hpp"
#include "map/chart_generator.hpp"
#include "map/ge0_parser.hpp"
#include "map/geourl_process.hpp"
@ -1731,6 +1732,8 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
m_drapeApi.SetEngine(make_ref(m_drapeEngine));
m_trafficManager.SetDrapeEngine(make_ref(m_drapeEngine));
benchmark::RunGraphicsBenchmark(this);
}
void Framework::OnRecoverGLContext(int width, int height)

View file

@ -12,6 +12,7 @@ include($$ROOT_DIR/common.pri)
HEADERS += \
api_mark_point.hpp \
benchmark_tools.hpp \
bookmark.hpp \
bookmark_manager.hpp \
chart_generator.hpp \
@ -37,6 +38,7 @@ SOURCES += \
../api/src/c/api-client.c \
address_finder.cpp \
api_mark_point.cpp \
benchmark_tools.cpp \
bookmark.cpp \
bookmark_manager.cpp \
chart_generator.cpp \

View file

@ -105,6 +105,7 @@
6743D3451C3533AE0095054B /* support_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6743D3431C3533AE0095054B /* support_manager.hpp */; };
675D21991BFB876E00717E4F /* projection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675D21971BFB876E00717E4F /* projection.cpp */; };
675D219A1BFB876E00717E4F /* projection.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675D21981BFB876E00717E4F /* projection.hpp */; };
BB035F6C1E3A2A5C00519962 /* drape_diagnostics.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */; };
BB06FBE91DDDFFBE00B41AF0 /* area_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC01DDDFDC300B41AF0 /* area_vertex_shader.vsh */; };
BB06FBEA1DDDFFBE00B41AF0 /* area3d_outline_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC11DDDFDC300B41AF0 /* area3d_outline_vertex_shader.vsh */; };
BB06FBEB1DDDFFBE00B41AF0 /* area3d_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC21DDDFDC300B41AF0 /* area3d_vertex_shader.vsh */; };
@ -278,6 +279,7 @@
6743D3431C3533AE0095054B /* support_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = support_manager.hpp; sourceTree = "<group>"; };
675D21971BFB876E00717E4F /* projection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = projection.cpp; sourceTree = "<group>"; };
675D21981BFB876E00717E4F /* projection.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = projection.hpp; sourceTree = "<group>"; };
BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drape_diagnostics.hpp; sourceTree = "<group>"; };
BB06FBC01DDDFDC300B41AF0 /* area_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area_vertex_shader.vsh; sourceTree = "<group>"; };
BB06FBC11DDDFDC300B41AF0 /* area3d_outline_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area3d_outline_vertex_shader.vsh; sourceTree = "<group>"; };
BB06FBC21DDDFDC300B41AF0 /* area3d_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area3d_vertex_shader.vsh; sourceTree = "<group>"; };
@ -391,6 +393,7 @@
6729A50E1A69213A007D5872 /* cpu_buffer.hpp */,
6729A50F1A69213A007D5872 /* data_buffer.cpp */,
6729A5101A69213A007D5872 /* data_buffer.hpp */,
BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */,
6729A5111A69213A007D5872 /* drape_global.hpp */,
347F32F71C45383E009758CC /* debug_rect_renderer.cpp */,
347F32F81C45383E009758CC /* debug_rect_renderer.hpp */,
@ -577,6 +580,7 @@
6729A57F1A69213A007D5872 /* glIncludes.hpp in Headers */,
6729A5A91A69213A007D5872 /* texture_of_colors.hpp in Headers */,
6729A5871A69213A007D5872 /* gpu_buffer.hpp in Headers */,
BB035F6C1E3A2A5C00519962 /* drape_diagnostics.hpp in Headers */,
6729A56E1A69213A007D5872 /* buffer_base.hpp in Headers */,
6729A58F1A69213A007D5872 /* index_buffer.hpp in Headers */,
);

View file

@ -39,6 +39,8 @@
454C19BB1CCE3EC0002A2C86 /* animation_constants.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 454C19B81CCE3EC0002A2C86 /* animation_constants.hpp */; };
454C19BC1CCE3EC0002A2C86 /* animation_system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 454C19B91CCE3EC0002A2C86 /* animation_system.cpp */; };
454C19BD1CCE3EC0002A2C86 /* animation_system.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 454C19BA1CCE3EC0002A2C86 /* animation_system.hpp */; };
45580ABA1E28DB2600CD535D /* scenario_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45580AB81E28DB2600CD535D /* scenario_manager.cpp */; };
45580ABB1E28DB2600CD535D /* scenario_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45580AB91E28DB2600CD535D /* scenario_manager.hpp */; };
45B4B8CB1CF5C16B00A54761 /* screen_animations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45B4B8C71CF5C16B00A54761 /* screen_animations.cpp */; };
45B4B8CC1CF5C16B00A54761 /* screen_animations.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45B4B8C81CF5C16B00A54761 /* screen_animations.hpp */; };
45B4B8CD1CF5C16B00A54761 /* screen_operations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45B4B8C91CF5C16B00A54761 /* screen_operations.cpp */; };
@ -206,6 +208,8 @@
67E91C7C1BDFC85E005CEE88 /* selection_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 670947701BDF9BE0005014C0 /* selection_shape.cpp */; };
67E91C7D1BDFC85E005CEE88 /* user_marks_provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6709478B1BDF9BE0005014C0 /* user_marks_provider.cpp */; };
67E91C7E1BDFC85E005CEE88 /* visual_params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6709478F1BDF9BE1005014C0 /* visual_params.cpp */; };
BB035F6F1E3A2AAE00519962 /* drape_measurer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */; };
BB035F701E3A2AAE00519962 /* drape_measurer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */; };
F6B283101C1B04680081957A /* gps_track_point.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B2830B1C1B04680081957A /* gps_track_point.hpp */; };
F6B283111C1B04680081957A /* gps_track_renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B2830C1C1B04680081957A /* gps_track_renderer.cpp */; };
F6B283121C1B04680081957A /* gps_track_renderer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B2830D1C1B04680081957A /* gps_track_renderer.hpp */; };
@ -248,6 +252,8 @@
454C19B81CCE3EC0002A2C86 /* animation_constants.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = animation_constants.hpp; sourceTree = "<group>"; };
454C19B91CCE3EC0002A2C86 /* animation_system.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animation_system.cpp; sourceTree = "<group>"; };
454C19BA1CCE3EC0002A2C86 /* animation_system.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = animation_system.hpp; sourceTree = "<group>"; };
45580AB81E28DB2600CD535D /* scenario_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scenario_manager.cpp; sourceTree = "<group>"; };
45580AB91E28DB2600CD535D /* scenario_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = scenario_manager.hpp; sourceTree = "<group>"; };
45B4B8C71CF5C16B00A54761 /* screen_animations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_animations.cpp; sourceTree = "<group>"; };
45B4B8C81CF5C16B00A54761 /* screen_animations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = screen_animations.hpp; sourceTree = "<group>"; };
45B4B8C91CF5C16B00A54761 /* screen_operations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screen_operations.cpp; sourceTree = "<group>"; };
@ -417,6 +423,8 @@
675D218B1BFB871D00717E4F /* text_engine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_engine.h; sourceTree = "<group>"; };
677A2DE31C0DD55D00635A00 /* requested_tiles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = requested_tiles.cpp; sourceTree = "<group>"; };
677A2DE41C0DD55D00635A00 /* requested_tiles.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = requested_tiles.hpp; sourceTree = "<group>"; };
BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drape_measurer.cpp; sourceTree = "<group>"; };
BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drape_measurer.hpp; sourceTree = "<group>"; };
F6B2830B1C1B04680081957A /* gps_track_point.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track_point.hpp; sourceTree = "<group>"; };
F6B2830C1C1B04680081957A /* gps_track_renderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_track_renderer.cpp; sourceTree = "<group>"; };
F6B2830D1C1B04680081957A /* gps_track_renderer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track_renderer.hpp; sourceTree = "<group>"; };
@ -464,6 +472,8 @@
347F520A1DC2334A0064B273 /* drape_api_renderer.hpp */,
347F520B1DC2334A0064B273 /* drape_api.cpp */,
347F520C1DC2334A0064B273 /* drape_api.hpp */,
BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */,
BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */,
34C624BF1DABDB0400510300 /* traffic_generator.cpp */,
34C624C01DABDB0400510300 /* traffic_generator.hpp */,
34C624C11DABDB0400510300 /* traffic_renderer.cpp */,
@ -487,6 +497,8 @@
6743D3681C3A9F090095054B /* arrow3d.hpp */,
6743D3691C3A9F090095054B /* framebuffer.cpp */,
6743D36A1C3A9F090095054B /* framebuffer.hpp */,
45580AB91E28DB2600CD535D /* scenario_manager.hpp */,
45580AB81E28DB2600CD535D /* scenario_manager.cpp */,
6743D36B1C3A9F090095054B /* transparent_layer.cpp */,
6743D36C1C3A9F090095054B /* transparent_layer.hpp */,
F6B2830B1C1B04680081957A /* gps_track_point.hpp */,
@ -700,6 +712,7 @@
files = (
670947971BDF9BE1005014C0 /* line_shape.hpp in Headers */,
56BF56DB1C7608C0006DD7CB /* choose_position_mark.hpp in Headers */,
45580ABB1E28DB2600CD535D /* scenario_manager.hpp in Headers */,
670948031BDF9BF5005014C0 /* drape_engine.hpp in Headers */,
6709486A1BDF9C7F005014C0 /* brush_info.hpp in Headers */,
675D218E1BFB871D00717E4F /* rect.h in Headers */,
@ -799,6 +812,7 @@
670948751BDF9C7F005014C0 /* geometry_processors.hpp in Headers */,
6709487A1BDF9C7F005014C0 /* icon_info.hpp in Headers */,
670948151BDF9C39005014C0 /* base_interpolator.hpp in Headers */,
BB035F701E3A2AAE00519962 /* drape_measurer.hpp in Headers */,
670947A61BDF9BE1005014C0 /* my_position.hpp in Headers */,
675D21901BFB871D00717E4F /* software_renderer.hpp in Headers */,
670947A81BDF9BE1005014C0 /* navigator.hpp in Headers */,
@ -913,8 +927,10 @@
F6B283131C1B04680081957A /* gps_track_shape.cpp in Sources */,
45B4B8CB1CF5C16B00A54761 /* screen_animations.cpp in Sources */,
6709483D1BDF9C48005014C0 /* copyright_label.cpp in Sources */,
45580ABA1E28DB2600CD535D /* scenario_manager.cpp in Sources */,
670947C81BDF9BE1005014C0 /* text_shape.cpp in Sources */,
34C624C31DABDB0400510300 /* traffic_generator.cpp in Sources */,
BB035F6F1E3A2AAE00519962 /* drape_measurer.cpp in Sources */,
670947CC1BDF9BE1005014C0 /* tile_info.cpp in Sources */,
34C624C51DABDB0400510300 /* traffic_renderer.cpp in Sources */,
670947961BDF9BE1005014C0 /* line_shape.cpp in Sources */,

View file

@ -19,6 +19,8 @@
34DDA1811DBE5DF40088A609 /* libpartners_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34DDA17F1DBE5DF40088A609 /* libpartners_api.a */; };
34DDA1821DBE5DF40088A609 /* libtracking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34DDA1801DBE5DF40088A609 /* libtracking.a */; };
45201E931CE4AC90008A4842 /* api_mark_point.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45201E921CE4AC90008A4842 /* api_mark_point.cpp */; };
45580ABE1E2CBD5E00CD535D /* benchmark_tools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */; };
45580ABF1E2CBD5E00CD535D /* benchmark_tools.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */; };
670E39401C46C5C700E9C0A6 /* gps_tracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 670E393E1C46C5C700E9C0A6 /* gps_tracker.cpp */; };
670E39411C46C5C700E9C0A6 /* gps_tracker.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 670E393F1C46C5C700E9C0A6 /* gps_tracker.hpp */; };
674231CB1DF984F600913FEB /* libtraffic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674231CA1DF984F600913FEB /* libtraffic.a */; };
@ -129,6 +131,8 @@
34DDA17F1DBE5DF40088A609 /* libpartners_api.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpartners_api.a; path = "/Users/igrechuhin/Repo/omim/xcode/partners_api/../../../omim-xcode-build/Debug/libpartners_api.a"; sourceTree = "<absolute>"; };
34DDA1801DBE5DF40088A609 /* libtracking.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtracking.a; path = "/Users/igrechuhin/Repo/omim/xcode/tracking/../../../omim-xcode-build/Debug/libtracking.a"; sourceTree = "<absolute>"; };
45201E921CE4AC90008A4842 /* api_mark_point.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = api_mark_point.cpp; sourceTree = "<group>"; };
45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = benchmark_tools.cpp; sourceTree = "<group>"; };
45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = benchmark_tools.hpp; sourceTree = "<group>"; };
670E393E1C46C5C700E9C0A6 /* gps_tracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_tracker.cpp; sourceTree = "<group>"; };
670E393F1C46C5C700E9C0A6 /* gps_tracker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_tracker.hpp; sourceTree = "<group>"; };
674231CA1DF984F600913FEB /* libtraffic.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtraffic.a; path = "../../../omim-build/xcode/Debug/libtraffic.a"; sourceTree = "<group>"; };
@ -390,6 +394,8 @@
675345BD1A4054AD00A0A8C3 /* map */ = {
isa = PBXGroup;
children = (
45580ABD1E2CBD5E00CD535D /* benchmark_tools.hpp */,
45580ABC1E2CBD5E00CD535D /* benchmark_tools.cpp */,
F63421F61DF9BF9100A96868 /* reachable_by_taxi_checker.cpp */,
F63421F71DF9BF9100A96868 /* reachable_by_taxi_checker.hpp */,
347B60741DD9926D0050FA24 /* traffic_manager.cpp */,
@ -466,6 +472,7 @@
675346651A4054E800A0A8C3 /* framework.hpp in Headers */,
674A2A381B2715FB001A525C /* osm_opening_hours.hpp in Headers */,
670E39411C46C5C700E9C0A6 /* gps_tracker.hpp in Headers */,
45580ABF1E2CBD5E00CD535D /* benchmark_tools.hpp in Headers */,
342D833B1D5233E8000D8AEA /* displacement_mode_manager.hpp in Headers */,
F6B283041C1B03320081957A /* gps_track_collection.hpp in Headers */,
);
@ -590,6 +597,7 @@
6753463A1A4054E800A0A8C3 /* address_finder.cpp in Sources */,
670E39401C46C5C700E9C0A6 /* gps_tracker.cpp in Sources */,
6753464A1A4054E800A0A8C3 /* bookmark.cpp in Sources */,
45580ABE1E2CBD5E00CD535D /* benchmark_tools.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};