From 442caf6961546a0754340c24d8e194d83291616a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 24 Jan 2011 20:45:02 +0000 Subject: [PATCH] Added osggraphicscost example as a base of for developing and testing the new osgUtil::GraphicsCostEsimator class. --- examples/CMakeLists.txt | 1 + examples/osggraphicscost/CMakeLists.txt | 4 + examples/osggraphicscost/osggraphicscost.cpp | 307 +++++++++++++++++++ 3 files changed, 312 insertions(+) create mode 100644 examples/osggraphicscost/CMakeLists.txt create mode 100644 examples/osggraphicscost/osggraphicscost.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f10decf89..7934331f3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -61,6 +61,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osglogicop) ADD_SUBDIRECTORY(osglogo) ADD_SUBDIRECTORY(osggpx) + ADD_SUBDIRECTORY(osggraphicscost) ADD_SUBDIRECTORY(osgmanipulator) ADD_SUBDIRECTORY(osgmovie) ADD_SUBDIRECTORY(osgmultiplerendertargets) diff --git a/examples/osggraphicscost/CMakeLists.txt b/examples/osggraphicscost/CMakeLists.txt new file mode 100644 index 000000000..4086ffdb3 --- /dev/null +++ b/examples/osggraphicscost/CMakeLists.txt @@ -0,0 +1,4 @@ +SET(TARGET_SRC osggraphicscost.cpp) + +#### end var setup ### +SETUP_EXAMPLE(osggraphicscost) diff --git a/examples/osggraphicscost/osggraphicscost.cpp b/examples/osggraphicscost/osggraphicscost.cpp new file mode 100644 index 000000000..5635961cb --- /dev/null +++ b/examples/osggraphicscost/osggraphicscost.cpp @@ -0,0 +1,307 @@ +/* OpenSceneGraph example, osgterrain. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + + +#include +#include + +#include +#include +#include + + +#include +#include +#include + +namespace osgUtil +{ + + +struct CostFunction1D +{ + virtual double operator() (unsigned int input) = 0; +}; + +struct LinearCostFunction1D : public CostFunction1D +{ + LinearCostFunction1D(double cost0, double dcost_di): + _cost0(cost0), + _dcost_di(dcost_di) {} + virtual double operator() (unsigned int input) { return _cost0 + _dcost_di * double(input); } + double _cost0; + double _dcost_di; +}; + +struct ClampedLinearCostFunction1D : public CostFunction1D +{ + ClampedLinearCostFunction1D(double cost0, double dcost_di, unsigned int min_input): + _cost0(cost0), + _dcost_di(dcost_di), + _min_input(min_input) {} + + virtual double operator() (unsigned int input) { return _cost0 + _dcost_di * double(input<=_min_input ? 0u : input-_min_input); } + double _cost0; + double _dcost_di; + unsigned int _min_input; +}; + +/** Pair of double representing CPU and GPU times in seconds as first and second elements in std::pair. */ +typedef std::pair CostPair; + + +class GeometryCostEstimator : public osg::Referenced +{ +public: + CostPair estimateCompileCost(const osg::Geometry* geometry) const; + CostPair estimateDrawCost(const osg::Geometry* geometry) const; +}; + +class TextureCostEstimator : public osg::Referenced +{ +public: + CostPair estimateCompileCost(const osg::Texture* texture) const; + CostPair estimateDrawCost(const osg::Texture* texture) const; +}; + + +class ProgramCostEstimator : public osg::Referenced +{ +public: + CostPair estimateCompileCost(const osg::Program* program) const; + CostPair estimateDrawCost(const osg::Program* program) const; +}; + +class GraphicsCostEstimator : public osg::Referenced +{ +public: + GraphicsCostEstimator(); + + /** set defaults for computing the costs.*/ + void setDefaults(); + + /** calibrate the costs of various compile and draw operations */ + void calibrate(osg::RenderInfo& renderInfo); + + CostPair estimateCompileCost(const osg::Geometry* geometry) const { return _geometryEstimator->estimateCompileCost(geometry); } + CostPair estimateDrawCost(const osg::Geometry* geometry) const { return _geometryEstimator->estimateDrawCost(geometry); } + + CostPair estimateCompileCost(const osg::Texture* texture) const { return _textureEstimator->estimateDrawCost(texture); } + CostPair estimateDrawCost(const osg::Texture* texture) const { return _textureEstimator->estimateDrawCost(texture); } + + CostPair estimateCompileCost(const osg::Program* program) const { return _programEstimator->estimateCompileCost(program); } + CostPair estimateDrawCost(const osg::Program* program) const { return _programEstimator->estimateDrawCost(program); } + + CostPair estimateCompileCost(const osg::Node* node) const; + CostPair estimateDrawCost(const osg::Node* node) const; + +protected: + + virtual ~GraphicsCostEstimator(); + + osg::ref_ptr _geometryEstimator; + osg::ref_ptr _textureEstimator; + osg::ref_ptr _programEstimator; + +}; + + + +CostPair GeometryCostEstimator::estimateCompileCost(const osg::Geometry* geometry) const +{ + return CostPair(1.0,2.0); +} + +CostPair GeometryCostEstimator::estimateDrawCost(const osg::Geometry* geometry) const +{ + return CostPair(0.0,0.0); +} + +CostPair TextureCostEstimator::estimateCompileCost(const osg::Texture* texture) const +{ + return CostPair(0.0,0.0); +} + +CostPair TextureCostEstimator::estimateDrawCost(const osg::Texture* texture) const +{ + return CostPair(0.0,0.0); +} + +CostPair ProgramCostEstimator::estimateCompileCost(const osg::Program* program) const +{ + return CostPair(0.0,0.0); +} + +CostPair ProgramCostEstimator::estimateDrawCost(const osg::Program* program) const +{ + return CostPair(0.0,0.0); +} + + +GraphicsCostEstimator::GraphicsCostEstimator() +{ + setDefaults(); +} + +GraphicsCostEstimator::~GraphicsCostEstimator() +{ +} + +void GraphicsCostEstimator::setDefaults() +{ + OSG_NOTICE<<"GraphicsCostEstimator::setDefaults()"<getStateSet()); + osg::Geometry* geometry = geode.getDrawable(i)->asGeometry(); + if (geometry) apply(geometry); + } + } + + void apply(osg::StateSet* stateset) + { + if (!stateset) return; + if (_statesets.count(stateset)) return; + _statesets.insert(stateset); + + const osg::Program* program = dynamic_cast(stateset->getAttribute(osg::StateAttribute::PROGRAM)); + if (program) + { + CostPair cost = _gce->estimateCompileCost(program); + _costs.first += cost.first; + _costs.second += cost.second; + } + + for(unsigned int i=0; igetNumTextureAttributeLists(); ++i) + { + const osg::Texture* texture = dynamic_cast(stateset->getTextureAttribute(i, osg::StateAttribute::TEXTURE)); + CostPair cost = _gce->estimateCompileCost(texture); + _costs.first += cost.first; + _costs.second += cost.second; + } + } + + void apply(osg::Geometry* geometry) + { + if (!geometry) return; + if (_geometries.count(geometry)) return; + _geometries.insert(geometry); + + CostPair cost = _gce->estimateCompileCost(geometry); + _costs.first += cost.first; + _costs.second += cost.second; + } + + + typedef std::set StateSets; + typedef std::set Textures; + typedef std::set Geometries; + + const GraphicsCostEstimator* _gce; + StateSets _statesets; + Textures _textures; + Geometries _geometries; + CostPair _costs; +}; + +CostPair GraphicsCostEstimator::estimateCompileCost(const osg::Node* node) const +{ + if (!node) return CostPair(0.0,0.0); + CollectCompileCosts ccc(this); + const_cast(node)->accept(ccc); + return ccc._costs; +} + +CostPair GraphicsCostEstimator::estimateDrawCost(const osg::Node* node) const +{ + return CostPair(0.0,0.0); +} + +} + + +class CalibrateCostEsimator : public osg::GraphicsOperation +{ +public: + + CalibrateCostEsimator(osgUtil::GraphicsCostEstimator* gce): + osg::GraphicsOperation("CalbirateCostEstimator",false), + _gce(gce) {} + + virtual void operator () (osg::GraphicsContext* context) + { + osg::RenderInfo renderInfo(context->getState(), 0); + _gce->calibrate(renderInfo); + } + + osg::ref_ptr _gce; + +}; + + +int main(int argc, char** argv) +{ + osg::ArgumentParser arguments(&argc, argv); + + // construct the viewer. + osgViewer::Viewer viewer(arguments); + + + osg::ref_ptr node = osgDB::readNodeFiles(arguments); + if (!node) return 0; + + osg::ref_ptr gce = new osgUtil::GraphicsCostEstimator; + + viewer.setSceneData(node.get()); + + viewer.realize(); + + osgUtil::CostPair compileCost = gce->estimateCompileCost(node.get()); + osgUtil::CostPair drawCost = gce->estimateDrawCost(node.get()); + + OSG_NOTICE<<"estimateCompileCost("<getName()<<"), CPU="<getName()<<"), CPU="<