diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-04-30 12:01:26 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-04-30 12:01:26 +0200 |
commit | 1216a061d3e46eae983a38e42e71115e5c9faef6 (patch) | |
tree | 7ddb57f2885072db82657dc56dff64e49e28db76 /common | |
parent | ddc359f006c47e2a503b616d27e22f5d29c13e5b (diff) | |
download | qtlocation-mapboxgl-1216a061d3e46eae983a38e42e71115e5c9faef6.tar.gz |
move to libuv for the rendering loop
Diffstat (limited to 'common')
-rw-r--r-- | common/curl_request.cpp | 25 | ||||
-rw-r--r-- | common/foundation_request.mm | 28 | ||||
-rw-r--r-- | common/glfw_view.cpp | 66 | ||||
-rw-r--r-- | common/glfw_view.hpp | 5 |
4 files changed, 32 insertions, 92 deletions
diff --git a/common/curl_request.cpp b/common/curl_request.cpp index e00e805786..0702e1e720 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -88,10 +88,9 @@ static std::queue<CURL *> curl_handle_cache; class CURLRequest : public llmr::platform::Request { public: CURLRequest(const std::string &url, - std::function<void(llmr::platform::Response *)> background_function, - std::function<void()> foreground_callback, + std::function<void(llmr::platform::Response *)> callback, uv_loop_t *loop) - : Request(url, background_function, foreground_callback, loop) {} + : Request(url, callback, loop) {} CURL *curl = nullptr; }; @@ -169,16 +168,7 @@ void curl_perform(uv_poll_t *req, int /*status*/, int events) { // We're currently in the CURL request thread. We're going to schedule a uv_work request // that executes the background function in a threadpool, and tell it to call the // after callback back in the main uv loop. - - uv_work_t *work = new uv_work_t(); - - // We're passing on the pointer we created to the work structure. - // It is going to be deleted in the after_work_cb; - work->data = req; - - // Executes the background_function in a libuv thread pool, and the after_work_cb back - // in the *main* event loop. - uv_queue_work((*req)->loop, work, Request::work_callback, Request::after_work_callback); + (*req)->complete(); CURL *handle = message->easy_handle; remove_curl_handle(handle); @@ -187,6 +177,8 @@ void curl_perform(uv_poll_t *req, int /*status*/, int events) { // be cancelled. ((CURLRequest *)req->get())->curl = nullptr; + // Delete the shared_ptr pointer we created earlier. + delete req; break; } @@ -312,8 +304,6 @@ void async_add_cb(uv_async_t * /*async*/) { continue; } - (*req)->res = std::make_unique<Response>(); - // Obtain a curl handle (and try to reuse existing handles before creating new ones). CURL *handle = nullptr; if (!curl_handle_cache.empty()) { @@ -367,12 +357,11 @@ void thread_init_cb() { std::shared_ptr<platform::Request> platform::request_http(const std::string &url, - std::function<void(Response *)> background_function, - std::function<void()> foreground_callback, + std::function<void(Response *)> callback, uv_loop_t *loop) { using namespace request; init_thread_once(thread_init_cb); - std::shared_ptr<CURLRequest> req = std::make_shared<CURLRequest>(url, background_function, foreground_callback, loop); + std::shared_ptr<CURLRequest> req = std::make_shared<CURLRequest>(url, callback, loop); // Note that we are creating a new shared_ptr pointer(!) because the lockless queue can't store // objects with nontrivial destructors. We have to make absolutely sure that we manually delete diff --git a/common/foundation_request.mm b/common/foundation_request.mm index c0b12cc734..d188349462 100644 --- a/common/foundation_request.mm +++ b/common/foundation_request.mm @@ -40,10 +40,9 @@ void request_initialize_cb() { class FoundationRequest : public llmr::platform::Request { public: FoundationRequest(const std::string &url, - std::function<void(llmr::platform::Response *)> background_function, - std::function<void()> foreground_callback, + std::function<void(llmr::platform::Response *)> callback, uv_loop_t *loop) - : Request(url, background_function, foreground_callback, loop) { + : Request(url, callback, loop) { #if TARGET_OS_IPHONE active_tasks++; dispatch_async(dispatch_get_main_queue(), ^(void) { @@ -68,13 +67,12 @@ public: std::shared_ptr<llmr::platform::Request> llmr::platform::request_http(const std::string &url, - std::function<void(Response *)> background_function, - std::function<void()> foreground_callback, + std::function<void(Response *)> callback, uv_loop_t *loop) { uv_once(&request_initialize, request_initialize_cb); std::shared_ptr<FoundationRequest> req = - std::make_shared<FoundationRequest>(url, background_function, foreground_callback, loop); + std::make_shared<FoundationRequest>(url, callback, loop); // Note that we are creating a new shared_ptr pointer(!) to make sure there is at least one // shared_ptr in existence while the NSURLSession is loading our data. We are making sure in the @@ -93,8 +91,6 @@ llmr::platform::request_http(const std::string &url, return; } - (*req_ptr)->res = std::make_unique<Response>(); - if (!error && [response isKindOfClass:[NSHTTPURLResponse class]]) { (*req_ptr)->res->code = [(NSHTTPURLResponse *)response statusCode]; (*req_ptr)->res->body = {(const char *)[data bytes], [data length]}; @@ -102,19 +98,9 @@ llmr::platform::request_http(const std::string &url, (*req_ptr)->res->error_message = [[error localizedDescription] UTF8String]; } - // We're currently in the request thread. We're going to schedule a uv_work request that - // executes the background function in a threadpool, and tell it to call the after callback - // back in the main uv loop. - uv_work_t *work = new uv_work_t(); - - // We're passing on the pointer we created to the work structure. It is going to be deleted - // in the after_work_cb; - work->data = req_ptr; - - // Executes the background_function in a libuv thread pool, and the after_work_cb back in - // the *main* event loop. - uv_queue_work((*req_ptr)->loop, work, Request::work_callback, - Request::after_work_callback); + (*req_ptr)->complete(); + + delete req_ptr; }]; req->task = task; diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp index d3034016fc..cfa1156a1c 100644 --- a/common/glfw_view.cpp +++ b/common/glfw_view.cpp @@ -1,39 +1,7 @@ #include "glfw_view.hpp" - -#ifndef HAVE_KQUEUE -# if defined(__APPLE__) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__OpenBSD__) || \ - defined(__NetBSD__) -# define HAVE_KQUEUE 1 -# endif -#endif - -#ifndef HAVE_EPOLL -# if defined(__linux__) -# define HAVE_EPOLL 1 -# endif -#endif - -#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) - -#if defined(HAVE_KQUEUE) -# include <sys/types.h> -# include <sys/event.h> -# include <sys/time.h> -#endif - -#if defined(HAVE_EPOLL) -# include <sys/epoll.h> -#endif - -#endif - - MapView::MapView(llmr::Settings &settings, bool fullscreen) - : fullscreen(fullscreen), settings(settings), map(settings) {} + : fullscreen(fullscreen), settings(settings), map(*this) {} MapView::~MapView() { glfwTerminate(); } @@ -77,20 +45,17 @@ void MapView::init() { glfwGetFramebufferSize(window, &fb_width, &fb_height); settings.load(); - map.setup(); resize(window, 0, 0); - glfwSwapInterval(1); - - map.loadSettings(); - glfwSetCursorPosCallback(window, mousemove); glfwSetMouseButtonCallback(window, mouseclick); glfwSetWindowSizeCallback(window, resize); glfwSetFramebufferSizeCallback(window, resize); glfwSetScrollCallback(window, scroll); glfwSetKeyCallback(window, key); + + glfwMakeContextCurrent(nullptr); } void MapView::key(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { @@ -152,7 +117,6 @@ void MapView::resize(GLFWwindow *window, int, int) { glfwGetFramebufferSize(window, &fb_width, &fb_height); mapView->map.resize(width, height, (float)fb_width / (float)width, fb_width, fb_height); - mapView->map.update(); } void MapView::mouseclick(GLFWwindow *window, int button, int action, int modifiers) { @@ -199,17 +163,11 @@ int MapView::run() { map.start(); while (!glfwWindowShouldClose(window)) { - if (map.clean.test_and_set() == false) { - // This branch is executed when the previous value of the "clean" - // flag is false (i.e. it is unclean == dirty). - try { - map.render(); - } - catch (std::exception &ex) { - fprintf(stderr, "exception: %s\n", ex.what()); - } + if (map.swapped.test_and_set() == false) { glfwSwapBuffers(window); + map.rendered.clear(); fps(); + map.rerender(); } glfwWaitEvents(); @@ -220,6 +178,14 @@ int MapView::run() { return 0; } +void MapView::make_active() { + glfwMakeContextCurrent(window); +} + +void MapView::swap() { + glfwPostEmptyEvent(); +} + void MapView::fps() { static int frames = 0; static double time_elapsed = 0; @@ -267,9 +233,5 @@ void show_debug_image(std::string name, const char *data, size_t width, size_t h glfwMakeContextCurrent(current_window); } -void restart() { - glfwPostEmptyEvent(); -} - } } diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp index 5dbb64efb2..7c9f41811c 100644 --- a/common/glfw_view.hpp +++ b/common/glfw_view.hpp @@ -5,13 +5,16 @@ #include <GLFW/glfw3.h> #include <uv.h> -class MapView { +class MapView : public llmr::View { public: MapView(llmr::Settings &settings, bool fullscreen = false); ~MapView(); void init(); + void swap(); + void make_active(); + static void key(GLFWwindow *window, int key, int scancode, int action, int mods); static void scroll(GLFWwindow *window, double xoffset, double yoffset); static void resize(GLFWwindow *window, int, int); |