Example #1
0
VkBool32 VKTS_APIENTRY engineAddUpdateThread(const IUpdateThreadSP& updateThread)
{
    if (g_engineState != VKTS_ENGINE_INIT_STATE)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Adding update thread failed! Not in initialize state.");

        return VK_FALSE;
    }

    if (!updateThread.get())
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Adding update thread failed! No update thread.");

        return VK_FALSE;
    }

    if (engineGetNumberUpdateThreads() >= VKTS_MAX_UPDATE_THREADS)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Adding update thread failed! Too many update threads.");

        return VK_FALSE;
    }

    g_allUpdateThreads.append(updateThread);

    return VK_TRUE;
}
Example #2
0
    VkBool32 set(const K& key, const V& value)
    {
        for (size_t i = 0; i < allKeys.size(); i++)
        {
            if (key == allKeys[i])
            {
                allValues[i] = value;

                return VK_TRUE;
            }
            else if (key < allKeys[i])
            {
                allKeys.insert(i, key);
                allValues.insert(i, value);

                return VK_TRUE;
            }
        }

        allKeys.append(key);
        allValues.append(value);

        return VK_TRUE;
    }
Example #3
0
VkBool32 VKTS_APIENTRY engineRun()
{
    if (g_engineState != VKTS_ENGINE_INIT_STATE)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Not in initialize state.");

        return VK_FALSE;
    }

    if (engineGetNumberUpdateThreads() < VKTS_MIN_UPDATE_THREADS || engineGetNumberUpdateThreads() > VKTS_MAX_UPDATE_THREADS)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Number of update threads not correct.");

        return VK_FALSE;
    }

    //
    // Main thread gets all displays and windows attached.
    //

    const auto& displayList = _visualGetActiveDisplays();

    for (size_t i = 0; i < displayList.size(); i++)
    {
        engineAttachDisplayToUpdateThread(displayList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    const auto& windowList = _visualGetActiveWindows();

    for (size_t i = 0; i < windowList.size(); i++)
    {
        engineAttachWindowToUpdateThread(windowList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    //

    g_engineState = VKTS_ENGINE_UPDATE_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Started.");

    // Task queue creation.

    TaskQueueSP sendTaskQueue;
    TaskQueueSP executedTaskQueue;

    if (g_taskExecutorCount > 0)
    {
        sendTaskQueue = TaskQueueSP(new TaskQueue);

        if (!sendTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }

        executedTaskQueue = TaskQueueSP(new TaskQueue);

        if (!executedTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }
    }

    // Message dispatcher creation.

    MessageDispatcherSP messageDispatcher = MessageDispatcherSP(new MessageDispatcher());

    if (!messageDispatcher.get())
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create message dispatcher.");

        return VK_FALSE;
    }

    // Object, needed for synchronizing the executors.

    ExecutorSync executorSync;

    //
    // Task executor creation and launching,
    //

    SmartPointerVector<TaskExecutorSP> realTaskExecutors;
    SmartPointerVector<ThreadSP> realTaskThreads;

    for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    {
        auto currentTaskExecutor = TaskExecutorSP(new TaskExecutor(i, executorSync, sendTaskQueue, executedTaskQueue));

        if (!currentTaskExecutor.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current task executor.");

            return VK_FALSE;
        }

        auto currentRealThread = ThreadSP(new std::thread(&TaskExecutor::run, currentTaskExecutor));

        if (!currentRealThread.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

            return VK_FALSE;
        }

        //

        realTaskExecutors.append(currentTaskExecutor);
        realTaskThreads.append(currentRealThread);

        logPrint(VKTS_LOG_INFO, "Engine: Task %d started.", currentTaskExecutor->getIndex());
    }

    //
    // Update Thread creation and launching.
    //

    UpdateThreadExecutorSP mainUpdateThreadExecutor;

    SmartPointerVector<UpdateThreadExecutorSP> realUpdateThreadExecutors;
    SmartPointerVector<ThreadSP> realUpdateThreads;

    int32_t index = 0;

    for (size_t updateThreadIndex = 0; updateThreadIndex < g_allUpdateThreads.size(); updateThreadIndex++)
    {
        const auto& currentUpdateThread = g_allUpdateThreads[updateThreadIndex];

        //

        const auto currentMessageDispatcher = (index == engineGetNumberUpdateThreads() - 1) ? messageDispatcher : MessageDispatcherSP();

        //

        auto currentUpdateThreadContext = UpdateThreadContextSP(new UpdateThreadContext((int32_t) updateThreadIndex, (int32_t) g_allUpdateThreads.size(), g_tickTime, sendTaskQueue, executedTaskQueue));

        if (!currentUpdateThreadContext.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create update thread context.");

            return VK_FALSE;
        }

        //

        for (auto currentDisplayWalker = g_allAttachedDisplays.lower_bound(currentUpdateThread); currentDisplayWalker != g_allAttachedDisplays.upper_bound(currentUpdateThread); currentDisplayWalker++)
        {
            currentUpdateThreadContext->attachDisplay(currentDisplayWalker->second);
        }

        //

        for (auto currentWindowWalker = g_allAttachedWindows.lower_bound(currentUpdateThread); currentWindowWalker != g_allAttachedWindows.upper_bound(currentUpdateThread); currentWindowWalker++)
        {
            currentUpdateThreadContext->attachWindow(currentWindowWalker->second);
        }

        //

        if (index == engineGetNumberUpdateThreads() - 1)
        {
            // Last thread is the main thread.
            mainUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!mainUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create main update thread executor.");

                return VK_FALSE;
            }
        }
        else
        {
            // Receive queue is the threads send queue.
            auto currentUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!currentUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current update thread executor.");

                return VK_FALSE;
            }

            realUpdateThreadExecutors.append(currentUpdateThreadExecutor);

            logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", currentUpdateThreadExecutor->getIndex());

            auto currentRealThread = ThreadSP(new std::thread(&UpdateThreadExecutor::run, currentUpdateThreadExecutor));

            if (!currentRealThread.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

                return VK_FALSE;
            }
            realUpdateThreads.append(currentRealThread);
        }
        index++;
    }

    // Run last thread and loop.
    logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", mainUpdateThreadExecutor->getIndex());

    mainUpdateThreadExecutor->run();

    //
    // Stopping everything.
    //

    logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", mainUpdateThreadExecutor->getIndex());

    // Wait for all threads to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realUpdateThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realUpdateThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", reverseIndex);
    }

    realUpdateThreadExecutors.clear();
    realUpdateThreads.clear();

    //

    if (sendTaskQueue.get())
    {
    	// Empty the queue.
    	// As no update thread can feed the queue anymore, it is save to call reset.

    	sendTaskQueue->reset();

    	//

    	ITaskSP stopTask;

        logPrint(VKTS_LOG_SEVERE, "Engine: Disabling task queue.");

    	for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    	{
    		// Send an empty task to the queue, to exit the thread.
    		sendTaskQueue->addTask(stopTask);
    	}
    }

    // Wait for all tasks to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realTaskThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realTaskThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Task %d stopped.", reverseIndex);
    }

    realTaskExecutors.clear();
    realTaskThreads.clear();

    //

    g_engineState = VKTS_ENGINE_INIT_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Stopped.");

    return VK_TRUE;
}
Example #4
0
SmartPointerVector<IImageDataSP> VKTS_APIENTRY imageDataMipmap(const IImageDataSP& sourceImage, VkBool32 addSourceAsCopy, const std::string& name)
{
    if (name.size() == 0 || !sourceImage.get())
    {
        return SmartPointerVector<IImageDataSP>();
    }

    std::string sourceImageFilename = name;

    auto dotIndex = sourceImageFilename.rfind(".");

    if (dotIndex == sourceImageFilename.npos)
    {
        return SmartPointerVector<IImageDataSP>();
    }

    auto sourceImageName = sourceImageFilename.substr(0, dotIndex);
    auto sourceImageExtension = sourceImageFilename.substr(dotIndex);

    IImageDataSP currentSourceImage = sourceImage;
    int32_t width = currentSourceImage->getWidth();
    int32_t height = currentSourceImage->getHeight();
    int32_t depth = currentSourceImage->getDepth();

    IImageDataSP currentTargetImage;
    std::string targetImageFilename;

    int32_t level = 0;

    SmartPointerVector<IImageDataSP> result;

    if (addSourceAsCopy)
    {
        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCopy(sourceImage, targetImageFilename);

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        result.append(currentTargetImage);
    }
    else
    {
        result.append(sourceImage);

        level++;
    }

    while (width > 1 || height > 1 || depth > 1)
    {
        width = glm::max(width / 2, 1);
        height = glm::max(height / 2, 1);
        depth = glm::max(depth / 2, 1);

        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCreate(targetImageFilename, width, height, depth, 0.0f, 0.0f, 0.0f, 0.0f, sourceImage->getImageType(), sourceImage->getFormat());

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        for (int32_t z = 0; z < depth; z++)
        {
            for (int32_t y = 0; y < height; y++)
            {
                for (int32_t x = 0; x < width; x++)
                {
                    glm::vec4 rgba = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
                    float sampleCount = 0.0f;

                    for (int32_t iz = z * 2; iz < z * 2 + 1; iz++)
                    {
                        for (int32_t iy = y * 2; iy < y * 2 + 1; iy++)
                        {
                            for (int32_t ix = x * 2; ix < x * 2 + 1; ix++)
                            {
                                rgba += currentSourceImage->getTexel(ix, iy, iz);

                                sampleCount += 1.0f;
                            }
                        }
                    }

                    if (sampleCount > 0.0f)
                    {
                        rgba /= sampleCount;

                        currentTargetImage->setTexel(rgba, x, y, z);
                    }
                }
            }
        }

        result.append(currentTargetImage);

        //

        currentSourceImage = currentTargetImage;
        width = currentSourceImage->getWidth();
        height = currentSourceImage->getHeight();
        depth = currentSourceImage->getDepth();
    }

    return result;
}