Merge pull request #9212 from AndrewMeadows/benji-001

add profile stats relating to avatar CPU costs
This commit is contained in:
samcake 2016-12-16 13:57:55 -08:00 committed by GitHub
commit 8cdfef4887
6 changed files with 46 additions and 25 deletions

View file

@ -3225,6 +3225,8 @@ bool Application::shouldPaint(float nsecsElapsed) {
} }
void Application::idle(float nsecsElapsed) { void Application::idle(float nsecsElapsed) {
PROFILE_RANGE(interfaceapp, __FUNCTION__);
PerformanceTimer perfTimer("idle");
// Update the deadlock watchdog // Update the deadlock watchdog
updateHeartbeat(); updateHeartbeat();
@ -3239,8 +3241,6 @@ void Application::idle(float nsecsElapsed) {
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop); connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
} }
PROFILE_RANGE(interfaceapp, __FUNCTION__);
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->runCallbacks(); steamClient->runCallbacks();
} }
@ -3261,8 +3261,6 @@ void Application::idle(float nsecsElapsed) {
_simCounter.increment(); _simCounter.increment();
PerformanceTimer perfTimer("idle");
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
// details normally. // details normally.
@ -4536,8 +4534,8 @@ QRect Application::getDesirableApplicationGeometry() const {
// or the "myCamera". // or the "myCamera".
// //
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
PerformanceTimer perfTimer("loadViewFrustum");
PROFILE_RANGE(interfaceapp, __FUNCTION__); PROFILE_RANGE(interfaceapp, __FUNCTION__);
PerformanceTimer perfTimer("loadViewFrustum");
// We will use these below, from either the camera or head vectors calculated above // We will use these below, from either the camera or head vectors calculated above
viewFrustum.setProjection(camera.getProjection()); viewFrustum.setProjection(camera.getProjection());

View file

@ -184,6 +184,7 @@ void Avatar::animateScaleChanges(float deltaTime) {
} }
void Avatar::updateAvatarEntities() { void Avatar::updateAvatarEntities() {
PerformanceTimer perfTimer("attachments");
// - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity()
// - updateAvatarEntity saves the bytes and sets _avatarEntityDataLocallyEdited // - updateAvatarEntity saves the bytes and sets _avatarEntityDataLocallyEdited
// - MyAvatar::update notices _avatarEntityDataLocallyEdited and calls sendIdentityPacket // - MyAvatar::update notices _avatarEntityDataLocallyEdited and calls sendIdentityPacket
@ -285,28 +286,38 @@ void Avatar::simulate(float deltaTime) {
} }
animateScaleChanges(deltaTime); animateScaleChanges(deltaTime);
// update the shouldAnimate flag to match whether or not we will render the avatar. bool avatarPositionInView = false;
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f; bool avatarMeshInView = false;
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f; { // update the shouldAnimate flag to match whether or not we will render the avatar.
ViewFrustum viewFrustum; PerformanceTimer perfTimer("cull");
qApp->copyViewFrustum(viewFrustum); ViewFrustum viewFrustum;
float visibility = calculateRenderAccuracy(viewFrustum.getPosition(), {
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale()); PerformanceTimer perfTimer("LOD");
if (!_shouldAnimate) { const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
if (visibility > MINIMUM_VISIBILITY_FOR_ON) { const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
_shouldAnimate = true; qApp->copyViewFrustum(viewFrustum);
qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility; float visibility = calculateRenderAccuracy(viewFrustum.getPosition(),
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
if (!_shouldAnimate) {
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
_shouldAnimate = true;
qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
}
} else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) {
_shouldAnimate = false;
qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
}
} }
} else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) {
_shouldAnimate = false;
qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
}
// simple frustum check {
float boundingRadius = getBoundingRadius(); PerformanceTimer perfTimer("inView");
qApp->copyDisplayViewFrustum(viewFrustum); // simple frustum check
bool avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius); float boundingRadius = getBoundingRadius();
bool avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound()); qApp->copyDisplayViewFrustum(viewFrustum);
avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius);
avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
}
}
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) { if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
{ {
@ -331,6 +342,7 @@ void Avatar::simulate(float deltaTime) {
} else { } else {
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
getHead()->setPosition(getPosition()); getHead()->setPosition(getPosition());
PerformanceTimer perfTimer("skeleton");
_skeletonModel->simulate(deltaTime, false); _skeletonModel->simulate(deltaTime, false);
} }
@ -379,6 +391,7 @@ void Avatar::applyPositionDelta(const glm::vec3& delta) {
} }
void Avatar::measureMotionDerivatives(float deltaTime) { void Avatar::measureMotionDerivatives(float deltaTime) {
PerformanceTimer perfTimer("derivatives");
// linear // linear
float invDeltaTime = 1.0f / deltaTime; float invDeltaTime = 1.0f / deltaTime;
// Floating point error prevents us from computing velocity in a naive way // Floating point error prevents us from computing velocity in a naive way
@ -645,6 +658,7 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
// virtual // virtual
void Avatar::simulateAttachments(float deltaTime) { void Avatar::simulateAttachments(float deltaTime) {
PerformanceTimer perfTimer("attachments");
for (int i = 0; i < (int)_attachmentModels.size(); i++) { for (int i = 0; i < (int)_attachmentModels.size(); i++) {
const AttachmentData& attachment = _attachmentData.at(i); const AttachmentData& attachment = _attachmentData.at(i);
auto& model = _attachmentModels.at(i); auto& model = _attachmentModels.at(i);
@ -1039,6 +1053,7 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
int Avatar::parseDataFromBuffer(const QByteArray& buffer) { int Avatar::parseDataFromBuffer(const QByteArray& buffer) {
PerformanceTimer perfTimer("unpack");
if (!_initialized) { if (!_initialized) {
// now that we have data for this Avatar we are go for init // now that we have data for this Avatar we are go for init
init(); init();
@ -1258,6 +1273,7 @@ void Avatar::setOrientation(const glm::quat& orientation) {
} }
void Avatar::updatePalms() { void Avatar::updatePalms() {
PerformanceTimer perfTimer("palms");
// update thread-safe caches // update thread-safe caches
_leftPalmRotationCache.set(getUncachedLeftPalmRotation()); _leftPalmRotationCache.set(getUncachedLeftPalmRotation());
_rightPalmRotationCache.set(getUncachedRightPalmRotation()); _rightPalmRotationCache.set(getUncachedRightPalmRotation());

View file

@ -20,6 +20,7 @@
#include <GeometryUtil.h> #include <GeometryUtil.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include <DebugDraw.h> #include <DebugDraw.h>
#include <PerfStat.h>
#include <ScriptValueUtils.h> #include <ScriptValueUtils.h>
#include <shared/NsightHelpers.h> #include <shared/NsightHelpers.h>
@ -1249,6 +1250,7 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
} }
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) { void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
PerformanceTimer perfTimer("copyJoints");
if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) { if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) {
// transform all the default poses into rig space. // transform all the default poses into rig space.

View file

@ -13,6 +13,7 @@
#include <NodeList.h> #include <NodeList.h>
#include <udt/PacketHeaders.h> #include <udt/PacketHeaders.h>
#include <PerfStat.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include "AvatarLogging.h" #include "AvatarLogging.h"
@ -98,6 +99,7 @@ AvatarSharedPointer AvatarHashMap::findAvatar(const QUuid& sessionUUID) {
} }
void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) { void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
PerformanceTimer perfTimer("receiveAvatar");
// enumerate over all of the avatars in this packet // enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around) // only add them if mixerWeakPointer points to something (meaning that mixer is still around)
while (message->getBytesLeftToRead()) { while (message->getBytesLeftToRead()) {

View file

@ -1169,6 +1169,7 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector<bool>& tra
void RenderableModelEntityItem::locationChanged(bool tellPhysics) { void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
PerformanceTimer pertTimer("locationChanged");
EntityItem::locationChanged(tellPhysics); EntityItem::locationChanged(tellPhysics);
if (_model && _model->isActive()) { if (_model && _model->isActive()) {
_model->setRotation(getRotation()); _model->setRotation(getRotation());

View file

@ -282,6 +282,7 @@ void Model::reset() {
bool Model::updateGeometry() { bool Model::updateGeometry() {
PROFILE_RANGE(renderutils, __FUNCTION__); PROFILE_RANGE(renderutils, __FUNCTION__);
PerformanceTimer perfTimer("Model::updateGeometry");
bool needFullUpdate = false; bool needFullUpdate = false;
if (!isLoaded()) { if (!isLoaded()) {
@ -1090,6 +1091,7 @@ void Model::snapToRegistrationPoint() {
void Model::simulate(float deltaTime, bool fullUpdate) { void Model::simulate(float deltaTime, bool fullUpdate) {
PROFILE_RANGE(renderutils, __FUNCTION__); PROFILE_RANGE(renderutils, __FUNCTION__);
PerformanceTimer perfTimer("Model::simulate");
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit) fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint); || (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);