From efeaf213050e0be79e441099cbf167daf7608491 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 7 Sep 2015 16:32:51 -0700 Subject: [PATCH] Checkpoint smoother. --- interface/src/Application.cpp | 19 +++++-- interface/src/avatar/Avatar.cpp | 10 ++-- interface/src/avatar/MyAvatar.cpp | 3 -- libraries/avatars/src/AvatarData.cpp | 78 ++++++++++++++++++---------- libraries/avatars/src/AvatarData.h | 7 ++- libraries/render-utils/src/Model.cpp | 3 -- 6 files changed, 76 insertions(+), 44 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 92f64303c7..eeb6563bb4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1019,8 +1019,6 @@ void Application::paintGL() { return; } _inPaint = true; - _myAvatar->captureAttitude(); - _myAvatar->startRender(); //FIXME Finally clearFlagLambda([this] { _inPaint = false; }); auto displayPlugin = getActiveDisplayPlugin(); @@ -1028,6 +1026,8 @@ void Application::paintGL() { _offscreenContext->makeCurrent(); // update the avatar with a fresh HMD pose _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose()); + //_myAvatar->captureAttitude(); //FIXME + //_myAvatar->startRender(); //FIXME auto lodManager = DependencyManager::get(); @@ -1046,7 +1046,7 @@ void Application::paintGL() { // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened renderArgs._context->syncCache(); - + if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); @@ -1079,6 +1079,7 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } + _myAvatar->startCapture(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); @@ -1128,7 +1129,7 @@ void Application::paintGL() { if (!isHMDMode()) { _myCamera.update(1.0f / _fps); } - + _myAvatar->endCapture(); // Primary rendering pass auto framebufferCache = DependencyManager::get(); @@ -1237,8 +1238,9 @@ void Application::paintGL() { // Back to the default framebuffer; gpu::Batch batch; batch.resetStages(); + //_myAvatar->startRender(); //FIXME renderArgs._context->render(batch); - _myAvatar->endRender(); + //_myAvatar->endRender(); //FIXME } void Application::runTests() { @@ -3473,7 +3475,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. + _myAvatar->startRender(); //FIXME _myAvatar->preRender(renderArgs); + _myAvatar->endRender(); //FIXME + activeRenderingThread = QThread::currentThread(); PROFILE_RANGE(__FUNCTION__); @@ -3587,7 +3592,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine + _myAvatar->startRenderRun(); //FIXME _renderEngine->run(); + _myAvatar->endRenderRun(); //FIXME auto engineRC = _renderEngine->getRenderContext(); sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); @@ -3619,6 +3626,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi float fov = MIRROR_FIELD_OF_VIEW; // bool eyeRelativeCamera = false; + _myAvatar->startRenderCam(); //FIXME if (billboard) { fov = BILLBOARD_FIELD_OF_VIEW; // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + @@ -3664,6 +3672,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi viewport = gpu::Vec4i(0, 0, width, height); } renderArgs->_viewport = viewport; + _myAvatar->endRenderCam(); //FIXME // render rear mirror view displaySide(renderArgs, _mirrorCamera, true, billboard); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index fbc940078e..913afbb2af 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -316,7 +316,7 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptrupdate(); } @@ -391,7 +391,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { - //FIXME endRender(); + endRenderAv(); //FIXME return; } @@ -542,7 +542,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { renderDisplayName(batch, *renderArgs->_viewFrustum, renderArgs->_viewport); } - //FIXME endRender(); + endRenderAv(); //FIXME } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { @@ -1022,7 +1022,7 @@ void Avatar::setBillboard(const QByteArray& billboard) { } int Avatar::parseDataFromBuffer(const QByteArray& buffer) { - avatarLock.lockForWrite(); + startUpdate(); if (!_initialized) { // now that we have data for this Avatar we are go for init init(); @@ -1038,7 +1038,7 @@ int Avatar::parseDataFromBuffer(const QByteArray& buffer) { if (_moving && _motionState) { _motionState->addDirtyFlags(EntityItem::DIRTY_POSITION); } - avatarLock.unlock(); + endUpdate(); return bytesRead; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4e4043b28b..cc850eab9e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -192,9 +192,6 @@ void MyAvatar::simulate(float deltaTime) { PerformanceTimer perfTimer("transform"); updateOrientation(deltaTime); updatePosition(deltaTime); - // The 2 updates set position, orientation, and all manner of physics stuff. - // Here we record the results. - nextAttitude(getPosition(), getOrientation()); } { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9d7f974a68..db8837fb79 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -110,52 +110,78 @@ void AvatarData::setOrientation(const glm::quat& orientation, bool overideRefere } } -// There are a number of possible strategies, some more optimal than others in terms of using the latest info -// The current one does not update anything until captureAttitude, and then keeps that value until rendered. +// There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { - setPosition(position, true); setOrientation(orientation, true); - _nextPending = 1; // FIXME type bool -} -void AvatarData::captureAttitude() { - if (!_nextAllowed) { // We haven't finished rendering the last one - return; - } - avatarLock.lockForWrite(); - if (_nextPending) { - _nextAllowed = false; - _nextPosition = getPosition(); - _nextOrientation = getOrientation(); - } else { - qCDebug(avatars) << "FIXME capture with nothing pending"; - } + avatarLock.lock(); + setPosition(position, true); + setOrientation(orientation, true); avatarLock.unlock(); } +void AvatarData::captureAttitude() { + avatarLock.lock(); + assert(_nextAllowed); + _nextAllowed = false; + _nextPosition = getPosition(); + _nextOrientation = getOrientation(); + avatarLock.unlock(); +} +void AvatarData::startCapture() { + avatarLock.lock(); + assert(_nextAllowed); + _nextAllowed = false; + _nextPosition = getPosition(); + _nextOrientation = getOrientation(); +} +void AvatarData::endCapture() { + avatarLock.unlock(); +} + void AvatarData::startUpdate() { - avatarLock.lockForWrite(); + avatarLock.lock(); } void AvatarData::endUpdate() { avatarLock.unlock(); } +void AvatarData::startRenderRun() { + _nextPending = true; // FIXME remove here and in .h + //startRender(); // when on: smooth when startRenderCam off; mini-mirror judder (only, both axes) when startRenderCam on + avatarLock.lock(); +} +void AvatarData::endRenderRun() { + _nextPending = false; // FIXME remove here and in .h + //endRender(); + avatarLock.unlock(); +} +void AvatarData::startRenderAv() { + startRender(); // when on: small rotate judder in all views when starRenderCam off; big rotate judder in all views (and mini-mirror forward judder) when startRenderCam on +} +void AvatarData::endRenderAv() { + endRender(); +} +void AvatarData::startRenderCam() { + //startRender(); +} +void AvatarData::endRenderCam() { + //endRender(); +} void AvatarData::startRender() { - avatarLock.lockForRead(); - if (!_nextPending) { - return; - } + //avatarLock.lock(); + _nextPending = true; // FIXME remove here and in .h glm::vec3 pos = getPosition(); glm::quat rot = getOrientation(); setPosition(_nextPosition, true); - //setOrientation(_nextOrientation, true); + setOrientation(_nextOrientation, true); updateAttitude(); _nextPosition = pos; _nextOrientation = rot; } void AvatarData::endRender() { + _nextPending = false; // FIXME remove here and in .h setPosition(_nextPosition, true); - //setOrientation(_nextOrientation, true); + setOrientation(_nextOrientation, true); updateAttitude(); - _nextPending = 0; _nextAllowed = true; - avatarLock.unlock(); + //avatarLock.unlock(); } float AvatarData::getTargetScale() const { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 41d8cba997..2b557e79b1 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -200,9 +200,12 @@ public: void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void captureAttitude(); // Indicates that the latest values are about to be captured for camera, etc. + void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. + void endCapture(); void startUpdate(); // start/end of update iteration void endUpdate(); void startRender(); // start/end of rendering + void startRenderRun(); void endRenderRun(); void startRenderAv(); void endRenderAv(); void startRenderCam(); void endRenderCam(); void endRender(); virtual void updateAttitude() {} // Tell skeleton mesh about changes @@ -319,7 +322,7 @@ public: bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; } - QReadWriteLock avatarLock; // Name is redundant, but it aids searches. + QMutex avatarLock; // Name is redundant, but it aids searches. public slots: void sendAvatarDataPacket(); @@ -368,7 +371,7 @@ protected: glm::vec3 _nextPosition {}; glm::quat _nextOrientation {}; - int _nextPending = 0; + bool _nextPending = false; bool _nextAllowed = true; // Body scale diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 99a0c81d4b..438bed437a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1473,9 +1473,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } avatarLockForWriteIfApplicable(); - if (!_calculatedMeshPartOffsetValid) - qCDebug(renderutils) << "FIXME surprise!"; - _calculatedMeshPartOffsetValid = false; // FIXME // We need to make sure we have valid offsets calculated before we can render if (!_calculatedMeshPartOffsetValid) { _mutex.lock();