Esempio n. 1
0
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();
    }
}
Esempio n. 2
0
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();
    }
}