void TileWorker::run() { setCurrentThreadPriority(WORKER_NICENESS); StyleContext context; while (true) { std::shared_ptr<TileTask> task; { std::unique_lock<std::mutex> lock(m_mutex); m_condition.wait(lock, [&, this]{ return !m_running || !m_queue.empty(); }); // Check if thread should stop if (!m_running) { break; } // Remove all canceled tasks auto removes = std::remove_if(m_queue.begin(), m_queue.end(), [](const auto& a) { return a->isCanceled(); }); m_queue.erase(removes, m_queue.end()); if (m_queue.empty()) { continue; } // Pop highest priority tile from queue auto it = std::min_element(m_queue.begin(), m_queue.end(), [](const auto& a, const auto& b) { if (a->isProxy() != b->isProxy()) { return !a->isProxy(); } if (a->source().id() == b->source().id() && a->sourceGeneration() != b->sourceGeneration()) { return a->sourceGeneration() < b->sourceGeneration(); } return a->getPriority() < b->getPriority(); }); task = std::move(*it); m_queue.erase(it); } if (task->isCanceled()) { continue; } // Save shared reference to Scene while building tile // FIXME: Scene could be released on Worker-Thread and // therefore call unsafe glDelete* functions... auto scene = m_scene; if (!scene) { continue; } auto tileData = task->source().parse(*task, *scene->mapProjection()); // const clock_t begin = clock(); context.initFunctions(*scene); if (tileData) { auto tile = std::make_shared<Tile>(task->tileId(), *scene->mapProjection(), &task->source()); tile->build(context, *scene, *tileData, task->source()); // Mark task as ready task->setTile(std::move(tile)); // float loadTime = (float(clock() - begin) / CLOCKS_PER_SEC) * 1000; // LOG("loadTime %s - %f", task->tile()->getID().toString().c_str(), loadTime); } else { task->cancel(); } m_pendingTiles = true; requestRender(); } }
void TileWorker::run() { setCurrentThreadPriority(WORKER_NICENESS); StyleContext context; while (true) { std::shared_ptr<TileTask> task; { std::unique_lock<std::mutex> lock(m_mutex); m_condition.wait(lock, [&, this]{ return !m_running || !m_queue.empty(); }); // Check if thread should stop if (!m_running) { break; } // Remove all canceled tasks auto removes = std::remove_if(m_queue.begin(), m_queue.end(), [](const auto& a) { return a->tile->isCanceled(); }); m_queue.erase(removes, m_queue.end()); if (m_queue.empty()) { continue; } // Pop highest priority tile from queue auto it = std::min_element(m_queue.begin(), m_queue.end(), [](const auto& a, const auto& b) { if (a->tile->isVisible() != b->tile->isVisible()) { return a->tile->isVisible(); } return a->tile->getPriority() < b->tile->getPriority(); }); task = std::move(*it); m_queue.erase(it); } if (task->tile->isCanceled()) { continue; } auto tileData = task->process(); // NB: Save shared reference to Scene while building tile auto scene = m_tileManager.getScene(); const clock_t begin = clock(); context.initFunctions(*scene); if (tileData) { task->tile->build(context, *scene, *tileData, *task->source); float loadTime = (float(clock() - begin) / CLOCKS_PER_SEC) * 1000; LOG("loadTime %s - %f", task->tile->getID().toString().c_str(), loadTime); m_tileManager.tileProcessed(std::move(task)); } requestRender(); } }