#include "drape_frontend/drape_engine.hpp" #include "drape_frontend/message_subclasses.hpp" #include "drape_frontend/gui/drape_gui.hpp" #include "drape_frontend/my_position_controller.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/drape_routine.hpp" #include "drape/glyph_generator.hpp" #include "drape/support_manager.hpp" #include "platform/settings.hpp" using namespace std::placeholders; namespace df { DrapeEngine::DrapeEngine(Params && params) : m_myPositionModeChanged(std::move(params.m_myPositionModeChanged)) , m_viewport(std::move(params.m_viewport)) { dp::DrapeRoutine::Init(); VisualParams::Init(params.m_vs, df::CalculateTileSize(m_viewport.GetWidth(), m_viewport.GetHeight())); df::VisualParams::Instance().SetFontScale(params.m_fontsScaleFactor); gui::DrapeGui::Instance().SetSurfaceSize(m2::PointF(m_viewport.GetWidth(), m_viewport.GetHeight())); m_glyphGenerator = make_unique_dp(df::VisualParams::Instance().GetGlyphSdfScale()); m_textureManager = make_unique_dp(make_ref(m_glyphGenerator)); m_threadCommutator = make_unique_dp(); m_requestedTiles = make_unique_dp(); location::EMyPositionMode mode = params.m_initialMyPositionMode.first; if (!params.m_initialMyPositionMode.second && !settings::Get(settings::kLocationStateMode, mode)) { mode = location::PendingPosition; } else if (mode == location::FollowAndRotate) { // If the screen rect setting in follow and rotate mode is missing or invalid, it could cause // invalid animations, so the follow and rotate mode should be discarded. m2::AnyRectD rect; if (!(settings::Get("ScreenClipRect", rect) && df::GetWorldRect().IsRectInside(rect.GetGlobalRect()))) mode = location::Follow; } double timeInBackground = 0.0; double lastEnterBackground = 0.0; if (settings::Get("LastEnterBackground", lastEnterBackground)) timeInBackground = base::Timer::LocalTime() - lastEnterBackground; std::vector effects; bool enabledAntialiasing; if (!settings::Get(dp::kSupportedAntialiasing, enabledAntialiasing)) enabledAntialiasing = false; // Turn off AA for a while by energy-saving issues. //if (enabledAntialiasing) //{ // LOG(LINFO, ("Antialiasing is enabled")); // effects.push_back(PostprocessRenderer::Antialiasing); //} MyPositionController::Params mpParams(mode, timeInBackground, params.m_hints, params.m_isRoutingActive, params.m_isAutozoomEnabled, std::bind(&DrapeEngine::MyPositionModeChanged, this, _1, _2)); FrontendRenderer::Params frParams(params.m_apiVersion, make_ref(m_threadCommutator), params.m_factory, make_ref(m_textureManager), std::move(mpParams), m_viewport, std::bind(&DrapeEngine::ModelViewChanged, this, _1), std::bind(&DrapeEngine::TapEvent, this, _1), std::bind(&DrapeEngine::UserPositionChanged, this, _1, _2), make_ref(m_requestedTiles), std::move(params.m_overlaysShowStatsCallback), params.m_allow3dBuildings, params.m_trafficEnabled, params.m_blockTapEvents, std::move(effects), params.m_onGraphicsContextInitialized); m_frontend = make_unique_dp(std::move(frParams)); BackendRenderer::Params brParams(params.m_apiVersion, frParams.m_commutator, frParams.m_oglContextFactory, frParams.m_texMng, params.m_model, params.m_model.UpdateCurrentCountryFn(), make_ref(m_requestedTiles), params.m_allow3dBuildings, params.m_trafficEnabled, params.m_simplifiedTrafficColors, std::move(params.m_isUGCFn), params.m_onGraphicsContextInitialized); m_backend = make_unique_dp(std::move(brParams)); m_widgetsInfo = std::move(params.m_info); RecacheGui(false); RecacheMapShapes(); if (params.m_showChoosePositionMark) EnableChoosePositionMode(true, std::move(params.m_boundAreaTriangles), false, m2::PointD()); ResizeImpl(m_viewport.GetWidth(), m_viewport.GetHeight()); } DrapeEngine::~DrapeEngine() { dp::DrapeRoutine::Shutdown(); // Call Teardown explicitly! We must wait for threads completion. m_frontend->Teardown(); m_backend->Teardown(); // Reset thread commutator, it stores BaseRenderer pointers. m_threadCommutator.reset(); // Reset pointers to FrontendRenderer and BackendRenderer. m_frontend.reset(); m_backend.reset(); gui::DrapeGui::Instance().Destroy(); m_textureManager->Release(); m_glyphGenerator.reset(); } void DrapeEngine::RecoverSurface(int w, int h, bool recreateContextDependentResources) { if (m_choosePositionMode) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); } if (recreateContextDependentResources) { RecacheGui(false); RecacheMapShapes(); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } ResizeImpl(w, h); } void DrapeEngine::Resize(int w, int h) { ASSERT_GREATER(w, 0, ()); ASSERT_GREATER(h, 0, ()); if (m_viewport.GetHeight() != static_cast(h) || m_viewport.GetWidth() != static_cast(w)) ResizeImpl(w, h); } void DrapeEngine::SetVisibleViewport(m2::RectD const & rect) const { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(rect), MessagePriority::Normal); } void DrapeEngine::Invalidate() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::High); } void DrapeEngine::AddTouchEvent(TouchEvent const & event) { AddUserEvent(make_unique_dp(event)); } void DrapeEngine::Scale(double factor, m2::PointD const & pxPoint, bool isAnim) { AddUserEvent(make_unique_dp(factor, pxPoint, isAnim)); } void DrapeEngine::Move(double factorX, double factorY, bool isAnim) { AddUserEvent(make_unique_dp(factorX, factorY, isAnim)); } void DrapeEngine::Rotate(double azimuth, bool isAnim) { AddUserEvent(make_unique_dp(azimuth, isAnim, nullptr /* parallelAnimCreator */)); } void DrapeEngine::SetModelViewCenter(m2::PointD const & centerPt, int zoom, bool isAnim, bool trackVisibleViewport) { PostUserEvent(make_unique_dp(centerPt, zoom, isAnim, trackVisibleViewport, nullptr /* parallelAnimCreator */)); } void DrapeEngine::SetModelViewRect(m2::RectD const & rect, bool applyRotation, int zoom, bool isAnim, bool useVisibleViewport) { PostUserEvent(make_unique_dp(rect, applyRotation, zoom, isAnim, useVisibleViewport, nullptr /* parallelAnimCreator */ )); } void DrapeEngine::SetModelViewAnyRect(m2::AnyRectD const & rect, bool isAnim, bool useVisibleViewport) { PostUserEvent(make_unique_dp(rect, isAnim, true /* fitInViewport */, useVisibleViewport)); } void DrapeEngine::ClearUserMarksGroup(kml::MarkGroupId groupId) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(groupId), MessagePriority::Normal); } void DrapeEngine::ChangeVisibilityUserMarksGroup(kml::MarkGroupId groupId, bool isVisible) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(groupId, isVisible), MessagePriority::Normal); } void DrapeEngine::InvalidateUserMarks() { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::UpdateUserMarks(UserMarksProvider * provider, bool firstTime) { auto const dirtyGroupIds = firstTime ? provider->GetAllGroupIds() : provider->GetDirtyGroupIds(); if (dirtyGroupIds.empty()) return; auto marksRenderCollection = make_unique_dp(); auto linesRenderCollection = make_unique_dp(); auto createdIdCollection = make_unique_dp(); auto removedIdCollection = make_unique_dp(); if (!firstTime) { kml::MarkGroupId lastGroupId = *dirtyGroupIds.begin(); bool visibilityChanged = provider->IsGroupVisibilityChanged(lastGroupId); bool groupIsVisible = provider->IsGroupVisible(lastGroupId); auto const handleMark = [&]( kml::MarkId markId, UserMarksRenderCollection & renderCollection, kml::MarkIdCollection *idCollection) { auto const *mark = provider->GetUserPointMark(markId); if (!mark->IsDirty()) return; auto const groupId = mark->GetGroupId(); if (groupId != lastGroupId) { lastGroupId = groupId; visibilityChanged = provider->IsGroupVisibilityChanged(groupId); groupIsVisible = provider->IsGroupVisible(groupId); } if (!visibilityChanged && groupIsVisible) { if (idCollection) idCollection->push_back(markId); renderCollection.emplace(markId, GenerateMarkRenderInfo(mark)); } }; for (auto markId : provider->GetCreatedMarkIds()) handleMark(markId, *marksRenderCollection, &createdIdCollection->m_markIds); for (auto markId : provider->GetUpdatedMarkIds()) handleMark(markId, *marksRenderCollection, nullptr); auto const & removedMarkIds = provider->GetRemovedMarkIds(); removedIdCollection->m_markIds.reserve(removedMarkIds.size()); removedIdCollection->m_markIds.assign(removedMarkIds.begin(), removedMarkIds.end()); auto const & removedLineIds = provider->GetRemovedLineIds(); removedIdCollection->m_lineIds.reserve(removedLineIds.size()); removedIdCollection->m_lineIds.assign(removedLineIds.begin(), removedLineIds.end()); } std::map> dirtyMarkIds; for (auto groupId : dirtyGroupIds) { auto & idCollection = *(dirtyMarkIds.emplace(groupId, make_unique_dp()).first->second); bool const visibilityChanged = provider->IsGroupVisibilityChanged(groupId); bool const groupIsVisible = provider->IsGroupVisible(groupId); if (!groupIsVisible && !visibilityChanged) continue; auto const & markIds = provider->GetGroupPointIds(groupId); auto const & lineIds = provider->GetGroupLineIds(groupId); if (groupIsVisible) { idCollection.m_markIds.reserve(markIds.size()); idCollection.m_markIds.assign(markIds.begin(), markIds.end()); idCollection.m_lineIds.reserve(lineIds.size()); idCollection.m_lineIds.assign(lineIds.begin(), lineIds.end()); for (auto lineId : lineIds) { auto const * line = provider->GetUserLineMark(lineId); if (visibilityChanged || line->IsDirty()) linesRenderCollection->emplace(lineId, GenerateLineRenderInfo(line)); } if (visibilityChanged || firstTime) { for (auto markId : markIds) { marksRenderCollection->emplace( markId, GenerateMarkRenderInfo(provider->GetUserPointMark(markId))); } } } else if (!firstTime) { auto & points = removedIdCollection->m_markIds; points.reserve(points.size() + markIds.size()); points.insert(points.end(), markIds.begin(), markIds.end()); auto & lines = removedIdCollection->m_lineIds; lines.reserve(lines.size() + lineIds.size()); lines.insert(lines.end(), lineIds.begin(), lineIds.end()); } } if (!marksRenderCollection->empty() || !linesRenderCollection->empty() || !removedIdCollection->IsEmpty() || !createdIdCollection->IsEmpty()) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp( std::move(createdIdCollection), std::move(removedIdCollection), std::move(marksRenderCollection), std::move(linesRenderCollection)), MessagePriority::Normal); } for (auto & v : dirtyMarkIds) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp( v.first, std::move(v.second)), MessagePriority::Normal); } } void DrapeEngine::SetRenderingEnabled(ref_ptr contextFactory) { m_backend->SetRenderingEnabled(contextFactory); m_frontend->SetRenderingEnabled(contextFactory); LOG(LDEBUG, ("Rendering enabled")); } void DrapeEngine::SetRenderingDisabled(bool const destroySurface) { m_frontend->SetRenderingDisabled(destroySurface); m_backend->SetRenderingDisabled(destroySurface); LOG(LDEBUG, ("Rendering disabled")); } void DrapeEngine::InvalidateRect(m2::RectD const & rect) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(rect), MessagePriority::High); } void DrapeEngine::UpdateMapStyle() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::High); } void DrapeEngine::RecacheMapShapes() { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); } dp::DrapeID DrapeEngine::GenerateDrapeID() { std::lock_guard lock(m_drapeIdGeneratorMutex); ++m_drapeIdGenerator; return m_drapeIdGenerator; } void DrapeEngine::RecacheGui(bool needResetOldGui) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(m_widgetsInfo, needResetOldGui), MessagePriority::Normal); } void DrapeEngine::PostUserEvent(drape_ptr && e) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(std::move(e)), MessagePriority::Normal); } void DrapeEngine::AddUserEvent(drape_ptr && e) { m_frontend->AddUserEvent(std::move(e)); } void DrapeEngine::ModelViewChanged(ScreenBase const & screen) { if (m_modelViewChanged != nullptr) m_modelViewChanged(screen); } void DrapeEngine::MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive) { settings::Set(settings::kLocationStateMode, mode); if (m_myPositionModeChanged != nullptr) m_myPositionModeChanged(mode, routingActive); } void DrapeEngine::TapEvent(TapInfo const & tapInfo) { if (m_tapListener != nullptr) m_tapListener(tapInfo); } void DrapeEngine::UserPositionChanged(m2::PointD const & position, bool hasPosition) { if (m_userPositionChanged != nullptr) m_userPositionChanged(position, hasPosition); } void DrapeEngine::ResizeImpl(int w, int h) { gui::DrapeGui::Instance().SetSurfaceSize(m2::PointF(w, h)); m_viewport.SetViewport(0, 0, w, h); PostUserEvent(make_unique_dp(w, h)); } void DrapeEngine::SetCompassInfo(location::CompassInfo const & info) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(info), MessagePriority::Normal); } void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable, const location::RouteMatchingInfo & routeInfo) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(info, isNavigable, routeInfo), MessagePriority::Normal); } void DrapeEngine::SwitchMyPositionNextMode() { using Mode = ChangeMyPositionModeMessage::EChangeType; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(Mode::SwitchNextMode), MessagePriority::Normal); } void DrapeEngine::LoseLocation() { using Mode = ChangeMyPositionModeMessage::EChangeType; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(Mode::LoseLocation), MessagePriority::Normal); } void DrapeEngine::StopLocationFollow() { using Mode = ChangeMyPositionModeMessage::EChangeType; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(Mode::StopFollowing), MessagePriority::Normal); } void DrapeEngine::FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, bool enableAutoZoom) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(preferredZoomLevel, preferredZoomLevel3d, enableAutoZoom), MessagePriority::Normal); } void DrapeEngine::SetModelViewListener(TModelViewListenerFn && fn) { m_modelViewChanged = std::move(fn); } #if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX) void DrapeEngine::NotifyGraphicsReady(TGraphicsReadyFn const & fn) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(fn), MessagePriority::Normal); } #endif void DrapeEngine::SetTapEventInfoListener(TTapEventInfoFn && fn) { m_tapListener = std::move(fn); } void DrapeEngine::SetUserPositionListener(TUserPositionChangedFn && fn) { m_userPositionChanged = std::move(fn); } void DrapeEngine::SelectObject(SelectionShape::ESelectedObject obj, m2::PointD const & pt, FeatureID const & featureId, bool isAnim) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(obj, pt, featureId, isAnim), MessagePriority::Normal); } void DrapeEngine::DeselectObject() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(SelectObjectMessage::DismissTag()), MessagePriority::Normal); } dp::DrapeID DrapeEngine::AddSubroute(SubrouteConstPtr subroute) { dp::DrapeID const id = GenerateDrapeID(); m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(id, subroute), MessagePriority::Normal); return id; } void DrapeEngine::RemoveSubroute(dp::DrapeID subrouteId, bool deactivateFollowing) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(subrouteId, deactivateFollowing), MessagePriority::Normal); } void DrapeEngine::DeactivateRouteFollowing() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::SetSubrouteVisibility(dp::DrapeID subrouteId, bool isVisible) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(subrouteId, isVisible), MessagePriority::Normal); } dp::DrapeID DrapeEngine::AddRoutePreviewSegment(m2::PointD const & startPt, m2::PointD const & finishPt) { dp::DrapeID const id = GenerateDrapeID(); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(id, startPt, finishPt), MessagePriority::Normal); return id; } void DrapeEngine::RemoveRoutePreviewSegment(dp::DrapeID segmentId) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(segmentId), MessagePriority::Normal); } void DrapeEngine::RemoveAllRoutePreviewSegments() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info) { m_widgetsLayout = std::move(info); for (auto const & layout : m_widgetsLayout) { auto const itInfo = m_widgetsInfo.find(layout.first); if (itInfo != m_widgetsInfo.end()) itInfo->second.m_pixelPivot = layout.second; } m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(m_widgetsLayout), MessagePriority::Normal); } void DrapeEngine::AllowAutoZoom(bool allowAutoZoom) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(allowAutoZoom), MessagePriority::Normal); } void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(allow3dBuildings), MessagePriority::Normal); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(allowPerspectiveInNavigation, allow3dBuildings), MessagePriority::Normal); } void DrapeEngine::EnablePerspective() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::UpdateGpsTrackPoints(std::vector && toAdd, std::vector && toRemove) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(std::move(toAdd), std::move(toRemove)), MessagePriority::Normal); } void DrapeEngine::ClearGpsTrackPoints() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::EnableChoosePositionMode(bool enable, std::vector && boundAreaTriangles, bool hasPosition, m2::PointD const & position) { m_choosePositionMode = enable; bool kineticScroll = m_kineticScrollEnabled; if (enable) { StopLocationFollow(); m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); kineticScroll = false; } else { RecacheGui(true); } m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(enable, std::move(boundAreaTriangles), kineticScroll, hasPosition, position), MessagePriority::Normal); } void DrapeEngine::BlockTapEvents(bool block) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(block), MessagePriority::Normal); } void DrapeEngine::SetKineticScrollEnabled(bool enabled) { m_kineticScrollEnabled = enabled; if (m_choosePositionMode) return; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(m_kineticScrollEnabled), MessagePriority::Normal); } void DrapeEngine::SetTimeInBackground(double time) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(time), MessagePriority::High); } void DrapeEngine::SetDisplacementMode(int mode) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(mode), MessagePriority::Normal); } void DrapeEngine::RequestSymbolsSize(std::vector const & symbols, TRequestSymbolsSizeCallback const & callback) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(symbols, callback), MessagePriority::Normal); } void DrapeEngine::EnableTraffic(bool trafficEnabled) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(trafficEnabled), MessagePriority::Normal); } void DrapeEngine::UpdateTraffic(traffic::TrafficInfo const & info) { if (info.GetColoring().empty()) return; #ifdef DEBUG for (auto const & segmentPair : info.GetColoring()) ASSERT_NOT_EQUAL(segmentPair.second, traffic::SpeedGroup::Unknown, ()); #endif df::TrafficSegmentsColoring segmentsColoring; segmentsColoring.emplace(info.GetMwmId(), info.GetColoring()); m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(std::move(segmentsColoring)), MessagePriority::Normal); } void DrapeEngine::ClearTrafficCache(MwmSet::MwmId const & mwmId) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(mwmId), MessagePriority::Normal); } void DrapeEngine::SetSimplifiedTrafficColors(bool simplified) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(simplified), MessagePriority::Normal); } void DrapeEngine::EnableTransitScheme(bool enable) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(enable), MessagePriority::Normal); } void DrapeEngine::ClearTransitSchemeCache(MwmSet::MwmId const & mwmId) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(mwmId), MessagePriority::Normal); } void DrapeEngine::ClearAllTransitSchemeCache() { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::UpdateTransitScheme(TransitDisplayInfos && transitDisplayInfos) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(std::move(transitDisplayInfos)), MessagePriority::Normal); } void DrapeEngine::SetFontScaleFactor(double scaleFactor) { double const kMinScaleFactor = 0.5; double const kMaxScaleFactor = 2.0; scaleFactor = base::clamp(scaleFactor, kMinScaleFactor, kMaxScaleFactor); VisualParams::Instance().SetFontScale(scaleFactor); } void DrapeEngine::RunScenario(ScenarioManager::ScenarioData && scenarioData, ScenarioManager::ScenarioCallback const & onStartFn, ScenarioManager::ScenarioCallback const & onFinishFn) { auto const & manager = m_frontend->GetScenarioManager(); if (manager != nullptr) manager->RunScenario(std::move(scenarioData), onStartFn, onFinishFn); } void DrapeEngine::SetCustomFeatures(df::CustomFeatures && ids) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(std::move(ids)), MessagePriority::Normal); } void DrapeEngine::RemoveCustomFeatures(MwmSet::MwmId const & mwmId) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(mwmId), MessagePriority::Normal); } void DrapeEngine::RemoveAllCustomFeatures() { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::SetPosteffectEnabled(PostprocessRenderer::Effect effect, bool enabled) { if (effect == df::PostprocessRenderer::Antialiasing) { LOG(LINFO, ("Antialiasing is", (enabled ? "enabled" : "disabled"))); settings::Set(dp::kSupportedAntialiasing, enabled); } m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(effect, enabled), MessagePriority::Normal); } void DrapeEngine::EnableUGCRendering(bool enabled) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(enabled), MessagePriority::Normal); } void DrapeEngine::RunFirstLaunchAnimation() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } void DrapeEngine::ShowDebugInfo(bool shown) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(shown), MessagePriority::Normal); } void DrapeEngine::EnableDebugRectRendering(bool enabled) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(enabled), MessagePriority::Normal); } drape_ptr DrapeEngine::GenerateMarkRenderInfo(UserPointMark const * mark) { auto renderInfo = make_unique_dp(); renderInfo->m_anchor = mark->GetAnchor(); renderInfo->m_depthTestEnabled = mark->GetDepthTestEnabled(); renderInfo->m_depth = mark->GetDepth(); renderInfo->m_depthLayer = mark->GetDepthLayer(); renderInfo->m_minZoom = mark->GetMinZoom(); renderInfo->m_minTitleZoom = mark->GetMinTitleZoom(); renderInfo->m_isVisible = mark->IsVisible(); renderInfo->m_pivot = mark->GetPivot(); renderInfo->m_pixelOffset = mark->GetPixelOffset(); renderInfo->m_titleDecl = mark->GetTitleDecl(); renderInfo->m_symbolNames = mark->GetSymbolNames(); renderInfo->m_badgeNames = mark->GetBadgeNames(); renderInfo->m_coloredSymbols = mark->GetColoredSymbols(); renderInfo->m_symbolSizes = mark->GetSymbolSizes(); renderInfo->m_symbolOffsets = mark->GetSymbolOffsets(); renderInfo->m_color = mark->GetColorConstant(); renderInfo->m_symbolIsPOI = mark->SymbolIsPOI(); renderInfo->m_hasTitlePriority = mark->HasTitlePriority(); renderInfo->m_priority = mark->GetPriority(); renderInfo->m_displacement = mark->GetDisplacement(); renderInfo->m_index = mark->GetIndex(); renderInfo->m_featureId = mark->GetFeatureID(); renderInfo->m_hasCreationAnimation = mark->HasCreationAnimation(); renderInfo->m_isMarkAboveText = mark->IsMarkAboveText(); return renderInfo; } drape_ptr DrapeEngine::GenerateLineRenderInfo(UserLineMark const * mark) { auto renderInfo = make_unique_dp(); renderInfo->m_minZoom = mark->GetMinZoom(); renderInfo->m_depthLayer = mark->GetDepthLayer(); renderInfo->m_spline = m2::SharedSpline(mark->GetPoints()); renderInfo->m_layers.reserve(mark->GetLayerCount()); for (size_t layerIndex = 0, layersCount = mark->GetLayerCount(); layerIndex < layersCount; ++layerIndex) { renderInfo->m_layers.emplace_back(mark->GetColor(layerIndex), mark->GetWidth(layerIndex), mark->GetDepth(layerIndex)); } return renderInfo; } void DrapeEngine::UpdateVisualScale(double vs, bool needStopRendering) { if (needStopRendering) SetRenderingDisabled(true /* destroySurface */); VisualParams::Instance().SetVisualScale(vs); if (needStopRendering) SetRenderingEnabled(); RecacheGui(false); RecacheMapShapes(); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), MessagePriority::Normal); } } // namespace df