Files
ResInsight/VisualizationModules/LibViewing/cvfConstantFrameRate.cpp

283 lines
9.2 KiB
C++
Raw Normal View History

//##################################################################################################
//
// 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 <<http://www.gnu.org/licenses/gpl.html>>
// 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<double>(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<RenderQueueSorterTargetFramerate*>(m_rendering->renderQueueSorter());
if (rqs)
{
rqs->setMaxNumPartsToDraw(static_cast<uint>(m_numPartsToDraw + 0.5));
rqs->setNumPartsToDistanceSort(static_cast<uint>(numPartsToDistanceSort + 0.5));
}
m_rendering->setMaxNumPartsToDraw(static_cast<size_t>(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<RenderQueueSorterTargetFramerate*>(rendering->renderQueueSorter());
if (rqs)
{
rqs->setMaxNumPartsToDraw(static_cast<size_t>(g_numPartsToDRaw + 0.5));
rqs->setNumPartsToDistanceSort(static_cast<size_t>(g_numDistSorted + 0.5));
}
rendering->setMaxNumPartsToDraw(static_cast<size_t>(g_numPartsToDRaw));
}
*/
} // namespace cvf