From 0f11b6d6302f9c4b928e982c2f838f25f676b1c8 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Thu, 18 Aug 2016 15:34:39 +0300 Subject: [PATCH 1/4] Soft processing of android context destruction. --- android/jni/com/mapswithme/maps/Framework.cpp | 82 +++++++------------ android/jni/com/mapswithme/maps/Framework.hpp | 16 +--- .../jni/com/mapswithme/maps/MapFragment.cpp | 10 +-- .../jni/com/mapswithme/maps/SearchEngine.cpp | 11 +-- .../maps/bookmarks/data/BookmarkManager.cpp | 5 +- .../src/com/mapswithme/maps/MapFragment.java | 30 +++---- .../src/com/mapswithme/maps/MwmActivity.java | 4 +- drape_frontend/backend_renderer.cpp | 29 +++++-- drape_frontend/backend_renderer.hpp | 3 + drape_frontend/base_renderer.cpp | 77 ++++++++++------- drape_frontend/base_renderer.hpp | 11 ++- drape_frontend/drape_engine.cpp | 34 +++++++- drape_frontend/drape_engine.hpp | 5 +- drape_frontend/frontend_renderer.cpp | 79 +++++++++++++++--- drape_frontend/frontend_renderer.hpp | 4 + drape_frontend/gps_track_renderer.cpp | 6 ++ drape_frontend/gps_track_renderer.hpp | 1 + drape_frontend/my_position_controller.cpp | 5 ++ drape_frontend/my_position_controller.hpp | 1 + drape_frontend/route_renderer.cpp | 27 +++++- drape_frontend/route_renderer.hpp | 3 + drape_frontend/user_event_stream.cpp | 5 +- map/framework.cpp | 26 ++++-- map/framework.hpp | 6 +- 24 files changed, 316 insertions(+), 164 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 4e11713605..cf0ff3c133 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -63,6 +63,7 @@ enum MultiTouchAction Framework::Framework() : m_lastCompass(0.0) + , m_isContextDestroyed(false) , m_currentMode(location::PendingPosition) , m_isCurrentModeInitialized(false) , m_isChoosePositionMode(false) @@ -143,23 +144,9 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi m_work.CreateDrapeEngine(make_ref(m_contextFactory), move(p)); m_work.EnterForeground(); - // Execute drape tasks which set up custom state. - { - lock_guard lock(m_drapeQueueMutex); - if (!m_drapeTasksQueue.empty()) - ExecuteDrapeTasks(); - } - return true; } -void Framework::DeleteDrapeEngine() -{ - m_work.EnterBackground(); - - m_work.DestroyDrapeEngine(); -} - bool Framework::IsDrapeEngineCreated() { return m_work.IsDrapeEngineCreated(); @@ -171,9 +158,16 @@ void Framework::Resize(int w, int h) m_work.OnSize(w, h); } -void Framework::DetachSurface() +void Framework::DetachSurface(bool destroyContext) { - m_work.SetRenderingEnabled(false); + LOG(LWARNING, ("Detach surface")); + if (destroyContext) + { + LOG(LWARNING, ("Destroy context")); + m_isContextDestroyed = true; + m_work.EnterBackground(); + } + m_work.SetRenderingDisabled(destroyContext); ASSERT(m_contextFactory != nullptr, ()); AndroidOGLContextFactory * factory = m_contextFactory->CastFactory(); @@ -182,11 +176,24 @@ void Framework::DetachSurface() void Framework::AttachSurface(JNIEnv * env, jobject jSurface) { + LOG(LWARNING, ("Attach surface")); + ASSERT(m_contextFactory != nullptr, ()); AndroidOGLContextFactory * factory = m_contextFactory->CastFactory(); factory->SetSurface(env, jSurface); - m_work.SetRenderingEnabled(true); + ASSERT(!m_guiPositions.empty(), ("GUI elements must be set-up before engine is created")); + + m_work.SetRenderingEnabled(factory); + + if (m_isContextDestroyed) + { + LOG(LWARNING, ("Recover resources, size:", factory->GetWidth(), factory->GetHeight())); + m_work.UpdateDrapeEngine(factory->GetWidth(), factory->GetHeight()); + m_isContextDestroyed = false; + + m_work.EnterForeground(); + } } void Framework::SetMapStyle(MapStyle mapStyle) @@ -196,6 +203,7 @@ void Framework::SetMapStyle(MapStyle mapStyle) void Framework::MarkMapStyle(MapStyle mapStyle) { + LOG(LWARNING, ("MarkMapStyle")); m_work.MarkMapStyle(mapStyle); } @@ -437,23 +445,6 @@ void Framework::SetupMeasurementSystem() m_work.SetupMeasurementSystem(); } -void Framework::PostDrapeTask(TDrapeTask && task) -{ - ASSERT(task != nullptr, ()); - lock_guard lock(m_drapeQueueMutex); - if (IsDrapeEngineCreated()) - task(); - else - m_drapeTasksQueue.push_back(move(task)); -} - -void Framework::ExecuteDrapeTasks() -{ - for (auto & task : m_drapeTasksQueue) - task(); - m_drapeTasksQueue.clear(); -} - void Framework::SetPlacePageInfo(place_page::Info const & info) { m_info = info; @@ -803,20 +794,15 @@ Java_com_mapswithme_maps_Framework_nativeBuildRoute(JNIEnv * env, jclass, jdouble startLat, jdouble startLon, jdouble finishLat, jdouble finishLon) { - g_framework->PostDrapeTask([startLat, startLon, finishLat, finishLon]() - { - frm()->BuildRoute(MercatorBounds::FromLatLon(startLat, startLon), - MercatorBounds::FromLatLon(finishLat, finishLon), 0 /* timeoutSec */); - }); + frm()->BuildRoute(MercatorBounds::FromLatLon(startLat, startLon), + MercatorBounds::FromLatLon(finishLat, finishLon), 0 /* timeoutSec */); + } JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeFollowRoute(JNIEnv * env, jclass) { - g_framework->PostDrapeTask([]() - { - frm()->FollowRoute(); - }); + frm()->FollowRoute(); } JNIEXPORT void JNICALL @@ -1013,10 +999,7 @@ Java_com_mapswithme_maps_Framework_nativeSet3dMode(JNIEnv * env, jclass, jboolea bool const allow3dBuildings = static_cast(allowBuildings); g_framework->Save3dMode(allow3d, allow3dBuildings); - g_framework->PostDrapeTask([allow3d, allow3dBuildings]() - { - g_framework->Set3dMode(allow3d, allow3dBuildings); - }); + g_framework->Set3dMode(allow3d, allow3dBuildings); } JNIEXPORT void JNICALL @@ -1040,10 +1023,7 @@ Java_com_mapswithme_maps_Framework_nativeSetAutoZoomEnabled(JNIEnv * env, jclass { bool const autoZoomEnabled = static_cast(enabled); frm()->SaveAutoZoom(autoZoomEnabled); - g_framework->PostDrapeTask([autoZoomEnabled]() - { - frm()->AllowAutoZoom(autoZoomEnabled); - }); + frm()->AllowAutoZoom(autoZoomEnabled); } JNIEXPORT jboolean JNICALL diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index a9b719a4f4..332606de49 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -45,6 +45,8 @@ namespace android string m_searchQuery; + bool m_isContextDestroyed; + map m_guiPositions; void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive); @@ -73,10 +75,9 @@ namespace android void Invalidate(); bool CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi, bool firstLaunch); - void DeleteDrapeEngine(); bool IsDrapeEngineCreated(); - void DetachSurface(); + void DetachSurface(bool destroyContext); void AttachSurface(JNIEnv * env, jobject jSurface); void SetMapStyle(MapStyle mapStyle); @@ -151,10 +152,6 @@ namespace android void ApplyWidgets(); void CleanWidgets(); - using TDrapeTask = function; - // Posts a task which must be executed when Drape Engine is alive. - void PostDrapeTask(TDrapeTask && task); - void SetPlacePageInfo(place_page::Info const & info); place_page::Info & GetPlacePageInfo(); void RequestBookingMinPrice(string const & hotelId, string const & currency, function const & callback); @@ -167,13 +164,6 @@ namespace android bool IsAutoRetryDownloadFailed(); bool IsDownloadOn3gEnabled(); void EnableDownloadOn3g(); - - private: - vector m_drapeTasksQueue; - mutex m_drapeQueueMutex; - - // This method must be executed under mutex m_drapeQueueMutex. - void ExecuteDrapeTasks(); }; } diff --git a/android/jni/com/mapswithme/maps/MapFragment.cpp b/android/jni/com/mapswithme/maps/MapFragment.cpp index 54c057c639..9b32591850 100644 --- a/android/jni/com/mapswithme/maps/MapFragment.cpp +++ b/android/jni/com/mapswithme/maps/MapFragment.cpp @@ -69,12 +69,6 @@ Java_com_mapswithme_maps_MapFragment_nativeCreateEngine(JNIEnv * env, jclass cla return g_framework->CreateDrapeEngine(env, surface, density, firstLaunch); } -JNIEXPORT void JNICALL -Java_com_mapswithme_maps_MapFragment_nativeDestroyEngine(JNIEnv * env, jclass clazz) -{ - g_framework->DeleteDrapeEngine(); -} - JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_MapFragment_nativeIsEngineCreated(JNIEnv * env, jclass clazz) { @@ -88,9 +82,9 @@ Java_com_mapswithme_maps_MapFragment_nativeAttachSurface(JNIEnv * env, jclass cl } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_MapFragment_nativeDetachSurface(JNIEnv * env, jclass clazz) +Java_com_mapswithme_maps_MapFragment_nativeDetachSurface(JNIEnv * env, jclass clazz, jboolean destroyContext) { - g_framework->DetachSurface(); + g_framework->DetachSurface(destroyContext); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index 0c04e4e2bb..63d6384a0b 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -240,21 +240,14 @@ extern "C" { lock_guard guard(g_resultsMutex); Result const & result = g_results.GetResult(index); - g_framework->PostDrapeTask([result]() - { - g_framework->NativeFramework()->ShowSearchResult(result); - }); + g_framework->NativeFramework()->ShowSearchResult(result); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_search_SearchEngine_nativeShowAllResults(JNIEnv * env, jclass clazz) { lock_guard guard(g_resultsMutex); - auto const & results = g_results; - g_framework->PostDrapeTask([results]() - { - g_framework->NativeFramework()->ShowSearchResults(results); - }); + g_framework->NativeFramework()->ShowSearchResults(g_results); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp index ec87921647..a31f86cae2 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp @@ -37,10 +37,7 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeShowBookmarkOnMap( JNIEnv * env, jobject thiz, jint c, jint b) { BookmarkAndCategory bnc = BookmarkAndCategory(c,b); - g_framework->PostDrapeTask([bnc]() - { - frm()->ShowBookmark(bnc); - }); + frm()->ShowBookmark(bnc); } JNIEXPORT void JNICALL diff --git a/android/src/com/mapswithme/maps/MapFragment.java b/android/src/com/mapswithme/maps/MapFragment.java index 2e55d28230..3a7ae66df7 100644 --- a/android/src/com/mapswithme/maps/MapFragment.java +++ b/android/src/com/mapswithme/maps/MapFragment.java @@ -52,7 +52,7 @@ public class MapFragment extends BaseMwmFragment private int mHeight; private int mWidth; private boolean mRequireResize; - private boolean mEngineCreated; + private boolean mContextCreated; private boolean mFirstStart; private static boolean sWasCopyrightDisplayed; @@ -98,7 +98,7 @@ public class MapFragment extends BaseMwmFragment UiUtils.dimen(R.dimen.margin_compass_left) + offsetX, mHeight - UiUtils.dimen(R.dimen.margin_compass_bottom) + offsetY, ANCHOR_CENTER); - if (forceRedraw && mEngineCreated) + if (forceRedraw && mContextCreated) nativeApplyWidgets(); } @@ -108,7 +108,7 @@ public class MapFragment extends BaseMwmFragment mWidth - UiUtils.dimen(R.dimen.margin_ruler_right) + offsetX, mHeight - UiUtils.dimen(R.dimen.margin_ruler_bottom) + offsetY, ANCHOR_RIGHT_BOTTOM); - if (forceRedraw && mEngineCreated) + if (forceRedraw && mContextCreated) nativeApplyWidgets(); } @@ -141,6 +141,7 @@ public class MapFragment extends BaseMwmFragment if (nativeIsEngineCreated()) { nativeAttachSurface(surface); + mContextCreated = true; mRequireResize = true; return; } @@ -154,20 +155,20 @@ public class MapFragment extends BaseMwmFragment final float exactDensityDpi = metrics.densityDpi; mFirstStart = ((MwmActivity) getMwmActivity()).isFirstStart(); - mEngineCreated = nativeCreateEngine(surface, (int) exactDensityDpi, mFirstStart); - if (!mEngineCreated) + if (!nativeCreateEngine(surface, (int) exactDensityDpi, mFirstStart)) { reportUnsupported(); return; } + mContextCreated = true; onRenderingInitialized(); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { - if (!mEngineCreated || + if (!mContextCreated || (!mRequireResize && surfaceHolder.isCreating())) return; @@ -181,22 +182,22 @@ public class MapFragment extends BaseMwmFragment @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { - if (!mEngineCreated) + if (!mContextCreated) return; if (getActivity() == null || !getActivity().isChangingConfigurations()) - destroyEngine(); + destroyContext(); else - nativeDetachSurface(); + nativeDetachSurface(false); } - void destroyEngine() + void destroyContext() { - if (!mEngineCreated) + if (!mContextCreated) return; - nativeDestroyEngine(); - mEngineCreated = false; + nativeDetachSurface(true); + mContextCreated = false; } @Override @@ -281,9 +282,8 @@ public class MapFragment extends BaseMwmFragment static native boolean nativeShowMapForUrl(String url); static native boolean nativeIsEngineCreated(); private static native boolean nativeCreateEngine(Surface surface, int density, boolean firstLaunch); - private static native void nativeDestroyEngine(); private static native void nativeAttachSurface(Surface surface); - private static native void nativeDetachSurface(); + private static native void nativeDetachSurface(boolean destroyContext); private static native void nativeSurfaceChanged(int w, int h); private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, int maskedPointer); private static native void nativeSetupWidget(int widget, float x, float y, int anchor); diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 19cdd0c125..84489a0994 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -751,8 +751,8 @@ public class MwmActivity extends BaseMwmFragmentActivity @Override public void recreate() { - // Explicitly destroy engine before activity recreation. - mMapFragment.destroyEngine(); + // Explicitly destroy context before activity recreation. + mMapFragment.destroyContext(); super.recreate(); } diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index d7a7af41f5..b959923619 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -319,16 +319,33 @@ void BackendRenderer::ReleaseResources() m_contextFactory->getResourcesUploadContext()->doneCurrent(); } +void BackendRenderer::OnContextCreate() +{ + LOG(LWARNING, ("On context create.")); + m_contextFactory->waitForInitialization(); + m_contextFactory->getResourcesUploadContext()->makeCurrent(); + + GLFunctions::Init(); + + InitGLDependentResource(); +} + +void BackendRenderer::OnContextDestroy() +{ + LOG(LWARNING, ("On context destroy.")); + m_readManager->InvalidateAll(); + m_batchersPool.reset(); + m_texMng->Release(); + + m_contextFactory->getResourcesUploadContext()->doneCurrent(); +} + BackendRenderer::Routine::Routine(BackendRenderer & renderer) : m_renderer(renderer) {} void BackendRenderer::Routine::Do() { - m_renderer.m_contextFactory->waitForInitialization(); - - m_renderer.m_contextFactory->getResourcesUploadContext()->makeCurrent(); - GLFunctions::Init(); - - m_renderer.InitGLDependentResource(); + LOG(LWARNING, ("Start routine.")); + m_renderer.OnContextCreate(); while (!IsCancelled()) { diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index 8222f674a7..ca34b14e4a 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -58,6 +58,9 @@ public: protected: unique_ptr CreateRoutine() override; + void OnContextCreate() override; + void OnContextDestroy() override; + private: void RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool needResetOldGui); void RecacheChoosePositionMark(); diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index 8cc083b2ca..725c43b7a5 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -39,23 +39,18 @@ void BaseRenderer::StopThread() m_selfThread.Join(); } -void BaseRenderer::SetRenderingEnabled(bool const isEnabled) +void BaseRenderer::SetRenderingEnabled(ref_ptr contextFactory) { - // here we have to wait for completion of internal SetRenderingEnabled - mutex completionMutex; - condition_variable completionCondition; - bool notified = false; - auto completionHandler = [&]() - { - lock_guard lock(completionMutex); - notified = true; - completionCondition.notify_one(); - }; + if (m_wasContextReset) + m_contextFactory = contextFactory; + SetRenderingEnabled(true); +} - SetRenderingEnabled(isEnabled, completionHandler); - - unique_lock lock(completionMutex); - completionCondition.wait(lock, [¬ified] { return notified; }); +void BaseRenderer::SetRenderingDisabled(bool const destroyContext) +{ + if (destroyContext) + m_wasContextReset = true; + SetRenderingEnabled(false); } bool BaseRenderer::IsRenderingEnabled() const @@ -63,17 +58,22 @@ bool BaseRenderer::IsRenderingEnabled() const return m_isEnabled; } -void BaseRenderer::SetRenderingEnabled(bool const isEnabled, TCompletionHandler completionHandler) +void BaseRenderer::SetRenderingEnabled(bool const isEnabled) { if (isEnabled == m_isEnabled) - { - if (completionHandler != nullptr) - completionHandler(); - return; - } - m_renderingEnablingCompletionHandler = move(completionHandler); + // here we have to wait for completion of internal SetRenderingEnabled + mutex completionMutex; + condition_variable completionCondition; + bool notified = false; + m_renderingEnablingCompletionHandler = [&]() + { + lock_guard lock(completionMutex); + notified = true; + completionCondition.notify_one(); + }; + if (isEnabled) { // wake up rendering thread @@ -87,19 +87,30 @@ void BaseRenderer::SetRenderingEnabled(bool const isEnabled, TCompletionHandler // if renderer thread is waiting for message let it go CancelMessageWaiting(); } + + unique_lock lock(completionMutex); + completionCondition.wait(lock, [¬ified] { return notified; }); } void BaseRenderer::CheckRenderingEnabled() { if (!m_isEnabled) { - bool const isDrawContext = m_threadName == ThreadsCommutator::RenderThread; - dp::OGLContext * context = isDrawContext ? m_contextFactory->getDrawContext() : - m_contextFactory->getResourcesUploadContext(); + dp::OGLContext * context = nullptr; - context->setRenderingEnabled(false); + if (m_wasContextReset) + { + OnContextDestroy(); + } + else + { + bool const isDrawContext = m_threadName == ThreadsCommutator::RenderThread; + context = isDrawContext ? m_contextFactory->getDrawContext() : + m_contextFactory->getResourcesUploadContext(); + context->setRenderingEnabled(false); + } - // nofity initiator-thread about rendering disabling + // notify initiator-thread about rendering disabling Notify(); // wait for signal @@ -110,9 +121,17 @@ void BaseRenderer::CheckRenderingEnabled() m_wasNotified = false; m_isEnabled = true; - context->setRenderingEnabled(true); + if (m_wasContextReset) + { + m_wasContextReset = false; + OnContextCreate(); + } + else + { + context->setRenderingEnabled(true); + } - // nofity initiator-thread about rendering enabling + // notify initiator-thread about rendering enabling // m_renderingEnablingCompletionHandler will be setup before awakening of this thread Notify(); } diff --git a/drape_frontend/base_renderer.hpp b/drape_frontend/base_renderer.hpp index 14d4da18b4..d0e446d7c3 100644 --- a/drape_frontend/base_renderer.hpp +++ b/drape_frontend/base_renderer.hpp @@ -40,7 +40,9 @@ public: bool CanReceiveMessages(); - void SetRenderingEnabled(bool const isEnabled); + void SetRenderingEnabled(ref_ptr contextFactory); + void SetRenderingDisabled(bool const destroyContext); + bool IsRenderingEnabled() const; protected: @@ -55,6 +57,9 @@ protected: virtual unique_ptr CreateRoutine() = 0; + virtual void OnContextCreate() = 0; + virtual void OnContextDestroy() = 0; + private: using TCompletionHandler = function; @@ -67,7 +72,9 @@ private: TCompletionHandler m_renderingEnablingCompletionHandler; bool m_wasNotified; - void SetRenderingEnabled(bool const isEnabled, TCompletionHandler completionHandler); + atomic m_wasContextReset; + + void SetRenderingEnabled(bool const isEnabled); void Notify(); void WakeUp(); }; diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 9b2698c9b8..5b2d4be1dc 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -92,6 +92,24 @@ DrapeEngine::~DrapeEngine() m_textureManager->Release(); } +void DrapeEngine::Update(int w, int h) +{ + LOG(LWARNING, (w, h)); + + RecacheGui(false); + + UpdateMapStyleMessage::Blocker blocker; + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(blocker), + MessagePriority::High); + blocker.Wait(); + + m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(m_widgetsLayout), + MessagePriority::Normal); + ResizeImpl(w, h); +} + void DrapeEngine::Resize(int w, int h) { if (m_viewport.GetHeight() != h || m_viewport.GetWidth() != w) @@ -151,12 +169,20 @@ void DrapeEngine::UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvide MessagePriority::Normal); } -void DrapeEngine::SetRenderingEnabled(bool const isEnabled) +void DrapeEngine::SetRenderingEnabled(ref_ptr contextFactory) { - m_frontend->SetRenderingEnabled(isEnabled); - m_backend->SetRenderingEnabled(isEnabled); + m_backend->SetRenderingEnabled(contextFactory); + m_frontend->SetRenderingEnabled(contextFactory); - LOG(LDEBUG, (isEnabled ? "Rendering enabled" : "Rendering disabled")); + LOG(LDEBUG, ("Rendering enabled")); +} + +void DrapeEngine::SetRenderingDisabled(bool const destroyContext) +{ + m_frontend->SetRenderingDisabled(destroyContext); + m_backend->SetRenderingDisabled(destroyContext); + + LOG(LDEBUG, ("Rendering disabled")); } void DrapeEngine::InvalidateRect(m2::RectD const & rect) diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 12c86481cc..2b64b79eaf 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -84,6 +84,8 @@ public: DrapeEngine(Params && params); ~DrapeEngine(); + void Update(int w, int h); + void Resize(int w, int h); void Invalidate(); @@ -102,7 +104,8 @@ public: void ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible); void UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider); - void SetRenderingEnabled(bool const isEnabled); + void SetRenderingEnabled(ref_ptr contextFactory); + void SetRenderingDisabled(bool const destroyContext); void InvalidateRect(m2::RectD const & rect); void UpdateMapStyle(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 38d71b5e2e..dbf559fbb0 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -129,6 +129,7 @@ FrontendRenderer::FrontendRenderer(Params const & params) , m_userPositionChangedFn(params.m_positionChangedFn) , m_requestedTiles(params.m_requestedTiles) , m_maxGeneration(0) + , m_needRestoreSize(false) { #ifdef DRAW_INFO m_tpf = 0.0; @@ -819,8 +820,13 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) { m_myPositionController->OnNewViewportRect(); m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); + } + + if (viewportChanged || m_needRestoreSize) + { m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY()); + m_needRestoreSize = false; } RefreshProjection(screen); @@ -1451,24 +1457,49 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) return tiles; } -FrontendRenderer::Routine::Routine(FrontendRenderer & renderer) : m_renderer(renderer) {} - -void FrontendRenderer::Routine::Do() +void FrontendRenderer::OnContextDestroy() { - m_renderer.m_contextFactory->waitForInitialization(); + LOG(LWARNING, ("On context destroy.")); - gui::DrapeGui::Instance().ConnectOnCompassTappedHandler(bind(&FrontendRenderer::OnCompassTapped, &m_renderer)); - m_renderer.m_myPositionController->SetListener(ref_ptr(&m_renderer)); - m_renderer.m_userEventStream.SetListener(ref_ptr(&m_renderer)); + // Clear all graphics. + for (RenderLayer & layer : m_layers) + { + layer.m_renderGroups.clear(); + layer.m_isDirty = false; + } - dp::OGLContext * context = m_renderer.m_contextFactory->getDrawContext(); + m_userMarkRenderGroups.clear(); + m_guiRenderer.reset(); + m_selectionShape.release(); + m_framebuffer.reset(); + m_transparentLayer.reset(); + + m_myPositionController->ResetRenderShape(); + m_routeRenderer->ClearGLDependentResources(); + m_gpsTrackRenderer->ClearRenderData(); + +#ifdef RENDER_DEBUG_RECTS + dp::DebugRectRenderer::Instance().Destroy(); +#endif + + m_gpuProgramManager.reset(); + m_contextFactory->getDrawContext()->doneCurrent(); + + m_needRestoreSize = true; +} + +void FrontendRenderer::OnContextCreate() +{ + LOG(LWARNING, ("On context create.")); + + m_contextFactory->waitForInitialization(); + + dp::OGLContext * context = m_contextFactory->getDrawContext(); context->makeCurrent(); - m_renderer.m_framebuffer->SetDefaultContext(context); + GLFunctions::Init(); GLFunctions::AttachCache(this_thread::get_id()); - dp::SupportManager::Instance().Init(); - GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1); GLFunctions::glEnable(gl_const::GLDepthTest); @@ -1481,7 +1512,10 @@ void FrontendRenderer::Routine::Do() GLFunctions::glEnable(gl_const::GLCullFace); GLFunctions::glEnable(gl_const::GLScissorTest); - m_renderer.m_gpuProgramManager->Init(); + dp::SupportManager::Instance().Init(); + + m_gpuProgramManager = make_unique_dp(); + m_gpuProgramManager->Init(); dp::BlendingParams blendingParams; blendingParams.Apply(); @@ -1490,6 +1524,25 @@ void FrontendRenderer::Routine::Do() dp::DebugRectRenderer::Instance().Init(make_ref(m_renderer.m_gpuProgramManager)); #endif + // resources recovering + m_framebuffer.reset(new Framebuffer()); + m_framebuffer->SetDefaultContext(context); + + m_transparentLayer.reset(new TransparentLayer()); +} + +FrontendRenderer::Routine::Routine(FrontendRenderer & renderer) : m_renderer(renderer) {} + +void FrontendRenderer::Routine::Do() +{ + LOG(LWARNING, ("Start routine")); + + gui::DrapeGui::Instance().ConnectOnCompassTappedHandler(bind(&FrontendRenderer::OnCompassTapped, &m_renderer)); + m_renderer.m_myPositionController->SetListener(ref_ptr(&m_renderer)); + m_renderer.m_userEventStream.SetListener(ref_ptr(&m_renderer)); + + m_renderer.OnContextCreate(); + double const kMaxInactiveSeconds = 2.0; my::Timer timer; @@ -1499,6 +1552,8 @@ void FrontendRenderer::Routine::Do() bool modelViewChanged = true; bool viewportChanged = true; + dp::OGLContext * context = m_renderer.m_contextFactory->getDrawContext(); + while (!IsCancelled()) { ScreenBase modelView = m_renderer.ProcessEvents(modelViewChanged, viewportChanged); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 2bb43a25be..54267771ce 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -151,6 +151,8 @@ public: protected: void AcceptMessage(ref_ptr message) override; unique_ptr CreateRoutine() override; + void OnContextCreate() override; + void OnContextDestroy() override; private: void OnResize(ScreenBase const & screen); @@ -325,6 +327,8 @@ private: drape_ptr m_selectObjectMessage; + bool m_needRestoreSize; + #ifdef DEBUG bool m_isTeardowned; #endif diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index d3c82e404e..b5137402be 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -90,6 +90,12 @@ void GpsTrackRenderer::AddRenderData(ref_ptr mng, m_waitForRenderData = false; } +void GpsTrackRenderer::ClearRenderData() +{ + m_renderData.clear(); + m_waitForRenderData = false; +} + void GpsTrackRenderer::UpdatePoints(vector const & toAdd, vector const & toRemove) { bool wasChanged = false; diff --git a/drape_frontend/gps_track_renderer.hpp b/drape_frontend/gps_track_renderer.hpp index 0ddd6063d3..cb40cb34e8 100644 --- a/drape_frontend/gps_track_renderer.hpp +++ b/drape_frontend/gps_track_renderer.hpp @@ -34,6 +34,7 @@ public: void Update(); void Clear(); + void ClearRenderData(); private: float CalculateRadius(ScreenBase const & screen) const; diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 3d868a8efd..e51f72c1ce 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -285,6 +285,11 @@ void MyPositionController::SetRenderShape(drape_ptr && shape) m_shape = move(shape); } +void MyPositionController::ResetRenderShape() +{ + m_shape.reset(); +} + void MyPositionController::NextMode(ScreenBase const & screen) { string const kAlohalyticsClickEvent = "$onClick"; diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 00bd0be3bc..9d555fc880 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -69,6 +69,7 @@ public: void CorrectGlobalScalePoint(m2::PointD & pt) const; void SetRenderShape(drape_ptr && shape); + void ResetRenderShape(); void ActivateRouting(int zoomLevel, bool enableAutoZoom); void DeactivateRouting(); diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 4a7b115980..3f041b3ce7 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -229,7 +229,7 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCall void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { - if (!m_routeData) + if (!m_routeData || m_invalidGLResources) return; // Render route. @@ -284,6 +284,9 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { + if (m_invalidGLResources) + return; + if (m_startRouteSign) { ASSERT(m_startRouteSign->m_isValid, ()); @@ -301,6 +304,9 @@ void RouteRenderer::RenderRouteSign(drape_ptr const & sign, Scree ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { + if (m_invalidGLResources) + return; + dp::GLState const & state = sign->m_sign.m_state; dp::UniformValuesStorage uniforms = commonUniforms; @@ -322,6 +328,8 @@ void RouteRenderer::RenderRouteSign(drape_ptr const & sign, Scree void RouteRenderer::SetRouteData(drape_ptr && routeData, ref_ptr mng) { + m_invalidGLResources = false; + m_routeData = move(routeData); m_arrowBorders.clear(); @@ -331,6 +339,8 @@ void RouteRenderer::SetRouteData(drape_ptr && routeData, ref_ptr && routeSignData, ref_ptr mng) { + m_invalidGLResources = false; + if (routeSignData->m_isStart) { if (!routeSignData->m_isValid) @@ -373,6 +383,8 @@ drape_ptr const & RouteRenderer::GetRouteData() const void RouteRenderer::SetRouteArrows(drape_ptr && routeArrowsData, ref_ptr mng) { + m_invalidGLResources = false; + m_routeArrows = move(routeArrowsData); BuildBuckets(m_routeArrows->m_arrows, mng); } @@ -389,6 +401,19 @@ void RouteRenderer::Clear(bool keepDistanceFromBegin) m_distanceFromBegin = 0.0; } +void RouteRenderer::ClearGLDependentResources() +{ + m_invalidGLResources = true; + + if (m_routeData != nullptr) + m_routeData->m_route.m_buckets.clear(); + if (m_startRouteSign != nullptr) + m_startRouteSign->m_sign.m_buckets.clear(); + if (m_finishRouteSign != nullptr) + m_finishRouteSign->m_sign.m_buckets.clear(); + m_routeArrows.reset(); +} + void RouteRenderer::UpdateDistanceFromBegin(double distanceFromBegin) { m_distanceFromBegin = distanceFromBegin; diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index a9f530704c..f98b9858f5 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -35,6 +35,7 @@ public: void SetRouteArrows(drape_ptr && routeArrowsData, ref_ptr mng); void Clear(bool keepDistanceFromBegin = false); + void ClearGLDependentResources(); void UpdateDistanceFromBegin(double distanceFromBegin); @@ -54,6 +55,8 @@ private: float m_currentHalfWidth = 0.0f; float m_currentAlpha = 0.0f; + + bool m_invalidGLResources = false; }; } // namespace df diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index c51a63338f..e97e74a7e5 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -160,7 +160,9 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool m2::RectD const prevPixelRect = GetCurrentScreen().PixelRect(); + viewportChanged = false; m_modelViewChanged = !events.empty() || m_state == STATE_SCALE || m_state == STATE_DRAG; + for (auto const & e : events) { bool breakAnim = false; @@ -178,6 +180,7 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool { ref_ptr resizeEvent = make_ref(e); m_navigator.OnSize(resizeEvent->GetWidth(), resizeEvent->GetHeight()); + viewportChanged = true; breakAnim = true; TouchCancel(m_touches); if (m_state == STATE_DOUBLE_TAP_HOLD) @@ -258,7 +261,7 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool modelViewChanged = m_modelViewChanged; double const kEps = 1e-5; - viewportChanged = !m2::IsEqualSize(prevPixelRect, GetCurrentScreen().PixelRect(), kEps, kEps); + viewportChanged |= !m2::IsEqualSize(prevPixelRect, GetCurrentScreen().PixelRect(), kEps, kEps); m_modelViewChanged = false; return m_navigator.Screen(); diff --git a/map/framework.cpp b/map/framework.cpp index aa9732b0ff..38de0dce7b 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -290,7 +290,7 @@ void Framework::Migrate(bool keepDownloaded) // If we do not suspend drape, it tries to access framework fields (i.e. m_infoGetter) which are null // while migration is performed. if (m_drapeEngine && m_isRenderingEnabled) - m_drapeEngine->SetRenderingEnabled(false); + m_drapeEngine->SetRenderingDisabled(false); m_selectedFeature = FeatureID(); m_searchEngine.reset(); m_infoGetter.reset(); @@ -303,7 +303,7 @@ void Framework::Migrate(bool keepDownloaded) InitSearchEngine(); RegisterAllMaps(); if (m_drapeEngine && m_isRenderingEnabled) - m_drapeEngine->SetRenderingEnabled(true); + m_drapeEngine->SetRenderingEnabled(nullptr); InvalidateRect(MercatorBounds::FullRect()); } @@ -1659,6 +1659,15 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, }); } +void Framework::UpdateDrapeEngine(int width, int height) +{ + if (m_drapeEngine) + { + m_drapeEngine->Update(width, height); + InvalidateUserMarks(); + } +} + ref_ptr Framework::GetDrapeEngine() { return make_ref(m_drapeEngine); @@ -1670,11 +1679,18 @@ void Framework::DestroyDrapeEngine() m_drapeEngine.reset(); } -void Framework::SetRenderingEnabled(bool enable) +void Framework::SetRenderingEnabled(ref_ptr contextFactory) { - m_isRenderingEnabled = enable; + m_isRenderingEnabled = true; if (m_drapeEngine) - m_drapeEngine->SetRenderingEnabled(enable); + m_drapeEngine->SetRenderingEnabled(contextFactory); +} + +void Framework::SetRenderingDisabled(bool destroyContext) +{ + m_isRenderingEnabled = false; + if (m_drapeEngine) + m_drapeEngine->SetRenderingDisabled(destroyContext); } void Framework::ConnectToGpsTracker() diff --git a/map/framework.hpp b/map/framework.hpp index ff78f9b079..60b3f47277 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -392,7 +392,11 @@ public: bool IsDrapeEngineCreated() const { return m_drapeEngine != nullptr; } void DestroyDrapeEngine(); /// Called when graphics engine should be temporarily paused and then resumed. - void SetRenderingEnabled(bool enable); + void SetRenderingEnabled(ref_ptr contextFactory); + void SetRenderingDisabled(bool destroyContext); + + void UpdateDrapeEngine(int width, int height); + private: /// Depends on initialized Drape engine. void SaveViewport(); From 10b22b77e2e6e5ef298fe4b1c58ac1e99ac86083 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Wed, 24 Aug 2016 01:57:41 +0300 Subject: [PATCH 2/4] Filter context dependent messages. --- drape_frontend/backend_renderer.cpp | 7 ++- drape_frontend/base_renderer.cpp | 7 +++ drape_frontend/base_renderer.hpp | 1 + drape_frontend/drape_engine.cpp | 15 ++++- drape_frontend/drape_engine.hpp | 1 + drape_frontend/frontend_renderer.cpp | 91 +++++++++++++++------------ drape_frontend/frontend_renderer.hpp | 1 + drape_frontend/message.hpp | 5 +- drape_frontend/message_acceptor.cpp | 14 +++++ drape_frontend/message_acceptor.hpp | 5 ++ drape_frontend/message_queue.cpp | 13 ++++ drape_frontend/message_queue.hpp | 3 + drape_frontend/message_subclasses.hpp | 27 ++++++++ 13 files changed, 145 insertions(+), 45 deletions(-) diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index b959923619..eba5ceb3bb 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -176,6 +176,11 @@ void BackendRenderer::AcceptMessage(ref_ptr message) } break; } + case Message::MapShapesRecache: + { + RecacheMapShapes(); + break; + } case Message::MapShapeReaded: { ref_ptr msg = message; @@ -374,7 +379,7 @@ void BackendRenderer::InitGLDependentResource() m_texMng->Init(params); - RecacheMapShapes(); + //RecacheMapShapes(); } void BackendRenderer::RecacheMapShapes() diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index 725c43b7a5..c751902de6 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -92,6 +92,11 @@ void BaseRenderer::SetRenderingEnabled(bool const isEnabled) completionCondition.wait(lock, [¬ified] { return notified; }); } +bool BaseRenderer::FilterGLContextDependentMessage(ref_ptr msg) +{ + return msg->IsGLContextDependent(); +} + void BaseRenderer::CheckRenderingEnabled() { if (!m_isEnabled) @@ -100,6 +105,7 @@ void BaseRenderer::CheckRenderingEnabled() if (m_wasContextReset) { + EnableMessageFiltering(bind(&BaseRenderer::FilterGLContextDependentMessage, this, _1)); OnContextDestroy(); } else @@ -124,6 +130,7 @@ void BaseRenderer::CheckRenderingEnabled() if (m_wasContextReset) { m_wasContextReset = false; + DisableMessageFiltering(); OnContextCreate(); } else diff --git a/drape_frontend/base_renderer.hpp b/drape_frontend/base_renderer.hpp index d0e446d7c3..b56a9c21a8 100644 --- a/drape_frontend/base_renderer.hpp +++ b/drape_frontend/base_renderer.hpp @@ -74,6 +74,7 @@ private: atomic m_wasContextReset; + bool FilterGLContextDependentMessage(ref_ptr msg); void SetRenderingEnabled(bool const isEnabled); void Notify(); void WakeUp(); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 5b2d4be1dc..b0413f6359 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -68,6 +68,7 @@ DrapeEngine::DrapeEngine(Params && params) m_widgetsInfo = move(params.m_info); RecacheGui(false); + RecacheMapShapes(); if (params.m_showChoosePositionMark) EnableChoosePositionMode(true, move(params.m_boundAreaTriangles), false, m2::PointD()); @@ -97,16 +98,17 @@ void DrapeEngine::Update(int w, int h) LOG(LWARNING, (w, h)); RecacheGui(false); + RecacheMapShapes(); - UpdateMapStyleMessage::Blocker blocker; m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(blocker), + make_unique_dp(), MessagePriority::High); - blocker.Wait(); m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(m_widgetsLayout), MessagePriority::Normal); + + ResizeImpl(w, h); } @@ -213,6 +215,13 @@ void DrapeEngine::UpdateMapStyle() } } +void DrapeEngine::RecacheMapShapes() +{ + m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(), + MessagePriority::Normal); +} + void DrapeEngine::RecacheGui(bool needResetOldGui) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 2b64b79eaf..d887b2b974 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -169,6 +169,7 @@ private: void ResizeImpl(int w, int h); void RecacheGui(bool needResetOldGui); + void RecacheMapShapes(); private: drape_ptr m_frontend; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index dbf559fbb0..9754984a18 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -549,6 +549,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } + case Message::RecoverGLResources: + { + UpdateGLResources(); + break; + } + case Message::UpdateMapStyle: { // Clear all graphics. @@ -576,46 +582,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) blocker.Wait(); } - // Invalidate route. - if (m_routeRenderer->GetStartPoint()) - { - m2::PointD const & position = m_routeRenderer->GetStartPoint()->m_position; - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(position, true /* isStart */, - true /* isValid */), - MessagePriority::High); - } - if (m_routeRenderer->GetFinishPoint()) - { - m2::PointD const & position = m_routeRenderer->GetFinishPoint()->m_position; - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(position, false /* isStart */, - true /* isValid */), - MessagePriority::High); - } - - auto const & routeData = m_routeRenderer->GetRouteData(); - if (routeData != nullptr) - { - auto recacheRouteMsg = make_unique_dp(routeData->m_sourcePolyline, - routeData->m_sourceTurns, - routeData->m_color, - routeData->m_pattern); - m_routeRenderer->Clear(true /* keepDistanceFromBegin */); - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, move(recacheRouteMsg), - MessagePriority::Normal); - } - - // Request new tiles. - ScreenBase screen = m_userEventStream.GetCurrentScreen(); - m_lastReadedModelView = screen; - m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), ResolveTileKeys(screen)); - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(), - MessagePriority::UberHighSingleton); - - m_gpsTrackRenderer->Update(); - + UpdateGLResources(); break; } @@ -753,6 +720,50 @@ unique_ptr FrontendRenderer::CreateRoutine() return make_unique(*this); } +void FrontendRenderer::UpdateGLResources() +{ + // Invalidate route. + if (m_routeRenderer->GetStartPoint()) + { + m2::PointD const & position = m_routeRenderer->GetStartPoint()->m_position; + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(position, true /* isStart */, + true /* isValid */), + MessagePriority::High); + } + + if (m_routeRenderer->GetFinishPoint()) + { + m2::PointD const & position = m_routeRenderer->GetFinishPoint()->m_position; + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(position, false /* isStart */, + true /* isValid */), + MessagePriority::High); + } + + auto const & routeData = m_routeRenderer->GetRouteData(); + if (routeData != nullptr) + { + auto recacheRouteMsg = make_unique_dp(routeData->m_sourcePolyline, + routeData->m_sourceTurns, + routeData->m_color, + routeData->m_pattern); + m_routeRenderer->Clear(true /* keepDistanceFromBegin */); + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, move(recacheRouteMsg), + MessagePriority::Normal); + } + + // Request new tiles. + ScreenBase screen = m_userEventStream.GetCurrentScreen(); + m_lastReadedModelView = screen; + m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), ResolveTileKeys(screen)); + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(), + MessagePriority::UberHighSingleton); + + m_gpsTrackRenderer->Update(); +} + void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d, bool enableAutoZoom) { diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 54267771ce..6152e408f1 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -215,6 +215,7 @@ private: }; void ReleaseResources(); + void UpdateGLResources(); void BeginUpdateOverlayTree(ScreenBase const & modelView); void UpdateOverlayTree(ScreenBase const & modelView, drape_ptr & renderGroup); diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 7319c255b6..bdc97bc437 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -26,6 +26,7 @@ public: GuiLayerRecached, GuiRecache, GuiLayerLayout, + MapShapesRecache, MapShapes, ChangeMyPostitionMode, CompassInfo, @@ -60,11 +61,13 @@ public: SetAddNewPlaceMode, SetDisplacementMode, AllowAutoZoom, - RequestSymbolsSize + RequestSymbolsSize, + RecoverGLResources }; virtual ~Message() {} virtual Type GetType() const { return Unknown; } + virtual bool IsGLContextDependent() const { return false; } }; enum class MessagePriority diff --git a/drape_frontend/message_acceptor.cpp b/drape_frontend/message_acceptor.cpp index 322b6158c4..db070f5790 100644 --- a/drape_frontend/message_acceptor.cpp +++ b/drape_frontend/message_acceptor.cpp @@ -23,8 +23,22 @@ bool MessageAcceptor::ProcessSingleMessage(bool waitForMessage) return true; } +void MessageAcceptor::EnableMessageFiltering(TFilterMessageFn needFilterMessageFn) +{ + m_needFilterMessageFn = needFilterMessageFn; + m_messageQueue.FilterMessages(needFilterMessageFn); +} + +void MessageAcceptor::DisableMessageFiltering() +{ + m_needFilterMessageFn = nullptr; +} + void MessageAcceptor::PostMessage(drape_ptr && message, MessagePriority priority) { + if (m_needFilterMessageFn != nullptr && m_needFilterMessageFn(make_ref(message))) + return; + m_messageQueue.PushMessage(move(message), priority); } diff --git a/drape_frontend/message_acceptor.hpp b/drape_frontend/message_acceptor.hpp index 24ab837497..d2e2f14e86 100644 --- a/drape_frontend/message_acceptor.hpp +++ b/drape_frontend/message_acceptor.hpp @@ -33,6 +33,10 @@ protected: size_t GetQueueSize() const; #endif + using TFilterMessageFn = function)>; + void EnableMessageFiltering(TFilterMessageFn needFilterMessageFn); + void DisableMessageFiltering(); + private: friend class ThreadsCommutator; @@ -40,6 +44,7 @@ private: MessageQueue m_messageQueue; atomic m_infinityWaiting; + TFilterMessageFn m_needFilterMessageFn; }; } // namespace df diff --git a/drape_frontend/message_queue.cpp b/drape_frontend/message_queue.cpp index 69f9edbdc3..ff7595c8c9 100644 --- a/drape_frontend/message_queue.cpp +++ b/drape_frontend/message_queue.cpp @@ -80,6 +80,19 @@ void MessageQueue::PushMessage(drape_ptr && message, MessagePriority pr CancelWaitImpl(); } +void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn) +{ + lock_guard lock(m_mutex); + auto iter = m_messages.begin(); + while (iter != m_messages.end()) + { + if (needFilterMessageFn(make_ref(iter->first))) + iter = m_messages.erase(iter); + else + ++iter; + } +} + #ifdef DEBUG_MESSAGE_QUEUE bool MessageQueue::IsEmpty() const diff --git a/drape_frontend/message_queue.hpp b/drape_frontend/message_queue.hpp index 2562d4954c..6caaa1f292 100644 --- a/drape_frontend/message_queue.hpp +++ b/drape_frontend/message_queue.hpp @@ -27,6 +27,9 @@ public: void CancelWait(); void ClearQuery(); + using TFilterMessageFn = function)>; + void FilterMessages(TFilterMessageFn needFilterMessageFn); + #ifdef DEBUG_MESSAGE_QUEUE bool IsEmpty() const; size_t GetSize() const; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index a8bfb5b336..5fc9412856 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -121,6 +121,7 @@ public: {} Type GetType() const override { return Message::FlushTile; } + bool IsGLContextDependent() const override { return true; } dp::GLState const & GetState() const { return m_state; } drape_ptr && AcceptBuffer() { return move(m_buffer); } @@ -136,6 +137,8 @@ public: FlushOverlaysMessage(TOverlaysRenderData && data) : m_data(move(data)) {} Type GetType() const override { return Message::FlushOverlays; } + bool IsGLContextDependent() const override { return true; } + TOverlaysRenderData && AcceptRenderData() { return move(m_data); } private: @@ -265,6 +268,7 @@ public: {} Type GetType() const override { return Message::GuiLayerRecached; } + bool IsGLContextDependent() const override { return true; } drape_ptr && AcceptRenderer() { return move(m_renderer); } bool NeedResetOldGui() const { return m_needResetOldGui; } @@ -292,6 +296,14 @@ private: bool const m_needResetOldGui; }; +class MapShapesRecacheMessage : public Message +{ +public: + MapShapesRecacheMessage() = default; + + Type GetType() const override { return Message::MapShapesRecache; } +}; + class GuiLayerLayoutMessage : public Message { public: @@ -380,6 +392,7 @@ public: {} Type GetType() const override { return Message::MapShapes; } + bool IsGLContextDependent() const override { return true; } drape_ptr && AcceptShape() { return move(m_shape); } drape_ptr AcceptSelection() { return move(m_selection); } @@ -630,6 +643,8 @@ public: {} Type GetType() const override { return Message::FlushRoute; } + bool IsGLContextDependent() const override { return true; } + drape_ptr && AcceptRouteData() { return move(m_routeData); } private: @@ -658,6 +673,8 @@ public: {} Type GetType() const override { return Message::FlushRouteSign; } + bool IsGLContextDependent() const override { return true; } + drape_ptr && AcceptRouteSignData() { return move(m_routeSignData); } private: @@ -712,6 +729,14 @@ public: Type GetType() const override { return Message::Invalidate; } }; +class RecoverGLResourcesMessage : public Message +{ +public: + RecoverGLResourcesMessage(){} + + Type GetType() const override { return Message::RecoverGLResources; } +}; + class DeactivateRouteFollowingMessage : public Message { public: @@ -792,6 +817,8 @@ public: {} Type GetType() const override { return Message::FlushGpsTrackPoints; } + bool IsGLContextDependent() const override { return true; } + drape_ptr && AcceptRenderData() { return move(m_renderData); } private: From cf1ea4d512e65a5c5ab9f45c0be8e51765650428 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Wed, 24 Aug 2016 21:20:33 +0300 Subject: [PATCH 3/4] Selection shape recovering. --- drape_frontend/base_renderer.cpp | 1 + drape_frontend/drape_engine.hpp | 2 +- iphone/Maps/Classes/MapsAppDelegate.mm | 4 ++-- map/framework.cpp | 31 +++++++------------------- map/framework.hpp | 6 +---- 5 files changed, 13 insertions(+), 31 deletions(-) diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index c751902de6..a3d2c0bd01 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -14,6 +14,7 @@ BaseRenderer::BaseRenderer(ThreadsCommutator::ThreadName name, Params const & pa , m_isEnabled(true) , m_renderingEnablingCompletionHandler(nullptr) , m_wasNotified(false) + , m_wasContextReset(false) { m_commutator->RegisterThread(m_threadName, this); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index d887b2b974..63f38e616f 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -104,7 +104,7 @@ public: void ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible); void UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider); - void SetRenderingEnabled(ref_ptr contextFactory); + void SetRenderingEnabled(ref_ptr contextFactory = nullptr); void SetRenderingDisabled(bool const destroyContext); void InvalidateRect(m2::RectD const & rect); void UpdateMapStyle(); diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index f0868a26e8..c8cb743c06 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -633,7 +633,7 @@ using namespace osm_auth_ios; [self.mapViewController onGetFocus:NO]; [self.mapViewController.appWallAd close]; [MWMRouterSavedState store]; - GetFramework().SetRenderingEnabled(false); + GetFramework().SetRenderingDisabled(false); [MWMLocationManager applicationWillResignActive]; } @@ -667,7 +667,7 @@ using namespace osm_auth_ios; [self.mapViewController onGetFocus:YES]; [self handleURLs]; [[Statistics instance] applicationDidBecomeActive]; - GetFramework().SetRenderingEnabled(true); + GetFramework().SetRenderingEnabled(); [MWMLocationManager applicationDidBecomeActive]; [MWMRouterSavedState restore]; } diff --git a/map/framework.cpp b/map/framework.cpp index 38de0dce7b..4b18eb1a3e 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -189,9 +189,6 @@ void Framework::OnLocationUpdate(GpsInfo const & info) GpsInfo rInfo(info); #endif -#ifdef OMIM_OS_ANDROID - m_lastGPSInfo.reset(new GpsInfo(rInfo)); -#endif location::RouteMatchingInfo routeMatchingInfo; CheckLocationForRouting(rInfo); @@ -210,9 +207,6 @@ void Framework::OnCompassUpdate(CompassInfo const & info) CompassInfo const & rInfo = info; #endif -#ifdef OMIM_OS_ANDROID - m_lastCompassInfo.reset(new CompassInfo(rInfo)); -#endif CallDrapeFunction(bind(&df::DrapeEngine::SetCompassInfo, _1, rInfo)); } @@ -303,7 +297,7 @@ void Framework::Migrate(bool keepDownloaded) InitSearchEngine(); RegisterAllMaps(); if (m_drapeEngine && m_isRenderingEnabled) - m_drapeEngine->SetRenderingEnabled(nullptr); + m_drapeEngine->SetRenderingEnabled(); InvalidateRect(MercatorBounds::FullRect()); } @@ -1623,15 +1617,6 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, InvalidateUserMarks(); -#ifdef OMIM_OS_ANDROID - // In case of the engine reinitialization recover compass and location data - // for correct my position state. - if (m_lastCompassInfo != nullptr) - OnCompassUpdate(*m_lastCompassInfo.release()); - if (m_lastGPSInfo != nullptr) - OnLocationUpdate(*m_lastGPSInfo.release()); -#endif - Allow3dMode(allow3d, allow3dBuildings); LoadViewport(); @@ -1646,13 +1631,6 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, if (m_connectToGpsTrack) GpsTracker::Instance().Connect(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); - // In case of the engine reinitialization simulate the last tap to show selection mark. - if (m_lastTapEvent) - { - place_page::Info info; - ActivateMapSelection(false, OnTapEventImpl(*m_lastTapEvent, info), info); - } - m_drapeEngine->RequestSymbolsSize(kSearchMarks, [this](vector const & sizes) { GetPlatform().RunOnGuiThread([this, sizes](){ m_searchMarksSizes = sizes; }); @@ -1664,7 +1642,14 @@ void Framework::UpdateDrapeEngine(int width, int height) if (m_drapeEngine) { m_drapeEngine->Update(width, height); + InvalidateUserMarks(); + + if (m_lastTapEvent) + { + place_page::Info info; + ActivateMapSelection(false, OnTapEventImpl(*m_lastTapEvent, info), info); + } } } diff --git a/map/framework.hpp b/map/framework.hpp index 60b3f47277..0b9ef4823d 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -331,10 +331,6 @@ public: private: unique_ptr m_lastTapEvent; -#ifdef OMIM_OS_ANDROID - unique_ptr m_lastCompassInfo; - unique_ptr m_lastGPSInfo; -#endif void OnTapEvent(df::TapInfo const & tapInfo); /// outInfo is valid only if return value is not df::SelectionShape::OBJECT_EMPTY. @@ -392,7 +388,7 @@ public: bool IsDrapeEngineCreated() const { return m_drapeEngine != nullptr; } void DestroyDrapeEngine(); /// Called when graphics engine should be temporarily paused and then resumed. - void SetRenderingEnabled(ref_ptr contextFactory); + void SetRenderingEnabled(ref_ptr contextFactory = nullptr); void SetRenderingDisabled(bool destroyContext); void UpdateDrapeEngine(int width, int height); From 157062b5c5099bf2a6e149c73d3b6ba9d6505b5a Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Thu, 25 Aug 2016 20:21:26 +0300 Subject: [PATCH 4/4] Review fixes. --- android/jni/com/mapswithme/maps/Framework.cpp | 22 ++++++++++++++----- android/jni/com/mapswithme/maps/Framework.hpp | 2 +- .../jni/com/mapswithme/maps/MapFragment.cpp | 4 ++-- .../jni/com/mapswithme/maps/SearchEngine.cpp | 13 +++++++---- .../src/com/mapswithme/maps/MapFragment.java | 8 +++++-- drape_frontend/backend_renderer.cpp | 10 ++++----- drape_frontend/base_renderer.cpp | 2 +- drape_frontend/base_renderer.hpp | 1 - drape_frontend/drape_engine.cpp | 2 -- drape_frontend/frontend_renderer.cpp | 6 ++--- drape_frontend/map_shape.hpp | 1 + drape_frontend/message_acceptor.cpp | 2 ++ drape_frontend/message_queue.cpp | 11 +++++----- drape_frontend/message_queue.hpp | 2 +- geometry/screenbase.hpp | 2 +- map/framework.cpp | 6 ++++- 16 files changed, 59 insertions(+), 35 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index cf0ff3c133..5ab24cac2a 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -125,7 +125,10 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi m_contextFactory = make_unique_dp(new AndroidOGLContextFactory(env, jSurface)); AndroidOGLContextFactory const * factory = m_contextFactory->CastFactory(); if (!factory->IsValid()) + { + LOG(LWARNING, ("Invalid GL context.")); return false; + } ::Framework::DrapeCreationParams p; p.m_surfaceWidth = factory->GetWidth(); @@ -160,10 +163,10 @@ void Framework::Resize(int w, int h) void Framework::DetachSurface(bool destroyContext) { - LOG(LWARNING, ("Detach surface")); + LOG(LINFO, ("Detach surface.")); if (destroyContext) { - LOG(LWARNING, ("Destroy context")); + LOG(LINFO, ("Destroy context.")); m_isContextDestroyed = true; m_work.EnterBackground(); } @@ -174,26 +177,34 @@ void Framework::DetachSurface(bool destroyContext) factory->ResetSurface(); } -void Framework::AttachSurface(JNIEnv * env, jobject jSurface) +bool Framework::AttachSurface(JNIEnv * env, jobject jSurface) { - LOG(LWARNING, ("Attach surface")); + LOG(LINFO, ("Attach surface.")); ASSERT(m_contextFactory != nullptr, ()); AndroidOGLContextFactory * factory = m_contextFactory->CastFactory(); factory->SetSurface(env, jSurface); + if (!factory->IsValid()) + { + LOG(LWARNING, ("Invalid GL context.")); + return false; + } + ASSERT(!m_guiPositions.empty(), ("GUI elements must be set-up before engine is created")); m_work.SetRenderingEnabled(factory); if (m_isContextDestroyed) { - LOG(LWARNING, ("Recover resources, size:", factory->GetWidth(), factory->GetHeight())); + LOG(LINFO, ("Recover GL resources, viewport size:", factory->GetWidth(), factory->GetHeight())); m_work.UpdateDrapeEngine(factory->GetWidth(), factory->GetHeight()); m_isContextDestroyed = false; m_work.EnterForeground(); } + + return true; } void Framework::SetMapStyle(MapStyle mapStyle) @@ -203,7 +214,6 @@ void Framework::SetMapStyle(MapStyle mapStyle) void Framework::MarkMapStyle(MapStyle mapStyle) { - LOG(LWARNING, ("MarkMapStyle")); m_work.MarkMapStyle(mapStyle); } diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index 332606de49..d2c4e549a1 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -78,7 +78,7 @@ namespace android bool IsDrapeEngineCreated(); void DetachSurface(bool destroyContext); - void AttachSurface(JNIEnv * env, jobject jSurface); + bool AttachSurface(JNIEnv * env, jobject jSurface); void SetMapStyle(MapStyle mapStyle); void MarkMapStyle(MapStyle mapStyle); diff --git a/android/jni/com/mapswithme/maps/MapFragment.cpp b/android/jni/com/mapswithme/maps/MapFragment.cpp index 9b32591850..b06ff33247 100644 --- a/android/jni/com/mapswithme/maps/MapFragment.cpp +++ b/android/jni/com/mapswithme/maps/MapFragment.cpp @@ -75,10 +75,10 @@ Java_com_mapswithme_maps_MapFragment_nativeIsEngineCreated(JNIEnv * env, jclass return g_framework->IsDrapeEngineCreated(); } -JNIEXPORT void JNICALL +JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_MapFragment_nativeAttachSurface(JNIEnv * env, jclass clazz, jobject surface) { - g_framework->AttachSurface(env, surface); + return g_framework->AttachSurface(env, surface); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index 63d6384a0b..a96bf29375 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -238,16 +238,21 @@ extern "C" JNIEXPORT void JNICALL Java_com_mapswithme_maps_search_SearchEngine_nativeShowResult(JNIEnv * env, jclass clazz, jint index) { - lock_guard guard(g_resultsMutex); - Result const & result = g_results.GetResult(index); + unique_lock guard(g_resultsMutex); + Result const result = g_results.GetResult(index); + guard.unlock(); g_framework->NativeFramework()->ShowSearchResult(result); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_search_SearchEngine_nativeShowAllResults(JNIEnv * env, jclass clazz) { - lock_guard guard(g_resultsMutex); - g_framework->NativeFramework()->ShowSearchResults(g_results); + Results results; + { + lock_guard guard(g_resultsMutex); + results = g_results; + } + g_framework->NativeFramework()->ShowSearchResults(results); } JNIEXPORT void JNICALL diff --git a/android/src/com/mapswithme/maps/MapFragment.java b/android/src/com/mapswithme/maps/MapFragment.java index 3a7ae66df7..778d625189 100644 --- a/android/src/com/mapswithme/maps/MapFragment.java +++ b/android/src/com/mapswithme/maps/MapFragment.java @@ -140,7 +140,11 @@ public class MapFragment extends BaseMwmFragment final Surface surface = surfaceHolder.getSurface(); if (nativeIsEngineCreated()) { - nativeAttachSurface(surface); + if (!nativeAttachSurface(surface)) + { + reportUnsupported(); + return; + } mContextCreated = true; mRequireResize = true; return; @@ -282,7 +286,7 @@ public class MapFragment extends BaseMwmFragment static native boolean nativeShowMapForUrl(String url); static native boolean nativeIsEngineCreated(); private static native boolean nativeCreateEngine(Surface surface, int density, boolean firstLaunch); - private static native void nativeAttachSurface(Surface surface); + private static native boolean nativeAttachSurface(Surface surface); private static native void nativeDetachSurface(boolean destroyContext); private static native void nativeSurfaceChanged(int w, int h); private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, int maskedPointer); diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index eba5ceb3bb..b26819750b 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -319,6 +319,7 @@ void BackendRenderer::ReleaseResources() m_readManager.reset(); m_batchersPool.reset(); m_routeBuilder.reset(); + m_overlays.clear(); m_texMng->Release(); m_contextFactory->getResourcesUploadContext()->doneCurrent(); @@ -326,7 +327,7 @@ void BackendRenderer::ReleaseResources() void BackendRenderer::OnContextCreate() { - LOG(LWARNING, ("On context create.")); + LOG(LINFO, ("On context create.")); m_contextFactory->waitForInitialization(); m_contextFactory->getResourcesUploadContext()->makeCurrent(); @@ -337,10 +338,11 @@ void BackendRenderer::OnContextCreate() void BackendRenderer::OnContextDestroy() { - LOG(LWARNING, ("On context destroy.")); + LOG(LINFO, ("On context destroy.")); m_readManager->InvalidateAll(); m_batchersPool.reset(); m_texMng->Release(); + m_overlays.clear(); m_contextFactory->getResourcesUploadContext()->doneCurrent(); } @@ -349,7 +351,7 @@ BackendRenderer::Routine::Routine(BackendRenderer & renderer) : m_renderer(rende void BackendRenderer::Routine::Do() { - LOG(LWARNING, ("Start routine.")); + LOG(LINFO, ("Start routine.")); m_renderer.OnContextCreate(); while (!IsCancelled()) @@ -378,8 +380,6 @@ void BackendRenderer::InitGLDependentResource() GetPlatform().GetFontNames(params.m_glyphMngParams.m_fonts); m_texMng->Init(params); - - //RecacheMapShapes(); } void BackendRenderer::RecacheMapShapes() diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index a3d2c0bd01..265d28ed96 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -42,7 +42,7 @@ void BaseRenderer::StopThread() void BaseRenderer::SetRenderingEnabled(ref_ptr contextFactory) { - if (m_wasContextReset) + if (m_wasContextReset && contextFactory != nullptr) m_contextFactory = contextFactory; SetRenderingEnabled(true); } diff --git a/drape_frontend/base_renderer.hpp b/drape_frontend/base_renderer.hpp index b56a9c21a8..6171f4929a 100644 --- a/drape_frontend/base_renderer.hpp +++ b/drape_frontend/base_renderer.hpp @@ -71,7 +71,6 @@ private: atomic m_isEnabled; TCompletionHandler m_renderingEnablingCompletionHandler; bool m_wasNotified; - atomic m_wasContextReset; bool FilterGLContextDependentMessage(ref_ptr msg); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index b0413f6359..e406525800 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -95,8 +95,6 @@ DrapeEngine::~DrapeEngine() void DrapeEngine::Update(int w, int h) { - LOG(LWARNING, (w, h)); - RecacheGui(false); RecacheMapShapes(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 9754984a18..19e8b5db04 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1470,7 +1470,7 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) void FrontendRenderer::OnContextDestroy() { - LOG(LWARNING, ("On context destroy.")); + LOG(LINFO, ("On context destroy.")); // Clear all graphics. for (RenderLayer & layer : m_layers) @@ -1501,7 +1501,7 @@ void FrontendRenderer::OnContextDestroy() void FrontendRenderer::OnContextCreate() { - LOG(LWARNING, ("On context create.")); + LOG(LINFO, ("On context create.")); m_contextFactory->waitForInitialization(); @@ -1546,7 +1546,7 @@ FrontendRenderer::Routine::Routine(FrontendRenderer & renderer) : m_renderer(ren void FrontendRenderer::Routine::Do() { - LOG(LWARNING, ("Start routine")); + LOG(LINFO, ("Start routine.")); gui::DrapeGui::Instance().ConnectOnCompassTappedHandler(bind(&FrontendRenderer::OnCompassTapped, &m_renderer)); m_renderer.m_myPositionController->SetListener(ref_ptr(&m_renderer)); diff --git a/drape_frontend/map_shape.hpp b/drape_frontend/map_shape.hpp index 49b1e8d9f5..cdde3a35f4 100644 --- a/drape_frontend/map_shape.hpp +++ b/drape_frontend/map_shape.hpp @@ -74,6 +74,7 @@ public: {} Type GetType() const override { return Message::MapShapeReaded; } + bool IsGLContextDependent() const override { return true; } TMapShapes const & GetShapes() { return m_shapes; } private: diff --git a/drape_frontend/message_acceptor.cpp b/drape_frontend/message_acceptor.cpp index db070f5790..4f05bcdb06 100644 --- a/drape_frontend/message_acceptor.cpp +++ b/drape_frontend/message_acceptor.cpp @@ -25,6 +25,8 @@ bool MessageAcceptor::ProcessSingleMessage(bool waitForMessage) void MessageAcceptor::EnableMessageFiltering(TFilterMessageFn needFilterMessageFn) { + ASSERT(needFilterMessageFn != nullptr, ()); + m_needFilterMessageFn = needFilterMessageFn; m_messageQueue.FilterMessages(needFilterMessageFn); } diff --git a/drape_frontend/message_queue.cpp b/drape_frontend/message_queue.cpp index ff7595c8c9..fce3e04e30 100644 --- a/drape_frontend/message_queue.cpp +++ b/drape_frontend/message_queue.cpp @@ -82,14 +82,15 @@ void MessageQueue::PushMessage(drape_ptr && message, MessagePriority pr void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn) { + ASSERT(needFilterMessageFn != nullptr, ()); + lock_guard lock(m_mutex); - auto iter = m_messages.begin(); - while (iter != m_messages.end()) + for (auto it = m_messages.begin(); it != m_messages.end(); ) { - if (needFilterMessageFn(make_ref(iter->first))) - iter = m_messages.erase(iter); + if (needFilterMessageFn(make_ref(it->first))) + it = m_messages.erase(it); else - ++iter; + ++it; } } diff --git a/drape_frontend/message_queue.hpp b/drape_frontend/message_queue.hpp index 6caaa1f292..dc2147191b 100644 --- a/drape_frontend/message_queue.hpp +++ b/drape_frontend/message_queue.hpp @@ -27,7 +27,7 @@ public: void CancelWait(); void ClearQuery(); - using TFilterMessageFn = function)>; + using TFilterMessageFn = function)>; void FilterMessages(TFilterMessageFn needFilterMessageFn); #ifdef DEBUG_MESSAGE_QUEUE diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 2346f1dd0b..5094eabc8f 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -156,7 +156,7 @@ public: m2::PointD PtoP3d(m2::PointD const & pt) const; m2::PointD PtoP3d(m2::PointD const & pt, double ptZ) const; - m2::RectD PixelRectIn3d() const + m2::RectD const & PixelRectIn3d() const { return m_ViewportRect; } diff --git a/map/framework.cpp b/map/framework.cpp index 4b18eb1a3e..7029c4fc84 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -284,7 +284,7 @@ void Framework::Migrate(bool keepDownloaded) // If we do not suspend drape, it tries to access framework fields (i.e. m_infoGetter) which are null // while migration is performed. if (m_drapeEngine && m_isRenderingEnabled) - m_drapeEngine->SetRenderingDisabled(false); + m_drapeEngine->SetRenderingDisabled(true); m_selectedFeature = FeatureID(); m_searchEngine.reset(); m_infoGetter.reset(); @@ -297,7 +297,11 @@ void Framework::Migrate(bool keepDownloaded) InitSearchEngine(); RegisterAllMaps(); if (m_drapeEngine && m_isRenderingEnabled) + { m_drapeEngine->SetRenderingEnabled(); + UpdateDrapeEngine(m_currentModelView.PixelRectIn3d().SizeX(), + m_currentModelView.PixelRectIn3d().SizeY()); + } InvalidateRect(MercatorBounds::FullRect()); }