diff --git a/android/jni/com/mapswithme/maps/MapFragment.cpp b/android/jni/com/mapswithme/maps/MapFragment.cpp index 612ba9aa60..ec4e717274 100644 --- a/android/jni/com/mapswithme/maps/MapFragment.cpp +++ b/android/jni/com/mapswithme/maps/MapFragment.cpp @@ -11,6 +11,15 @@ #include "platform/file_logging.hpp" #include "platform/settings.hpp" +namespace +{ +void OnRenderingInitializationFinished(std::shared_ptr const & listener) +{ + JNIEnv * env = jni::GetEnv(); + env->CallVoidMethod(*listener, jni::GetMethodID(env, *listener.get(), + "onRenderingInitializationFinished", "()V")); +} +} // namespace extern "C" { @@ -125,7 +134,8 @@ Java_com_mapswithme_maps_MapFragment_nativeOnTouch(JNIEnv * env, jclass clazz, j } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_MapFragment_nativeSetupWidget(JNIEnv * env, jclass clazz, jint widget, jfloat x, jfloat y, jint anchor) +Java_com_mapswithme_maps_MapFragment_nativeSetupWidget( + JNIEnv * env, jclass clazz, jint widget, jfloat x, jfloat y, jint anchor) { g_framework->SetupWidget(static_cast(widget), x, y, static_cast(anchor)); } @@ -142,4 +152,18 @@ Java_com_mapswithme_maps_MapFragment_nativeCleanWidgets(JNIEnv * env, jclass cla g_framework->CleanWidgets(); } +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_MapFragment_nativeSetRenderingInitializationFinishedListener( + JNIEnv * env, jclass clazz, jobject listener) +{ + if (listener) + { + g_framework->NativeFramework()->SetGraphicsContextInitializationHandler( + std::bind(&OnRenderingInitializationFinished, jni::make_global_ref(listener))); + } + else + { + g_framework->NativeFramework()->SetGraphicsContextInitializationHandler(nullptr); + } +} } // extern "C" diff --git a/android/src/com/mapswithme/maps/MapFragment.java b/android/src/com/mapswithme/maps/MapFragment.java index 47f67923a2..b9b31d1b51 100644 --- a/android/src/com/mapswithme/maps/MapFragment.java +++ b/android/src/com/mapswithme/maps/MapFragment.java @@ -26,7 +26,8 @@ import com.mapswithme.util.log.LoggerFactory; public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, - SurfaceHolder.Callback + SurfaceHolder.Callback, + MapRenderingListener { public static final String ARG_LAUNCH_BY_DEEP_LINK = "launch_by_deep_link"; private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); @@ -72,12 +73,6 @@ public class MapFragment extends BaseMwmFragment @NonNull private SurfaceView mSurfaceView; - interface MapRenderingListener - { - void onRenderingInitialized(); - void onRenderingRestored(); - } - private void setupWidgets(int width, int height) { mHeight = height; @@ -137,20 +132,30 @@ public class MapFragment extends BaseMwmFragment nativeApplyWidgets(); } - private void onRenderingInitialized() + @Override + public void onRenderingCreated() { final Activity activity = getActivity(); if (isAdded() && activity instanceof MapRenderingListener) - ((MapRenderingListener) activity).onRenderingInitialized(); + ((MapRenderingListener) activity).onRenderingCreated(); } - private void onRenderingRestored() + @Override + public void onRenderingRestored() { final Activity activity = getActivity(); if (isAdded() && activity instanceof MapRenderingListener) ((MapRenderingListener) activity).onRenderingRestored(); } + @Override + public void onRenderingInitializationFinished() + { + final Activity activity = getActivity(); + if (isAdded() && activity instanceof MapRenderingListener) + ((MapRenderingListener) activity).onRenderingInitializationFinished(); + } + private void reportUnsupported() { new AlertDialog.Builder(getActivity()) @@ -222,7 +227,7 @@ public class MapFragment extends BaseMwmFragment mSurfaceCreated = true; mSurfaceAttached = true; nativeResumeSurfaceRendering(); - onRenderingInitialized(); + onRenderingCreated(); } @Override @@ -280,9 +285,17 @@ public class MapFragment extends BaseMwmFragment public void onStart() { super.onStart(); + nativeSetRenderingInitializationFinishedListener(this); LOGGER.d(TAG, "onStart"); } + public void onStop() + { + super.onStop(); + nativeSetRenderingInitializationFinishedListener(null); + LOGGER.d(TAG, "onStop"); + } + private boolean isThemeChangingProcess() { return mUiThemeOnPause != null && !mUiThemeOnPause.equals(Config.getCurrentUiTheme()); @@ -391,4 +404,5 @@ public class MapFragment extends BaseMwmFragment private static native void nativeSetupWidget(int widget, float x, float y, int anchor); private static native void nativeApplyWidgets(); private static native void nativeCleanWidgets(); + private static native void nativeSetRenderingInitializationFinishedListener(MapRenderingListener listener); } diff --git a/android/src/com/mapswithme/maps/MapRenderingListener.java b/android/src/com/mapswithme/maps/MapRenderingListener.java new file mode 100644 index 0000000000..726b325d74 --- /dev/null +++ b/android/src/com/mapswithme/maps/MapRenderingListener.java @@ -0,0 +1,8 @@ +package com.mapswithme.maps; + +interface MapRenderingListener +{ + void onRenderingCreated(); + void onRenderingRestored(); + void onRenderingInitializationFinished(); +} diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 9b5f1f9f86..4856ed5742 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -135,7 +135,7 @@ public class MwmActivity extends BaseMwmFragmentActivity implements MapObjectListener, View.OnTouchListener, OnClickListener, - MapFragment.MapRenderingListener, + MapRenderingListener, CustomNavigateUpListener, RoutingController.Container, LocationHelper.UiCallback, @@ -278,13 +278,12 @@ public class MwmActivity extends BaseMwmFragmentActivity } @Override - public void onRenderingInitialized() + public void onRenderingCreated() { checkMeasurementSystem(); checkKitkatMigrationMove(); LocationHelper.INSTANCE.attach(this); - runTasks(); } @Override @@ -293,6 +292,12 @@ public class MwmActivity extends BaseMwmFragmentActivity runTasks(); } + @Override + public void onRenderingInitializationFinished() + { + runTasks(); + } + private void myPositionClick() { mLocationErrorDialogAnnoying = false; diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index f48ee3c9f1..11023365af 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -671,7 +671,7 @@ BackendRenderer::Routine::Routine(BackendRenderer & renderer) : m_renderer(rende void BackendRenderer::Routine::Do() { LOG(LINFO, ("Start routine.")); - m_renderer.OnContextCreate(); + m_renderer.CreateContext(); while (!IsCancelled()) { RENDER_FRAME(m_renderer.RenderFrame()); diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index e47755a641..44d3003488 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -44,8 +44,9 @@ public: ref_ptr factory, ref_ptr texMng, MapDataProvider const & model, TUpdateCurrentCountryFn const & updateCurrentCountryFn, ref_ptr requestedTiles, bool allow3dBuildings, bool trafficEnabled, - bool simplifiedTrafficColors, TIsUGCFn && isUGCFn) - : BaseRenderer::Params(apiVersion, commutator, factory, texMng) + bool simplifiedTrafficColors, TIsUGCFn && isUGCFn, + OnGraphicsContextInitialized const & onGraphicsContextInitialized) + : BaseRenderer::Params(apiVersion, commutator, factory, texMng, onGraphicsContextInitialized) , m_model(model) , m_updateCurrentCountryFn(updateCurrentCountryFn) , m_requestedTiles(requestedTiles) diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index 8889a2e895..f7a357ffc4 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -5,6 +5,9 @@ namespace df { +// static +std::atomic BaseRenderer::m_contextCounter(0); + BaseRenderer::BaseRenderer(ThreadsCommutator::ThreadName name, Params const & params) : m_apiVersion(params.m_apiVersion) , m_commutator(params.m_commutator) @@ -15,6 +18,7 @@ BaseRenderer::BaseRenderer(ThreadsCommutator::ThreadName name, Params const & pa , m_renderingEnablingCompletionHandler(nullptr) , m_wasNotified(false) , m_wasContextReset(false) + , m_onGraphicsContextInitialized(params.m_onGraphicsContextInitialized) { m_commutator->RegisterThread(m_threadName, this); } @@ -103,6 +107,16 @@ bool BaseRenderer::FilterContextDependentMessage(ref_ptr msg) return msg->IsGraphicsContextDependent(); } +void BaseRenderer::CreateContext() +{ + OnContextCreate(); + + m_contextCounter++; + uint8_t constexpr kContextCount = 2; + if (m_contextCounter == kContextCount && m_onGraphicsContextInitialized) + m_onGraphicsContextInitialized(); +} + void BaseRenderer::CheckRenderingEnabled() { if (!m_isEnabled) @@ -114,6 +128,8 @@ void BaseRenderer::CheckRenderingEnabled() using namespace std::placeholders; EnableMessageFiltering(std::bind(&BaseRenderer::FilterContextDependentMessage, this, _1)); OnContextDestroy(); + CHECK(m_contextCounter > 0, ()); + m_contextCounter--; } else { @@ -161,7 +177,7 @@ void BaseRenderer::CheckRenderingEnabled() OnRenderingEnabled(); if (needCreateContext) - OnContextCreate(); + CreateContext(); } } diff --git a/drape_frontend/base_renderer.hpp b/drape_frontend/base_renderer.hpp index d426e6baf3..8cbf641dcb 100644 --- a/drape_frontend/base_renderer.hpp +++ b/drape_frontend/base_renderer.hpp @@ -27,24 +27,28 @@ extern void RenderFrameMediator(std::function && renderFrameFunction); namespace df { +using OnGraphicsContextInitialized = std::function; + class BaseRenderer : public MessageAcceptor { public: struct Params { Params(dp::ApiVersion apiVersion, ref_ptr commutator, - ref_ptr factory, ref_ptr texMng) + ref_ptr factory, ref_ptr texMng, + OnGraphicsContextInitialized const & onGraphicsContextInitialized) : m_apiVersion(apiVersion) , m_commutator(commutator) , m_oglContextFactory(factory) , m_texMng(texMng) - { - } + , m_onGraphicsContextInitialized(onGraphicsContextInitialized) + {} dp::ApiVersion m_apiVersion; ref_ptr m_commutator; ref_ptr m_oglContextFactory; ref_ptr m_texMng; + OnGraphicsContextInitialized m_onGraphicsContextInitialized; }; BaseRenderer(ThreadsCommutator::ThreadName name, Params const & params); @@ -66,6 +70,8 @@ protected: void StartThread(); void StopThread(); + void CreateContext(); + void CheckRenderingEnabled(); virtual std::unique_ptr CreateRoutine() = 0; @@ -90,6 +96,9 @@ private: bool m_wasNotified; std::atomic m_wasContextReset; + OnGraphicsContextInitialized m_onGraphicsContextInitialized; + static std::atomic m_contextCounter; + bool FilterContextDependentMessage(ref_ptr msg); void SetRenderingEnabled(bool const isEnabled); void Notify(); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index d17a2e2b30..b3a50d9bcc 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -85,7 +85,8 @@ DrapeEngine::DrapeEngine(Params && params) params.m_allow3dBuildings, params.m_trafficEnabled, params.m_blockTapEvents, - std::move(effects)); + std::move(effects), + params.m_onGraphicsContextInitialized); m_frontend = make_unique_dp(std::move(frParams)); @@ -99,7 +100,8 @@ DrapeEngine::DrapeEngine(Params && params) params.m_allow3dBuildings, params.m_trafficEnabled, params.m_simplifiedTrafficColors, - std::move(params.m_isUGCFn)); + std::move(params.m_isUGCFn), + params.m_onGraphicsContextInitialized); m_backend = make_unique_dp(std::move(brParams)); diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 08ffa9986a..380b3a9cb3 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -70,7 +70,8 @@ public: bool isAutozoomEnabled, bool simplifiedTrafficColors, OverlaysShowStatsCallback && overlaysShowStatsCallback, - TIsUGCFn && isUGCFn) + TIsUGCFn && isUGCFn, + OnGraphicsContextInitialized && onGraphicsContextInitialized) : m_apiVersion(apiVersion) , m_factory(factory) , m_viewport(viewport) @@ -91,6 +92,7 @@ public: , m_simplifiedTrafficColors(simplifiedTrafficColors) , m_overlaysShowStatsCallback(std::move(overlaysShowStatsCallback)) , m_isUGCFn(std::move(isUGCFn)) + , m_onGraphicsContextInitialized(std::move(onGraphicsContextInitialized)) {} dp::ApiVersion m_apiVersion; @@ -113,6 +115,7 @@ public: bool m_simplifiedTrafficColors; OverlaysShowStatsCallback m_overlaysShowStatsCallback; TIsUGCFn m_isUGCFn; + OnGraphicsContextInitialized m_onGraphicsContextInitialized; }; DrapeEngine(Params && params); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 078fa01c12..30eec74b99 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -2339,7 +2339,7 @@ void FrontendRenderer::Routine::Do() m_renderer.m_myPositionController->SetListener(ref_ptr(&m_renderer)); m_renderer.m_userEventStream.SetListener(ref_ptr(&m_renderer)); - m_renderer.OnContextCreate(); + m_renderer.CreateContext(); #if defined(DEBUG) || defined(DEBUG_DRAPE_XCODE) || defined(SCENARIO_ENABLE) gui::DrapeGui::Instance().GetScaleFpsHelper().SetVisible(true); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index d08bbd305e..d2a2a31171 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -89,8 +89,9 @@ public: TUserPositionChangedFn const & positionChangedFn, ref_ptr requestedTiles, OverlaysShowStatsCallback && overlaysShowStatsCallback, bool allow3dBuildings, bool trafficEnabled, bool blockTapEvents, - std::vector && enabledEffects) - : BaseRenderer::Params(apiVersion, commutator, factory, texMng) + std::vector && enabledEffects, + OnGraphicsContextInitialized const & onGraphicsContextInitialized) + : BaseRenderer::Params(apiVersion, commutator, factory, texMng, onGraphicsContextInitialized) , m_myPositionParams(std::move(myPositionParams)) , m_viewport(viewport) , m_modelViewChangedFn(modelViewChangedFn) diff --git a/map/framework.cpp b/map/framework.cpp index b9acb9de17..af74fca2cb 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1890,6 +1890,15 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac m_localAdsManager.GetStatistics().RegisterEvents(std::move(statEvents)); }; + auto onGraphicsContextInitialized = [this]() + { + GetPlatform().RunTask(Platform::Thread::Gui, [this]() + { + if (m_onGraphicsContextInitialized) + m_onGraphicsContextInitialized(); + }); + }; + auto isUGCFn = [this](FeatureID const & id) { auto const ugc = m_ugcApi->GetLoader().GetUGC(id); @@ -1917,7 +1926,8 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode, params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), m_routingManager.IsRoutingActive() && m_routingManager.IsRoutingFollowing(), - isAutozoomEnabled, simplifiedTrafficColors, move(overlaysShowStatsFn), move(isUGCFn)); + isAutozoomEnabled, simplifiedTrafficColors, move(overlaysShowStatsFn), move(isUGCFn), + move(onGraphicsContextInitialized)); m_drapeEngine = make_unique_dp(move(p)); m_drapeEngine->SetModelViewListener([this](ScreenBase const & screen) @@ -2030,6 +2040,11 @@ void Framework::SetRenderingDisabled(bool destroySurface) m_drapeEngine->SetRenderingDisabled(destroySurface); } +void Framework::SetGraphicsContextInitializationHandler(df::OnGraphicsContextInitialized && handler) +{ + m_onGraphicsContextInitialized = std::move(handler); +} + void Framework::EnableDebugRectRendering(bool enabled) { if (m_drapeEngine) diff --git a/map/framework.hpp b/map/framework.hpp index 5830ef68a5..d4a135a53d 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -516,6 +516,8 @@ public: void SetRenderingEnabled(ref_ptr contextFactory = nullptr); void SetRenderingDisabled(bool destroySurface); + void SetGraphicsContextInitializationHandler(df::OnGraphicsContextInitialized && handler); + void OnRecoverSurface(int width, int height, bool recreateContextDependentResources); void OnDestroySurface(); @@ -525,6 +527,8 @@ private: /// Depends on initialized Drape engine. void LoadViewport(); + df::OnGraphicsContextInitialized m_onGraphicsContextInitialized; + public: void ConnectToGpsTracker(); void DisconnectFromGpsTracker();