fix work with TRACK_POINTERS enabled #358

Merged
Dushistov merged 5 commits from drape-ptr-refs into master 2021-05-01 12:16:01 +00:00
8 changed files with 52 additions and 37 deletions

View file

@ -153,13 +153,21 @@ void OverlayTree::StartOverlayPlacing(ScreenBase const & screen, int zoomLevel)
m_zoomLevel = zoomLevel;
}
void OverlayTree::Remove(ref_ptr<OverlayHandle> handle)
bool OverlayTree::Remove(ref_ptr<OverlayHandle> handle)
{
if (m_frameCounter == kInvalidFrame)
return;
{
if (!IsEmpty())
Clear();
return true;
}
vng commented 2021-05-01 07:22:13 +00:00 (Migrated from github.com)
Review

Hm, Is it a valid state or something went wrong and we made this patch? When

m_frameCounter == kInvalidFrame && !IsEmpty()
Hm, Is it a valid state or something went wrong and we made this patch? When ``` m_frameCounter == kInvalidFrame && !IsEmpty() ```
Dushistov commented 2021-05-01 11:42:05 +00:00 (Migrated from github.com)
Review

Yes, there are several places where m_frameCounter setted to kInvalidFrame without call of Clear(), for example OverlayTree::SetVisualScale.
And this is ok, because of only OverlayTree::Remove call can cause dangling ref_ptr.
So with something like map scale change and move we can get kInvalidFrame via OverlayTree::SetVisualScale and only then call to OverlayTree::Remove before start of next frame. And in that case we get danging ref_ptr without extra Clear call.

Yes, there are several places where `m_frameCounter` setted to `kInvalidFrame` without call of `Clear()`, for example `OverlayTree::SetVisualScale`. And this is ok, because of only `OverlayTree::Remove` call can cause dangling `ref_ptr`. So with something like map scale change and move we can get kInvalidFrame via `OverlayTree::SetVisualScale` and only then call to `OverlayTree::Remove` before start of next frame. And in that case we get danging `ref_ptr` without extra `Clear` call.
if (m_handlesCache.find(handle) != m_handlesCache.end())
InvalidateOnNextFrame();
{
Clear();
return true;
}
return false;
}
void OverlayTree::Add(ref_ptr<OverlayHandle> handle)
@ -205,7 +213,7 @@ void OverlayTree::Add(ref_ptr<OverlayHandle> handle)
ASSERT_GREATER_OR_EQUAL(handle->GetOverlayRank(), 0, ());
size_t const rank = static_cast<size_t>(handle->GetOverlayRank());
ASSERT_LESS(rank, m_handles.size(), ());
m_handles[rank].emplace_back(handle);
m_handles[rank].emplace_back(std::move(handle));
}
void OverlayTree::InsertHandle(ref_ptr<OverlayHandle> handle, int currentRank,

View file

@ -71,7 +71,8 @@ public:
void StartOverlayPlacing(ScreenBase const & screen, int zoomLevel);
void Add(ref_ptr<OverlayHandle> handle);
void Remove(ref_ptr<OverlayHandle> handle);
//! \return true if tree completely invalidated and next call has no sense
bool Remove(ref_ptr<OverlayHandle> handle);
void EndOverlayPlacing();
biodranik commented 2021-04-30 11:57:10 +00:00 (Migrated from github.com)
Review

Комментарий, что возвращается, не помешал бы.

Комментарий, что возвращается, не помешал бы.
Dushistov commented 2021-04-30 12:32:57 +00:00 (Migrated from github.com)
Review

Done

Done
HandlesCache const & GetHandlesCache() const { return m_handlesCache; }

View file

@ -79,10 +79,14 @@ bool RenderBucket::HasOverlayHandles() const
return !m_overlay.empty();
}
void RenderBucket::RemoveOverlayHandles(ref_ptr<OverlayTree> tree)
bool RenderBucket::RemoveOverlayHandles(ref_ptr<OverlayTree> tree)
{
for (auto const & overlayHandle : m_overlay)
tree->Remove(make_ref(overlayHandle));
{
if (tree->Remove(make_ref(overlayHandle)))
return true;
}
return false;
}
void RenderBucket::SetOverlayVisibility(bool isVisible)

View file

@ -32,7 +32,8 @@ public:
void Update(ScreenBase const & modelView);
void CollectOverlayHandles(ref_ptr<OverlayTree> tree);
bool HasOverlayHandles() const;
void RemoveOverlayHandles(ref_ptr<OverlayTree> tree);
//! \return true if tree completely invalidated and next call has no sense
bool RemoveOverlayHandles(ref_ptr<OverlayTree> tree);
void SetOverlayVisibility(bool isVisible);
biodranik commented 2021-04-30 11:57:40 +00:00 (Migrated from github.com)
Review

И здесь.

И здесь.
Dushistov commented 2021-04-30 12:32:48 +00:00 (Migrated from github.com)
Review

Done

Done
void Render(ref_ptr<GraphicsContext> context, bool drawAsLine);

View file

@ -60,7 +60,8 @@ bool RenderGroup::HasOverlayHandles() const
void RenderGroup::RemoveOverlay(ref_ptr<dp::OverlayTree> tree)
{
for (auto & renderBucket : m_renderBuckets)
renderBucket->RemoveOverlayHandles(tree);
if (renderBucket->RemoveOverlayHandles(tree))
break;
}
void RenderGroup::SetOverlayVisibility(bool isVisible)

View file

@ -2,22 +2,35 @@
#include <array>
namespace
{
using namespace df;
std::array<RenderStateExtension, static_cast<size_t>(DepthLayer::LayersCount)> kStateExtensions = {
RenderStateExtension(DepthLayer::GeometryLayer),
RenderStateExtension(DepthLayer::Geometry3dLayer),
RenderStateExtension(DepthLayer::UserLineLayer),
RenderStateExtension(DepthLayer::OverlayLayer),
RenderStateExtension(DepthLayer::TransitSchemeLayer),
RenderStateExtension(DepthLayer::UserMarkLayer),
RenderStateExtension(DepthLayer::NavigationLayer),
RenderStateExtension(DepthLayer::RoutingBottomMarkLayer),
RenderStateExtension(DepthLayer::RoutingMarkLayer),
RenderStateExtension(DepthLayer::SearchMarkLayer),
RenderStateExtension(DepthLayer::GuiLayer)};
struct RenderStateExtensionFactory
{
static ref_ptr<RenderStateExtension> Get(DepthLayer depthLayer)
{
ASSERT_LESS(static_cast<size_t>(depthLayer), kStateExtensions.size(), ());
return make_ref(&kStateExtensions[static_cast<size_t>(depthLayer)]);
}
};
} // namespace
namespace df
{
std::array<drape_ptr<RenderStateExtension>, static_cast<size_t>(DepthLayer::LayersCount)> kStateExtensions = {
make_unique_dp<RenderStateExtension>(DepthLayer::GeometryLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::Geometry3dLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::UserLineLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::OverlayLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::TransitSchemeLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::UserMarkLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::NavigationLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::RoutingBottomMarkLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::RoutingMarkLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::SearchMarkLayer),
make_unique_dp<RenderStateExtension>(DepthLayer::GuiLayer)
};
RenderStateExtension::RenderStateExtension(DepthLayer depthLayer)
: m_depthLayer(depthLayer)
{}
@ -36,13 +49,6 @@ bool RenderStateExtension::Equal(ref_ptr<dp::BaseRenderStateExtension> other) co
return m_depthLayer == renderState->m_depthLayer;
}
// static
ref_ptr<RenderStateExtension> RenderStateExtensionFactory::Get(DepthLayer depthLayer)
{
ASSERT_LESS(static_cast<size_t>(depthLayer), kStateExtensions.size(), ());
return make_ref(kStateExtensions[static_cast<size_t>(depthLayer)]);
}
DepthLayer GetDepthLayer(dp::RenderState const & state)
{
return state.GetRenderStateExtension<RenderStateExtension>()->GetDepthLayer();

View file

@ -40,12 +40,6 @@ private:
DepthLayer const m_depthLayer;
};
class RenderStateExtensionFactory
{
public:
static ref_ptr<RenderStateExtension> Get(DepthLayer depthLayer);
};
extern DepthLayer GetDepthLayer(dp::RenderState const & state);
extern dp::RenderState CreateRenderState(gpu::Program program, DepthLayer depthLayer);

View file

@ -40,8 +40,8 @@ private:
using Programs = std::array<drape_ptr<dp::GpuProgram>,
static_cast<size_t>(Program::ProgramsCount)>;
Programs m_programs;
drape_ptr<ProgramPool> m_pool;
Programs m_programs;
drape_ptr<ProgramParamsSetter> m_paramsSetter;
DECLARE_THREAD_CHECKER(m_threadChecker);