Initial work on performance measuring

This commit is contained in:
Alexander Bock
2014-12-09 01:41:42 +01:00
parent 31191106fc
commit 90eac194dc
8 changed files with 204 additions and 39 deletions

View File

@@ -27,6 +27,10 @@
#include <openspace/scripting/scriptengine.h>
namespace ghoul {
class SharedMemory;
}
namespace openspace {
// Forward declare to minimize dependencies
@@ -59,6 +63,8 @@ public:
void takeScreenshot();
void toggleVisualizeABuffer(bool b);
void setPerformanceMeasurements(bool performanceMeasurements);
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
@@ -72,8 +78,9 @@ public:
*/
static scripting::ScriptEngine::LuaLibrary luaLibrary();
private:
void storePerformanceMeasurements();
Camera* _mainCamera;
SceneGraph* _sceneGraph;
ABuffer* _abuffer;
@@ -83,6 +90,9 @@ private:
bool _showScreenLog;
bool _takeScreenshot;
bool _doPerformanceMeasurements;
ghoul::SharedMemory* _performanceMemory;
void generateGlslConfig();
bool _visualizeABuffer;

View File

@@ -35,7 +35,6 @@
#include <openspace/util/updatestructures.h>
#include <openspace/scripting/scriptengine.h>
// ghoul includes
#include <ghoul/opengl/programobject.h>
#include <ghoul/misc/dictionary.h>
@@ -44,6 +43,8 @@ namespace openspace {
class SceneGraphNode;
// Notifications:
// SceneGraphFinishedLoading
class SceneGraph {
public:
// constructors & destructor
@@ -99,6 +100,8 @@ public:
*/
SceneGraphNode* sceneGraphNode(const std::string& name) const;
std::vector<SceneGraphNode*> allSceneGraphNodes() const;
/**
* Returns the Lua library that contains all Lua functions available to change the
* scene graph. The functions contained are

View File

@@ -44,9 +44,14 @@ namespace openspace {
class SceneGraphNode : public properties::PropertyOwner {
public:
struct PerformanceRecord {
long long renderTime; // time in ns
long long updateTimeRenderable; // time in ns
long long updateTimeEphemeris; // time in ns
};
static std::string RootNodeName;
// constructors & destructor
SceneGraphNode();
~SceneGraphNode();
@@ -55,12 +60,10 @@ public:
bool initialize();
bool deinitialize();
// essential
void update(const UpdateData& data);
void evaluate(const Camera* camera, const psc& parentPosition = psc());
void render(const RenderData& data);
// set & get
void addNode(SceneGraphNode* child);
void setParent(SceneGraphNode* parent);
@@ -70,7 +73,6 @@ public:
SceneGraphNode* parent() const;
const std::vector<SceneGraphNode*>& children() const;
// bounding sphere
PowerScaledScalar calculateBoundingSphere();
PowerScaledScalar boundingSphere() const;
@@ -78,27 +80,26 @@ public:
void print() const;
// renderable
const PerformanceRecord& performanceRecord() const { return _performanceRecord; }
void setRenderable(Renderable* renderable);
const Renderable* renderable() const;
Renderable* renderable();
private:
// essential
std::vector<SceneGraphNode*> _children;
bool sphereInsideFrustum(const psc s_pos, const PowerScaledScalar& s_rad, const Camera* camera);
std::vector<SceneGraphNode*> _children;
SceneGraphNode* _parent;
Ephemeris* _ephemeris;
// renderable
PerformanceRecord _performanceRecord;
Renderable* _renderable;
bool _renderableVisible;
// bounding sphere
bool _boundingSphereVisible;
PowerScaledScalar _boundingSphere;
// private helper methods
bool sphereInsideFrustum(const psc s_pos, const PowerScaledScalar& s_rad, const Camera* camera);
};
} // namespace openspace

View File

@@ -33,12 +33,13 @@ namespace openspace {
struct UpdateData {
double time;
double delta;
bool doPerformanceMeasurement;
};
struct RenderData {
const Camera& camera;
psc position;
bool doPerformanceMeasurement;
};
}

View File

@@ -40,6 +40,7 @@
#include <openspace/util/syncbuffer.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/lua/lua_helper.h>
#include <ghoul/misc/sharedmemory.h>
#include <ghoul/io/texture/texturereader.h>
#ifdef GHOUL_USE_DEVIL
@@ -68,6 +69,9 @@
namespace {
const std::string _loggerCat = "RenderEngine";
const std::string PerformanceMeasurementSharedData =
"OpenSpacePerformanceMeasurementSharedData";
}
namespace openspace {
@@ -103,6 +107,21 @@ int visualizeABuffer(lua_State* L) {
return 0;
}
/**
* \ingroup LuaScripts
* visualizeABuffer(bool):
* Toggle the visualization of the ABuffer
*/
int setPerformanceMeasurement(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
bool b = lua_toboolean(L, -1) != 0;
OsEng.renderEngine().setPerformanceMeasurements(b);
return 0;
}
} // namespace luascriptfunctions
@@ -114,6 +133,8 @@ RenderEngine::RenderEngine()
, _showInfo(true)
, _showScreenLog(true)
, _takeScreenshot(false)
, _doPerformanceMeasurements(false)
, _performanceMemory(nullptr)
, _visualizeABuffer(false)
, _visualizer(nullptr)
{
@@ -124,6 +145,10 @@ RenderEngine::~RenderEngine()
delete _mainCamera;
if (_visualizer)
delete _visualizer;
delete _performanceMemory;
if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData))
ghoul::SharedMemory::remove(PerformanceMeasurementSharedData);
}
bool RenderEngine::initialize()
@@ -266,7 +291,11 @@ void RenderEngine::postSynchronizationPreDraw()
UpdateData a = { Time::ref().currentTime(), Time::ref().deltaTime() };
// update and evaluate the scene starting from the root node
_sceneGraph->update(a);
_sceneGraph->update({
Time::ref().currentTime(),
Time::ref().deltaTime(),
_doPerformanceMeasurements
});
_sceneGraph->evaluate(_mainCamera);
// clear the abuffer before rendering the scene
@@ -320,7 +349,11 @@ void RenderEngine::render()
// render the scene starting from the root node
if (!_visualizeABuffer) {
_abuffer->preRender();
_sceneGraph->render({ *_mainCamera, psc() });
_sceneGraph->render({
*_mainCamera,
psc(),
_doPerformanceMeasurements
});
_abuffer->postRender();
glEnable(GL_BLEND);
@@ -442,6 +475,9 @@ void RenderEngine::postDraw() {
sgct::Engine::instance()->takeScreenshot();
_takeScreenshot = false;
}
if (_doPerformanceMeasurements)
storePerformanceMeasurements();
}
void RenderEngine::takeScreenshot() {
@@ -544,9 +580,93 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() {
&luascriptfunctions::visualizeABuffer,
"bool",
"Toggles the visualization of the ABuffer"
},
{
"setPerformanceMeasurement",
&luascriptfunctions::setPerformanceMeasurement,
"bool",
"Sets the performance measurements"
}
},
};
}
void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) {
_doPerformanceMeasurements = performanceMeasurements;
}
void RenderEngine::storePerformanceMeasurements() {
const int nValues = 1000;
const int lengthName = 256;
const int maxValues = 50;
struct PerformanceLayout {
int32_t nValuesPerEntry;
int32_t nEntries;
int32_t maxNameLength;
int32_t maxEntries;
struct PerformanceLayoutEntry {
char name[lengthName];
int64_t renderTime[nValues];
int64_t updateRenderable[nValues];
int64_t updateEphemeris[nValues];
int32_t currentRenderTime;
int32_t currentUpdateRenderable;
int32_t currentUpdateEphemeris;
};
PerformanceLayoutEntry entries[maxValues];
};
const int nNodes = sceneGraph()->allSceneGraphNodes().size();
if (!_performanceMemory) {
// Compute the total size
const int totalSize = 4 * sizeof(int32_t) +
maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry);
LINFO("Create shared memory of size '" << totalSize << "' bytes");
ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize);
_performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData);
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(_performanceMemory->pointer());
layout->nValuesPerEntry = nValues;
layout->nEntries = nNodes;
layout->maxNameLength = lengthName;
layout->maxEntries = maxValues;
memset(layout->entries, 0, maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry));
for (int i = 0; i < nNodes; ++i) {
SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i];
memset(layout->entries[i].name, 0, lengthName);
strcpy(layout->entries[i].name, node->name().c_str());
layout->entries[i].currentRenderTime = 0;
layout->entries[i].currentUpdateRenderable = 0;
layout->entries[i].currentUpdateEphemeris = 0;
}
}
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(_performanceMemory->pointer());
_performanceMemory->acquireLock();
for (int i = 0; i < nNodes; ++i) {
SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i];
SceneGraphNode::PerformanceRecord r = node->performanceRecord();
PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i];
entry.renderTime[entry.currentRenderTime] = r.renderTime;
entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris;
entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable;
entry.currentRenderTime = (entry.currentRenderTime + 1) % nValues;
entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % nValues;
entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % nValues;
}
_performanceMemory->releaseLock();
}
} // namespace openspace

View File

@@ -22,7 +22,6 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
// open space includes
#include <openspace/scenegraph/scenegraph.h>
#include <openspace/scenegraph/scenegraphnode.h>
#include <openspace/engine/openspaceengine.h>
@@ -34,7 +33,6 @@
#include <openspace/abuffer/abuffer.h>
#include <openspace/engine/gui.h>
// ghoul includes
#include "ghoul/logging/logmanager.h"
#include "ghoul/opengl/programobject.h"
#include "ghoul/io/texture/texturereader.h"
@@ -526,6 +524,10 @@ SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const {
return it->second;
}
std::vector<SceneGraphNode*> SceneGraph::allSceneGraphNodes() const {
return _nodes;
}
scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() {
return {
"",

View File

@@ -34,6 +34,7 @@
#include <ghoul/opengl/shadermanager.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/shaderobject.h>
#include <ghoul/misc/highresclock.h>
#include <openspace/scenegraph/staticephemeris.h>
#include <openspace/engine/openspaceengine.h>
@@ -128,6 +129,7 @@ SceneGraphNode::SceneGraphNode()
, _renderable(nullptr)
, _renderableVisible(false)
, _boundingSphereVisible(false)
, _performanceRecord({0, 0, 0})
{
}
@@ -170,17 +172,39 @@ bool SceneGraphNode::deinitialize()
return true;
}
// essential
void SceneGraphNode::update(const UpdateData& data)
{
if (_ephemeris)
_ephemeris->update(data);
if (_renderable && _renderable->isReady())
_renderable->update(data);
void SceneGraphNode::update(const UpdateData& data) {
if (_ephemeris) {
if (data.doPerformanceMeasurement) {
glFinish();
ghoul::HighResClock::time_point start = ghoul::HighResClock::now();
_ephemeris->update(data);
glFinish();
ghoul::HighResClock::time_point end = ghoul::HighResClock::now();
_performanceRecord.updateTimeEphemeris = (end - start).count();
}
else
_ephemeris->update(data);
}
if (_renderable && _renderable->isReady()) {
if (data.doPerformanceMeasurement) {
glFinish();
ghoul::HighResClock::time_point start = ghoul::HighResClock::now();
_renderable->update(data);
glFinish();
ghoul::HighResClock::time_point end = ghoul::HighResClock::now();
_performanceRecord.updateTimeRenderable = (end - start).count();
}
else
_renderable->update(data);
}
}
void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition)
{
void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
//const psc thisPosition = parentPosition + _ephemeris->position();
//const psc camPos = camera->position();
//const psc toCamera = thisPosition - camPos;
@@ -221,20 +245,24 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition)
}
}
void SceneGraphNode::render(const RenderData& data)
{
void SceneGraphNode::render(const RenderData& data) {
const psc thisPosition = data.position + _ephemeris->position();
RenderData newData = {data.camera, thisPosition};
// check if camera is outside the node boundingsphere
/*if (!_boundingSphereVisible) {
return;
}*/
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
if (_renderableVisible && _renderable->isVisible() && _renderable->isReady()) {
// LDEBUG("Render");
_renderable->render(newData);
if (data.doPerformanceMeasurement) {
glFinish();
ghoul::HighResClock::time_point start = ghoul::HighResClock::now();
_renderable->render(newData);
glFinish();
ghoul::HighResClock::time_point end = ghoul::HighResClock::now();
_performanceRecord.renderTime = (end - start).count();
}
else
_renderable->render(newData);
}
// evaluate all the children, tail-recursive function(?)