//################################################################################################## // // Custom Visualization Core library // Copyright (C) 2011-2012 Ceetron AS // // This library is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at <> // for more details. // //################################################################################################## #include "cvfBase.h" #include "cvfConstantFrameRate.h" #include "cvfTrace.h" namespace cvf { //================================================================================================== /// /// \class cvf::ConstantFrameRate /// \ingroup Viewing /// /// /// //================================================================================================== //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- ConstantFrameRate::ConstantFrameRate() { m_targetFrameRate = 10.0; m_minNumPartsToDraw = 1; m_enableDistanceSorting = false; m_numPartsToDraw = -1.0; m_pixelSizeCullingWasOn = false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void ConstantFrameRate::setTargetFrameRate(double targetFrameRate) { CVF_ASSERT(targetFrameRate >= 0); m_targetFrameRate = targetFrameRate; if (m_targetFrameRate < 0) m_targetFrameRate = 0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void ConstantFrameRate::setMinNumPartsToDraw(int minNumParts) { CVF_ASSERT(minNumParts >= 1); m_minNumPartsToDraw = minNumParts; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void ConstantFrameRate::enableDistanceSorting(bool enableDistanceSorting) { m_enableDistanceSorting = enableDistanceSorting; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double ConstantFrameRate::targetFrameRate() const { return m_targetFrameRate; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- int ConstantFrameRate::minNumPartsToDraw() const { return m_minNumPartsToDraw; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool ConstantFrameRate::isDistanceSortingEnabled() const { return m_enableDistanceSorting; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void ConstantFrameRate::attachRendering(Rendering* rendering) { if (rendering == m_rendering.p()) return; if (m_rendering.notNull()) { m_rendering->setRenderQueueSorter(m_previousSorter.p()); m_rendering->clearMaxNumPartsToDraw(); m_rendering->cullSettings()->enablePixelSizeCulling(m_pixelSizeCullingWasOn); m_rendering = NULL; } if (rendering) { m_previousSorter = rendering->renderQueueSorter(); m_pixelSizeCullingWasOn = rendering->cullSettings()->isPixelSizeCullingEnabled(); m_rendering = rendering; m_rendering->clearMaxNumPartsToDraw(); RenderQueueSorterTargetFramerate* rqs = new RenderQueueSorterTargetFramerate; m_rendering->setRenderQueueSorter(rqs); // Currently, we need to enable pixel size culling in order to get CeeViz to // compute the screen projected areas of the part's bounding boxes m_rendering->cullSettings()->enablePixelSizeCulling(true); m_numPartsToDraw = -1.0; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- Rendering* ConstantFrameRate::attachedRendering() { return m_rendering.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void ConstantFrameRate::adjust(double currentFrameRate) { CVF_ASSERT(m_rendering.notNull()); if (m_rendering.isNull()) return; const int maxNumPartsToDraw = 10000000; const int maxNumPartsToDistanceSort = 1000; const double lastDrawTime = (currentFrameRate > 0) ? 1.0/currentFrameRate : 999.0; const double targetDrawTime = (m_targetFrameRate > 0) ? 1.0/m_targetFrameRate : 999.0; // Initialize if this is first call if (m_numPartsToDraw < 0) { PerformanceInfo perfInfo = m_rendering->performanceInfo(); m_numPartsToDraw = static_cast(perfInfo.renderedPartsCount); if (m_numPartsToDraw < m_minNumPartsToDraw) m_numPartsToDraw = m_minNumPartsToDraw; } double numPartsToDistanceSort = 0; double absDiff = Math::abs(lastDrawTime - targetDrawTime); double fractionDiff = absDiff/targetDrawTime; if (fractionDiff > 0.05) { if (lastDrawTime > targetDrawTime) { // We need fewer parts!! // Ratio always > 1 double ratio = lastDrawTime/targetDrawTime; m_numPartsToDraw = m_numPartsToDraw/(1 + 0.5*(ratio - 1)); if (m_numPartsToDraw < m_minNumPartsToDraw) m_numPartsToDraw = m_minNumPartsToDraw; } else { // We need more parts!! // Ratio always <= 1 double ratio = lastDrawTime/targetDrawTime; m_numPartsToDraw = m_numPartsToDraw/(0.5*ratio); } // Unlikely that we'll ever exceed max of 10 mill parts if (m_numPartsToDraw > maxNumPartsToDraw) m_numPartsToDraw = maxNumPartsToDraw; } if (m_enableDistanceSorting) { numPartsToDistanceSort = 0.2*m_numPartsToDraw; if (numPartsToDistanceSort > maxNumPartsToDistanceSort) numPartsToDistanceSort = maxNumPartsToDistanceSort; } Trace::show("m_numPartsToDraw=%f numPartsToDistanceSort=%f", m_numPartsToDraw, numPartsToDistanceSort); RenderQueueSorterTargetFramerate* rqs = dynamic_cast(m_rendering->renderQueueSorter()); if (rqs) { rqs->setMaxNumPartsToDraw(static_cast(m_numPartsToDraw + 0.5)); rqs->setNumPartsToDistanceSort(static_cast(numPartsToDistanceSort + 0.5)); } m_rendering->setMaxNumPartsToDraw(static_cast(m_numPartsToDraw + 0.5)); } /* double g_targetDrawTime = 0.05; double g_numDistSorted = 1000; double g_numPartsToDRaw = 5000; void AdjustSettingsBasedOnTargetDrawTime(double lastFrameDrawTime, Rendering* rendering) { if (g_targetDrawTime <= 0) return; double absDiff = abs(lastFrameDrawTime - g_targetDrawTime); double fractionDiff = absDiff/g_targetDrawTime; if (fractionDiff > 0.05) { if (lastFrameDrawTime > g_targetDrawTime) { // Ratio always > 1 double ratio = lastFrameDrawTime/g_targetDrawTime; g_numPartsToDRaw = g_numPartsToDRaw/(1 + 0.5*(ratio - 1)); if (g_numPartsToDRaw < 10) g_numPartsToDRaw = 10; } else { // We need more parts!! // Ratio always <= 1 double ratio = lastFrameDrawTime/g_targetDrawTime; g_numPartsToDRaw = g_numPartsToDRaw/(0.5*ratio); } if (g_numPartsToDRaw > 10000000) { g_numPartsToDRaw = 10000000; } g_numDistSorted = (int)(0.2*g_numPartsToDRaw); if (g_numDistSorted < 1) g_numDistSorted = 1; } Trace::show("g_numPartsToDRaw=%f g_numDistSorted=%f", g_numPartsToDRaw, g_numDistSorted); RenderQueueSorterTargetFramerate* rqs = dynamic_cast(rendering->renderQueueSorter()); if (rqs) { rqs->setMaxNumPartsToDraw(static_cast(g_numPartsToDRaw + 0.5)); rqs->setNumPartsToDistanceSort(static_cast(g_numDistSorted + 0.5)); } rendering->setMaxNumPartsToDraw(static_cast(g_numPartsToDRaw)); } */ } // namespace cvf