From e01561185df8d56f3978ed4fdfcf2b240c06da11 Mon Sep 17 00:00:00 2001 From: Clement Date: Fri, 19 Apr 2019 20:15:56 -0700 Subject: [PATCH 01/14] Dependencies have correct osx deploy target --- CMakeLists.txt | 9 ++++++++- cmake/compiler.cmake | 4 +--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 551cfd2636..49994d27b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,14 @@ endif() include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/TargetPython.cmake") target_python() -if (HIFI_ANDROID ) +# set our OS X deployment target +# (needs to be set before first project() call and before prebuild.py) +# Will affect VCPKG dependencies +if (APPLE) + set(ENV{MACOSX_DEPLOYMENT_TARGET} 10.9) +endif() + +if (HIFI_ANDROID) execute_process( COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_CURRENT_SOURCE_DIR}/prebuild.py --android ${HIFI_ANDROID_APP} --build-root ${CMAKE_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index bc35d2f2f8..bfdc851905 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -88,12 +88,10 @@ if (APPLE) exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE OSX_VERSION) string(REGEX MATCH "^[0-9]+\\.[0-9]+" OSX_VERSION ${OSX_VERSION}) message(STATUS "Detected OS X version = ${OSX_VERSION}") + message(STATUS "OS X deployment target = ${CMAKE_OSX_DEPLOYMENT_TARGET}") set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH") - # set our OS X deployment target - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) - # find the SDK path for the desired SDK find_path( _OSX_DESIRED_SDK_PATH From 0a3a6c52f972dcc4d3f6b5454bcd8f67202b0521 Mon Sep 17 00:00:00 2001 From: raveenajain Date: Tue, 30 Apr 2019 17:12:35 -0700 Subject: [PATCH 02/14] initial information needed for joint shape info --- libraries/fbx/src/GLTFSerializer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/fbx/src/GLTFSerializer.cpp b/libraries/fbx/src/GLTFSerializer.cpp index 622fb92ce7..9952072668 100755 --- a/libraries/fbx/src/GLTFSerializer.cpp +++ b/libraries/fbx/src/GLTFSerializer.cpp @@ -874,6 +874,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash& joint.isSkeletonJoint = false; hfmModel.joints.push_back(joint); } + hfmModel.shapeVertices.resize(hfmModel.joints.size()); // Build skeleton @@ -1243,6 +1244,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash& } } + for (int clusterIndex = 0; clusterIndex < mesh.clusters.size() - 1; clusterIndex++) { + ShapeVertices& points = hfmModel.shapeVertices.at(clusterIndex); + for (glm::vec3 vertex : mesh.vertices) { + points.push_back(vertex); + } + } + mesh.meshExtents.reset(); foreach(const glm::vec3& vertex, mesh.vertices) { mesh.meshExtents.addPoint(vertex); From 9321cf89d3ea11b14d0014a9b467555302ef33af Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 1 May 2019 07:20:52 -0700 Subject: [PATCH 03/14] allow independent camera to be set by scripts --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fdf7b6960..03677f7784 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5804,7 +5804,8 @@ void Application::cameraModeChanged() { Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true); break; default: - break; + // we don't have menu items for the others, so just leave it alone. + return; } cameraMenuChanged(); } From 281f92e3ea7844fff0068e4e0b5051d1ff6572d2 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 30 Apr 2019 17:57:37 -0700 Subject: [PATCH 04/14] Query shape type outside lock --- libraries/entities/src/EntityItem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index e1ede9192a..7cc35f8be0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2023,9 +2023,10 @@ void EntityItem::setCollisionMask(uint16_t value) { void EntityItem::setDynamic(bool value) { if (getDynamic() != value) { + auto shapeType = getShapeType(); withWriteLock([&] { // dynamic and STATIC_MESH are incompatible so we check for that case - if (value && getShapeType() == SHAPE_TYPE_STATIC_MESH) { + if (value && shapeType == SHAPE_TYPE_STATIC_MESH) { if (_dynamic) { _dynamic = false; _flags |= Simulation::DIRTY_MOTION_TYPE; From ecc38a82872a4d52c56de2edd488684cdae84903 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 30 Apr 2019 18:29:00 -0700 Subject: [PATCH 05/14] Push protocol version --- libraries/networking/src/udt/PacketHeaders.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 274c34a268..4adc5b8e5c 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -269,6 +269,7 @@ enum class EntityVersion : PacketVersion { CertificateTypeProperty, DisableWebMedia, ParticleShapeType, + ParticleShapeTypeDeadlockFix, // Add new versions above here NUM_PACKET_TYPE, From 02b960db333d6134db4d6a1ce76e8b78cbe05df6 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 1 May 2019 15:06:02 -0700 Subject: [PATCH 06/14] Increase max heartbeat time to 10 sec on mac (for now - not long-term solution) --- interface/src/Application.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9a2d320329..3c03edb170 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -377,7 +377,12 @@ const std::vector> Application: class DeadlockWatchdogThread : public QThread { public: static const unsigned long HEARTBEAT_UPDATE_INTERVAL_SECS = 1; + // TODO: go back to 2 min across the board, after figuring out the issues with mac +#if defined(Q_OS_MAC) + static const unsigned long MAX_HEARTBEAT_AGE_USECS = 600 * USECS_PER_SECOND; // 10 mins with no checkin probably a deadlock, right now, on MAC +#else static const unsigned long MAX_HEARTBEAT_AGE_USECS = 120 * USECS_PER_SECOND; // 2 mins with no checkin probably a deadlock +#endif static const int WARNING_ELAPSED_HEARTBEAT = 500 * USECS_PER_MSEC; // warn if elapsed heartbeat average is large static const int HEARTBEAT_SAMPLES = 100000; // ~5 seconds worth of samples @@ -2767,14 +2772,14 @@ Application::~Application() { avatarManager->handleProcessedPhysicsTransaction(transaction); avatarManager->deleteAllAvatars(); - + auto myCharacterController = getMyAvatar()->getCharacterController(); myCharacterController->clearDetailedMotionStates(); - + myCharacterController->buildPhysicsTransaction(transaction); _physicsEngine->processTransaction(transaction); myCharacterController->handleProcessedPhysicsTransaction(transaction); - + _physicsEngine->setCharacterController(nullptr); // the _shapeManager should have zero references @@ -2906,7 +2911,7 @@ void Application::initializeGL() { #if !defined(DISABLE_QML) QStringList chromiumFlags; - // Bug 21993: disable microphone and camera input + // Bug 21993: disable microphone and camera input chromiumFlags << "--use-fake-device-for-media-stream"; // Disable signed distance field font rendering on ATI/AMD GPUs, due to // https://highfidelity.manuscript.com/f/cases/13677/Text-showing-up-white-on-Marketplace-app @@ -4002,8 +4007,8 @@ bool Application::notify(QObject * object, QEvent * event) { if (thread() == QThread::currentThread()) { PROFILE_RANGE_IF_LONGER(app, "notify", 2) return QApplication::notify(object, event); - } - + } + return QApplication::notify(object, event); } From d31ed9ac2257246fe97728b20a24cc1e06d87bc1 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 2 May 2019 12:23:58 -0700 Subject: [PATCH 07/14] adding timer for muted warning --- .../qml/hifi/audio/MicBarApplication.qml | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/audio/MicBarApplication.qml b/interface/resources/qml/hifi/audio/MicBarApplication.qml index bc3f4dff89..838cc73cb8 100644 --- a/interface/resources/qml/hifi/audio/MicBarApplication.qml +++ b/interface/resources/qml/hifi/audio/MicBarApplication.qml @@ -24,6 +24,20 @@ Rectangle { property var pushingToTalk: AudioScriptingInterface.pushingToTalk; readonly property var userSpeakingLevel: 0.4; property bool gated: false; + + Timer { + // used to hold the muted warning. + id: mutedTimer + + interval: 2000; + running: false; + repeat: false; + property bool isRunning: false; + onTriggered: { + isRunning = false; + } + } + Component.onCompleted: { AudioScriptingInterface.noiseGateOpened.connect(function() { gated = false; }); AudioScriptingInterface.noiseGateClosed.connect(function() { gated = true; }); @@ -54,7 +68,17 @@ Rectangle { opacity: 0.7; onLevelChanged: { - var rectOpacity = (muted && (level >= userSpeakingLevel)) ? 1.0 : 0.7; + var mutedAndSpeaking = (muted && (level >= userSpeakingLevel)); + if (!mutedTimer.isRunning && !pushToTalk) { + if (mutedAndSpeaking) { + mutedTimer.start(); + mutedTimer.isRunning = true; + statusText.text = "MUTED"; + } else { + statusText.text = ""; + } + } + var rectOpacity = mutedAndSpeaking ? 1.0 : 0.7; if (pushToTalk && !pushingToTalk) { rectOpacity = (mouseArea.containsMouse) ? 1.0 : 0.7; } else if (mouseArea.containsMouse && rectOpacity != 1.0) { @@ -63,6 +87,10 @@ Rectangle { micBar.opacity = rectOpacity; } + onPushToTalkChanged: { + statusText.text = pushToTalk ? HMD.active ? "PTT" : "PTT-(T)" : ""; + } + color: "#00000000"; border { width: mouseArea.containsMouse || mouseArea.containsPress ? 2 : 0; @@ -190,7 +218,6 @@ Rectangle { color: pushToTalk ? (pushingToTalk ? colors.unmutedColor : colors.mutedColor) : (level >= userSpeakingLevel && muted) ? colors.mutedColor : colors.unmutedColor; font.bold: true - text: pushToTalk ? (HMD.active ? "PTT" : "PTT-(T)") : (muted ? "MUTED" : "MUTE"); size: 12; } } From ea9690d72b1c51371b488bd93655d9023991272b Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 6 May 2019 10:46:54 -0700 Subject: [PATCH 08/14] Disable MIDI rescan after devicechange, to avoid deadlock --- interface/src/Application.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 59f4934dca..6b956e7f55 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -557,7 +557,10 @@ public: return true; } } - + // Attempting to close MIDI interfaces of a hot-unplugged device can result in audio-driver deadlock. + // Detecting MIDI devices that have been added/removed after starting Inteface has been disabled. + // https://support.microsoft.com/en-us/help/4460006/midi-device-app-hangs-when-former-midi-api-is-used +#if 0 if (message->message == WM_DEVICECHANGE) { const float MIN_DELTA_SECONDS = 2.0f; // de-bounce signal static float lastTriggerTime = 0.0f; @@ -567,6 +570,7 @@ public: Midi::USBchanged(); // re-scan the MIDI bus } } +#endif } return false; } From f133ab65e4adb138413c2ecee84932fc158dff45 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 6 May 2019 10:48:53 -0700 Subject: [PATCH 09/14] MIDI bugfix --- libraries/midi/src/Midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 1f190111f2..06c370761e 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -206,7 +206,7 @@ void Midi::MidiSetup() { MIDIOUTCAPS outcaps; for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { - midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); + midiOutGetDevCaps(i, &outcaps, sizeof(MIDIOUTCAPS)); bool found = false; for (int j = 0; j < midiOutExclude.size(); j++) { From 408fb56d57d5b89f3351e99ee2f2554aebb176f1 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 6 May 2019 10:53:58 -0700 Subject: [PATCH 10/14] MIDI error checking --- libraries/midi/src/Midi.cpp | 51 ++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 06c370761e..1b58148e98 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -187,38 +187,43 @@ void Midi::MidiSetup() { MIDIINCAPS incaps; for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { - midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); + if (MMSYSERR_NOERROR == midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS))) { - bool found = false; - for (int j = 0; j < midiInExclude.size(); j++) { - if (midiInExclude[j].toStdString().compare(incaps.szPname) == 0) { - found = true; - break; + bool found = false; + for (int j = 0; j < midiInExclude.size(); j++) { + if (midiInExclude[j].toStdString().compare(incaps.szPname) == 0) { + found = true; + break; + } + } + if (!found) { // EXCLUDE AN INPUT BY NAME + HMIDIIN tmphin; + if (MMSYSERR_NOERROR == midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION)) { + if (MMSYSERR_NOERROR == midiInStart(tmphin)) { + midihin.push_back(tmphin); + } + } } - } - if (!found) { // EXCLUDE AN INPUT BY NAME - HMIDIIN tmphin; - midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); - midiInStart(tmphin); - midihin.push_back(tmphin); } } MIDIOUTCAPS outcaps; for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { - midiOutGetDevCaps(i, &outcaps, sizeof(MIDIOUTCAPS)); + if (MMSYSERR_NOERROR == midiOutGetDevCaps(i, &outcaps, sizeof(MIDIOUTCAPS))) { - bool found = false; - for (int j = 0; j < midiOutExclude.size(); j++) { - if (midiOutExclude[j].toStdString().compare(outcaps.szPname) == 0) { - found = true; - break; + bool found = false; + for (int j = 0; j < midiOutExclude.size(); j++) { + if (midiOutExclude[j].toStdString().compare(outcaps.szPname) == 0) { + found = true; + break; + } + } + if (!found) { // EXCLUDE AN OUTPUT BY NAME + HMIDIOUT tmphout; + if (MMSYSERR_NOERROR == midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION)) { + midihout.push_back(tmphout); + } } - } - if (!found) { // EXCLUDE AN OUTPUT BY NAME - HMIDIOUT tmphout; - midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION); - midihout.push_back(tmphout); } } From 2886e94cdc7e9141b7f5dc4d053e437be572c85a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 6 May 2019 12:44:53 -0700 Subject: [PATCH 11/14] Fix VS2019 build failure --- libraries/shaders/src/shaders/Shaders.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shaders/src/shaders/Shaders.h b/libraries/shaders/src/shaders/Shaders.h index 025abf7b0b..134b2bdcf8 100644 --- a/libraries/shaders/src/shaders/Shaders.h +++ b/libraries/shaders/src/shaders/Shaders.h @@ -13,6 +13,7 @@ #include #include #include +#include #include From c33ad93a55645784aa04fcf9baa579bc20771c3e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 6 May 2019 08:07:18 -0700 Subject: [PATCH 12/14] SharedObject::onRender deadlock fix Call gl::globalRelease() for paused surfaces, this fixes a very common deadlock on mac. But for PC, by inspection, a race condition could occur over the _syncRequested boolean, between the main and qml rendering thread. To fix this, we split render and renderSync into separate messages. --- libraries/qml/src/qml/impl/RenderEventHandler.cpp | 15 ++++++++++++++- libraries/qml/src/qml/impl/RenderEventHandler.h | 5 ++++- libraries/qml/src/qml/impl/SharedObject.cpp | 10 +++++----- libraries/qml/src/qml/impl/SharedObject.h | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/libraries/qml/src/qml/impl/RenderEventHandler.cpp b/libraries/qml/src/qml/impl/RenderEventHandler.cpp index 97c222337b..a1edfd6789 100644 --- a/libraries/qml/src/qml/impl/RenderEventHandler.cpp +++ b/libraries/qml/src/qml/impl/RenderEventHandler.cpp @@ -31,6 +31,10 @@ bool RenderEventHandler::event(QEvent* e) { onRender(); return true; + case OffscreenEvent::RenderSync: + onRenderSync(); + return true; + case OffscreenEvent::Initialize: onInitalize(); return true; @@ -106,6 +110,14 @@ void RenderEventHandler::resize() { } void RenderEventHandler::onRender() { + qmlRender(false); +} + +void RenderEventHandler::onRenderSync() { + qmlRender(true); +} + +void RenderEventHandler::qmlRender(bool sceneGraphSync) { if (_shared->isQuit()) { return; } @@ -117,7 +129,8 @@ void RenderEventHandler::onRender() { PROFILE_RANGE(render_qml_gl, __FUNCTION__); gl::globalLock(); - if (!_shared->preRender()) { + if (!_shared->preRender(sceneGraphSync)) { + gl::globalRelease(); return; } diff --git a/libraries/qml/src/qml/impl/RenderEventHandler.h b/libraries/qml/src/qml/impl/RenderEventHandler.h index 86046c3721..139f062d0d 100644 --- a/libraries/qml/src/qml/impl/RenderEventHandler.h +++ b/libraries/qml/src/qml/impl/RenderEventHandler.h @@ -25,6 +25,7 @@ public: enum Type { Initialize = QEvent::User + 1, Render, + RenderSync, Quit }; @@ -45,6 +46,8 @@ private: void onInitalize(); void resize(); void onRender(); + void onRenderSync(); + void qmlRender(bool sceneGraphSync); void onQuit(); SharedObject* const _shared; @@ -59,4 +62,4 @@ private: }}} // namespace hifi::qml::impl -#endif \ No newline at end of file +#endif diff --git a/libraries/qml/src/qml/impl/SharedObject.cpp b/libraries/qml/src/qml/impl/SharedObject.cpp index a064be79bd..b72f37481b 100644 --- a/libraries/qml/src/qml/impl/SharedObject.cpp +++ b/libraries/qml/src/qml/impl/SharedObject.cpp @@ -344,17 +344,17 @@ void SharedObject::setSize(const QSize& size) { #endif } -bool SharedObject::preRender() { +bool SharedObject::preRender(bool sceneGraphSync) { #ifndef DISABLE_QML QMutexLocker lock(&_mutex); if (_paused) { - if (_syncRequested) { + if (sceneGraphSync) { wake(); } return false; } - if (_syncRequested) { + if (sceneGraphSync) { bool syncResult = true; if (!nsightActive()) { PROFILE_RANGE(render_qml_gl, "sync") @@ -364,7 +364,6 @@ bool SharedObject::preRender() { if (!syncResult) { return false; } - _syncRequested = false; } #endif @@ -475,9 +474,10 @@ void SharedObject::onRender() { lock.unlock(); _renderControl->polishItems(); lock.relock(); - QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Render)); + QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync)); // sync and render request, main and render threads must be synchronized wait(); + _syncRequested = false; } else { QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Render)); } diff --git a/libraries/qml/src/qml/impl/SharedObject.h b/libraries/qml/src/qml/impl/SharedObject.h index ce9fcd46d2..c9c0ef7bd0 100644 --- a/libraries/qml/src/qml/impl/SharedObject.h +++ b/libraries/qml/src/qml/impl/SharedObject.h @@ -71,7 +71,7 @@ public: private: bool event(QEvent* e) override; - bool preRender(); + bool preRender(bool sceneGraphSync); void shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size); // Called by the render event handler, from the render thread void initializeRenderControl(QOpenGLContext* context); From 2b1267ffeb5223c29d40704a59c951dc7c4311ae Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 6 May 2019 12:22:39 -0700 Subject: [PATCH 13/14] Disable the use of tbb::parallel_for in Blender --- libraries/render-utils/src/Model.cpp | 54 +++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b24c1a01cc..eb2508d0e4 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1741,15 +1741,23 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe _blendshapeCoefficients(blendshapeCoefficients) { } +#define BLENDER_USE_NONE 0 +#define BLENDER_USE_TBB 1 +#define BLENDER_TBB_CHUNK_SIZE 512 +#define BLENDER_USE_OPENMP 2 + + +#define BLENDER_PARALLELISM BLENDER_USE_NONE + void Blender::run() { QVector blendshapeOffsets; QVector blendedMeshSizes; if (_model && _model->isLoaded()) { DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); int offset = 0; - auto meshes = _model->getHFMModel().meshes; + const auto& meshes = _model->getHFMModel().meshes; int meshIndex = 0; - foreach(const HFMMesh& mesh, meshes) { + for(const HFMMesh& mesh : meshes) { auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++); if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) { // Not blendshaped or not initialized @@ -1780,9 +1788,18 @@ void Blender::run() { float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; const HFMBlendshape& blendshape = mesh.blendshapes.at(i); - - tbb::parallel_for(tbb::blocked_range(0, blendshape.indices.size()), [&](const tbb::blocked_range& range) { +#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) + tbb::parallel_for(tbb::blocked_range(0, blendshape.indices.size(), BLENDER_TBB_CHUNK_SIZE), [&](const tbb::blocked_range& range) { for (auto j = range.begin(); j < range.end(); j++) { +#elif (BLENDER_PARALLELISM == BLENDER_USE_OPENMP) + { + #pragma omp parallel for + for (int j = 0; j < (int)blendshape.indices.size(); ++j) { +#else + { + for (int j = 0; j < blendshape.indices.size(); ++j) { +#endif + int index = blendshape.indices.at(j); auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[index]; @@ -1793,20 +1810,41 @@ void Blender::run() { currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient; } } +#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) }); +#else + } +#endif } // Blendshape offsets are generrated, now let's pack it on its way to gpu - tbb::parallel_for(tbb::blocked_range(0, (int) unpackedBlendshapeOffsets.size()), [&](const tbb::blocked_range& range) { +#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) + tbb::parallel_for(tbb::blocked_range(0, (int) unpackedBlendshapeOffsets.size(), BLENDER_TBB_CHUNK_SIZE), [&](const tbb::blocked_range& range) { auto unpacked = unpackedBlendshapeOffsets.data() + range.begin(); auto packed = meshBlendshapeOffsets + range.begin(); for (auto j = range.begin(); j < range.end(); j++) { +#elif (BLENDER_PARALLELISM == BLENDER_USE_OPENMP) + { + auto unpacked = unpackedBlendshapeOffsets.data(); + auto packed = meshBlendshapeOffsets; + #pragma omp parallel for + for (int j = 0; j < (int)unpackedBlendshapeOffsets.size(); ++j) { +#else + { + auto unpacked = unpackedBlendshapeOffsets.data(); + auto packed = meshBlendshapeOffsets; + for (int j = 0; j < (int)unpackedBlendshapeOffsets.size(); ++j) { +#endif + //for (auto j = range.begin(); j < range.end(); j++) { packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked)); - - unpacked++; - packed++; + ++unpacked; + ++packed; } +#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) }); +#else + } +#endif } } // post the result to the ModelBlender, which will dispatch to the model if still alive From 17632e3c5092c52e81bc3b285d712e7c3cd66fdd Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 7 May 2019 10:36:14 -0700 Subject: [PATCH 14/14] PR feedback --- libraries/render-utils/src/Model.cpp | 57 ++++------------------------ 1 file changed, 8 insertions(+), 49 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index eb2508d0e4..7d0119a0f2 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1741,14 +1741,6 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe _blendshapeCoefficients(blendshapeCoefficients) { } -#define BLENDER_USE_NONE 0 -#define BLENDER_USE_TBB 1 -#define BLENDER_TBB_CHUNK_SIZE 512 -#define BLENDER_USE_OPENMP 2 - - -#define BLENDER_PARALLELISM BLENDER_USE_NONE - void Blender::run() { QVector blendshapeOffsets; QVector blendedMeshSizes; @@ -1788,63 +1780,30 @@ void Blender::run() { float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; const HFMBlendshape& blendshape = mesh.blendshapes.at(i); -#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) - tbb::parallel_for(tbb::blocked_range(0, blendshape.indices.size(), BLENDER_TBB_CHUNK_SIZE), [&](const tbb::blocked_range& range) { - for (auto j = range.begin(); j < range.end(); j++) { -#elif (BLENDER_PARALLELISM == BLENDER_USE_OPENMP) - { - #pragma omp parallel for - for (int j = 0; j < (int)blendshape.indices.size(); ++j) { -#else - { - for (int j = 0; j < blendshape.indices.size(); ++j) { -#endif + for (int j = 0; j < blendshape.indices.size(); ++j) { + int index = blendshape.indices.at(j); - int index = blendshape.indices.at(j); + auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[index]; + currentBlendshapeOffset.positionOffset += blendshape.vertices.at(j) * vertexCoefficient; - auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[index]; - currentBlendshapeOffset.positionOffset += blendshape.vertices.at(j) * vertexCoefficient; - - currentBlendshapeOffset.normalOffset += blendshape.normals.at(j) * normalCoefficient; - if (j < blendshape.tangents.size()) { - currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient; - } + currentBlendshapeOffset.normalOffset += blendshape.normals.at(j) * normalCoefficient; + if (j < blendshape.tangents.size()) { + currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient; } -#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) - }); -#else } -#endif } // Blendshape offsets are generrated, now let's pack it on its way to gpu -#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) - tbb::parallel_for(tbb::blocked_range(0, (int) unpackedBlendshapeOffsets.size(), BLENDER_TBB_CHUNK_SIZE), [&](const tbb::blocked_range& range) { - auto unpacked = unpackedBlendshapeOffsets.data() + range.begin(); - auto packed = meshBlendshapeOffsets + range.begin(); - for (auto j = range.begin(); j < range.end(); j++) { -#elif (BLENDER_PARALLELISM == BLENDER_USE_OPENMP) - { - auto unpacked = unpackedBlendshapeOffsets.data(); - auto packed = meshBlendshapeOffsets; - #pragma omp parallel for - for (int j = 0; j < (int)unpackedBlendshapeOffsets.size(); ++j) { -#else + // FIXME it feels like we could be more effectively using SIMD here { auto unpacked = unpackedBlendshapeOffsets.data(); auto packed = meshBlendshapeOffsets; for (int j = 0; j < (int)unpackedBlendshapeOffsets.size(); ++j) { -#endif - //for (auto j = range.begin(); j < range.end(); j++) { packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked)); ++unpacked; ++packed; } -#if (BLENDER_PARALLELISM == BLENDER_USE_TBB) - }); -#else } -#endif } } // post the result to the ModelBlender, which will dispatch to the model if still alive