forked from organicmaps/organicmaps
refactored benchmarks support.
This commit is contained in:
parent
f46cfe5570
commit
132f7aa288
15 changed files with 994 additions and 605 deletions
2
data/benchmark.txt
Normal file
2
data/benchmark.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Belarus.mwm 10
|
||||
Minsk 27.3271 64.1124 27.7853 64.3744 17
|
|
@ -12,7 +12,7 @@
|
|||
#include "../../map/drawer_yg.hpp"
|
||||
#include "../../storage/storage.hpp"
|
||||
|
||||
typedef FrameWork<model::FeaturesFetcher, Navigator> framework_t;
|
||||
typedef FrameWork<model::FeaturesFetcher> framework_t;
|
||||
|
||||
@implementation MapViewController
|
||||
|
||||
|
|
33
map/benchmark_provider.cpp
Normal file
33
map/benchmark_provider.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "../base/SRC_FIRST.hpp"
|
||||
#include "benchmark_provider.hpp"
|
||||
#include "../indexer/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;
|
||||
}
|
15
map/benchmark_provider.hpp
Normal file
15
map/benchmark_provider.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#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();
|
||||
};
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
#include "framework.hpp"
|
||||
#include "draw_processor.hpp"
|
||||
#include "drawer_yg.hpp"
|
||||
#include "feature_vec_model.hpp"
|
||||
#include "benchmark_provider.hpp"
|
||||
|
||||
#include "../indexer/feature_visibility.hpp"
|
||||
#include "../indexer/feature.hpp"
|
||||
|
@ -12,6 +14,7 @@
|
|||
#include "../base/math.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
#include "../version/version.hpp"
|
||||
|
||||
#include "../base/start_mem_debug.hpp"
|
||||
|
||||
|
@ -181,4 +184,787 @@ namespace fwork
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::AddRedrawCommandSure()
|
||||
{
|
||||
m_renderQueue.AddCommand(bind(&this_type::PaintImpl, this, _1, _2, _3, _4), m_navigator.Screen());
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::AddRedrawCommand()
|
||||
{
|
||||
yg::gl::RenderState const state = m_renderQueue.CopyState();
|
||||
if ((state.m_currentScreen != m_navigator.Screen()) && (m_isRedrawEnabled))
|
||||
AddRedrawCommandSure();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::AddMap(string const & datFile)
|
||||
{
|
||||
// update rect for Show All button
|
||||
feature::DataHeader header;
|
||||
header.Load(FilesContainerR(datFile).GetReader(HEADER_FILE_TAG));
|
||||
|
||||
m2::RectD bounds = header.GetBounds();
|
||||
|
||||
m_model.AddWorldRect(bounds);
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
m_model.AddMap(datFile);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::RemoveMap(string const & datFile)
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
m_model.RemoveMap(datFile);
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::OnGpsUpdate(location::GpsInfo const & info)
|
||||
{
|
||||
if (info.m_timestamp < location::POSITION_TIMEOUT_SECONDS)
|
||||
{
|
||||
// notify GUI that we received gps position
|
||||
if (!(m_locationState & location::State::EGps) && m_locationObserver)
|
||||
m_locationObserver();
|
||||
|
||||
m_locationState.UpdateGps(info);
|
||||
if (m_centeringMode == ECenterAndScale)
|
||||
{
|
||||
CenterAndScaleViewport();
|
||||
m_centeringMode = ECenterOnly;
|
||||
}
|
||||
else if (m_centeringMode == ECenterOnly)
|
||||
CenterViewport(m_locationState.Position());
|
||||
UpdateNow();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::OnCompassUpdate(location::CompassInfo const & info)
|
||||
{
|
||||
if (info.m_timestamp < location::POSITION_TIMEOUT_SECONDS)
|
||||
{
|
||||
m_locationState.UpdateCompass(info);
|
||||
UpdateNow();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
FrameWork<TModel>::FrameWork(shared_ptr<WindowHandle> windowHandle,
|
||||
size_t bottomShift)
|
||||
: m_windowHandle(windowHandle),
|
||||
m_isBenchmarking(GetPlatform().IsBenchmarking()),
|
||||
m_isBenchmarkInitialized(false),
|
||||
m_bgColor(0xEE, 0xEE, 0xDD, 0xFF),
|
||||
m_renderQueue(GetPlatform().SkinName(),
|
||||
GetPlatform().IsMultiSampled(),
|
||||
GetPlatform().DoPeriodicalUpdate(),
|
||||
GetPlatform().PeriodicalUpdateInterval(),
|
||||
GetPlatform().IsBenchmarking(),
|
||||
GetPlatform().ScaleEtalonSize(),
|
||||
m_bgColor),
|
||||
m_isRedrawEnabled(true),
|
||||
m_metresMinWidth(20),
|
||||
m_minRulerWidth(97),
|
||||
m_centeringMode(EDoNothing),
|
||||
m_maxDuration(0)
|
||||
{
|
||||
m_informationDisplay.setBottomShift(bottomShift);
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.enableDebugPoints(true);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
m_informationDisplay.enableGlobalRect(!m_isBenchmarking);
|
||||
#endif
|
||||
|
||||
m_informationDisplay.enableCenter(true);
|
||||
|
||||
m_informationDisplay.enableRuler(true);
|
||||
m_informationDisplay.setRulerParams(m_minRulerWidth, m_metresMinWidth);
|
||||
m_navigator.SetMinScreenParams(m_minRulerWidth, m_metresMinWidth);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_informationDisplay.enableDebugInfo(true);
|
||||
#endif
|
||||
|
||||
m_informationDisplay.enableLog(GetPlatform().IsVisualLog(), m_windowHandle.get());
|
||||
|
||||
m_informationDisplay.enableBenchmarkInfo(m_isBenchmarking);
|
||||
|
||||
m_informationDisplay.setVisualScale(GetPlatform().VisualScale());
|
||||
m_renderQueue.AddWindowHandle(m_windowHandle);
|
||||
|
||||
// initialize gps and compass subsystem
|
||||
GetLocationService().SetGpsObserver(
|
||||
boost::bind(&this_type::OnGpsUpdate, this, _1));
|
||||
GetLocationService().SetCompassObserver(
|
||||
boost::bind(&this_type::OnCompassUpdate, this, _1));
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::BenchmarkCommandFinished()
|
||||
{
|
||||
double duration = m_renderQueue.renderState().m_duration;
|
||||
if (duration > m_maxDuration)
|
||||
{
|
||||
m_maxDuration = duration;
|
||||
m_maxDurationRect = m_curBenchmarkRect;
|
||||
m_informationDisplay.addBenchmarkInfo("maxDurationRect: ", m_maxDurationRect, m_maxDuration);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
NextBenchmarkCommand();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::SaveBenchmarkResults()
|
||||
{
|
||||
string deviceID = GetPlatform().DeviceID();
|
||||
transform(deviceID.begin(), deviceID.end(), deviceID.begin(), ::tolower);
|
||||
|
||||
ofstream fout(GetPlatform().WritablePathForFile(deviceID + "_benchmark_results.txt").c_str(), ios::app);
|
||||
|
||||
for (int i = 0; i < m_benchmarkResults.size(); ++i)
|
||||
{
|
||||
fout << GetPlatform().DeviceID() << " "
|
||||
<< VERSION_STRING << " "
|
||||
<< 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();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::NextBenchmarkCommand()
|
||||
{
|
||||
if ((m_benchmarks[m_curBenchmark].m_provider->hasRect()) || (++m_curBenchmark < m_benchmarks.size()))
|
||||
{
|
||||
m_curBenchmarkRect = m_benchmarks[m_curBenchmark].m_provider->nextRect();
|
||||
m_navigator.SetFromRect(m_curBenchmarkRect);
|
||||
m_renderQueue.AddBenchmarkCommand(bind(&this_type::PaintImpl, this, _1, _2, _3, _4), m_navigator.Screen());
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveBenchmarkResults();
|
||||
LOG(LINFO, ("Bechmarks took ", m_benchmarksTimer.ElapsedSeconds(), " seconds to complete"));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::EnumLocalMaps(Platform::FilesList & filesList)
|
||||
{
|
||||
// activate all downloaded maps
|
||||
Platform & p = GetPlatform();
|
||||
string const dataPath = p.WritableDir();
|
||||
filesList.clear();
|
||||
p.GetFilesInDir(dataPath, "*" DATA_FILE_EXTENSION, filesList);
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::EnumBenchmarkMaps(Platform::FilesList & filesList)
|
||||
{
|
||||
filesList.clear();
|
||||
filesList.push_back("Belarus.mwm");
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::InitBenchmark()
|
||||
{
|
||||
// m2::RectD wr(MercatorBounds::minX, MercatorBounds::minY, MercatorBounds::maxX, MercatorBounds::maxY);
|
||||
// m2::RectD r(wr.Center().x, wr.Center().y + wr.SizeY() / 8, wr.Center().x + wr.SizeX() / 8, wr.Center().y + wr.SizeY() / 4);
|
||||
|
||||
ifstream fin(GetPlatform().WritablePathForFile("benchmark.txt").c_str());
|
||||
while (true)
|
||||
{
|
||||
string name;
|
||||
m2::RectD r;
|
||||
|
||||
fin >> name;
|
||||
|
||||
if (!fin)
|
||||
break;
|
||||
|
||||
if (GetPlatform().IsFileExists(GetPlatform().WritablePathForFile(name)))
|
||||
{
|
||||
try
|
||||
{
|
||||
feature::DataHeader header;
|
||||
header.Load(FilesContainerR(GetPlatform().WritablePathForFile(name)).GetReader(HEADER_FILE_TAG));
|
||||
|
||||
r = header.GetBounds();
|
||||
}
|
||||
catch (std::exception const & e)
|
||||
{
|
||||
double x0, y0, x1, y1;
|
||||
fin >> x0 >> y0 >> x1 >> y1;
|
||||
r = m2::RectD(x0, y0, x1, y1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double x0, y0, x1, y1;
|
||||
fin >> x0 >> y0 >> x1 >> y1;
|
||||
r = m2::RectD(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
if (!fin)
|
||||
break;
|
||||
|
||||
int lastScale;
|
||||
fin >> lastScale;
|
||||
|
||||
Benchmark b;
|
||||
b.m_name = name;
|
||||
b.m_provider.reset(new BenchmarkRectProvider(scales::GetScaleLevel(r), r, lastScale));
|
||||
m_benchmarks.push_back(b);
|
||||
}
|
||||
|
||||
m_curBenchmark = 0;
|
||||
|
||||
m_renderQueue.addRenderCommandFinishedFn(bind(&this_type::BenchmarkCommandFinished, this));
|
||||
m_benchmarksTimer.Reset();
|
||||
NextBenchmarkCommand();
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::initializeGL(shared_ptr<yg::gl::RenderContext> const & primaryContext,
|
||||
shared_ptr<yg::ResourceManager> const & resourceManager)
|
||||
{
|
||||
m_resourceManager = resourceManager;
|
||||
m_renderQueue.initializeGL(primaryContext, m_resourceManager, GetPlatform().VisualScale());
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
TModel & FrameWork<TModel>::get_model()
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StartLocationService(LocationRetrievedCallbackT observer)
|
||||
{
|
||||
m_locationObserver = observer;
|
||||
m_centeringMode = ECenterAndScale;
|
||||
// by default, we always start in accurate mode
|
||||
GetLocationService().StartUpdate(true);
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StopLocationService()
|
||||
{
|
||||
// reset callback
|
||||
m_locationObserver.clear();
|
||||
m_centeringMode = EDoNothing;
|
||||
GetLocationService().StopUpdate();
|
||||
m_locationState.TurnOff();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
bool FrameWork<TModel>::IsEmptyModel()
|
||||
{
|
||||
return m_model.GetWorldRect() == m2::RectD::GetEmptyRect();
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Clean()
|
||||
{
|
||||
m_model.Clean();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::SetMaxWorldRect()
|
||||
{
|
||||
m_navigator.SetFromRect(m_model.GetWorldRect());
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::UpdateNow()
|
||||
{
|
||||
AddRedrawCommand();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Invalidate()
|
||||
{
|
||||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::SaveState()
|
||||
{
|
||||
m_navigator.SaveState();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
bool FrameWork<TModel>::LoadState()
|
||||
{
|
||||
if (!m_navigator.LoadState())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Resize event from window.
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::OnSize(int w, int h)
|
||||
{
|
||||
if (w < 2) w = 2;
|
||||
if (h < 2) h = 2;
|
||||
|
||||
m_renderQueue.OnSize(w, h);
|
||||
|
||||
m2::PointU ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m_informationDisplay.setDisplayRect(m2::RectI(ptShift, ptShift + m2::PointU(w, h)));
|
||||
|
||||
m_navigator.OnSize(ptShift.x, ptShift.y, w, h);
|
||||
|
||||
if ((m_isBenchmarking) && (!m_isBenchmarkInitialized))
|
||||
{
|
||||
m_isBenchmarkInitialized = true;
|
||||
InitBenchmark();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
bool FrameWork<TModel>::SetUpdatesEnabled(bool doEnable)
|
||||
{
|
||||
return m_windowHandle->setUpdatesEnabled(doEnable);
|
||||
}
|
||||
|
||||
/// enabling/disabling AddRedrawCommand
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::SetRedrawEnabled(bool isRedrawEnabled)
|
||||
{
|
||||
m_isRedrawEnabled = isRedrawEnabled;
|
||||
AddRedrawCommand();
|
||||
}
|
||||
|
||||
/// respond to device orientation changes
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::SetOrientation(EOrientation orientation)
|
||||
{
|
||||
m_navigator.SetOrientation(orientation);
|
||||
m_locationState.SetOrientation(orientation);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
int FrameWork<TModel>::GetCurrentScale() const
|
||||
{
|
||||
m2::PointD textureCenter(m_renderQueue.renderState().m_textureWidth / 2,
|
||||
m_renderQueue.renderState().m_textureHeight / 2);
|
||||
m2::RectD glbRect;
|
||||
|
||||
unsigned scaleEtalonSize = GetPlatform().ScaleEtalonSize();
|
||||
m_navigator.Screen().PtoG(m2::RectD(textureCenter - m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2),
|
||||
textureCenter + m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2)),
|
||||
glbRect);
|
||||
return scales::GetScaleLevel(glbRect);
|
||||
}
|
||||
|
||||
/// Actual rendering function.
|
||||
/// Called, as the renderQueue processes RenderCommand
|
||||
/// Usually it happens in the separate thread.
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::PaintImpl(shared_ptr<PaintEvent> e,
|
||||
ScreenBase const & screen,
|
||||
m2::RectD const & selectRect,
|
||||
int scaleLevel
|
||||
)
|
||||
{
|
||||
fwork::DrawProcessor doDraw(selectRect, screen, e, scaleLevel, m_renderQueue.renderStatePtr());
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelCurrent = true;
|
||||
|
||||
try
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
|
||||
#ifdef PROFILER_DRAWING
|
||||
using namespace prof;
|
||||
|
||||
start<for_each_feature>();
|
||||
reset<feature_count>();
|
||||
#endif
|
||||
|
||||
m_model.ForEachFeatureWithScale(selectRect, bind<bool>(ref(doDraw), _1), scaleLevel);
|
||||
|
||||
#ifdef PROFILER_DRAWING
|
||||
end<for_each_feature>();
|
||||
LOG(LPROF, ("ForEachFeature=", metric<for_each_feature>(),
|
||||
"FeatureCount=", metric<feature_count>(),
|
||||
"TextureUpload= ", metric<yg_upload_data>()));
|
||||
#endif
|
||||
}
|
||||
catch (redraw_operation_cancelled const &)
|
||||
{
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelCurrent = false;
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelActual = false;
|
||||
}
|
||||
|
||||
if (m_navigator.Update(GetPlatform().TimeInSec()))
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/// Function for calling from platform dependent-paint function.
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Paint(shared_ptr<PaintEvent> e)
|
||||
{
|
||||
/// Making a copy of actualFrameInfo to compare without synchronizing.
|
||||
// typename yg::gl::RenderState state = m_renderQueue.CopyState();
|
||||
|
||||
DrawerYG * pDrawer = e->drawer().get();
|
||||
|
||||
m_informationDisplay.setScreen(m_navigator.Screen());
|
||||
|
||||
m_informationDisplay.setDebugInfo(m_renderQueue.renderState().m_duration, GetCurrentScale());
|
||||
|
||||
m_informationDisplay.enableRuler(!IsEmptyModel());
|
||||
|
||||
m2::PointD const center = m_navigator.Screen().ClipRect().Center();
|
||||
|
||||
m_informationDisplay.setGlobalRect(m_navigator.Screen().GlobalRect());
|
||||
m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y)));
|
||||
|
||||
{
|
||||
threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get());
|
||||
|
||||
if (m_isBenchmarking)
|
||||
{
|
||||
m2::PointD const center = m_renderQueue.renderState().m_actualScreen.ClipRect().Center();
|
||||
m_informationDisplay.setScreen(m_renderQueue.renderState().m_actualScreen);
|
||||
m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y)));
|
||||
|
||||
if (!m_isBenchmarkInitialized)
|
||||
{
|
||||
e->drawer()->screen()->beginFrame();
|
||||
e->drawer()->screen()->clear(m_bgColor);
|
||||
m_informationDisplay.setDisplayRect(m2::RectI(0, 0, 100, 100));
|
||||
m_informationDisplay.enableRuler(false);
|
||||
m_informationDisplay.doDraw(e->drawer().get());
|
||||
e->drawer()->screen()->endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_renderQueue.renderState().m_actualTarget.get() != 0)
|
||||
{
|
||||
e->drawer()->screen()->beginFrame();
|
||||
e->drawer()->screen()->clear(m_bgColor);
|
||||
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false);
|
||||
|
||||
OGLCHECK(glMatrixMode(GL_MODELVIEW));
|
||||
OGLCHECK(glPushMatrix());
|
||||
OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0));
|
||||
|
||||
ScreenBase currentScreen = m_navigator.Screen();
|
||||
|
||||
m_informationDisplay.enableEmptyModelMessage(m_renderQueue.renderStatePtr()->m_isEmptyModelActual);
|
||||
|
||||
if (m_isBenchmarking)
|
||||
currentScreen = m_renderQueue.renderState().m_actualScreen;
|
||||
|
||||
pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget,
|
||||
m_renderQueue.renderState().m_actualScreen,
|
||||
currentScreen);
|
||||
|
||||
m_informationDisplay.doDraw(pDrawer);
|
||||
|
||||
InformationDisplay::DrawMyPosition(*pDrawer, m_navigator.Screen(), m_locationState);
|
||||
|
||||
e->drawer()->screen()->endFrame();
|
||||
|
||||
OGLCHECK(glPopMatrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::CenterViewport(m2::PointD const & pt)
|
||||
{
|
||||
m_navigator.CenterViewport(pt);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::ShowRect(m2::RectD const & rect)
|
||||
{
|
||||
m_navigator.SetFromRect(rect);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::MemoryWarning()
|
||||
{
|
||||
// clearing caches on memory warning.
|
||||
m_model.ClearCaches();
|
||||
LOG(LINFO, ("MemoryWarning"));
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::EnterBackground()
|
||||
{
|
||||
// clearing caches on entering background.
|
||||
m_model.ClearCaches();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::EnterForeground()
|
||||
{
|
||||
}
|
||||
|
||||
/// @TODO refactor to accept point and min visible length
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::CenterAndScaleViewport()
|
||||
{
|
||||
m2::PointD const pt = m_locationState.Position();
|
||||
m_navigator.CenterViewport(pt);
|
||||
|
||||
m2::RectD clipRect = m_navigator.Screen().ClipRect();
|
||||
|
||||
double const xMinSize = 6 * max(m_locationState.ErrorRadius(),
|
||||
MercatorBounds::ConvertMetresToX(pt.x, m_metresMinWidth));
|
||||
double const yMinSize = 6 * max(m_locationState.ErrorRadius(),
|
||||
MercatorBounds::ConvertMetresToY(pt.y, m_metresMinWidth));
|
||||
|
||||
bool needToScale = false;
|
||||
|
||||
if (clipRect.SizeX() < clipRect.SizeY())
|
||||
needToScale = clipRect.SizeX() > xMinSize * 3;
|
||||
else
|
||||
needToScale = clipRect.SizeY() > yMinSize * 3;
|
||||
|
||||
/* if ((ClipRect.SizeX() < 3 * errorRadius) || (ClipRect.SizeY() < 3 * errorRadius))
|
||||
needToScale = true;*/
|
||||
|
||||
if (needToScale)
|
||||
{
|
||||
double const k = max(xMinSize / clipRect.SizeX(),
|
||||
yMinSize / clipRect.SizeY());
|
||||
|
||||
clipRect.Scale(k);
|
||||
m_navigator.SetFromRect(clipRect);
|
||||
}
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
/// Show all model by it's world rect.
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::ShowAll()
|
||||
{
|
||||
SetMaxWorldRect();
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Repaint()
|
||||
{
|
||||
m_renderQueue.SetRedrawAll();
|
||||
AddRedrawCommandSure();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::RepaintRect(m2::RectD const & rect)
|
||||
{
|
||||
threads::MutexGuard lock(*m_renderQueue.renderState().m_mutex.get());
|
||||
m2::RectD pxRect(0, 0, m_renderQueue.renderState().m_surfaceWidth, m_renderQueue.renderState().m_surfaceHeight);
|
||||
m2::RectD glbRect;
|
||||
m_navigator.Screen().PtoG(pxRect, glbRect);
|
||||
if (glbRect.Intersect(rect))
|
||||
Repaint();
|
||||
}
|
||||
|
||||
/// @name Drag implementation.
|
||||
//@{
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StartDrag(DragEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
m_navigator.StartDrag(pos,
|
||||
GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pos);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::DoDrag(DragEvent const & e)
|
||||
{
|
||||
m_centeringMode = EDoNothing;
|
||||
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
m_navigator.DoDrag(pos, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pos);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StopDrag(DragEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
|
||||
m_navigator.StopDrag(pos,
|
||||
GetPlatform().TimeInSec(),
|
||||
true);
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
#endif
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Move(double azDir, double factor)
|
||||
{
|
||||
m_navigator.Move(azDir, factor);
|
||||
UpdateNow();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// @name Scaling.
|
||||
//@{
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::ScaleToPoint(ScaleToPointEvent const & e)
|
||||
{
|
||||
m2::PointD const pt = (m_centeringMode == EDoNothing)
|
||||
? m_navigator.OrientPoint(e.Pt()) + m_renderQueue.renderState().coordSystemShift(true)
|
||||
: m_navigator.Screen().PixelRect().Center();
|
||||
|
||||
m_navigator.ScaleToPoint(pt, e.ScaleFactor(), GetPlatform().TimeInSec());
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::ScaleDefault(bool enlarge)
|
||||
{
|
||||
Scale(enlarge ? 1.5 : 2.0/3.0);
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::Scale(double scale)
|
||||
{
|
||||
m_navigator.Scale(scale);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StartScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.StartScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt1);
|
||||
m_informationDisplay.setDebugPoint(1, pt2);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::DoScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.DoScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt1);
|
||||
m_informationDisplay.setDebugPoint(1, pt2);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
template <typename TModel>
|
||||
void FrameWork<TModel>::StopScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.StopScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
#endif
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
template class FrameWork<model::FeaturesFetcher>;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "information_display.hpp"
|
||||
#include "window_handle.hpp"
|
||||
#include "location_state.hpp"
|
||||
#include "navigator.hpp"
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
|
@ -48,6 +49,8 @@ namespace drule { class BaseRule; }
|
|||
|
||||
class redraw_operation_cancelled {};
|
||||
|
||||
struct BenchmarkRectProvider;
|
||||
|
||||
namespace fwork
|
||||
{
|
||||
class DrawProcessor
|
||||
|
@ -89,24 +92,20 @@ typedef boost::function<void (void)> LocationRetrievedCallbackT;
|
|||
|
||||
template
|
||||
<
|
||||
class TModel,
|
||||
class TNavigator
|
||||
class TModel
|
||||
>
|
||||
class FrameWork
|
||||
{
|
||||
typedef TModel model_t;
|
||||
typedef TNavigator navigator_t;
|
||||
|
||||
typedef FrameWork<model_t, navigator_t> this_type;
|
||||
typedef FrameWork<model_t> this_type;
|
||||
|
||||
model_t m_model;
|
||||
navigator_t m_navigator;
|
||||
Navigator m_navigator;
|
||||
shared_ptr<WindowHandle> m_windowHandle;
|
||||
|
||||
bool m_isBenchmarking;
|
||||
bool m_isBenchmarkInitialized;
|
||||
vector<pair<string, m2::RectD> > m_benchmarks;
|
||||
unsigned m_currentBenchmark;
|
||||
|
||||
yg::Color m_bgColor;
|
||||
|
||||
|
@ -126,152 +125,63 @@ class FrameWork
|
|||
ECenterAndScale,
|
||||
ECenterOnly
|
||||
};
|
||||
|
||||
TGpsCenteringMode m_centeringMode;
|
||||
LocationRetrievedCallbackT m_locationObserver;
|
||||
location::State m_locationState;
|
||||
|
||||
void AddRedrawCommandSure()
|
||||
{
|
||||
m_renderQueue.AddCommand(bind(&this_type::PaintImpl, this, _1, _2, _3, _4), m_navigator.Screen());
|
||||
}
|
||||
|
||||
void AddRedrawCommand()
|
||||
{
|
||||
yg::gl::RenderState const state = m_renderQueue.CopyState();
|
||||
if ((state.m_currentScreen != m_navigator.Screen()) && (m_isRedrawEnabled))
|
||||
AddRedrawCommandSure();
|
||||
}
|
||||
|
||||
threads::Mutex m_modelSyn;
|
||||
|
||||
void AddMap(string const & datFile)
|
||||
void AddRedrawCommandSure();
|
||||
void AddRedrawCommand();
|
||||
|
||||
double m_maxDuration;
|
||||
m2::RectD m_maxDurationRect;
|
||||
m2::RectD m_curBenchmarkRect;
|
||||
|
||||
struct BenchmarkResult
|
||||
{
|
||||
// update rect for Show All button
|
||||
feature::DataHeader header;
|
||||
header.Load(FilesContainerR(datFile).GetReader(HEADER_FILE_TAG));
|
||||
string m_name;
|
||||
m2::RectD m_rect;
|
||||
double m_time;
|
||||
};
|
||||
|
||||
m2::RectD bounds = header.GetBounds();
|
||||
vector<BenchmarkResult> m_benchmarkResults;
|
||||
my::Timer m_benchmarksTimer;
|
||||
|
||||
m_model.AddWorldRect(bounds);
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
m_model.AddMap(datFile);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveMap(string const & datFile)
|
||||
struct Benchmark
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
m_model.RemoveMap(datFile);
|
||||
}
|
||||
shared_ptr<BenchmarkRectProvider> m_provider;
|
||||
string m_name;
|
||||
};
|
||||
|
||||
void OnGpsUpdate(location::GpsInfo const & info)
|
||||
{
|
||||
if (info.m_timestamp < location::POSITION_TIMEOUT_SECONDS)
|
||||
{
|
||||
// notify GUI that we received gps position
|
||||
if (!(m_locationState & location::State::EGps) && m_locationObserver)
|
||||
m_locationObserver();
|
||||
vector<Benchmark> m_benchmarks;
|
||||
int m_curBenchmark;
|
||||
|
||||
m_locationState.UpdateGps(info);
|
||||
if (m_centeringMode == ECenterAndScale)
|
||||
{
|
||||
CenterAndScaleViewport();
|
||||
m_centeringMode = ECenterOnly;
|
||||
}
|
||||
else if (m_centeringMode == ECenterOnly)
|
||||
CenterViewport(m_locationState.Position());
|
||||
UpdateNow();
|
||||
}
|
||||
}
|
||||
void BenchmarkCommandFinished();
|
||||
void NextBenchmarkCommand();
|
||||
void SaveBenchmarkResults();
|
||||
|
||||
void OnCompassUpdate(location::CompassInfo const & info)
|
||||
{
|
||||
if (info.m_timestamp < location::POSITION_TIMEOUT_SECONDS)
|
||||
{
|
||||
m_locationState.UpdateCompass(info);
|
||||
UpdateNow();
|
||||
}
|
||||
}
|
||||
void AddMap(string const & datFile);
|
||||
void RemoveMap(string const & datFile);
|
||||
|
||||
void OnGpsUpdate(location::GpsInfo const & info);
|
||||
|
||||
void OnCompassUpdate(location::CompassInfo const & info);
|
||||
|
||||
public:
|
||||
FrameWork(shared_ptr<WindowHandle> windowHandle,
|
||||
size_t bottomShift)
|
||||
: m_windowHandle(windowHandle),
|
||||
m_isBenchmarking(GetPlatform().IsBenchmarking()),
|
||||
m_isBenchmarkInitialized(false),
|
||||
m_currentBenchmark(0),
|
||||
m_bgColor(0xEE, 0xEE, 0xDD, 0xFF),
|
||||
m_renderQueue(GetPlatform().SkinName(),
|
||||
GetPlatform().IsMultiSampled(),
|
||||
GetPlatform().DoPeriodicalUpdate(),
|
||||
GetPlatform().PeriodicalUpdateInterval(),
|
||||
GetPlatform().IsBenchmarking(),
|
||||
GetPlatform().ScaleEtalonSize(),
|
||||
m_bgColor),
|
||||
m_isRedrawEnabled(true),
|
||||
m_metresMinWidth(20),
|
||||
m_minRulerWidth(97),
|
||||
m_centeringMode(EDoNothing)
|
||||
{
|
||||
m_informationDisplay.setBottomShift(bottomShift);
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.enableDebugPoints(true);
|
||||
#endif
|
||||
size_t bottomShift);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_informationDisplay.enableGlobalRect(!m_isBenchmarking);
|
||||
#endif
|
||||
|
||||
m_informationDisplay.enableCenter(true);
|
||||
|
||||
m_informationDisplay.enableRuler(true);
|
||||
m_informationDisplay.setRulerParams(m_minRulerWidth, m_metresMinWidth);
|
||||
m_navigator.SetMinScreenParams(m_minRulerWidth, m_metresMinWidth);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_informationDisplay.enableDebugInfo(true);
|
||||
#endif
|
||||
|
||||
m_informationDisplay.enableLog(GetPlatform().IsVisualLog(), m_windowHandle.get());
|
||||
|
||||
m_informationDisplay.enableBenchmarkInfo(m_isBenchmarking);
|
||||
|
||||
m_informationDisplay.setVisualScale(GetPlatform().VisualScale());
|
||||
m_renderQueue.AddWindowHandle(m_windowHandle);
|
||||
|
||||
// initialize gps and compass subsystem
|
||||
GetLocationService().SetGpsObserver(
|
||||
boost::bind(&this_type::OnGpsUpdate, this, _1));
|
||||
GetLocationService().SetCompassObserver(
|
||||
boost::bind(&this_type::OnCompassUpdate, this, _1));
|
||||
}
|
||||
|
||||
void InitBenchmark()
|
||||
{
|
||||
ifstream fin(GetPlatform().WritablePathForFile("benchmark.txt").c_str());
|
||||
while (true)
|
||||
{
|
||||
string name;
|
||||
double x0, y0, x1, y1;
|
||||
fin >> name >> x0 >> y0 >> x1 >> y1;
|
||||
if (!fin)
|
||||
break;
|
||||
m_navigator.SetFromRect(m2::RectD(x0, y0, x1, y1));
|
||||
m_renderQueue.AddBenchmarkCommand(bind(&this_type::PaintImpl, this, _1, _2, _3, _4), m_navigator.Screen());
|
||||
m_benchmarks.push_back(make_pair(name, m2::RectD(x0, y0, x1, y1)));
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
void InitBenchmark();
|
||||
|
||||
void initializeGL(shared_ptr<yg::gl::RenderContext> const & primaryContext,
|
||||
shared_ptr<yg::ResourceManager> const & resourceManager)
|
||||
{
|
||||
m_resourceManager = resourceManager;
|
||||
m_renderQueue.initializeGL(primaryContext, m_resourceManager, GetPlatform().VisualScale());
|
||||
}
|
||||
shared_ptr<yg::ResourceManager> const & resourceManager);
|
||||
|
||||
model_t & get_model() { return m_model; }
|
||||
model_t & get_model();
|
||||
|
||||
void EnumLocalMaps(Platform::FilesList & filesList);
|
||||
void EnumBenchmarkMaps(Platform::FilesList & filesList);
|
||||
|
||||
/// Initialization.
|
||||
template <class TStorage>
|
||||
|
@ -279,130 +189,49 @@ public:
|
|||
{
|
||||
m_model.InitClassificator();
|
||||
|
||||
typename TStorage::TEnumMapsFunction enumMapsFn;
|
||||
if (m_isBenchmarking)
|
||||
enumMapsFn = bind(&FrameWork::EnumBenchmarkMaps, this, _1);
|
||||
else
|
||||
enumMapsFn = bind(&FrameWork::EnumLocalMaps, this, _1);
|
||||
|
||||
LOG(LINFO, ("Initializing storage"));
|
||||
// initializes model with locally downloaded maps
|
||||
storage.Init(bind(&FrameWork::AddMap, this, _1),
|
||||
bind(&FrameWork::RemoveMap, this, _1),
|
||||
bind(&FrameWork::RepaintRect, this, _1));
|
||||
bind(&FrameWork::RepaintRect, this, _1),
|
||||
enumMapsFn);
|
||||
LOG(LINFO, ("Storage initialized"));
|
||||
}
|
||||
};
|
||||
|
||||
void StartLocationService(LocationRetrievedCallbackT observer)
|
||||
{
|
||||
m_locationObserver = observer;
|
||||
m_centeringMode = ECenterAndScale;
|
||||
// by default, we always start in accurate mode
|
||||
GetLocationService().StartUpdate(true);
|
||||
}
|
||||
void StartLocationService(LocationRetrievedCallbackT observer);
|
||||
void StopLocationService();
|
||||
|
||||
void StopLocationService()
|
||||
{
|
||||
// reset callback
|
||||
m_locationObserver.clear();
|
||||
m_centeringMode = EDoNothing;
|
||||
GetLocationService().StopUpdate();
|
||||
m_locationState.TurnOff();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
bool IsEmptyModel()
|
||||
{
|
||||
return m_model.GetWorldRect() == m2::RectD::GetEmptyRect();
|
||||
}
|
||||
bool IsEmptyModel();
|
||||
|
||||
// Cleanup.
|
||||
void Clean()
|
||||
{
|
||||
m_model.Clean();
|
||||
}
|
||||
void Clean();
|
||||
|
||||
/// Save and load framework state to ini file between sessions.
|
||||
//@{
|
||||
public:
|
||||
|
||||
void SetMaxWorldRect()
|
||||
{
|
||||
m_navigator.SetFromRect(m_model.GetWorldRect());
|
||||
}
|
||||
|
||||
void UpdateNow()
|
||||
{
|
||||
AddRedrawCommand();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void Invalidate()
|
||||
{
|
||||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
void SaveState()
|
||||
{
|
||||
m_navigator.SaveState();
|
||||
}
|
||||
|
||||
bool LoadState()
|
||||
{
|
||||
if (!m_navigator.LoadState())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
//@}
|
||||
void SetMaxWorldRect();
|
||||
void UpdateNow();
|
||||
void Invalidate();
|
||||
void SaveState();
|
||||
bool LoadState();
|
||||
|
||||
/// Resize event from window.
|
||||
void OnSize(int w, int h)
|
||||
{
|
||||
if (w < 2) w = 2;
|
||||
if (h < 2) h = 2;
|
||||
void OnSize(int w, int h);
|
||||
|
||||
m_renderQueue.OnSize(w, h);
|
||||
|
||||
m2::PointU ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m_informationDisplay.setDisplayRect(m2::RectI(ptShift, ptShift + m2::PointU(w, h)));
|
||||
|
||||
m_navigator.OnSize(ptShift.x, ptShift.y, w, h);
|
||||
|
||||
if ((m_isBenchmarking) && (!m_isBenchmarkInitialized))
|
||||
{
|
||||
m_isBenchmarkInitialized = true;
|
||||
InitBenchmark();
|
||||
}
|
||||
}
|
||||
|
||||
bool SetUpdatesEnabled(bool doEnable)
|
||||
{
|
||||
return m_windowHandle->setUpdatesEnabled(doEnable);
|
||||
}
|
||||
bool SetUpdatesEnabled(bool doEnable);
|
||||
|
||||
/// enabling/disabling AddRedrawCommand
|
||||
void SetRedrawEnabled(bool isRedrawEnabled)
|
||||
{
|
||||
m_isRedrawEnabled = isRedrawEnabled;
|
||||
AddRedrawCommand();
|
||||
}
|
||||
void SetRedrawEnabled(bool isRedrawEnabled);
|
||||
|
||||
/// respond to device orientation changes
|
||||
void SetOrientation(EOrientation orientation)
|
||||
{
|
||||
m_navigator.SetOrientation(orientation);
|
||||
m_locationState.SetOrientation(orientation);
|
||||
UpdateNow();
|
||||
}
|
||||
void SetOrientation(EOrientation orientation);
|
||||
|
||||
int GetCurrentScale() const
|
||||
{
|
||||
m2::PointD textureCenter(m_renderQueue.renderState().m_textureWidth / 2,
|
||||
m_renderQueue.renderState().m_textureHeight / 2);
|
||||
m2::RectD glbRect;
|
||||
|
||||
unsigned scaleEtalonSize = GetPlatform().ScaleEtalonSize();
|
||||
m_navigator.Screen().PtoG(m2::RectD(textureCenter - m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2),
|
||||
textureCenter + m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2)),
|
||||
glbRect);
|
||||
return scales::GetScaleLevel(glbRect);
|
||||
}
|
||||
int GetCurrentScale() const;
|
||||
|
||||
/// Actual rendering function.
|
||||
/// Called, as the renderQueue processes RenderCommand
|
||||
|
@ -411,360 +240,54 @@ public:
|
|||
ScreenBase const & screen,
|
||||
m2::RectD const & selectRect,
|
||||
int scaleLevel
|
||||
)
|
||||
{
|
||||
fwork::DrawProcessor doDraw(selectRect, screen, e, scaleLevel, m_renderQueue.renderStatePtr());
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelCurrent = true;
|
||||
|
||||
try
|
||||
{
|
||||
threads::MutexGuard lock(m_modelSyn);
|
||||
|
||||
#ifdef PROFILER_DRAWING
|
||||
using namespace prof;
|
||||
|
||||
start<for_each_feature>();
|
||||
reset<feature_count>();
|
||||
#endif
|
||||
|
||||
m_model.ForEachFeatureWithScale(selectRect, bind<bool>(ref(doDraw), _1), scaleLevel);
|
||||
|
||||
#ifdef PROFILER_DRAWING
|
||||
end<for_each_feature>();
|
||||
LOG(LPROF, ("ForEachFeature=", metric<for_each_feature>(),
|
||||
"FeatureCount=", metric<feature_count>(),
|
||||
"TextureUpload= ", metric<yg_upload_data>()));
|
||||
#endif
|
||||
}
|
||||
catch (redraw_operation_cancelled const &)
|
||||
{
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelCurrent = false;
|
||||
m_renderQueue.renderStatePtr()->m_isEmptyModelActual = false;
|
||||
}
|
||||
|
||||
if (m_navigator.Update(GetPlatform().TimeInSec()))
|
||||
Invalidate();
|
||||
}
|
||||
);
|
||||
|
||||
/// Function for calling from platform dependent-paint function.
|
||||
void Paint(shared_ptr<PaintEvent> e)
|
||||
{
|
||||
/// Making a copy of actualFrameInfo to compare without synchronizing.
|
||||
// typename yg::gl::RenderState state = m_renderQueue.CopyState();
|
||||
void Paint(shared_ptr<PaintEvent> e);
|
||||
|
||||
DrawerYG * pDrawer = e->drawer().get();
|
||||
void CenterViewport(m2::PointD const & pt);
|
||||
|
||||
m_informationDisplay.setScreen(m_navigator.Screen());
|
||||
void ShowRect(m2::RectD const & rect);
|
||||
|
||||
m_informationDisplay.setDebugInfo(m_renderQueue.renderState().m_duration, GetCurrentScale());
|
||||
void MemoryWarning();
|
||||
|
||||
m_informationDisplay.enableRuler(!IsEmptyModel());
|
||||
void EnterBackground();
|
||||
|
||||
m2::PointD const center = m_navigator.Screen().ClipRect().Center();
|
||||
void CenterViewport(m2::PointD const & pt);
|
||||
|
||||
m_informationDisplay.setGlobalRect(m_navigator.Screen().GlobalRect());
|
||||
m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y)));
|
||||
void ShowRect(m2::RectD const & rect);
|
||||
|
||||
{
|
||||
threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get());
|
||||
void MemoryWarning();
|
||||
|
||||
if (m_isBenchmarking)
|
||||
{
|
||||
m2::PointD const center = m_renderQueue.renderState().m_actualScreen.ClipRect().Center();
|
||||
m_informationDisplay.setScreen(m_renderQueue.renderState().m_actualScreen);
|
||||
m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y)));
|
||||
void EnterBackground();
|
||||
|
||||
if (m_benchmarks.empty())
|
||||
{
|
||||
e->drawer()->screen()->beginFrame();
|
||||
e->drawer()->screen()->clear(m_bgColor);
|
||||
m_informationDisplay.setDisplayRect(m2::RectI(0, 0, 100, 100));
|
||||
m_informationDisplay.enableRuler(false);
|
||||
m_informationDisplay.doDraw(e->drawer().get());
|
||||
e->drawer()->screen()->endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_renderQueue.renderState().m_actualTarget.get() != 0)
|
||||
{
|
||||
if (m_isBenchmarking
|
||||
&& !m_benchmarks.empty()
|
||||
&& m_informationDisplay.addBenchmarkInfo(m_benchmarks[m_currentBenchmark].first,
|
||||
m_benchmarks[m_currentBenchmark].second,
|
||||
m_renderQueue.renderState().m_duration))
|
||||
m_currentBenchmark++;
|
||||
|
||||
e->drawer()->screen()->beginFrame();
|
||||
e->drawer()->screen()->clear(m_bgColor);
|
||||
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false);
|
||||
|
||||
OGLCHECK(glMatrixMode(GL_MODELVIEW));
|
||||
OGLCHECK(glPushMatrix());
|
||||
OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0));
|
||||
|
||||
ScreenBase currentScreen = m_navigator.Screen();
|
||||
|
||||
m_informationDisplay.enableEmptyModelMessage(m_renderQueue.renderStatePtr()->m_isEmptyModelActual);
|
||||
|
||||
if (m_isBenchmarking)
|
||||
currentScreen = m_renderQueue.renderState().m_actualScreen;
|
||||
|
||||
pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget,
|
||||
m_renderQueue.renderState().m_actualScreen,
|
||||
currentScreen);
|
||||
|
||||
m_informationDisplay.doDraw(pDrawer);
|
||||
|
||||
m_locationState.DrawMyPosition(*pDrawer, m_navigator.Screen());
|
||||
|
||||
e->drawer()->screen()->endFrame();
|
||||
|
||||
OGLCHECK(glPopMatrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CenterViewport(m2::PointD const & pt)
|
||||
{
|
||||
m_navigator.CenterViewport(pt);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
void ShowRect(m2::RectD const & rect)
|
||||
{
|
||||
m_navigator.SetFromRect(rect);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
void MemoryWarning()
|
||||
{
|
||||
// clearing caches on memory warning.
|
||||
m_model.ClearCaches();
|
||||
LOG(LINFO, ("MemoryWarning"));
|
||||
}
|
||||
|
||||
void EnterBackground()
|
||||
{
|
||||
// clearing caches on entering background.
|
||||
m_model.ClearCaches();
|
||||
}
|
||||
|
||||
void EnterForeground()
|
||||
{
|
||||
}
|
||||
void EnterForeground();
|
||||
|
||||
/// @TODO refactor to accept point and min visible length
|
||||
void CenterAndScaleViewport()
|
||||
{
|
||||
m2::PointD const pt = m_locationState.Position();
|
||||
m_navigator.CenterViewport(pt);
|
||||
|
||||
m2::RectD clipRect = m_navigator.Screen().ClipRect();
|
||||
|
||||
double const xMinSize = 6 * max(m_locationState.ErrorRadius(),
|
||||
MercatorBounds::ConvertMetresToX(pt.x, m_metresMinWidth));
|
||||
double const yMinSize = 6 * max(m_locationState.ErrorRadius(),
|
||||
MercatorBounds::ConvertMetresToY(pt.y, m_metresMinWidth));
|
||||
|
||||
bool needToScale = false;
|
||||
|
||||
if (clipRect.SizeX() < clipRect.SizeY())
|
||||
needToScale = clipRect.SizeX() > xMinSize * 3;
|
||||
else
|
||||
needToScale = clipRect.SizeY() > yMinSize * 3;
|
||||
|
||||
/* if ((ClipRect.SizeX() < 3 * errorRadius) || (ClipRect.SizeY() < 3 * errorRadius))
|
||||
needToScale = true;*/
|
||||
|
||||
if (needToScale)
|
||||
{
|
||||
double const k = max(xMinSize / clipRect.SizeX(),
|
||||
yMinSize / clipRect.SizeY());
|
||||
|
||||
clipRect.Scale(k);
|
||||
m_navigator.SetFromRect(clipRect);
|
||||
}
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
void CenterAndScaleViewport();
|
||||
|
||||
/// Show all model by it's world rect.
|
||||
void ShowAll()
|
||||
{
|
||||
SetMaxWorldRect();
|
||||
UpdateNow();
|
||||
}
|
||||
void ShowAll();
|
||||
|
||||
void Repaint()
|
||||
{
|
||||
m_renderQueue.SetRedrawAll();
|
||||
AddRedrawCommandSure();
|
||||
Invalidate();
|
||||
}
|
||||
void Repaint();
|
||||
|
||||
void RepaintRect(m2::RectD const & rect)
|
||||
{
|
||||
threads::MutexGuard lock(*m_renderQueue.renderState().m_mutex.get());
|
||||
m2::RectD pxRect(0, 0, m_renderQueue.renderState().m_surfaceWidth, m_renderQueue.renderState().m_surfaceHeight);
|
||||
m2::RectD glbRect;
|
||||
m_navigator.Screen().PtoG(pxRect, glbRect);
|
||||
if (glbRect.Intersect(rect))
|
||||
Repaint();
|
||||
}
|
||||
void RepaintRect(m2::RectD const & rect);
|
||||
|
||||
/// @name Drag implementation.
|
||||
//@{
|
||||
void StartDrag(DragEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
m_navigator.StartDrag(pos,
|
||||
GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pos);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
void DoDrag(DragEvent const & e)
|
||||
{
|
||||
m_centeringMode = EDoNothing;
|
||||
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
m_navigator.DoDrag(pos, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pos);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void StopDrag(DragEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift;
|
||||
|
||||
m_navigator.StopDrag(pos,
|
||||
GetPlatform().TimeInSec(),
|
||||
true);
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
#endif
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
void Move(double azDir, double factor)
|
||||
{
|
||||
m_navigator.Move(azDir, factor);
|
||||
UpdateNow();
|
||||
}
|
||||
void StartDrag(DragEvent const & e);
|
||||
void DoDrag(DragEvent const & e);
|
||||
void StopDrag(DragEvent const & e);
|
||||
void Move(double azDir, double factor);
|
||||
//@}
|
||||
|
||||
/// @name Scaling.
|
||||
//@{
|
||||
void ScaleToPoint(ScaleToPointEvent const & e)
|
||||
{
|
||||
m2::PointD const pt = (m_centeringMode == EDoNothing)
|
||||
? m_navigator.OrientPoint(e.Pt()) + m_renderQueue.renderState().coordSystemShift(true)
|
||||
: m_navigator.Screen().PixelRect().Center();
|
||||
|
||||
m_navigator.ScaleToPoint(pt, e.ScaleFactor(), GetPlatform().TimeInSec());
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
void ScaleDefault(bool enlarge)
|
||||
{
|
||||
Scale(enlarge ? 1.5 : 2.0/3.0);
|
||||
}
|
||||
|
||||
void Scale(double scale)
|
||||
{
|
||||
m_navigator.Scale(scale);
|
||||
UpdateNow();
|
||||
}
|
||||
|
||||
void StartScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.StartScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt1);
|
||||
m_informationDisplay.setDebugPoint(1, pt2);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void DoScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.DoScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt1);
|
||||
m_informationDisplay.setDebugPoint(1, pt2);
|
||||
#endif
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void StopScale(ScaleEvent const & e)
|
||||
{
|
||||
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true);
|
||||
|
||||
m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift;
|
||||
m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift;
|
||||
|
||||
if ((m_locationState & location::State::EGps) && (m_centeringMode == ECenterOnly))
|
||||
{
|
||||
m2::PointD ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD ptDiff = m_navigator.Screen().PixelRect().Center() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
|
||||
m_navigator.StopScale(pt1, pt2, GetPlatform().TimeInSec());
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
|
||||
#endif
|
||||
|
||||
UpdateNow();
|
||||
}
|
||||
void ScaleToPoint(ScaleToPointEvent const & e);
|
||||
void ScaleDefault(bool enlarge);
|
||||
void Scale(double scale);
|
||||
void StartScale(ScaleEvent const & e);
|
||||
void DoScale(ScaleEvent const & e);
|
||||
void StopScale(ScaleEvent const & e);
|
||||
//@}
|
||||
};
|
||||
|
|
|
@ -459,33 +459,26 @@ void InformationDisplay::enableBenchmarkInfo(bool doEnable)
|
|||
|
||||
bool InformationDisplay::addBenchmarkInfo(string const & name, m2::RectD const & globalRect, double frameDuration)
|
||||
{
|
||||
if (frameDuration == 0)
|
||||
return false;
|
||||
if ((m_benchmarkInfo.empty())
|
||||
||(m_benchmarkInfo.back().m_duration != frameDuration))
|
||||
{
|
||||
BenchmarkInfo info;
|
||||
info.m_name = name;
|
||||
info.m_duration = frameDuration;
|
||||
info.m_rect = globalRect;
|
||||
m_benchmarkInfo.push_back(info);
|
||||
BenchmarkInfo info;
|
||||
info.m_name = name;
|
||||
info.m_duration = frameDuration;
|
||||
info.m_rect = globalRect;
|
||||
m_benchmarkInfo.push_back(info);
|
||||
|
||||
string deviceID = GetPlatform().DeviceID();
|
||||
transform(deviceID.begin(), deviceID.end(), deviceID.begin(), ::tolower);
|
||||
/* string deviceID = GetPlatform().DeviceID();
|
||||
transform(deviceID.begin(), deviceID.end(), deviceID.begin(), ::tolower);
|
||||
|
||||
ofstream fout(GetPlatform().WritablePathForFile(deviceID + "_benchmark_results.txt").c_str(), ios::app);
|
||||
fout << GetPlatform().DeviceID() << " "
|
||||
<< VERSION_STRING << " "
|
||||
<< info.m_name << " "
|
||||
<< info.m_rect.minX() << " "
|
||||
<< info.m_rect.minY() << " "
|
||||
<< info.m_rect.maxX() << " "
|
||||
<< info.m_rect.maxY() << " "
|
||||
<< info.m_duration << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
ofstream fout(GetPlatform().WritablePathForFile(deviceID + "_benchmark_results.txt").c_str(), ios::app);
|
||||
fout << GetPlatform().DeviceID() << " "
|
||||
<< VERSION_STRING << " "
|
||||
<< info.m_name << " "
|
||||
<< info.m_rect.minX() << " "
|
||||
<< info.m_rect.minY() << " "
|
||||
<< info.m_rect.maxX() << " "
|
||||
<< info.m_rect.maxY() << " "
|
||||
<< info.m_duration << endl;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void InformationDisplay::drawBenchmarkInfo(DrawerYG * pDrawer)
|
||||
|
@ -500,7 +493,7 @@ void InformationDisplay::drawBenchmarkInfo(DrawerYG * pDrawer)
|
|||
yg::maxDepth,
|
||||
false);
|
||||
|
||||
for (unsigned i = 0; i < m_benchmarkInfo.size(); ++i)
|
||||
for (unsigned i = max(0, (int)m_benchmarkInfo.size() - 5); i < m_benchmarkInfo.size(); ++i)
|
||||
{
|
||||
ostringstream out;
|
||||
m2::RectD const & r = m_benchmarkInfo[i].m_rect;
|
||||
|
|
|
@ -23,6 +23,7 @@ HEADERS += \
|
|||
information_display.hpp \
|
||||
settings.hpp \
|
||||
location_state.hpp \
|
||||
benchmark_provider.hpp
|
||||
|
||||
SOURCES += \
|
||||
feature_vec_model.cpp \
|
||||
|
@ -35,6 +36,7 @@ SOURCES += \
|
|||
information_display.cpp \
|
||||
settings.cpp \
|
||||
location_state.cpp \
|
||||
benchmark_provider.cpp
|
||||
|
||||
!iphone*:!bada* {
|
||||
HEADERS += qgl_render_context.hpp
|
||||
|
|
|
@ -69,6 +69,11 @@ void RenderQueue::AddWindowHandle(shared_ptr<WindowHandle> const & windowHandle)
|
|||
m_routine->addWindowHandle(windowHandle);
|
||||
}
|
||||
|
||||
void RenderQueue::addRenderCommandFinishedFn(renderCommandFinishedFn fn)
|
||||
{
|
||||
m_routine->addRenderCommandFinishedFn(fn);
|
||||
}
|
||||
|
||||
void RenderQueue::OnSize(size_t w, size_t h)
|
||||
{
|
||||
m_renderState->onSize(w, h);
|
||||
|
|
|
@ -30,6 +30,9 @@ private:
|
|||
RenderQueueRoutine * m_routine;
|
||||
|
||||
public:
|
||||
|
||||
typedef RenderQueueRoutine::renderCommandFinishedFn renderCommandFinishedFn;
|
||||
|
||||
/// constructor.
|
||||
RenderQueue(string const & skinName,
|
||||
bool isMultiSampled,
|
||||
|
@ -54,6 +57,9 @@ public:
|
|||
|
||||
/// add window handle to notify when rendering operation finishes
|
||||
void AddWindowHandle(shared_ptr<WindowHandle> const & windowHandle);
|
||||
|
||||
void addRenderCommandFinishedFn(renderCommandFinishedFn fn);
|
||||
|
||||
/// process resize request
|
||||
void OnSize(size_t w, size_t h);
|
||||
/// copy primary render state
|
||||
|
|
|
@ -437,6 +437,9 @@ void RenderQueueRoutine::Do()
|
|||
}
|
||||
|
||||
invalidate();
|
||||
|
||||
callRenderCommandFinishedFns();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -518,3 +521,15 @@ void RenderQueueRoutine::enterForeground()
|
|||
m_threadDrawer->screen()->enterForeground();
|
||||
}
|
||||
|
||||
void RenderQueueRoutine::addRenderCommandFinishedFn(renderCommandFinishedFn fn)
|
||||
{
|
||||
m_renderCommandFinishedFns.push_back(fn);
|
||||
}
|
||||
|
||||
void RenderQueueRoutine::callRenderCommandFinishedFns()
|
||||
{
|
||||
if (!m_renderCommandFinishedFns.empty())
|
||||
for (list<renderCommandFinishedFn>::const_iterator it = m_renderCommandFinishedFns.begin(); it != m_renderCommandFinishedFns.end(); ++it)
|
||||
(*it)();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class RenderQueueRoutine : public threads::IRoutine
|
|||
public:
|
||||
|
||||
typedef function<void(shared_ptr<PaintEvent>, ScreenBase const &, m2::RectD const &, int)> render_fn_t;
|
||||
typedef function<void()> renderCommandFinishedFn;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -85,6 +86,10 @@ private:
|
|||
void waitForRenderCommand(list<shared_ptr<RenderModelCommand> > & cmdList,
|
||||
threads::ConditionGuard & guard);
|
||||
|
||||
list<renderCommandFinishedFn> m_renderCommandFinishedFns;
|
||||
|
||||
void callRenderCommandFinishedFns();
|
||||
|
||||
public:
|
||||
RenderQueueRoutine(shared_ptr<yg::gl::RenderState> const & renderState,
|
||||
string const & skinName,
|
||||
|
@ -124,4 +129,6 @@ public:
|
|||
void enterBackground();
|
||||
/// recreate all necessary opengl resources and prepare to run in foreground.
|
||||
void enterForeground();
|
||||
/// add render-command-finished callback
|
||||
void addRenderCommandFinishedFn(renderCommandFinishedFn fn);
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace qt
|
|||
|
||||
typedef model::FeaturesFetcher model_t;
|
||||
|
||||
FrameWork<model_t, Navigator> m_framework;
|
||||
FrameWork<model_t> m_framework;
|
||||
|
||||
bool m_isDrag;
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace storage
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Storage::Init(TAddMapFunction addFunc, TRemoveMapFunction removeFunc, TUpdateRectFunction updateRectFunc)
|
||||
void Storage::Init(TAddMapFunction addFunc, TRemoveMapFunction removeFunc, TUpdateRectFunction updateRectFunc, TEnumMapsFunction enumMapsFunc)
|
||||
{
|
||||
m_currentVersion = static_cast<uint32_t>(Version::BUILD);
|
||||
|
||||
|
@ -56,18 +56,16 @@ namespace storage
|
|||
m_removeMap = removeFunc;
|
||||
m_updateRect = updateRectFunc;
|
||||
|
||||
// activate all downloaded maps
|
||||
Platform & p = GetPlatform();
|
||||
Platform::FilesList filesList;
|
||||
string const dataPath = p.WritableDir();
|
||||
p.GetFilesInDir(dataPath, "*" DATA_FILE_EXTENSION, filesList);
|
||||
enumMapsFunc(filesList);
|
||||
|
||||
for (Platform::FilesList::iterator it = filesList.begin(); it != filesList.end(); ++it)
|
||||
{ // simple way to avoid continuous crashes with invalid data files
|
||||
try {
|
||||
m_addMap(dataPath + *it);
|
||||
m_addMap(GetPlatform().WritableDir() + *it);
|
||||
} catch (std::exception const & e)
|
||||
{
|
||||
FileWriter::DeleteFileX(dataPath + *it);
|
||||
FileWriter::DeleteFileX(GetPlatform().WritableDir() + *it);
|
||||
LOG(LWARNING, (e.what(), "while adding file", *it, "so this file is deleted"));
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +76,7 @@ namespace storage
|
|||
if (found == filesList.end())
|
||||
{
|
||||
try {
|
||||
m_addMap(p.ReadPathForFile(WORLD_FILE_NAME DATA_FILE_EXTENSION));
|
||||
m_addMap(GetPlatform().ReadPathForFile(WORLD_FILE_NAME DATA_FILE_EXTENSION));
|
||||
} catch (std::exception const & e)
|
||||
{
|
||||
LOG(LWARNING, (e.what(), "while adding world data file"));
|
||||
|
|
|
@ -89,9 +89,13 @@ namespace storage
|
|||
|
||||
/// @name Communicate with Framework
|
||||
//@{
|
||||
public:
|
||||
typedef boost::function<void (string const &)> TAddMapFunction;
|
||||
typedef boost::function<void (string const &)> TRemoveMapFunction;
|
||||
typedef boost::function<void (m2::RectD const & r)> TUpdateRectFunction;
|
||||
typedef boost::function<void (Platform::FilesList &)> TEnumMapsFunction;
|
||||
private:
|
||||
|
||||
TAddMapFunction m_addMap;
|
||||
TRemoveMapFunction m_removeMap;
|
||||
TUpdateRectFunction m_updateRect;
|
||||
|
@ -106,7 +110,7 @@ namespace storage
|
|||
Storage() {}
|
||||
|
||||
/// Adds all locally downloaded maps to the model
|
||||
void Init(TAddMapFunction addFunc, TRemoveMapFunction removeFunc, TUpdateRectFunction updateRectFunc);
|
||||
void Init(TAddMapFunction addFunc, TRemoveMapFunction removeFunc, TUpdateRectFunction updateRectFunc, TEnumMapsFunction enumMapFunction);
|
||||
|
||||
/// @name Called from DownloadManager
|
||||
//@{
|
||||
|
|
Loading…
Add table
Reference in a new issue