From: Matt Blair Date: Wed, 28 Jun 2017 02:15:36 +0000 (-0400) Subject: Update libtangram and fix crashes X-Git-Tag: accepted/tizen/unified/20170707.154913~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F67%2F136067%2F2;p=platform%2Fcore%2Flocation%2Fmaps-plugin-mapzen.git Update libtangram and fix crashes - Update libtangram to Tangram ES 0.7.0 release, built from Tangram ES commit 4dcdca26b625da545d65a795775351c64d83a2ba - fix: do not assign null to std::string - fix: use thread_safe_call_sync instead of async - prevent maps_service_instance_count go below zero - use unique_ptr, shutdown Map before GL context - poll for renderRequests from non-ui threads to avoid deadlocks Change-Id: Idd2818754ed65ce2013e4da50578455204af67fb --- diff --git a/lib/aarch64/libtangram.so b/lib/aarch64/libtangram.so index 0a0559c..6065adc 100755 Binary files a/lib/aarch64/libtangram.so and b/lib/aarch64/libtangram.so differ diff --git a/lib/arm/libtangram.so b/lib/arm/libtangram.so index c81a33f..3d8e693 100755 Binary files a/lib/arm/libtangram.so and b/lib/arm/libtangram.so differ diff --git a/lib/i586/libtangram.so b/lib/i586/libtangram.so index 128dd35..40aa675 100755 Binary files a/lib/i586/libtangram.so and b/lib/i586/libtangram.so differ diff --git a/lib/x86_64/libtangram.so b/lib/x86_64/libtangram.so index 93efedb..fe04ed2 100755 Binary files a/lib/x86_64/libtangram.so and b/lib/x86_64/libtangram.so differ diff --git a/src/mapzen/tangram_view.cpp b/src/mapzen/tangram_view.cpp index e7e5e90..45b8db5 100644 --- a/src/mapzen/tangram_view.cpp +++ b/src/mapzen/tangram_view.cpp @@ -30,6 +30,8 @@ extern "C" { #include #include +#include // SYS_gettid + #define NORMAL_SCENE_FILE_PATH "/usr/share/maps/mapzen/scenes/bubble-wrap/bubble-wrap.yaml" #define TERRAIN_SCENE_FILE_PATH "/usr/share/maps/mapzen/scenes/walkabout-style/walkabout-style.yaml" @@ -106,19 +108,40 @@ mapzen_error_e TangramView::create(maps_view_h view, maps_plugin_map_view_ready_ Tangram::UrlClient::Options urlOptions; char* proxyAddress = NULL; get_proxy_address(&proxyAddress); - urlOptions.proxyAddress = proxyAddress; - if (proxyAddress) + if (proxyAddress) { + urlOptions.proxyAddress = proxyAddress; free(proxyAddress); + } + + m_platform = std::make_shared(urlOptions); + + m_uiThreadId = syscall(SYS_gettid); - auto platform = std::shared_ptr(new Tangram::TizenPlatform(urlOptions)); - //auto platform = std::make_shared(); + m_platform->setRenderCallbackFunction([&]() { - platform->setRenderCallbackFunction([=](){ - ecore_main_loop_thread_safe_call_async(&renderingCb, m_image); + if (m_uiThreadId == syscall(SYS_gettid)) { + m_dirty = false; + evas_object_image_pixels_dirty_set(m_image, EINA_TRUE); + } else { + m_dirty = true; + } }); + // NB: Since there is no safe way to use ecore_main_loop_thread_safe_call_async in a + // module that could be unloaded at runtime we use polling to check on the mainloop + // whether a render request came in. + // TODO only run timer when async tasks (Tile- and Scene-Loading) are in progress. + m_renderRequestTimer = ecore_timer_add(0.05, [](void *data){ + auto tv = static_cast(data); + if (tv->m_dirty) { + tv->m_dirty = false; + evas_object_image_pixels_dirty_set((Evas_Object*)tv->m_image, EINA_TRUE); + } + return EINA_TRUE; + }, this); + // Set up the tangram map. - m_map = new Tangram::Map(platform); + m_map.reset(new Tangram::Map(m_platform)); float scaleFactor = elm_config_scale_get(); MAPS_LOGD("evas_gl_context_create() set PixelScale %f", scaleFactor); @@ -198,6 +221,11 @@ mapzen_error_e TangramView::destroy(maps_view_h view) m_isInitialized = false; m_sceneLoaded = false; + if (m_renderRequestTimer) { + ecore_timer_del(m_renderRequestTimer); + m_renderRequestTimer = nullptr; + } + if (m_image) { evas_object_image_pixels_get_callback_set(m_image, nullptr, nullptr); } @@ -206,6 +234,16 @@ mapzen_error_e TangramView::destroy(maps_view_h view) if (m_surface && m_context) { evas_gl_make_current(m_gl, m_surface, m_context); } + } + + if (m_map) { + removeAllObjects(); + + m_map.reset(); + m_platform.reset(); + } + + if (m_gl) { if (m_surface) { evas_object_image_native_surface_set(m_image, nullptr); evas_gl_surface_destroy(m_gl, m_surface); @@ -221,14 +259,6 @@ mapzen_error_e TangramView::destroy(maps_view_h view) evas_gl_config_free(m_config); } - if (m_map) { - static_cast(m_map->getPlatform().get())->setRenderCallbackFunction(nullptr); - removeAllObjects(); - delete m_map; - m_map = nullptr; - } - - return MAPZEN_ERROR_NONE; } @@ -959,7 +989,13 @@ void TangramView::pixelGetCb(void *data, Evas_Object *obj) { TangramView *tv = nullptr; int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&tv); - if (maps_error != MAPS_ERROR_NONE || !tv || !tv->m_gl || !tv->m_surface || !tv->m_context) { + if (maps_error != MAPS_ERROR_NONE || !tv) { + return; + } + + tv->m_dirty = false; + + if (!tv->m_gl || !tv->m_surface || !tv->m_context) { return; } @@ -973,10 +1009,3 @@ void TangramView::pixelGetCb(void *data, Evas_Object *obj) MAPS_LOGD("tv->m_map is null, in pixelGelCb"); } } - -void TangramView::renderingCb(void *data) { - if (!data) { - return; - } - evas_object_image_pixels_dirty_set((Evas_Object*)data, EINA_TRUE); -} diff --git a/src/mapzen/tangram_view.hpp b/src/mapzen/tangram_view.hpp index fe7b9c4..0a1c4f2 100644 --- a/src/mapzen/tangram_view.hpp +++ b/src/mapzen/tangram_view.hpp @@ -24,13 +24,17 @@ #include #include #include +#include #include #include "mapzen_types.h" #include "tangram/util/types.h" +#include // pid_t, gettid() + namespace Tangram { class Map; + class TizenPlatform; } typedef std::map MapViewObjects; @@ -79,18 +83,22 @@ private: static void sceneLoadedCb(void *data); static void readyMapCb(void *view); - static void renderingCb(void *data); static void pixelGetCb(void *data, Evas_Object *obj); // Emplaces the lng/lat from `coordinate` to `user_data` (Tangram::Coordinates) static bool emplaceCoord(int index, maps_coordinates_h coordinate, void *user_data); - Tangram::Map *m_map = nullptr; + std::unique_ptr m_map; + std::shared_ptr m_platform; + + pid_t m_uiThreadId = 0; + Evas_Object *m_image = nullptr; Evas_GL_Context *m_context = nullptr; Evas_GL_Surface *m_surface = nullptr; Evas_GL_Config *m_config = nullptr; Evas_GL *m_gl = nullptr; Evas_GL_API *m_api = nullptr; + Ecore_Timer *m_renderRequestTimer = nullptr; bool m_isInitialized = false; bool m_publicTransitEnabled = false; @@ -99,6 +107,7 @@ private: std::string m_language = "en"; std::string m_providerKey = ""; bool m_isProviderKeySet = false; + bool m_dirty = false; int m_x = 0; int m_y = 0; diff --git a/src/mapzen_plugin.c b/src/mapzen_plugin.c index 24f0698..702d75a 100644 --- a/src/mapzen_plugin.c +++ b/src/mapzen_plugin.c @@ -173,6 +173,10 @@ EXPORT_API int maps_plugin_shutdown(maps_plugin_h plugin) if (!plugin) return MAPS_ERROR_INVALID_PARAMETER; + if (__maps_service_instance_count == 0) { + return MAPS_ERROR_INVALID_PARAMETER; + } + __maps_service_instance_count--; int ret = MAPS_ERROR_NONE;