Merge pull request #5044 from Atlante45/lod

Team Teaching - Render stats work with engine
This commit is contained in:
Brad Hefta-Gaub 2015-06-05 07:47:33 -07:00
commit 5bace58a55
13 changed files with 91 additions and 197 deletions

View file

@ -969,6 +969,7 @@ void Application::paintGL() {
OculusManager::endFrameTiming();
}
_frameCount++;
Stats::getInstance()->setRenderDetails(renderArgs._details);
}
void Application::runTests() {
@ -3485,7 +3486,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
_main3DScene->processPendingChangesQueue();
}
// FOr now every frame pass the renderCOntext
// For now every frame pass the renderContext
{
PerformanceTimer perfTimer("EngineRun");
render::RenderContext renderContext;
@ -3522,7 +3523,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems);
sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems);
}

View file

@ -74,7 +74,6 @@ namespace render {
if (avatarPtr->isInitialized() && args) {
avatarPtr->render(args, Application::getInstance()->getCamera()->getPosition());
args->_elementsTouched++;
}
}
}

View file

@ -467,31 +467,30 @@ void Stats::display(
horizontalOffset += 5;
// Model/Entity render details
EntityTreeRenderer* entities = Application::getInstance()->getEntities();
octreeStats.str("");
octreeStats << "Entity Items rendered: " << entities->getItemsRendered()
<< " / Out of view:" << entities->getItemsOutOfView()
<< " / Too small:" << entities->getItemsTooSmall();
octreeStats << "Triangles: " << _renderDetails._trianglesRendered
<< " / Quads:" << _renderDetails._quadsRendered
<< " / Material Switches:" << _renderDetails._materialSwitches;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
if (_expanded) {
octreeStats.str("");
octreeStats << " Meshes rendered: " << entities->getMeshesRendered()
<< " / Out of view:" << entities->getMeshesOutOfView()
<< " / Too small:" << entities->getMeshesTooSmall();
octreeStats << " Mesh Parts Rendered Opaque: " << _renderDetails._opaque._rendered
<< " / Translucent:" << _renderDetails._translucent._rendered;
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
octreeStats.str("");
octreeStats << " Triangles: " << entities->getTrianglesRendered()
<< " / Quads:" << entities->getQuadsRendered()
<< " / Material Switches:" << entities->getMaterialSwitches();
octreeStats << " Opaque considered: " << _renderDetails._opaque._considered
<< " / Out of view:" << _renderDetails._opaque._outOfView
<< " / Too small:" << _renderDetails._opaque._tooSmall;
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
octreeStats.str("");
octreeStats << " Mesh Parts Rendered Opaque: " << entities->getOpaqueMeshPartsRendered()
<< " / Translucent:" << entities->getTranslucentMeshPartsRendered();
octreeStats << " Translucent considered: " << _renderDetails._translucent._considered
<< " / Out of view:" << _renderDetails._translucent._outOfView
<< " / Too small:" << _renderDetails._translucent._tooSmall;
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}

View file

@ -14,7 +14,7 @@
#include <QObject>
#include <NodeList.h>
#include <RenderArgs.h>
class Stats: public QObject {
Q_OBJECT
@ -35,6 +35,8 @@ public:
int inKbitsPerSecond, int outKbitsPerSecond, int voxelPacketsToProcess);
bool includeTimingRecord(const QString& name);
void setRenderDetails(const RenderDetails& details) { _renderDetails = details; }
private:
static Stats* _sharedInstance;
@ -51,6 +53,7 @@ private:
int _lastHorizontalOffset;
RenderDetails _renderDetails;
};
#endif // hifi_Stats_h

View file

@ -55,8 +55,6 @@ namespace render {
}
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
if (args) {
args->_elementsTouched++;
glPushMatrix();
if (overlay->getAnchor() == Overlay::MY_AVATAR) {
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();

View file

@ -508,24 +508,6 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) {
applyZonePropertiesToScene(_bestZone);
_tree->unlock();
// stats...
_meshesConsidered = renderArgs->_meshesConsidered;
_meshesRendered = renderArgs->_meshesRendered;
_meshesOutOfView = renderArgs->_meshesOutOfView;
_meshesTooSmall = renderArgs->_meshesTooSmall;
_elementsTouched = renderArgs->_elementsTouched;
_itemsRendered = renderArgs->_itemsRendered;
_itemsOutOfView = renderArgs->_itemsOutOfView;
_itemsTooSmall = renderArgs->_itemsTooSmall;
_materialSwitches = renderArgs->_materialSwitches;
_trianglesRendered = renderArgs->_trianglesRendered;
_quadsRendered = renderArgs->_quadsRendered;
_translucentMeshPartsRendered = renderArgs->_translucentMeshPartsRendered;
_opaqueMeshPartsRendered = renderArgs->_opaqueMeshPartsRendered;
}
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
}
@ -649,7 +631,6 @@ void EntityTreeRenderer::renderProxies(EntityItemPointer entity, RenderArgs* arg
}
void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) {
args->_elementsTouched++;
// actually render it here...
// we need to iterate the actual entityItems of the element
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);

View file

@ -30,7 +30,6 @@ namespace render {
}
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) {
if (args) {
args->_elementsTouched++;
if (payload && payload->entity && payload->entity->getVisible()) {
payload->entity->render(args);
}

View file

@ -160,7 +160,6 @@ namespace render {
}
template <> void payloadRender(const RenderableModelEntityItemMeta::Pointer& payload, RenderArgs* args) {
if (args) {
args->_elementsTouched++;
if (payload && payload->entity) {
payload->entity->render(args);
}

View file

@ -171,23 +171,6 @@ void OctreeRenderer::render(RenderArgs* renderArgs) {
_tree->recurseTreeWithOperation(renderOperation, renderArgs);
_tree->unlock();
}
_meshesConsidered = renderArgs->_meshesConsidered;
_meshesRendered = renderArgs->_meshesRendered;
_meshesOutOfView = renderArgs->_meshesOutOfView;
_meshesTooSmall = renderArgs->_meshesTooSmall;
_elementsTouched = renderArgs->_elementsTouched;
_itemsRendered = renderArgs->_itemsRendered;
_itemsOutOfView = renderArgs->_itemsOutOfView;
_itemsTooSmall = renderArgs->_itemsTooSmall;
_materialSwitches = renderArgs->_materialSwitches;
_trianglesRendered = renderArgs->_trianglesRendered;
_quadsRendered = renderArgs->_quadsRendered;
_translucentMeshPartsRendered = renderArgs->_translucentMeshPartsRendered;
_opaqueMeshPartsRendered = renderArgs->_opaqueMeshPartsRendered;
}
void OctreeRenderer::clear() {

View file

@ -60,23 +60,6 @@ public:
/// clears the tree
virtual void clear();
int getElementsTouched() const { return _elementsTouched; }
int getItemsRendered() const { return _itemsRendered; }
int getItemsOutOfView() const { return _itemsOutOfView; }
int getItemsTooSmall() const { return _itemsTooSmall; }
int getMeshesConsidered() const { return _meshesConsidered; }
int getMeshesRendered() const { return _meshesRendered; }
int getMeshesOutOfView() const { return _meshesOutOfView; }
int getMeshesTooSmall() const { return _meshesTooSmall; }
int getMaterialSwitches() const { return _materialSwitches; }
int getTrianglesRendered() const { return _trianglesRendered; }
int getQuadsRendered() const { return _quadsRendered; }
int getTranslucentMeshPartsRendered() const { return _translucentMeshPartsRendered; }
int getOpaqueMeshPartsRendered() const { return _opaqueMeshPartsRendered; }
protected:
virtual Octree* createTree() = 0;
@ -84,23 +67,6 @@ protected:
Octree* _tree;
bool _managedTree;
ViewFrustum* _viewFrustum;
int _elementsTouched;
int _itemsRendered;
int _itemsOutOfView;
int _itemsTooSmall;
int _meshesConsidered;
int _meshesRendered;
int _meshesOutOfView;
int _meshesTooSmall;
int _materialSwitches;
int _trianglesRendered;
int _quadsRendered;
int _translucentMeshPartsRendered;
int _opaqueMeshPartsRendered;
};
#endif // hifi_OctreeRenderer_h

View file

@ -847,7 +847,6 @@ namespace render {
}
template <> void payloadRender(const TransparentMeshPart::Pointer& payload, RenderArgs* args) {
if (args) {
args->_elementsTouched++;
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, true);
}
}
@ -882,7 +881,6 @@ namespace render {
}
template <> void payloadRender(const OpaqueMeshPart::Pointer& payload, RenderArgs* args) {
if (args) {
args->_elementsTouched++;
return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, false);
}
}
@ -1149,11 +1147,6 @@ bool Model::renderCore(RenderArgs* args, float alpha) {
// restore all the default material settings
_viewState->setupWorldLight();
if (args) {
args->_translucentMeshPartsRendered = translucentMeshPartsRendered;
args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered;
}
#ifdef WANT_DEBUG_MESHBOXES
renderDebugMeshBoxes();
#endif
@ -2044,7 +2037,6 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
batch.setViewTransform(_transforms[0]);
}
AABox Model::getPartBounds(int meshIndex, int partIndex) {
if (!_calculatedMeshPartBoxesValid) {
recalculateMeshBoxes(true);
@ -2103,8 +2095,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
args, locations);
int meshPartsRendered = 0;
updateVisibleJointStates();
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
@ -2219,7 +2209,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
}
if (args) {
args->_materialSwitches++;
args->_details._materialSwitches++;
}
// HACK: For unknown reason (yet!) this code that should be assigned only if the material changes need to be called for every
@ -2229,16 +2219,14 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
float emissiveOffset = part.emissiveParams.x;
float emissiveScale = part.emissiveParams.y;
GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale);
Texture* emissiveMap = networkPart.emissiveTexture.data();
batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ?
textureCache->getWhiteTexture() : emissiveMap->getGPUTexture());
textureCache->getWhiteTexture() : emissiveMap->getGPUTexture());
}
}
}
meshPartsRendered++;
qint64 offset = _calculatedMeshPartOffet[QPair<int,int>(meshIndex, partIndex)];
if (part.quadIndices.size() > 0) {
@ -2254,8 +2242,8 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
if (args) {
const int INDICES_PER_TRIANGLE = 3;
const int INDICES_PER_QUAD = 4;
args->_trianglesRendered += part.triangleIndices.size() / INDICES_PER_TRIANGLE;
args->_quadsRendered += part.quadIndices.size() / INDICES_PER_QUAD;
args->_details._trianglesRendered += part.triangleIndices.size() / INDICES_PER_TRIANGLE;
args->_details._quadsRendered += part.quadIndices.size() / INDICES_PER_QUAD;
}
}
@ -2447,8 +2435,6 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
// if we got here, then check to see if this mesh is in view
if (args) {
bool shouldRender = true;
args->_meshesConsidered++;
if (args->_viewFrustum) {
shouldRender = forceRenderMeshes ||
@ -2458,17 +2444,10 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
distance);
if (!shouldRender) {
args->_meshesTooSmall++;
}
} else {
args->_meshesOutOfView++;
}
}
if (shouldRender) {
args->_meshesRendered++;
} else {
if (!shouldRender) {
continue; // skip this mesh
}
}
@ -2559,11 +2538,6 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
batch.setUniformTexture(locations->specularTextureUnit, !specularMap ?
textureCache->getWhiteTexture() : specularMap->getGPUTexture());
}
if (args) {
args->_materialSwitches++;
}
}
// HACK: For unkwon reason (yet!) this code that should be assigned only if the material changes need to be called for every
@ -2594,12 +2568,6 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
offset += part.triangleIndices.size() * sizeof(int);
}
if (args) {
const int INDICES_PER_TRIANGLE = 3;
const int INDICES_PER_QUAD = 4;
args->_trianglesRendered += part.triangleIndices.size() / INDICES_PER_TRIANGLE;
args->_quadsRendered += part.quadIndices.size() / INDICES_PER_QUAD;
}
}
}

View file

@ -63,7 +63,10 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args;
auto renderDetails = renderContext->args->_details._item;
renderDetails->_considered += inItems.size();
// Culling / LOD
for (auto id : inItems) {
auto item = scene->getItem(id);
@ -71,7 +74,6 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
if (bound.isNull()) {
outItems.push_back(id); // One more Item to render
args->_itemsRendered++;
continue;
}
@ -80,17 +82,16 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont
bool outOfView = args->_viewFrustum->boxInFrustum(bound) == ViewFrustum::OUTSIDE;
if (!outOfView) {
bool bigEnoughToRender = (args->_shouldRender) ? args->_shouldRender(args, bound) : true;
if (bigEnoughToRender) {
outItems.push_back(id); // One more Item to render
args->_itemsRendered++;
} else {
args->_itemsTooSmall++;
renderDetails->_tooSmall++;
}
} else {
args->_itemsOutOfView++;
renderDetails->_outOfView++;
}
}
renderDetails->_rendered += outItems.size();
}
struct ItemBound {
@ -227,6 +228,7 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
// render opaques
auto& scene = sceneContext->_scene;
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape());
auto& renderDetails = renderContext->args->_details;
ItemIDs inItems;
inItems.reserve(items.size());
@ -239,7 +241,9 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer
ItemIDs culledItems;
if (renderContext->_cullOpaque) {
renderDetails.pointTo(RenderDetails::OPAQUE_ITEM);
cullItems(sceneContext, renderContext, renderedItems, culledItems);
renderDetails.pointTo(RenderDetails::OTHER_ITEM);
renderedItems = culledItems;
}
@ -290,6 +294,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
// render transparents
auto& scene = sceneContext->_scene;
auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape());
auto& renderDetails = renderContext->args->_details;
ItemIDs inItems;
inItems.reserve(items.size());
@ -302,7 +307,9 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo
ItemIDs culledItems;
if (renderContext->_cullTransparent) {
renderDetails.pointTo(RenderDetails::TRANSLUCENT_ITEM);
cullItems(sceneContext, renderContext, inItems, culledItems);
renderDetails.pointTo(RenderDetails::OTHER_ITEM);
renderedItems = culledItems;
}

View file

@ -22,6 +22,46 @@ class Batch;
class Context;
}
class RenderDetails {
public:
enum Type {
OPAQUE_ITEM,
TRANSLUCENT_ITEM,
OTHER_ITEM
};
struct Item {
int _considered = 0;
int _rendered = 0;
int _outOfView = 0;
int _tooSmall = 0;
};
int _materialSwitches = 0;
int _trianglesRendered = 0;
int _quadsRendered = 0;
Item _opaque;
Item _translucent;
Item _other;
Item* _item = &_other;
void pointTo(Type type) {
switch (type) {
case OPAQUE_ITEM:
_item = &_opaque;
break;
case TRANSLUCENT_ITEM:
_item = &_translucent;
break;
case OTHER_ITEM:
_item = &_other;
break;
}
}
};
class RenderArgs {
public:
typedef std::function<bool(const RenderArgs* args, const AABox& bounds)> ShoudRenderFunctor;
@ -45,24 +85,7 @@ public:
RenderSide renderSide = MONO,
DebugFlags debugFlags = RENDER_DEBUG_NONE,
gpu::Batch* batch = nullptr,
ShoudRenderFunctor shouldRender = nullptr,
int elementsTouched = 0,
int itemsRendered = 0,
int itemsOutOfView = 0,
int itemsTooSmall = 0,
int meshesConsidered = 0,
int meshesRendered = 0,
int meshesOutOfView = 0,
int meshesTooSmall = 0,
int materialSwitches = 0,
int trianglesRendered = 0,
int quadsRendered = 0,
int translucentMeshPartsRendered = 0,
int opaqueMeshPartsRendered = 0) :
ShoudRenderFunctor shouldRender = nullptr) :
_context(context),
_renderer(renderer),
_viewFrustum(viewFrustum),
@ -72,53 +95,21 @@ public:
_renderSide(renderSide),
_debugFlags(debugFlags),
_batch(batch),
_shouldRender(shouldRender),
_elementsTouched(elementsTouched),
_itemsRendered(itemsRendered),
_itemsOutOfView(itemsOutOfView),
_itemsTooSmall(itemsTooSmall),
_meshesConsidered(meshesConsidered),
_meshesRendered(meshesRendered),
_meshesOutOfView(meshesOutOfView),
_meshesTooSmall(meshesTooSmall),
_materialSwitches(materialSwitches),
_trianglesRendered(trianglesRendered),
_quadsRendered(quadsRendered),
_translucentMeshPartsRendered(translucentMeshPartsRendered),
_opaqueMeshPartsRendered(opaqueMeshPartsRendered) {
_shouldRender(shouldRender) {
}
gpu::Context* _context;
OctreeRenderer* _renderer;
ViewFrustum* _viewFrustum;
float _sizeScale;
int _boundaryLevelAdjust;
RenderMode _renderMode;
RenderSide _renderSide;
DebugFlags _debugFlags;
gpu::Batch* _batch;
gpu::Context* _context = nullptr;
OctreeRenderer* _renderer = nullptr;
ViewFrustum* _viewFrustum = nullptr;
float _sizeScale = 1.0f;
int _boundaryLevelAdjust = 0;
RenderMode _renderMode = DEFAULT_RENDER_MODE;
RenderSide _renderSide = MONO;
DebugFlags _debugFlags = RENDER_DEBUG_NONE;
gpu::Batch* _batch = nullptr;
ShoudRenderFunctor _shouldRender;
int _elementsTouched;
int _itemsRendered;
int _itemsOutOfView;
int _itemsTooSmall;
int _meshesConsidered;
int _meshesRendered;
int _meshesOutOfView;
int _meshesTooSmall;
int _materialSwitches;
int _trianglesRendered;
int _quadsRendered;
int _translucentMeshPartsRendered;
int _opaqueMeshPartsRendered;
RenderDetails _details;
float _alphaThreshold = 0.5f;
};