diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 4e1d6e66a3..0eff10c8f0 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -255,7 +255,7 @@ void FrontendRenderer::UpdateCanBeDeletedStatus() if (tileRect.IsIntersect(screenRect)) canBeDeleted = !HasIntersection(tileRect, notFinishedTileRects); } - layer.m_isDirty |= group->UpdateCanBeDeletedStatus(canBeDeleted, m_currentZoomLevel, + layer.m_isDirty |= group->UpdateCanBeDeletedStatus(canBeDeleted, GetCurrentZoom(), make_ref(m_overlayTree)); } } @@ -271,7 +271,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) dp::RenderState const & state = msg->GetState(); TileKey const & key = msg->GetKey(); drape_ptr bucket = msg->AcceptBuffer(); - if (key.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(key)) + if (key.m_zoomLevel == GetCurrentZoom() && CheckTileGenerations(key)) { PrepareBucket(state, bucket); AddToRenderGroup(state, std::move(bucket), key); @@ -285,7 +285,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) TOverlaysRenderData renderData = msg->AcceptRenderData(); for (auto & overlayRenderData : renderData) { - if (overlayRenderData.m_tileKey.m_zoomLevel == m_currentZoomLevel && + if (overlayRenderData.m_tileKey.m_zoomLevel == GetCurrentZoom() && CheckTileGenerations(overlayRenderData.m_tileKey)) { PrepareBucket(overlayRenderData.m_state, overlayRenderData.m_bucket); @@ -328,7 +328,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) #if defined(DRAPE_MEASURER_BENCHMARK) && defined(GENERATING_STATISTIC) DrapeMeasurer::Instance().EndScenePreparing(); #endif - m_trafficRenderer->OnGeometryReady(m_currentZoomLevel); + m_trafficRenderer->OnGeometryReady(GetCurrentZoom()); #if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX) if (m_graphicsStage == GraphicsStage::WaitReady) @@ -351,7 +351,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) TUserMarksRenderData marksRenderData = msg->AcceptRenderData(); for (auto & renderData : marksRenderData) { - if (renderData.m_tileKey.m_zoomLevel == m_currentZoomLevel && + if (renderData.m_tileKey.m_zoomLevel == GetCurrentZoom() && CheckTileGenerations(renderData.m_tileKey)) { PrepareBucket(renderData.m_state, renderData.m_bucket); @@ -483,11 +483,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m_selectObjectMessage = make_unique_dp( msg->GetSelectedObject(), msg->GetPosition(), msg->GetFeatureID(), msg->IsAnim(), msg->IsGeometrySelectionAllowed(), true /* isSelectionShapeVisible */); - break; } - ProcessSelection(msg); - AddUserEvent(make_unique_dp(m_userEventStream.GetVisibleViewport())); - + else + { + ProcessSelection(msg); + AddUserEvent(make_unique_dp(m_userEventStream.GetVisibleViewport())); + } break; } @@ -611,11 +612,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m_pendingFollowRoute = std::make_unique( msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(), msg->EnableAutoZoom(), msg->IsArrowGlued()); - break; } - - FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(), - msg->EnableAutoZoom(), msg->IsArrowGlued()); + else + { + FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(), + msg->EnableAutoZoom(), msg->IsArrowGlued()); + } break; } @@ -833,7 +835,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m2::PointD const pt = msg->HasPosition()? msg->GetPosition() : m_userEventStream.GetCurrentScreen().GlobalRect().Center(); int zoom = kDoNotChangeZoom; - if (m_currentZoomLevel < scales::GetAddNewPlaceScale()) + if (GetCurrentZoom() < scales::GetAddNewPlaceScale()) zoom = scales::GetAddNewPlaceScale(); AddUserEvent(make_unique_dp(pt, zoom, true /* isAnim */, false /* trackVisibleViewport */, nullptr /* parallelAnimCreator */)); @@ -1071,13 +1073,10 @@ void FrontendRenderer::UpdateContextDependentResources() m_trafficRenderer->ClearContextDependentResources(); - // In some cases UpdateContextDependentResources can be called before the rendering of - // the first frame. m_currentZoomLevel will be equal to -1, so ResolveTileKeys - // could not be called. - if (m_currentZoomLevel > 0) + if (IsValidCurrentZoom()) { // Request new tiles. - ScreenBase screen = m_userEventStream.GetCurrentScreen(); + ScreenBase const & screen = m_userEventStream.GetCurrentScreen(); m_lastReadedModelView = screen; m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), m_forceUpdateScene, m_forceUpdateUserMarks, @@ -1115,16 +1114,16 @@ bool FrontendRenderer::CheckRouteRecaching(ref_ptr subrouteDat void FrontendRenderer::InvalidateRect(m2::RectD const & gRect) { - ScreenBase screen = m_userEventStream.GetCurrentScreen(); + ScreenBase const screen = m_userEventStream.GetCurrentScreen(); m2::RectD rect = gRect; if (rect.Intersect(screen.ClipRect())) { // Find tiles to invalidate. TTilesCollection tiles; - int const dataZoomLevel = ClipTileZoomByMaxDataZoom(m_currentZoomLevel); + int const dataZoomLevel = ClipTileZoomByMaxDataZoom(GetCurrentZoom()); CalcTilesCoverage(rect, dataZoomLevel, [this, &rect, &tiles](int tileX, int tileY) { - TileKey const key(tileX, tileY, m_currentZoomLevel); + TileKey const key(tileX, tileY, GetCurrentZoom()); if (rect.IsIntersect(key.GetGlobalRect())) tiles.insert(key); }); @@ -1309,7 +1308,7 @@ void FrontendRenderer::PullToBoundArea(bool randomPlace, bool applyZoom) m2::PointD const dest = randomPlace ? m2::GetRandomPointInsideTriangles(m_dragBoundArea) : m2::ProjectPointToTriangles(center, m_dragBoundArea); int zoom = kDoNotChangeZoom; - if (applyZoom && m_currentZoomLevel < scales::GetAddNewPlaceScale()) + if (applyZoom && GetCurrentZoom() < scales::GetAddNewPlaceScale()) zoom = scales::GetAddNewPlaceScale(); AddUserEvent(make_unique_dp(dest, zoom, true /* isAnim */, false /* trackVisibleViewport */, nullptr /* parallelAnimCreator */)); @@ -1352,7 +1351,7 @@ void FrontendRenderer::ProcessSelection(ref_ptr msg) if (!m_myPositionController->IsModeChangeViewport()) { - if (auto const startPosition = m_selectionShape->GetPixelPosition(modelView, m_currentZoomLevel)) + if (auto const startPosition = m_selectionShape->GetPixelPosition(modelView, GetCurrentZoom())) m_selectionTrackInfo = SelectionTrackInfo(modelView.GlobalRect(), *startPosition); } @@ -1369,7 +1368,7 @@ void FrontendRenderer::ProcessSelection(ref_ptr msg) void FrontendRenderer::BeginUpdateOverlayTree(ScreenBase const & modelView) { if (m_overlayTree->Frame()) - m_overlayTree->StartOverlayPlacing(modelView, m_currentZoomLevel); + m_overlayTree->StartOverlayPlacing(modelView, GetCurrentZoom()); } void FrontendRenderer::UpdateOverlayTree(ScreenBase const & modelView, drape_ptr & renderGroup) @@ -1387,7 +1386,7 @@ void FrontendRenderer::EndUpdateOverlayTree() m_overlayTree->EndOverlayPlacing(); // Track overlays. - if (m_overlaysTracker->StartTracking(m_currentZoomLevel, + if (m_overlaysTracker->StartTracking(GetCurrentZoom(), m_myPositionController->IsModeHasPosition(), m_myPositionController->GetDrawablePosition(), m_myPositionController->GetHorizontalAccuracy())) @@ -1449,7 +1448,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram m_context->Clear(dp::ClearBits::DepthBit, dp::kClearBitsStoreAll); - if (m_selectionShape != nullptr) + if (m_selectionShape && IsValidCurrentZoom()) { SelectionShape::ESelectedObject selectedObject = m_selectionShape->GetSelectedObject(); if (selectedObject == SelectionShape::OBJECT_MY_POSITION) @@ -1457,12 +1456,12 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram ASSERT(m_myPositionController->IsModeHasPosition(), ()); m_selectionShape->SetPosition(m_myPositionController->Position()); m_selectionShape->Render(m_context, make_ref(m_gpuProgramManager), modelView, - m_currentZoomLevel, m_frameValues); + GetCurrentZoom(), m_frameValues); } else if (selectedObject == SelectionShape::OBJECT_POI) { m_selectionShape->Render(m_context, make_ref(m_gpuProgramManager), modelView, - m_currentZoomLevel, m_frameValues); + GetCurrentZoom(), m_frameValues); } } @@ -1471,15 +1470,18 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram RenderOverlayLayer(modelView); } - m_gpsTrackRenderer->RenderTrack(m_context, make_ref(m_gpuProgramManager), modelView, m_currentZoomLevel, - m_frameValues); - - if (m_selectionShape != nullptr && - (m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK || - m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_TRACK)) + if (IsValidCurrentZoom()) { - m_selectionShape->Render(m_context, make_ref(m_gpuProgramManager), modelView, m_currentZoomLevel, - m_frameValues); + m_gpsTrackRenderer->RenderTrack(m_context, make_ref(m_gpuProgramManager), modelView, GetCurrentZoom(), + m_frameValues); + + if (m_selectionShape && + (m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK || + m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_TRACK)) + { + m_selectionShape->Render(m_context, make_ref(m_gpuProgramManager), modelView, GetCurrentZoom(), + m_frameValues); + } } if (HasTransitRouteData()) @@ -1505,10 +1507,10 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram if (!m_postprocessRenderer->EndFrame(m_context, make_ref(m_gpuProgramManager), m_viewport)) return; - m_myPositionController->Render(m_context, make_ref(m_gpuProgramManager), modelView, m_currentZoomLevel, - m_frameValues); + if (IsValidCurrentZoom()) + m_myPositionController->Render(m_context, make_ref(m_gpuProgramManager), modelView, GetCurrentZoom(), m_frameValues); - if (m_guiRenderer != nullptr && !m_screenshotMode) + if (m_guiRenderer && !m_screenshotMode) { m_guiRenderer->Render(m_context, make_ref(m_gpuProgramManager), m_myPositionController->IsInRouting(), modelView); @@ -1615,7 +1617,7 @@ bool FrontendRenderer::HasRouteData() const void FrontendRenderer::RenderTransitSchemeLayer(ScreenBase const & modelView) { CHECK(m_context != nullptr, ()); - if (m_transitSchemeEnabled && m_transitSchemeRenderer->IsSchemeVisible(m_currentZoomLevel)) + if (m_transitSchemeEnabled && m_transitSchemeRenderer->IsSchemeVisible(GetCurrentZoom())) { DEBUG_LABEL(m_context, "Transit Scheme"); m_context->Clear(dp::ClearBits::DepthBit, dp::kClearBitsStoreAll); @@ -1634,7 +1636,7 @@ void FrontendRenderer::RenderTrafficLayer(ScreenBase const & modelView) DEBUG_LABEL(m_context, "Traffic Layer"); m_context->Clear(dp::ClearBits::DepthBit, dp::kClearBitsStoreAll); m_trafficRenderer->RenderTraffic(m_context, make_ref(m_gpuProgramManager), modelView, - m_currentZoomLevel, 1.0f /* opacity */, m_frameValues); + GetCurrentZoom(), 1.0f /* opacity */, m_frameValues); } } @@ -1855,19 +1857,21 @@ void FrontendRenderer::RenderFrame() void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) { - static std::array layers = {DepthLayer::OverlayLayer, - DepthLayer::NavigationLayer, - DepthLayer::RoutingBottomMarkLayer, - DepthLayer::RoutingMarkLayer}; + if (!IsValidCurrentZoom()) + return; + BeginUpdateOverlayTree(modelView); - for (auto const layerId : layers) + for (auto const layerId : {DepthLayer::OverlayLayer, + DepthLayer::NavigationLayer, + DepthLayer::RoutingBottomMarkLayer, + DepthLayer::RoutingMarkLayer}) { RenderLayer & overlay = m_layers[static_cast(layerId)]; overlay.Sort(make_ref(m_overlayTree)); - for (drape_ptr & group : overlay.m_renderGroups) + for (auto & group : overlay.m_renderGroups) UpdateOverlayTree(modelView, group); } - if (m_transitSchemeRenderer->IsSchemeVisible(m_currentZoomLevel) && !HasTransitRouteData()) + if (m_transitSchemeRenderer->IsSchemeVisible(GetCurrentZoom()) && !HasTransitRouteData()) m_transitSchemeRenderer->CollectOverlays(make_ref(m_overlayTree), modelView); EndUpdateOverlayTree(); } @@ -1949,7 +1953,7 @@ void FrontendRenderer::DisablePerspective() void FrontendRenderer::CheckIsometryMinScale(ScreenBase const & screen) { - bool const isScaleAllowableIn3d = IsScaleAllowableIn3d(m_currentZoomLevel); + bool const isScaleAllowableIn3d = IsScaleAllowableIn3d(GetCurrentZoom()); bool const isIsometry = m_enable3dBuildings && !m_choosePositionMode && isScaleAllowableIn3d; if (m_isIsometry != isIsometry) { @@ -1974,7 +1978,7 @@ void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen) void FrontendRenderer::UpdateDisplacementEnabled() { if (m_choosePositionMode) - m_overlayTree->SetDisplacementEnabled(m_currentZoomLevel < scales::GetAddNewPlaceScale()); + m_overlayTree->SetDisplacementEnabled(GetCurrentZoom() < scales::GetAddNewPlaceScale()); else m_overlayTree->SetDisplacementEnabled(true); } @@ -2135,8 +2139,8 @@ bool FrontendRenderer::OnNewVisibleViewport(m2::RectD const & oldViewport, m2::R ScreenBase targetScreen; AnimationSystem::Instance().GetTargetScreen(screen, targetScreen); - auto const pos = m_selectionShape->GetPixelPosition(screen, m_currentZoomLevel); - auto const targetPos = m_selectionShape->GetPixelPosition(targetScreen, m_currentZoomLevel); + auto const pos = m_selectionShape->GetPixelPosition(screen, GetCurrentZoom()); + auto const targetPos = m_selectionShape->GetPixelPosition(targetScreen, GetCurrentZoom()); if (!pos || !targetPos) return false; @@ -2217,7 +2221,7 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) double const vs = VisualParams::Instance().GetVisualScale(); double const extension = vs * dp::kScreenPixelRectExtension * screen.GetScale(); rect.Inflate(extension, extension); - int const dataZoomLevel = ClipTileZoomByMaxDataZoom(m_currentZoomLevel); + int const dataZoomLevel = ClipTileZoomByMaxDataZoom(GetCurrentZoom()); m_notFinishedTiles.clear(); @@ -2228,7 +2232,7 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) auto const result = CalcTilesCoverage(rect, dataZoomLevel, [this, &rect, &tiles, &tilesToDelete](int tileX, int tileY) { - TileKey const key(tileX, tileY, m_currentZoomLevel); + TileKey const key(tileX, tileY, GetCurrentZoom()); if (rect.IsIntersect(key.GetGlobalRect())) { tiles.insert(key); @@ -2244,7 +2248,7 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) auto removePredicate = [this, &result, &tilesToDelete](drape_ptr const & group) { TileKey const & key = group->GetTileKey(); - return key.m_zoomLevel == m_currentZoomLevel && + return key.m_zoomLevel == GetCurrentZoom() && (key.m_x < result.m_minTileX || key.m_x >= result.m_maxTileX || key.m_y < result.m_minTileY || key.m_y >= result.m_maxTileY || base::IsExist(tilesToDelete, key)); @@ -2254,10 +2258,10 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) RemoveRenderGroupsLater([this](drape_ptr const & group) { - return group->GetTileKey().m_zoomLevel != m_currentZoomLevel; + return group->GetTileKey().m_zoomLevel != GetCurrentZoom(); }); - m_trafficRenderer->OnUpdateViewport(result, m_currentZoomLevel, tilesToDelete); + m_trafficRenderer->OnUpdateViewport(result, GetCurrentZoom(), tilesToDelete); #if defined(DRAPE_MEASURER_BENCHMARK) && defined(GENERATING_STATISTIC) DrapeMeasurer::Instance().StartScenePreparing(); @@ -2560,7 +2564,7 @@ void FrontendRenderer::UpdateScene(ScreenBase const & modelView) uint32_t const kMaxGenerationRange = 5; TileKey const & key = group->GetTileKey(); - return (group->IsOverlay() && key.m_zoomLevel > m_currentZoomLevel) || + return (group->IsOverlay() && key.m_zoomLevel > GetCurrentZoom()) || (m_maxGeneration - key.m_generation > kMaxGenerationRange) || (group->IsUserMark() && (m_maxUserMarksGeneration - key.m_userMarksGeneration > kMaxGenerationRange)); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 20f2ce8d55..d8e08cb4ea 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -341,6 +341,22 @@ private: ScreenBase m_lastReadedModelView; TTilesCollection m_notFinishedTiles; + bool IsValidCurrentZoom() const + { + /// @todo Well, this function was introduced to ASSERT m_currentZoomLevel != -1. + /// Can't say for sure is it right or wrong, but also can't garantee with post-messages order. + + // In some cases RenderScene, UpdateContextDependentResources can be called before the rendering of + // the first frame. m_currentZoomLevel will be equal to -1, before ResolveZoomLevel call. + return m_currentZoomLevel >= 0; + } + + int GetCurrentZoom() const + { + ASSERT(IsValidCurrentZoom(), ()); + return m_currentZoomLevel; + } + int m_currentZoomLevel = -1; ref_ptr m_requestedTiles;