void StandaloneRenderManager::renderNextIteration()
{
    try
    {
        if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_currentScene != NULL)
        {
            m_noEmittedSignals = true;

            if(m_compileScene)
            {
                m_application.setRendererStatus(RendererStatus::INITIALIZING_SCENE);
                m_renderer.initScene(*m_currentScene);
                m_compileScene = false;
                m_application.setRendererStatus(RendererStatus::RENDERING);
            }

            // We only diplay one every X frames on screen (to make fair comparison with distributed renderer)
            bool shouldOutputIteration = m_nextIterationNumber % 5 == 0;

            const double PPMAlpha = 2.0/3.0;
            QVector<unsigned long long> iterationNumbers;
            QVector<double> ppmRadii;

            RenderServerRenderRequestDetails details (m_camera, QByteArray(m_currentScene->getSceneName()), 
                m_application.getRenderMethod(), m_application.getWidth(), m_application.getHeight(), PPMAlpha);

            RenderServerRenderRequest renderRequest (m_application.getSequenceNumber(), iterationNumbers, ppmRadii, details);

            m_renderer.renderNextIteration(m_nextIterationNumber, m_nextIterationNumber, m_PPMRadius, shouldOutputIteration, renderRequest.getDetails());
            const double ppmRadiusSquared = m_PPMRadius*m_PPMRadius;
            const double ppmRadiusSquaredNew = ppmRadiusSquared*(m_nextIterationNumber+PPMAlpha)/double(m_nextIterationNumber+1);
            m_PPMRadius = sqrt(ppmRadiusSquaredNew);

            // Transfer the output buffer to CPU and signal ready for display

            if(shouldOutputIteration)
            {
                if(m_outputBuffer == NULL)
                {
                    m_outputBuffer = new float[2000*2000*3];
                }
                m_renderer.getOutputBuffer(m_outputBuffer);
                emit newFrameReadyForDisplay(m_outputBuffer, m_nextIterationNumber);
            }

            fillRenderStatistics();
            m_nextIterationNumber++;
        }
    }
    catch(const std::exception & E)
    {
        m_application.setRunningStatus(RunningStatus::PAUSE);
        QString error = QString("%1").arg(E.what());
        emit renderManagerError(error);
    }
}
void StandaloneRenderManager::start()
{
    m_application.setRendererStatus(RendererStatus::INITIALIZING_ENGINE);
    try
    {
        m_renderer.initialize(m_device);
    }
    catch(const std::exception & E)
    {
        QString error = QString("Error during initialization: %1").arg(E.what());
        emit renderManagerError(error);
    }
}
void StandaloneRenderManager::renderNextIteration()
{
    try
    {
        if(m_application.getRunningStatus() == RunningStatus::RUNNING && m_currentScene != NULL)
        {
            m_noEmittedSignals = true;

            if(m_compileScene)
            {
                m_application.setRendererStatus(RendererStatus::INITIALIZING_SCENE);
                m_renderer.initScene(*m_currentScene);
                m_compileScene = false;
                m_application.setRendererStatus(RendererStatus::STARTING_RENDERING);
            }

            // We only display one every X frames on screen (to make fair comparison with distributed renderer)
            bool shouldOutputIteration = m_nextIterationNumber % 5 == 0;
            //bool shouldOutputIteration = m_nextIterationNumber % 1 == 0;

            const double PPMAlpha = 2.0/3.0;
            QVector<unsigned long long> iterationNumbers;
            QVector<double> ppmRadii;

            RenderServerRenderRequestDetails details (m_camera, QByteArray(m_currentScene->getSceneName()), 
                m_application.getRenderMethod(), m_application.getWidth(), m_application.getHeight(), PPMAlpha);

            RenderServerRenderRequest renderRequest (m_application.getSequenceNumber(), iterationNumbers, ppmRadii, details);

            m_renderer.renderNextIteration(m_nextIterationNumber, m_nextIterationNumber, m_PPMRadius, shouldOutputIteration, renderRequest.getDetails());
            const double ppmRadiusSquared = m_PPMRadius*m_PPMRadius;
            const double ppmRadiusSquaredNew = ppmRadiusSquared*(m_nextIterationNumber+PPMAlpha)/double(m_nextIterationNumber+1);
            m_PPMRadius = sqrt(ppmRadiusSquaredNew);

            // set as rendering only after first iteration, since that one can slow due init and sync with gpu
            if (m_application.getRendererStatus() != RendererStatus::RENDERING)
                m_application.setRendererStatus(RendererStatus::RENDERING);

            // Transfer the output buffer to CPU and signal ready for display
            m_outputBufferMutex.lock();
            m_lastRendererIterationNumber = m_nextIterationNumber;
            if(shouldOutputIteration)
            {
                if(m_outputBuffer == NULL)
                {
                    m_outputBuffer = new float[MAX_OUTPUT_X*MAX_OUTPUT_Y*3];
                }
                m_renderer.getOutputBuffer(m_outputBuffer);
                // FIXME
                // vmarz: m_lastRendererIterationNumber shouldn't be exposed like that, but passed next iteration number
                // can be invalid (already incremented) when render widget is updating and accumulated values get scaled incorrectly
                emit newFrameReadyForDisplay(m_outputBuffer, &m_lastRendererIterationNumber, &m_outputBufferMutex);
            }
            m_outputBufferMutex.unlock();

            fillRenderStatistics();
            m_nextIterationNumber++;
        }
    }
    catch(const std::exception & E)
    {
        m_application.setRunningStatus(RunningStatus::PAUSE);
        QString error = QString("%1").arg(E.what());
        emit renderManagerError(error);
    }
}