Merge pull request #1497 from ExMix/overlay_refactoring_2

Overlay refactoring 2 (reverse-merged from commit 4073d52f56c860bc2a43c0259ec475bd7fe63b41)
This commit is contained in:
ExMix 2013-04-29 12:01:44 +03:00 committed by Alex Zolotarev
parent ac21ab9675
commit 2e9b38bd35
18 changed files with 214 additions and 268 deletions

View file

@ -19,7 +19,6 @@
#include "../../testing/testing.hpp"
#include <QtGui/QKeyEvent>
#include "../../base/scope_guard.hpp"
#include "../../base/math.hpp"
#include "../../base/string_utils.hpp"
#include "../../std/shared_ptr.hpp"
@ -1267,9 +1266,7 @@ namespace
public:
void DoDraw(shared_ptr<graphics::Screen> p)
{
graphics::Overlay * overlay = new graphics::Overlay();
MY_SCOPE_GUARD(overlayGuard, bind(&graphics::Overlay::Deleter::DeleteOverlay, overlay));
p->setOverlay(overlay);
p->setOverlay(make_shared_ptr(new graphics::Overlay()));
p->overlay()->setCouldOverlap(false);
p->drawSymbol(m2::PointD(200, 200), "current-position", graphics::EPosUnder, graphics::maxDepth);

View file

@ -13,7 +13,7 @@
namespace graphics
{
Overlay::Lock::Lock(Overlay * overlay)
Overlay::Lock::Lock(shared_ptr<Overlay> overlay)
: m_overlay(overlay)
{
m_overlay->lock();
@ -24,8 +24,8 @@ namespace graphics
m_overlay->unlock();
}
bool betterOverlayElement(OverlayElement * l,
OverlayElement * r)
bool betterOverlayElement(shared_ptr<OverlayElement> const & l,
shared_ptr<OverlayElement> const & r)
{
/// "frozen" object shouldn't be popped out.
if (r->isFrozen())
@ -35,13 +35,13 @@ namespace graphics
return l->priority() > r->priority();
}
m2::RectD const OverlayElementTraits::LimitRect(OverlayElement * elem)
m2::RectD const OverlayElementTraits::LimitRect(shared_ptr<OverlayElement> const & elem)
{
return elem->roughBoundRect();
}
void DrawIfNotCancelled(OverlayRenderer * r,
OverlayElement * e,
shared_ptr<OverlayElement> const & e,
math::Matrix<double, 3, 3> const & m)
{
if (!r->isCancelled())
@ -153,20 +153,12 @@ namespace graphics
m_mutex.Unlock();
}
void Overlay::deleteElementsAndClear()
{
std::vector<OverlayElement *> elements;
m_tree.ForEach(MakeBackInsertFunctor(elements));
for_each(elements.begin(), elements.end(), DeleteFunctor());
clear();
}
void Overlay::clear()
{
m_tree.Clear();
}
void Overlay::addOverlayElement(OverlayElement * oe)
void Overlay::addOverlayElement(shared_ptr<OverlayElement> const & oe)
{
m_tree.Add(oe);
}
@ -174,31 +166,31 @@ namespace graphics
struct DoPreciseSelectByPoint
{
m2::PointD m_pt;
list<OverlayElement const * > & m_elements;
list<shared_ptr<OverlayElement> > * m_elements;
DoPreciseSelectByPoint(m2::PointD const & pt, list<OverlayElement const * > & elements)
DoPreciseSelectByPoint(m2::PointD const & pt, list<shared_ptr<OverlayElement> > * elements)
: m_pt(pt), m_elements(elements)
{}
void operator()(OverlayElement * e)
void operator()(shared_ptr<OverlayElement> const & e)
{
if (e->hitTest(m_pt))
m_elements.push_back(e);
m_elements->push_back(e);
}
};
struct DoPreciseSelectByRect
{
m2::AnyRectD m_rect;
list<OverlayElement const *> & m_elements;
list<shared_ptr<OverlayElement> > * m_elements;
DoPreciseSelectByRect(m2::RectD const & rect,
list<OverlayElement const *> & elements)
list<shared_ptr<OverlayElement> > * elements)
: m_rect(rect),
m_elements(elements)
{}
void operator()(OverlayElement * e)
void operator()(shared_ptr<OverlayElement> const & e)
{
vector<m2::AnyRectD> const & rects = e->boundRects();
@ -210,7 +202,7 @@ namespace graphics
if (m_rect.IsIntersect(rect))
{
m_elements.push_back(e);
m_elements->push_back(e);
break;
}
}
@ -219,17 +211,17 @@ namespace graphics
struct DoPreciseIntersect
{
OverlayElement const * m_oe;
bool & m_isIntersect;
shared_ptr<OverlayElement> m_oe;
bool * m_isIntersect;
DoPreciseIntersect(OverlayElement const * oe, bool & isIntersect)
DoPreciseIntersect(shared_ptr<OverlayElement> const & oe, bool * isIntersect)
: m_oe(oe),
m_isIntersect(isIntersect)
{}
void operator()(OverlayElement * e)
void operator()(shared_ptr<OverlayElement> const & e)
{
if (m_isIntersect)
if (*m_isIntersect)
return;
if (m_oe->m_userInfo == e->m_userInfo)
@ -242,30 +234,30 @@ namespace graphics
{
for (vector<m2::AnyRectD>::const_iterator rit = rr.begin(); rit != rr.end(); ++rit)
{
m_isIntersect = lit->IsIntersect(*rit);
if (m_isIntersect)
*m_isIntersect = lit->IsIntersect(*rit);
if (*m_isIntersect)
return;
}
}
}
};
void Overlay::selectOverlayElements(m2::RectD const & rect, list<OverlayElement const *> & res)
void Overlay::selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res)
{
DoPreciseSelectByRect fn(rect, res);
DoPreciseSelectByRect fn(rect, &res);
m_tree.ForEachInRect(rect, fn);
}
void Overlay::selectOverlayElements(m2::PointD const & pt, list<OverlayElement const *> & res)
void Overlay::selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res)
{
DoPreciseSelectByPoint fn(pt, res);
DoPreciseSelectByPoint fn(pt, &res);
m_tree.ForEachInRect(m2::RectD(pt - m2::PointD(1, 1), pt + m2::PointD(1, 1)), fn);
}
void Overlay::replaceOverlayElement(OverlayElement * oe)
void Overlay::replaceOverlayElement(shared_ptr<OverlayElement> const & oe)
{
bool isIntersect = false;
DoPreciseIntersect fn(oe, isIntersect);
DoPreciseIntersect fn(oe, &isIntersect);
m_tree.ForEachInRect(oe->roughBoundRect(), fn);
if (isIntersect)
m_tree.ReplaceIf(oe, &betterOverlayElement);
@ -273,21 +265,19 @@ namespace graphics
m_tree.Add(oe);
}
void Overlay::removeOverlayElement(OverlayElement * oe, m2::RectD const & r)
void Overlay::removeOverlayElement(shared_ptr<OverlayElement> const & oe, m2::RectD const & r)
{
m_tree.Erase(oe, r);
}
void Overlay::processOverlayElement(OverlayElement * oe, math::Matrix<double, 3, 3> const & m)
void Overlay::processOverlayElement(shared_ptr<OverlayElement> const & oe, math::Matrix<double, 3, 3> const & m)
{
oe->setTransformation(m);
if (oe->isValid())
processOverlayElement(oe);
else
m_notProcessedElements.insert(oe);
}
void Overlay::processOverlayElement(OverlayElement * oe)
void Overlay::processOverlayElement(shared_ptr<OverlayElement> const & oe)
{
if (oe->isValid())
{
@ -296,19 +286,17 @@ namespace graphics
else
replaceOverlayElement(oe);
}
else
m_notProcessedElements.insert(oe);
}
bool greater_priority(OverlayElement const * l,
OverlayElement const * r)
bool greater_priority(shared_ptr<OverlayElement> const & l,
shared_ptr<OverlayElement> const & r)
{
return l->priority() > r->priority();
}
void Overlay::merge(Overlay const & layer, math::Matrix<double, 3, 3> const & m)
{
vector<OverlayElement *> v;
vector<shared_ptr<OverlayElement> > v;
/// 1. collecting all elements from tree
layer.m_tree.ForEach(MakeBackInsertFunctor(v));
@ -319,27 +307,48 @@ namespace graphics
/// 3. merging them into the infoLayer starting from most
/// important one to optimize the space usage.
for_each(v.begin(), v.end(), bind(&Overlay::processOverlayElement, this, _1, cref(m)));
clearNotProcessed();
}
void Overlay::merge(Overlay const & infoLayer)
{
vector<shared_ptr<OverlayElement> > v;
/// 1. collecting all elements from tree
infoLayer.m_tree.ForEach(MakeBackInsertFunctor(v));
/// 2. sorting by priority, so the more important ones comes first
sort(v.begin(), v.end(), &greater_priority);
/// 3. merging them into the infoLayer starting from most
/// important one to optimize the space usage.
for_each(v.begin(), v.end(), bind(&Overlay::processOverlayElement, this, _1));
}
void Overlay::clip(m2::RectI const & r)
{
vector<OverlayElement * > v;
vector<shared_ptr<OverlayElement> > v;
m_tree.ForEach(MakeBackInsertFunctor(v));
m_tree.Clear();
//int clippedCnt = 0;
//int elemCnt = v.size();
m2::RectD rd(r);
m2::AnyRectD ard(rd);
for (unsigned i = 0; i < v.size(); ++i)
{
OverlayElement * e = v[i];
shared_ptr<OverlayElement> const & e = v[i];
bool hasIntersection = false;
if (e->isVisible() && e->roughBoundRect().IsIntersect(rd))
if (!e->isVisible())
{
//clippedCnt++;
continue;
}
if (e->roughBoundRect().IsIntersect(rd))
{
bool hasIntersection = false;
for (unsigned j = 0; j < e->boundRects().size(); ++j)
{
if (ard.IsIntersect(e->boundRects()[j]))
@ -348,12 +357,12 @@ namespace graphics
break;
}
}
}
if (hasIntersection)
processOverlayElement(e);
else
m_notProcessedElements.insert(e);
if (hasIntersection)
processOverlayElement(e);
}
//else
// clippedCnt++;
}
// LOG(LINFO, ("clipped out", clippedCnt, "elements,", elemCnt, "elements total"));
@ -361,46 +370,21 @@ namespace graphics
bool Overlay::checkHasEquals(Overlay const * l) const
{
vector<OverlayElement *> v0;
vector<shared_ptr<OverlayElement> > v0;
m_tree.ForEach(MakeBackInsertFunctor(v0));
sort(v0.begin(), v0.end());
vector<OverlayElement *> v1;
vector<shared_ptr<OverlayElement> > v1;
l->m_tree.ForEach(MakeBackInsertFunctor(v1));
sort(v1.begin(), v1.end());
vector<OverlayElement *> res;
vector<shared_ptr<OverlayElement> > res;
set_intersection(v0.begin(), v0.end(), v1.begin(), v1.end(), back_inserter(res));
return !res.empty();
}
void Overlay::clearNotProcessed()
{
m_notProcessedElements.clear();
}
void Overlay::deleteNotProcessed()
{
for_each(m_notProcessedElements.begin(), m_notProcessedElements.end(), DeleteFunctor());
m_notProcessedElements.clear();
}
#ifdef DEBUG
void Overlay::validateNotProcessed()
{
vector<OverlayElement *> v;
m_tree.ForEach(MakeBackInsertFunctor(v));
for (size_t i = 0; i < v.size(); ++i)
{
ASSERT(m_notProcessedElements.find(v[i]) == m_notProcessedElements.end(),
("Object marked to deletion in tree!!!"));
}
}
#endif
}

View file

@ -9,98 +9,71 @@
#include "../base/matrix.hpp"
#include "../base/mutex.hpp"
#ifdef DEBUG
#include "../base/thread.hpp"
#endif
#include "../std/map.hpp"
#include "../std/list.hpp"
namespace graphics
{
struct OverlayElementTraits
{
static m2::RectD const LimitRect(OverlayElement * elem);
static m2::RectD const LimitRect(shared_ptr<OverlayElement> const & elem);
};
class Overlay
{
private:
#ifdef DEBUG
threads::ThreadID m_threadID;
#endif
threads::Mutex m_mutex;
bool m_couldOverlap;
set<OverlayElement *> m_notProcessedElements;
m4::Tree<OverlayElement *, OverlayElementTraits> m_tree;
m4::Tree<shared_ptr<OverlayElement>, OverlayElementTraits> m_tree;
void addOverlayElement(OverlayElement * oe);
void replaceOverlayElement(OverlayElement * oe);
void addOverlayElement(shared_ptr<OverlayElement> const & oe);
void replaceOverlayElement(shared_ptr<OverlayElement> const & oe);
Overlay(Overlay const & src) {}
public:
struct Deleter
{
void operator()(Overlay * overlay) const
{
DeleteOverlay(overlay);
}
static void DeleteOverlay(Overlay * overlay)
{
overlay->deleteElementsAndClear();
delete overlay;
}
};
class Lock
{
public:
Lock(Overlay * overlay);
Lock(shared_ptr<Overlay> overlay);
~Lock();
private:
Overlay * m_overlay;
shared_ptr<Overlay> m_overlay;
};
Overlay();
void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m);
void selectOverlayElements(m2::PointD const & pt, list<OverlayElement const * > & res);
void selectOverlayElements(m2::RectD const & rect, list<OverlayElement const * > & res);
void selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res);
void selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res);
void removeOverlayElement(OverlayElement * oe, m2::RectD const & r);
void removeOverlayElement(shared_ptr<OverlayElement> const & oe, m2::RectD const & r);
void processOverlayElement(OverlayElement * oe);
void processOverlayElement(shared_ptr<OverlayElement> const & oe);
void processOverlayElement(OverlayElement * oe, math::Matrix<double, 3, 3> const & m);
void processOverlayElement(shared_ptr<OverlayElement> const & oe, math::Matrix<double, 3, 3> const & m);
void offset(m2::PointD const & offs, m2::RectD const & rect);
void lock();
void unlock();
void deleteElementsAndClear();
void clear();
void setCouldOverlap(bool flag);
void merge(Overlay const & infoLayer, math::Matrix<double, 3, 3> const & m);
void merge(Overlay const & infoLayer);
void clip(m2::RectI const & r);
void clearNotProcessed();
void deleteNotProcessed();
#ifdef DEBUG
void validateNotProcessed();
#endif
bool checkHasEquals(Overlay const * l) const;
template <typename Fn>
@ -108,18 +81,5 @@ namespace graphics
{
m_tree.ForEach(fn);
}
#ifdef DEBUG
void setThreadID(threads::ThreadID id)
{
m_threadID = id;
}
bool validateThread(threads::ThreadID id)
{
return m_threadID == id;
}
#endif
};
}

View file

@ -6,10 +6,6 @@
#include "defines.hpp"
#include "../std/vector.hpp"
#ifdef DEBUG
#include "../base/object_tracker.hpp"
#endif
namespace graphics
{
class OverlayRenderer;
@ -35,7 +31,7 @@ namespace graphics
m2::PointD m_pivot;
graphics::EPosition m_position;
double m_depth;
double m_depth;
bool m_isNeedRedraw;
bool m_isFrozen;
@ -49,10 +45,6 @@ namespace graphics
math::Matrix<double, 3, 3> m_inverseMatrix;
#ifdef DEBUG
dbg::ObjectTracker m_tracker;
#endif
protected:
math::Matrix<double, 3, 3> const & getResetMatrix() const;

View file

@ -12,8 +12,7 @@ namespace graphics
{
OverlayRenderer::Params::Params()
: m_drawTexts(true),
m_drawSymbols(true),
m_overlay(NULL)
m_drawSymbols(true)
{
}
@ -30,10 +29,14 @@ namespace graphics
if (!m_drawSymbols)
return;
if (!m_overlay)
SymbolElement(params).draw(this, math::Identity<double, 3>());
shared_ptr<OverlayElement> oe(new SymbolElement(params));
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
if (!m_overlay.get())
oe->draw(this, id);
else
m_overlay->processOverlayElement(new SymbolElement(params));
m_overlay->processOverlayElement(oe);
}
void OverlayRenderer::drawSymbol(m2::PointD const & pt, string const & name, EPosition pos, int depth)
@ -61,10 +64,14 @@ namespace graphics
params.m_pivot = pt;
params.m_ci = ci;
if (!m_overlay)
CircleElement(params).draw(this, math::Identity<double, 3>());
shared_ptr<OverlayElement> oe(new CircleElement(params));
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
if (!m_overlay.get())
oe->draw(this, id);
else
m_overlay->processOverlayElement(new CircleElement(params));
m_overlay->processOverlayElement(oe);
}
void OverlayRenderer::drawText(FontDesc const & fontDesc,
@ -90,10 +97,14 @@ namespace graphics
params.m_offset = m2::PointD(0,0);
params.m_glyphCache = glyphCache();
if (!m_overlay)
StraightTextElement(params).draw(this, math::Identity<double, 3>());
shared_ptr<OverlayElement> oe(new StraightTextElement(params));
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
if (!m_overlay.get())
oe->draw(this, id);
else
m_overlay->processOverlayElement(new StraightTextElement(params));
m_overlay->processOverlayElement(oe);
}
void OverlayRenderer::drawTextEx(StraightTextElement::Params & params)
@ -103,10 +114,14 @@ namespace graphics
params.m_glyphCache = glyphCache();
if (!m_overlay)
StraightTextElement(params).draw(this, math::Identity<double, 3>());
shared_ptr<OverlayElement> oe(new StraightTextElement(params));
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
if (!m_overlay.get())
oe->draw(this, id);
else
m_overlay->processOverlayElement(new StraightTextElement(params));
m_overlay->processOverlayElement(oe);
}
void OverlayRenderer::drawTextEx(FontDesc const & primaryFont,
@ -163,10 +178,14 @@ namespace graphics
params.m_glyphCache = glyphCache();
params.m_pivot = path[0];
if (!m_overlay)
PathTextElement(params).draw(this, math::Identity<double, 3>());
shared_ptr<PathTextElement> pte(new PathTextElement(params));
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
if (!m_overlay.get())
pte->draw(this, id);
else
m_overlay->processOverlayElement(new PathTextElement(params));
m_overlay->processOverlayElement(pte);
}
void OverlayRenderer::drawPathText(FontDesc const & fontDesc,
@ -193,18 +212,18 @@ namespace graphics
depth);
}
void OverlayRenderer::setOverlay(Overlay *overlay)
void OverlayRenderer::setOverlay(shared_ptr<Overlay> const & overlay)
{
m_overlay = overlay;
}
Overlay * OverlayRenderer::overlay() const
shared_ptr<Overlay> const & OverlayRenderer::overlay() const
{
return m_overlay;
}
void OverlayRenderer::resetOverlay()
{
m_overlay = NULL;
m_overlay.reset();
}
}

View file

@ -16,7 +16,11 @@ namespace graphics
bool m_drawTexts;
bool m_drawSymbols;
graphics::Overlay * m_overlay;
shared_ptr<graphics::Overlay> m_overlay;
typedef map<m2::PointI, shared_ptr<OverlayElement> > TElements;
TElements m_elements;
public:
@ -24,7 +28,7 @@ namespace graphics
{
bool m_drawTexts;
bool m_drawSymbols;
graphics::Overlay * m_overlay;
shared_ptr<graphics::Overlay> m_overlay;
Params();
};
@ -81,9 +85,9 @@ namespace graphics
size_t offsSize,
double depth);
void setOverlay(Overlay * overlay);
void setOverlay(shared_ptr<Overlay> const & overlay);
Overlay * overlay() const;
shared_ptr<Overlay> const & overlay() const;
void resetOverlay();
};

View file

@ -25,7 +25,6 @@ namespace graphics
Category m_category;
Info(Category cat);
virtual ~Info() {}
virtual Info const & cacheKey() const = 0;
/// returns the size of this resource info which will

View file

@ -264,9 +264,9 @@ void BasicTilingRenderPolicy::FrameUnlock()
m_CoverageGenerator->Mutex().Unlock();
}
graphics::Overlay * BasicTilingRenderPolicy::FrameOverlay() const
shared_ptr<graphics::Overlay> const BasicTilingRenderPolicy::FrameOverlay() const
{
return m_CoverageGenerator->GetOverlay();
return m_CoverageGenerator->CurrentCoverage()->GetOverlay();
}
int BasicTilingRenderPolicy::InsertBenchmarkFence()

View file

@ -81,7 +81,7 @@ public:
void FrameLock();
void FrameUnlock();
graphics::Overlay * FrameOverlay() const;
shared_ptr<graphics::Overlay> const FrameOverlay() const;
/// benchmarking protocol
int InsertBenchmarkFence();

View file

@ -9,9 +9,6 @@
#include "../graphics/opengl/gl_render_context.hpp"
#include "../base/logging.hpp"
#ifdef DEBUG
#include "../base/thread.hpp"
#endif
#include "../std/bind.hpp"
@ -45,7 +42,6 @@ CoverageGenerator::CoverageGenerator(
g_coverageGeneratorDestroyed = false;
m_resourceManager = rm;
m_overlay.setCouldOverlap(false);
if (!m_glQueue)
m_renderContext.reset(primaryRC->createShared());
@ -84,10 +80,6 @@ ScreenCoverage * CoverageGenerator::CreateCoverage()
void CoverageGenerator::InitializeThreadGL()
{
#ifdef DEBUG
m_overlay.setThreadID(threads::GetCurrentThreadID());
#endif
threads::MutexGuard g(m_mutex);
LOG(LINFO, ("initializing CoverageGenerator on it's own thread."));
@ -135,7 +127,6 @@ void CoverageGenerator::InvalidateTilesImpl(m2::AnyRectD const & r, int startSca
{
threads::MutexGuard g(m_mutex);
m_currentCoverage->RemoveTiles(r, startScale);
m_currentCoverage->MergeOverlay(&m_overlay);
}
TileCache & tileCache = m_tileRenderer->GetTileCache();
@ -213,14 +204,10 @@ void CoverageGenerator::CoverScreen(core::CommandsQueue::Environment const & env
if (sequenceID < m_sequenceID)
return;
m_currentCoverage->CopyInto(*m_workCoverage);
m_currentCoverage->CopyInto(*m_workCoverage, false);
m_workCoverage->SetSequenceID(sequenceID);
m_workCoverage->SetScreen(screen);
#ifdef DEBUG
m_overlay.validateThread(threads::GetCurrentThreadID());
#endif
m_workCoverage->MergeOverlay(&m_overlay);
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
{
@ -228,7 +215,7 @@ void CoverageGenerator::CoverScreen(core::CommandsQueue::Environment const & env
AddCheckEmptyModelTask(sequenceID);
}
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env, &m_overlay);
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
if (shouldSwap)
{
@ -269,12 +256,9 @@ void CoverageGenerator::MergeTile(core::CommandsQueue::Environment const & env,
}
//LOG(LDEBUG, ("UVRLOG : MergeTile s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " SequenceID=", sequenceID, " m_SequenceID=", m_sequenceID));
m_currentCoverage->CopyInto(*m_workCoverage);
m_currentCoverage->CopyInto(*m_workCoverage, true);
m_workCoverage->SetSequenceID(sequenceID);
#ifdef DEBUG
m_overlay.validateThread(threads::GetCurrentThreadID());
#endif
m_workCoverage->Merge(rectInfo, &m_overlay);
m_workCoverage->Merge(rectInfo);
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
{
@ -282,7 +266,7 @@ void CoverageGenerator::MergeTile(core::CommandsQueue::Environment const & env,
AddCheckEmptyModelTask(sequenceID);
}
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env, &m_overlay);
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
if (shouldSwap)
{
@ -358,11 +342,6 @@ ScreenCoverage * CoverageGenerator::CurrentCoverage()
return m_currentCoverage;
}
graphics::Overlay * CoverageGenerator::GetOverlay()
{
return &m_overlay;
}
threads::Mutex & CoverageGenerator::Mutex()
{
return m_mutex;

View file

@ -89,9 +89,6 @@ private:
bool m_isPaused;
bool m_isBenchmarking;
/// Overlay composed of overlays for visible tiles
graphics::Overlay m_overlay;
ScreenCoverage * CreateCoverage();
public:
@ -142,7 +139,6 @@ public:
storage::TIndex GetCountryIndex(m2::PointD const & pt) const;
ScreenCoverage * CurrentCoverage();
graphics::Overlay * GetOverlay();
int InsertBenchmarkFence();
void JoinBenchmarkFence(int fenceID);

View file

@ -1474,13 +1474,13 @@ bool Framework::IsBenchmarking() const
return m_benchmarkEngine != 0;
}
graphics::OverlayElement const * GetClosestToPivot(list<graphics::OverlayElement const * > const & l,
shared_ptr<graphics::OverlayElement> const GetClosestToPivot(list<shared_ptr<graphics::OverlayElement> > const & l,
m2::PointD const & pxPoint)
{
double dist = numeric_limits<double>::max();
graphics::OverlayElement const * res;
shared_ptr<graphics::OverlayElement> res;
for (list<graphics::OverlayElement const *>::const_iterator it = l.begin();
for (list<shared_ptr<graphics::OverlayElement> >::const_iterator it = l.begin();
it != l.end();
++it)
{
@ -1503,23 +1503,25 @@ bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot,
double const halfSize = TOUCH_PIXEL_RADIUS * GetVisualScale();
typedef graphics::OverlayElement ElementT;
ElementT::UserInfo ui;
list<shared_ptr<ElementT> > candidates;
m2::RectD rect(pt.x - halfSize, pt.y - halfSize,
pt.x + halfSize, pt.y + halfSize);
{
graphics::Overlay * frameOverlay = m_renderPolicy->FrameOverlay();
shared_ptr<graphics::Overlay> frameOverlay = m_renderPolicy->FrameOverlay();
graphics::Overlay::Lock guard(frameOverlay);
list<ElementT const * > candidates;
frameOverlay->selectOverlayElements(rect, candidates);
ElementT const * elem = GetClosestToPivot(candidates, pt);
if (elem)
ui = elem->userInfo();
}
shared_ptr<ElementT> elem = GetClosestToPivot(candidates, pt);
/// cloning element to avoid it's modification after FrameUnlock.
ElementT::UserInfo ui;
if (elem)
ui = elem->userInfo();
m_renderPolicy->FrameUnlock();
if (ui.IsValid())

View file

@ -239,10 +239,10 @@ void RenderPolicy::FrameUnlock()
LOG(LWARNING, ("unimplemented method called"));
}
graphics::Overlay * RenderPolicy::FrameOverlay() const
shared_ptr<graphics::Overlay> const RenderPolicy::FrameOverlay() const
{
LOG(LWARNING, ("unimplemented method called"));
return NULL;
return shared_ptr<graphics::Overlay>();
}
graphics::Color const RenderPolicy::GetBgColor() const

View file

@ -162,7 +162,7 @@ public:
/// Get current graphics::Overlay object.
/// Access to this resource should be synchronized using
/// FrameLock/FrameUnlock methods
virtual graphics::Overlay * FrameOverlay() const;
virtual shared_ptr<graphics::Overlay> const FrameOverlay() const;
/// Benchmarking protocol
virtual int InsertBenchmarkFence();

View file

@ -11,7 +11,6 @@
#include "../graphics/screen.hpp"
#include "../graphics/display_list.hpp"
#include "../graphics/opengl/base_texture.hpp"
#include "../graphics/overlay.hpp"
#include "screen_coverage.hpp"
#include "tile_renderer.hpp"
@ -19,31 +18,32 @@
#include "coverage_generator.hpp"
ScreenCoverage::ScreenCoverage()
: m_sequenceID(numeric_limits<int>::max()),
m_tileRenderer(NULL),
m_coverageGenerator(NULL),
m_isBenchmarking(false),
: m_tiler(),
m_overlay(new graphics::Overlay()),
m_isEmptyDrawingCoverage(false),
m_isEmptyModelAtCoverageCenter(true),
m_leafTilesToRender(0)
m_leafTilesToRender(0),
m_isBenchmarking(false)
{
m_overlay->setCouldOverlap(false);
}
ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer,
CoverageGenerator * coverageGenerator,
shared_ptr<graphics::Screen> const & cacheScreen)
: m_sequenceID(numeric_limits<int>::max()),
m_tileRenderer(tileRenderer),
: m_tileRenderer(tileRenderer),
m_coverageGenerator(coverageGenerator),
m_isBenchmarking(false),
m_overlay(new graphics::Overlay()),
m_isEmptyDrawingCoverage(false),
m_isEmptyModelAtCoverageCenter(true),
m_leafTilesToRender(0),
m_cacheScreen(cacheScreen)
m_cacheScreen(cacheScreen),
m_isBenchmarking(false)
{
m_overlay->setCouldOverlap(false);
}
void ScreenCoverage::CopyInto(ScreenCoverage & cvg)
void ScreenCoverage::CopyInto(ScreenCoverage & cvg, bool mergeOverlay)
{
cvg.m_tileRenderer = m_tileRenderer;
cvg.m_tiler = m_tiler;
@ -70,6 +70,11 @@ void ScreenCoverage::CopyInto(ScreenCoverage & cvg)
}
tileCache->Unlock();
if (mergeOverlay)
{
graphics::Overlay::Lock guard(cvg.m_overlay);
cvg.m_overlay->merge(*m_overlay);
}
}
void ScreenCoverage::Clear()
@ -77,6 +82,10 @@ void ScreenCoverage::Clear()
m_tileRects.clear();
m_newTileRects.clear();
m_newLeafTileRects.clear();
{
graphics::Overlay::Lock guard(m_overlay);
m_overlay->clear();
}
m_isEmptyDrawingCoverage = false;
m_isEmptyModelAtCoverageCenter = true;
m_leafTilesToRender = 0;
@ -96,7 +105,7 @@ void ScreenCoverage::Clear()
m_tiles.clear();
}
void ScreenCoverage::Merge(Tiler::RectInfo const & ri, graphics::Overlay * frameOverlay)
void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
{
ASSERT(m_tileRects.find(ri) != m_tileRects.end(), ());
@ -129,24 +138,24 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri, graphics::Overlay * frame
if (tile != NULL && m_tiler.isLeaf(ri))
{
graphics::Overlay::Lock guard(frameOverlay);
frameOverlay->merge(*tile->m_overlay,
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
graphics::Overlay::Lock guard(m_overlay);
m_overlay->merge(*tile->m_overlay,
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
}
//else
// LOG(LDEBUG, ("UVRLOG : Tile not found s=", ri.m_tileScale, " x=", ri.m_x, " y=", ri.m_y));
}
void FilterElementsBySharpness(graphics::OverlayElement * e,
vector<graphics::OverlayElement const *> & v,
void FilterElementsBySharpness(shared_ptr<graphics::OverlayElement> const & e,
vector<shared_ptr<graphics::OverlayElement> > & v,
bool flag)
{
if (e->hasSharpGeometry() == flag)
v.push_back(e);
}
bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env, graphics::Overlay * frameOverlay)
bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env)
{
/// caching tiles blitting commands.
@ -188,17 +197,17 @@ bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env, graphic
// selecting and rendering non-sharp elements.
{
graphics::Overlay::Lock guard(frameOverlay);
vector<graphics::OverlayElement const *> nonSharpElements;
frameOverlay->forEach(bind(&FilterElementsBySharpness, _1, ref(nonSharpElements), false));
graphics::Overlay::Lock guard(m_overlay);
vector<shared_ptr<graphics::OverlayElement> > nonSharpElements;
m_overlay->forEach(bind(&FilterElementsBySharpness, _1, ref(nonSharpElements), false));
for (unsigned i = 0; i < nonSharpElements.size(); ++i)
nonSharpElements[i]->draw(m_cacheScreen.get(), idM);
// selecting and rendering sharp elements
vector<graphics::OverlayElement const *> sharpElements;
frameOverlay->forEach(bind(&FilterElementsBySharpness, _1, ref(sharpElements), true));
vector<shared_ptr<graphics::OverlayElement> > sharpElements;
m_overlay->forEach(bind(&FilterElementsBySharpness, _1, ref(sharpElements), true));
m_cacheScreen->applySharpStates();
m_cacheScreen->setDisplayList(m_sharpTextDL.get());
@ -292,6 +301,8 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
m_tiles = tiles;
MergeOverlay();
vector<Tiler::RectInfo> firstClassTiles;
vector<Tiler::RectInfo> secondClassTiles;
@ -390,6 +401,11 @@ void ScreenCoverage::Draw(graphics::Screen * s, ScreenBase const & screen)
s->drawDisplayList(m_sharpTextDL.get(), m);
}
shared_ptr<graphics::Overlay> const & ScreenCoverage::GetOverlay() const
{
return m_overlay;
}
int ScreenCoverage::GetDrawScale() const
{
return m_tiler.tileScale();
@ -463,18 +479,20 @@ void ScreenCoverage::RemoveTiles(m2::AnyRectD const & r, int startScale)
m_tileRects.erase(ri);
}
tileCache->Unlock();
MergeOverlay();
}
void ScreenCoverage::MergeOverlay(graphics::Overlay * frameOverlay)
void ScreenCoverage::MergeOverlay()
{
graphics::Overlay::Lock guard(frameOverlay);
frameOverlay->clear();
graphics::Overlay::Lock guard(m_overlay);
m_overlay->clear();
for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
{
Tiler::RectInfo const & ri = (*it)->m_rectInfo;
if (m_tiler.isLeaf(ri))
frameOverlay->merge(*(*it)->m_overlay, (*it)->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
m_overlay->merge(*(*it)->m_overlay, (*it)->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
}
}

View file

@ -4,6 +4,8 @@
#include "../geometry/screenbase.hpp"
#include "../graphics/overlay.hpp"
#include "tile.hpp"
#include "tiler.hpp"
#include "render_policy.hpp"
@ -16,8 +18,6 @@ namespace graphics
{
class Screen;
}
class Overlay;
}
class CoverageGenerator;
@ -51,6 +51,8 @@ private:
/// Tiles in this set are locked to prevent their deletion
/// from TileCache while drawing them
TTileSet m_tiles;
/// Overlay composed of overlays for visible tiles
shared_ptr<graphics::Overlay> m_overlay;
/// State flags
bool m_isBenchmarking;
@ -78,6 +80,9 @@ private:
ScreenCoverage(ScreenCoverage const & src);
ScreenCoverage const & operator=(ScreenCoverage const & src);
/// For each tile in m_tiles merge it's overlay into the big one.
void MergeOverlay();
public:
/// Default Constructor
@ -89,7 +94,7 @@ public:
/// Destructor
~ScreenCoverage();
/// Copy all needed information into specified ScreenCoverage
void CopyInto(ScreenCoverage & cvg);
void CopyInto(ScreenCoverage & cvg, bool mergeOverlay);
/// Make screen coverage empty
void Clear();
/// set unique ID for all actions, used to compute this coverage
@ -109,15 +114,14 @@ public:
storage::TIndex GetCountryIndexAtCoverageCenter() const;
/// Check, whether the model is empty at the center of the coverage.
void CheckEmptyModelAtCoverageCenter();
/// Getter for Overlay
shared_ptr<graphics::Overlay> const & GetOverlay() const;
/// Cache coverage in display list
/// @return true - if the coverage was cached successfully,
/// false - otherwise(p.e. the caching was cancelled)
bool Cache(core::CommandsQueue::Environment const & env,
graphics::Overlay * frameOverlay);
bool Cache(core::CommandsQueue::Environment const & env);
/// add rendered tile to coverage. Tile is locked, so make sure to unlock it in case it's not needed.
void Merge(Tiler::RectInfo const & ri, graphics::Overlay * frameOverlay);
/// For each tile in m_tiles merge it's overlay into the big one.
void MergeOverlay(graphics::Overlay * frameOverlay);
void Merge(Tiler::RectInfo const & ri);
/// recalculate screen coverage, using as much info from prev coverage as possible
void SetScreen(ScreenBase const & screen);
/// draw screen coverage

View file

@ -3,8 +3,6 @@
#include "drawer.hpp"
#include "window_handle.hpp"
#include "../base/scope_guard.hpp"
#include "../graphics/overlay.hpp"
#include "../graphics/opengl/opengl.hpp"
#include "../graphics/render_context.hpp"
@ -124,8 +122,7 @@ void SimpleRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e,
pxCenter + m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2)),
glbRect);
graphics::Overlay * overlay = new graphics::Overlay();
MY_SCOPE_GUARD(overlayGuard, bind(&graphics::Overlay::Deleter::DeleteOverlay, overlay));
shared_ptr<graphics::Overlay> overlay(new graphics::Overlay());
Drawer * pDrawer = e->drawer();
graphics::Screen * pScreen = pDrawer->screen();

View file

@ -218,10 +218,10 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
drawer->screen()->setRenderTarget(tileTarget);
shared_ptr<graphics::Overlay> tileOverlay(new graphics::Overlay(), graphics::Overlay::Deleter());
shared_ptr<graphics::Overlay> tileOverlay(new graphics::Overlay());
tileOverlay->setCouldOverlap(true);
drawer->screen()->setOverlay(tileOverlay.get());
drawer->screen()->setOverlay(tileOverlay);
/// ensuring, that the render target is not bound as a texture
@ -271,11 +271,6 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
if (!env.isCancelled())
tileOverlay->clip(renderRect);
#ifdef DEBUG
tileOverlay->validateNotProcessed();
#endif
tileOverlay->deleteNotProcessed();
drawer->screen()->finish();
if (m_resourceManager->useReadPixelsToSynchronize())