From 46a209037040f688a450e29a5b8a18d2b16fe0dc Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 17 Jan 2018 16:08:12 -0800 Subject: [PATCH 01/42] fix black flashing on transparent objects --- libraries/render-utils/src/RenderDeferredTask.cpp | 6 ++++-- libraries/render/src/render/ShapePipeline.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index f860c0494e..2f4656627a 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -335,11 +335,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& // Setup lighting model for all items; batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); - // Setup haze iff curretn zone has haze + // Setup haze iff current zone has haze auto hazeStage = args->_scene->getStage(); if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { model::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); - batch.setUniformBuffer(render::ShapePipeline::Slot::HAZE_MODEL, hazePointer->getHazeParametersBuffer()); + if (hazePointer) { + batch.setUniformBuffer(render::ShapePipeline::Slot::HAZE_MODEL, hazePointer->getHazeParametersBuffer()); + } } // From the lighting model define a global shapKey ORED with individiual keys diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 4254280fa1..4cf1b306ab 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -87,7 +87,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT)); slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK)); slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS)); - slotBindings.insert(gpu::Shader::Binding(std::string("hazeParametersBuffer"), Slot::BUFFER::HAZE_MODEL)); + slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), Slot::BUFFER::HAZE_MODEL)); gpu::Shader::makeProgram(*program, slotBindings); From 59263840769ff54cd2506a1220caffde3df573d9 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 22 Jan 2018 14:52:05 -0800 Subject: [PATCH 02/42] Take defaultPoseFlag section into account when computing byteArraySize. (cherry picked from commit c13c9f301cf263aca26795a7a333c985dd73a7b2) --- libraries/avatars/src/AvatarData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9924cc137e..2a3c0452f3 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -308,7 +308,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent const size_t byteArraySize = AvatarDataPacket::MAX_CONSTANT_HEADER_SIZE + (hasFaceTrackerInfo ? AvatarDataPacket::maxFaceTrackerInfoSize(_headData->getNumSummedBlendshapeCoefficients()) : 0) + - (hasJointData ? AvatarDataPacket::maxJointDataSize(_jointData.size()) : 0); + (hasJointData ? AvatarDataPacket::maxJointDataSize(_jointData.size()) : 0) + + (hasJointDefaultPoseFlags ? AvatarDataPacket::maxJointDefaultPoseFlagsSize(_jointData.size()) : 0); QByteArray avatarDataByteArray((int)byteArraySize, 0); unsigned char* destinationBuffer = reinterpret_cast(avatarDataByteArray.data()); From 3c12ae892545e568606eecd62ac5ee4cc52f4abc Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 22 Jan 2018 20:52:18 -0700 Subject: [PATCH 03/42] Fix Edit/Asset Browser in HMD mode --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ffe2f781db..5854501809 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6195,7 +6195,7 @@ void Application::showAssetServerWidget(QString filePath) { if (!hmd->getShouldShowTablet() && !isHMDMode()) { DependencyManager::get()->show(url, "AssetServer", startUpload); } else { - static const QUrl url("../dialogs/TabletAssetServer.qml"); + static const QUrl url("hifi/dialogs/TabletAssetServer.qml"); tablet->pushOntoStack(url); } } From fddbf13796376c989f7f4c980a690140b207c8c7 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 23 Jan 2018 11:12:22 -0700 Subject: [PATCH 04/42] Fix Asset Browser access from Create --- interface/resources/qml/hifi/tablet/Edit.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index e2e8c4362e..efd797e12d 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -12,7 +12,7 @@ StackView { HifiConstants { id: hifi } function pushSource(path) { - editRoot.push(Qt.resolvedUrl(path)); + editRoot.push(Qt.resolvedUrl("../../" + path)); editRoot.currentItem.sendToScript.connect(editRoot.sendToScript); } From 29dd24b05f1a060c1f2700a57e00ffe61c1d2988 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 23 Jan 2018 15:50:32 -0700 Subject: [PATCH 05/42] Fix GoTo app in HMD mode --- interface/resources/qml/hifi/Feed.qml | 3 ++- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 1 + scripts/system/tablet-goto.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/Feed.qml b/interface/resources/qml/hifi/Feed.qml index a9629c0e4e..3f3a47a297 100644 --- a/interface/resources/qml/hifi/Feed.qml +++ b/interface/resources/qml/hifi/Feed.qml @@ -33,6 +33,7 @@ Column { property int labelSize: 20; property string metaverseServerUrl: ''; + property string protocol: ''; property string actions: 'snapshot'; // sendToScript doesn't get wired until after everything gets created. So we have to queue fillDestinations on nextTick. property string labelText: actions; @@ -102,7 +103,7 @@ Column { 'include_actions=' + actions, 'restriction=' + (Account.isLoggedIn() ? 'open,hifi' : 'open'), 'require_online=true', - 'protocol=' + encodeURIComponent(Window.protocolSignature()), + 'protocol=' + protocol, 'page=' + pageNumber ]; var url = metaverseBase + 'user_stories?' + options.join('&'); diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index f3cda533e9..d4550d3843 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -54,6 +54,7 @@ StackView { console.debug('TabletAddressDialog::fromScript: refreshFeeds', 'feeds = ', feeds); feeds.forEach(function(feed) { + feed.protocol = encodeURIComponent(message.protocolSignature); Qt.callLater(feed.fillDestinations); }); diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 43dae9625a..9cd8420a88 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -100,7 +100,7 @@ button.editProperties({isActive: shouldActivateButton}); wireEventBridge(true); messagesWaiting(false); - tablet.sendToQml({ method: 'refreshFeeds' }) + tablet.sendToQml({ method: 'refreshFeeds', protocolSignature: Window.protocolSignature() }) } else { shouldActivateButton = false; From 1529fea9837a75bb490d4bb58c5acde1bade004f Mon Sep 17 00:00:00 2001 From: John Conklin II Date: Fri, 19 Jan 2018 15:15:52 -0800 Subject: [PATCH 06/42] Revert "Display both lasers on tablet and Web surfaces" (cherry picked from commit 455090d2b94c6b6dd26b863bd8ec1b15936200fa) --- .../src/raypick/PointerScriptingInterface.cpp | 6 +- .../src/raypick/PointerScriptingInterface.h | 8 -- libraries/pointers/src/Pointer.cpp | 15 +--- libraries/pointers/src/Pointer.h | 3 +- libraries/pointers/src/PointerManager.cpp | 7 -- libraries/pointers/src/PointerManager.h | 1 - .../controllers/controllerDispatcher.js | 42 +--------- .../controllerModules/webSurfaceLaserInput.js | 84 ++++--------------- 8 files changed, 25 insertions(+), 141 deletions(-) diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index a334834979..ac5a467e76 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -175,8 +175,4 @@ QVariantMap PointerScriptingInterface::getPrevPickResult(unsigned int uid) const result = pickResult->toVariantMap(); } return result; -} - -void PointerScriptingInterface::setDoesHover(unsigned int uid, bool hover) const { - DependencyManager::get()->setDoesHover(uid, hover); -} +} \ No newline at end of file diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h index 451c132769..1cc7b56503 100644 --- a/interface/src/raypick/PointerScriptingInterface.h +++ b/interface/src/raypick/PointerScriptingInterface.h @@ -202,14 +202,6 @@ public: */ Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); } - /**jsdoc - * Sets whether or not a pointer should generate hover events. - * @function Pointers.setDoesHover - * @param {boolean} uid - The ID of the Pointer, as returned by {@link Pointers.createPointer}. - * @param {boolean} hover - If true then the pointer generates hover events, otherwise it does not. - */ - Q_INVOKABLE void setDoesHover(unsigned int uid, bool hove) const; - /**jsdoc * Check if a Pointer is associated with the left hand. * @function Pointers.isLeftHand diff --git a/libraries/pointers/src/Pointer.cpp b/libraries/pointers/src/Pointer.cpp index 287d5a3c97..5307e17355 100644 --- a/libraries/pointers/src/Pointer.cpp +++ b/libraries/pointers/src/Pointer.cpp @@ -64,12 +64,6 @@ bool Pointer::isMouse() const { return DependencyManager::get()->isMouse(_pickUID); } -void Pointer::setDoesHover(bool doesHover) { - withWriteLock([&] { - _hover = doesHover; - }); -} - void Pointer::update(unsigned int pointerID) { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts withReadLock([&] { @@ -101,8 +95,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin } // Hover events - bool doHover = _hover && shouldHover(pickResult); - + bool doHover = shouldHover(pickResult); Pointer::PickedObject hoveredObject = getHoveredObject(pickResult); PointerEvent hoveredEvent = buildPointerEvent(hoveredObject, pickResult); hoveredEvent.setType(PointerEvent::Move); @@ -111,7 +104,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin hoveredEvent.setMoveOnHoverLeave(moveOnHoverLeave); // if shouldHover && !_prevDoHover, only send hoverBegin - if (_enabled && doHover && !_prevDoHover) { + if (_enabled && _hover && doHover && !_prevDoHover) { if (hoveredObject.type == ENTITY) { emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent); } else if (hoveredObject.type == OVERLAY) { @@ -119,7 +112,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin } else if (hoveredObject.type == HUD) { emit pointerManager->hoverBeginHUD(hoveredEvent); } - } else if (_enabled && doHover) { + } else if (_enabled && _hover && doHover) { if (hoveredObject.type == OVERLAY) { if (_prevHoveredObject.type == OVERLAY) { if (hoveredObject.objectID == _prevHoveredObject.objectID) { @@ -236,7 +229,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const PickResultPoin } // if we disable the pointer or disable hovering, send hoverEnd events after triggerEnd - if ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover)) { + if (_hover && ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover))) { if (_prevHoveredObject.type == ENTITY) { emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent); } else if (_prevHoveredObject.type == OVERLAY) { diff --git a/libraries/pointers/src/Pointer.h b/libraries/pointers/src/Pointer.h index 9fd434fb15..3197c80cad 100644 --- a/libraries/pointers/src/Pointer.h +++ b/libraries/pointers/src/Pointer.h @@ -62,8 +62,6 @@ public: virtual void setLength(float length) {} virtual void setLockEndUUID(const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) {} - virtual void setDoesHover(bool hover); - void update(unsigned int pointerID); virtual void updateVisuals(const PickResultPointer& pickResult) = 0; void generatePointerEvents(unsigned int pointerID, const PickResultPointer& pickResult); @@ -103,6 +101,7 @@ private: std::unordered_map _triggeredObjects; PointerEvent::Button chooseButton(const std::string& button); + }; #endif // hifi_Pick_h diff --git a/libraries/pointers/src/PointerManager.cpp b/libraries/pointers/src/PointerManager.cpp index 13b38457b6..be890da392 100644 --- a/libraries/pointers/src/PointerManager.cpp +++ b/libraries/pointers/src/PointerManager.cpp @@ -122,13 +122,6 @@ void PointerManager::setLockEndUUID(unsigned int uid, const QUuid& objectID, boo } } -void PointerManager::setDoesHover(unsigned int uid, bool hover) const { - auto pointer = find(uid); - if (pointer) { - pointer->setDoesHover(hover); - } -} - bool PointerManager::isLeftHand(unsigned int uid) { auto pointer = find(uid); if (pointer) { diff --git a/libraries/pointers/src/PointerManager.h b/libraries/pointers/src/PointerManager.h index 2c9a37e129..b98558622f 100644 --- a/libraries/pointers/src/PointerManager.h +++ b/libraries/pointers/src/PointerManager.h @@ -37,7 +37,6 @@ public: void setLength(unsigned int uid, float length) const; void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const; - void setDoesHover(unsigned int uid, bool hover) const; void update(); diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index a8658933e7..16f1d086b7 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -44,12 +44,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.highVarianceCount = 0; this.veryhighVarianceCount = 0; this.tabletID = null; - this.TABLET_UI_UUIDS = []; this.blacklist = []; - this.leftPointerDoesHover = true; - this.leftPointerDoesHoverChanged = false; - this.rightPointerDoesHover = true; - this.rightPointerDoesHoverChanged = false; this.pointerManager = new PointerManager(); // a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are @@ -127,10 +122,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); return getControllerWorldLocation(Controller.Standard.RightHand, true); }; - this.isTabletID = function (uuid) { - return _this.TABLET_UI_UUIDS.indexOf(uuid) !== -1; - }; - this.updateTimings = function () { _this.intervalCount++; var thisInterval = Date.now(); @@ -157,35 +148,11 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.setIgnorePointerItems = function() { if (HMD.tabletID !== this.tabletID) { this.tabletID = HMD.tabletID; - this.TABLET_UI_UUIDS = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, HMD.homeButtonHighlightID]; Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist); Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist); } }; - this.updateDoesHover = function(handLaser, doesHover) { - if (handLaser.doesHover !== undefined) { - if (handLaser.hand === LEFT_HAND && _this.leftPointerDoesHover !== doesHover) { - _this.leftPointerDoesHover = doesHover; - _this.leftPointerDoesHoverChanged = true; - } else if (handLaser.hand === RIGHT_HAND && _this.rightPointerDoesHover !== doesHover) { - _this.rightPointerDoesHover = doesHover; - _this.rightPointerDoesHoverChanged = true; - } - } - } - - this.updateHovering = function () { - if (_this.leftPointerDoesHoverChanged) { - Pointers.setDoesHover(_this.leftPointer, _this.leftPointerDoesHover); - _this.leftPointerDoesHoverChanged = false; - } - if (_this.rightPointerDoesHoverChanged) { - Pointers.setDoesHover(_this.rightPointer, _this.rightPointerDoesHover); - _this.rightPointerDoesHoverChanged = false; - } - }; - this.update = function () { try { _this.updateInternal(); @@ -357,8 +324,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); _this.runningPluginNames[orderedPluginName] = true; _this.markSlots(candidatePlugin, orderedPluginName); _this.pointerManager.makePointerVisible(candidatePlugin.parameters.handLaser); - _this.updateDoesHover(candidatePlugin.parameters.handLaser, - candidatePlugin.parameters.handLaser.doesHover); if (DEBUG) { print("controllerDispatcher running " + orderedPluginName); } @@ -389,15 +354,12 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.beginProfileRange("dispatch.run." + runningPluginName); } var runningness = plugin.run(controllerData, deltaTime); - if (runningness.active) { - _this.updateDoesHover(plugin.parameters.handLaser, plugin.parameters.handLaser.doesHover); - } else { + if (!runningness.active) { // plugin is finished running, for now. remove it from the list // of running plugins and mark its activity-slots as "not in use" delete _this.runningPluginNames[runningPluginName]; _this.markSlots(plugin, false); _this.pointerManager.makePointerInvisible(plugin.parameters.handLaser); - _this.updateDoesHover(plugin.parameters.handLaser, true); if (DEBUG) { print("controllerDispatcher stopping " + runningPluginName); } @@ -410,8 +372,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } } _this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues); - _this.updateHovering(); - if (PROFILE) { Script.endProfileRange("dispatch.run"); } diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index cc8378af84..3d9d7979d5 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -87,89 +87,41 @@ Script.include("/~/system/libraries/controllers.js"); return MyAvatar.getDominantHand() === "right" ? 1 : 0; }; - this.letOtherHandRunFirst = function (controllerData, pointingAt) { - // If both hands are ready to run, let the other hand run first if it is the dominant hand so that it gets the - // highlight. - var isOtherTriggerPressed = controllerData.triggerValues[this.otherHand] > TRIGGER_OFF_VALUE; - var isLetOtherHandRunFirst = !this.getOtherModule().running - && this.getDominantHand() === this.otherHand - && (this.parameters.handLaser.allwaysOn || isOtherTriggerPressed); - if (isLetOtherHandRunFirst) { - var otherHandPointingAt = controllerData.rayPicks[this.otherHand].objectID; - if (this.isTabletID(otherHandPointingAt)) { - otherHandPointingAt = HMD.tabletID; - } - isLetOtherHandRunFirst = pointingAt === otherHandPointingAt; - } - return isLetOtherHandRunFirst; - }; - - this.hoverItem = null; - - this.isTabletID = function (uuid) { - return [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, HMD.homeButtonHighlightID].indexOf(uuid) !== -1; - }; + this.dominantHandOverride = false; this.isReady = function(controllerData) { - if (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData)) { + var otherModuleRunning = this.getOtherModule().running; + otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. + var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE + && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; + if ((!otherModuleRunning || isTriggerPressed) + && (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData))) { this.updateAllwaysOn(); - - var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; + if (isTriggerPressed) { + this.dominantHandOverride = true; // Override dominant hand. + this.getOtherModule().dominantHandOverride = false; + } if (this.parameters.handLaser.allwaysOn || isTriggerPressed) { - var pointingAt = controllerData.rayPicks[this.hand].objectID; - if (this.isTabletID(pointingAt)) { - pointingAt = HMD.tabletID; - } - - if (!this.letOtherHandRunFirst(controllerData, pointingAt)) { - - if (pointingAt !== this.getOtherModule().hoverItem) { - this.parameters.handLaser.doesHover = true; - this.hoverItem = pointingAt; - } else { - this.parameters.handLaser.doesHover = false; - this.hoverItem = null; - } - - return makeRunningValues(true, [], []); - } + return makeRunningValues(true, [], []); } } - - this.parameters.handLaser.doesHover = false; - this.hoverItem = null; - return makeRunningValues(false, [], []); }; this.run = function(controllerData, deltaTime) { + var otherModuleRunning = this.getOtherModule().running; + otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. + otherModuleRunning = otherModuleRunning || this.getOtherModule().dominantHandOverride; // Override dominant hand. var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData); - var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; - if (!grabModuleNeedsToRun && (isTriggerPressed || this.parameters.handLaser.allwaysOn + if (!otherModuleRunning && !grabModuleNeedsToRun && (controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE + || this.parameters.handLaser.allwaysOn && (this.isPointingAtOverlay(controllerData) || this.isPointingAtWebEntity(controllerData)))) { this.running = true; - - var pointingAt = controllerData.rayPicks[this.hand].objectID; - if (this.isTabletID(pointingAt)) { - pointingAt = HMD.tabletID; - } - - if (pointingAt !== this.getOtherModule().hoverItem || isTriggerPressed) { - this.parameters.handLaser.doesHover = true; - this.hoverItem = pointingAt; - } else { - this.parameters.handLaser.doesHover = false; - this.hoverItem = null; - } - return makeRunningValues(true, [], []); } this.deleteContextOverlay(); this.running = false; - - this.parameters.handLaser.doesHover = false; - this.hoverItem = null; - + this.dominantHandOverride = false; return makeRunningValues(false, [], []); }; } From 58d3d8ef3dc421bf39743a7f86cbf1bf3f9944a0 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 24 Jan 2018 18:58:08 -0800 Subject: [PATCH 07/42] Bug fix for incorrect positioned eyes on other peoples avatars There was a bug in writeBitVector(), where the last byte was not consistantly written into the destination buffer. A unit test was added to verify that writeBitVector() and readBitVector() are correct. (cherry picked from commit a252e90f969e85503f2a83380a6e101026732783) --- libraries/shared/src/BitVectorHelpers.h | 16 +++-- tests/shared/src/BitVectorHelperTests.cpp | 80 +++++++++++++++++++++++ tests/shared/src/BitVectorHelperTests.h | 23 +++++++ 3 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 tests/shared/src/BitVectorHelperTests.cpp create mode 100644 tests/shared/src/BitVectorHelperTests.h diff --git a/libraries/shared/src/BitVectorHelpers.h b/libraries/shared/src/BitVectorHelpers.h index 71826036eb..9f5af0c380 100644 --- a/libraries/shared/src/BitVectorHelpers.h +++ b/libraries/shared/src/BitVectorHelpers.h @@ -12,14 +12,14 @@ #ifndef hifi_BitVectorHelpers_h #define hifi_BitVectorHelpers_h -size_t calcBitVectorSize(int numBits) { +int calcBitVectorSize(int numBits) { return ((numBits - 1) >> 3) + 1; } // func should be of type bool func(int index) template -size_t writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { - size_t totalBytes = ((numBits - 1) >> 3) + 1; +int writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { + int totalBytes = calcBitVectorSize(numBits); uint8_t* cursor = destinationBuffer; uint8_t byte = 0; uint8_t bit = 0; @@ -34,13 +34,19 @@ size_t writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { bit = 0; } } + // write the last byte, if necessary + if (bit != 0) { + *cursor++ = byte; + } + + assert((int)(cursor - destinationBuffer) == totalBytes); return totalBytes; } // func should be of type 'void func(int index, bool value)' template -size_t readBitVector(const uint8_t* sourceBuffer, int numBits, const F& func) { - size_t totalBytes = ((numBits - 1) >> 3) + 1; +int readBitVector(const uint8_t* sourceBuffer, int numBits, const F& func) { + int totalBytes = calcBitVectorSize(numBits); const uint8_t* cursor = sourceBuffer; uint8_t bit = 0; diff --git a/tests/shared/src/BitVectorHelperTests.cpp b/tests/shared/src/BitVectorHelperTests.cpp new file mode 100644 index 0000000000..070e90eec7 --- /dev/null +++ b/tests/shared/src/BitVectorHelperTests.cpp @@ -0,0 +1,80 @@ +// +// BitVectorHelperTests.cpp +// tests/shared/src +// +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "BitVectorHelperTests.h" + +#include + +#include "../QTestExtensions.h" +#include +#include +#include +#include + +QTEST_MAIN(BitVectorHelperTests) + +const int BITS_IN_BYTE = 8; + +void BitVectorHelperTests::sizeTest() { + std::vector sizes = {0, 6, 7, 8, 30, 31, 32, 33, 87, 88, 89, 90, 90, 91, 92, 93}; + for (auto& size : sizes) { + const int oldWay = (int)ceil((float)size / (float)BITS_IN_BYTE); + const int newWay = (int)calcBitVectorSize(size); + QCOMPARE(oldWay, newWay); + } +} + +static void readWriteHelper(const std::vector& src) { + + int numBits = (int)src.size(); + int numBytes = calcBitVectorSize(numBits); + uint8_t* bytes = new uint8_t[numBytes]; + memset(bytes, numBytes, sizeof(uint8_t)); + int numBytesWritten = writeBitVector(bytes, numBits, [&](int i) { + return src[i]; + }); + QCOMPARE(numBytesWritten, numBytes); + + std::vector dst; + int numBytesRead = readBitVector(bytes, numBits, [&](int i, bool value) { + dst.push_back(value); + }); + QCOMPARE(numBytesRead, numBytes); + + QCOMPARE(numBits, (int)src.size()); + QCOMPARE(numBits, (int)dst.size()); + for (int i = 0; i < numBits; i++) { + bool a = src[i]; + bool b = dst[i]; + QCOMPARE(a, b); + } +} + +void BitVectorHelperTests::readWriteTest() { + std::vector sizes = {0, 6, 7, 8, 30, 31, 32, 33, 87, 88, 89, 90, 90, 91, 92, 93}; + + for (auto& size : sizes) { + std::vector allTrue(size, true); + std::vector allFalse(size, false); + std::vector evenSet; + evenSet.reserve(size); + std::vector oddSet; + oddSet.reserve(size); + for (int i = 0; i < size; i++) { + bool isOdd = (i & 0x1) > 0; + evenSet.push_back(!isOdd); + oddSet.push_back(isOdd); + } + readWriteHelper(allTrue); + readWriteHelper(allFalse); + readWriteHelper(evenSet); + readWriteHelper(oddSet); + } +} diff --git a/tests/shared/src/BitVectorHelperTests.h b/tests/shared/src/BitVectorHelperTests.h new file mode 100644 index 0000000000..1f52ba1ac9 --- /dev/null +++ b/tests/shared/src/BitVectorHelperTests.h @@ -0,0 +1,23 @@ +// +// BitVectorHelperTests.h +// tests/shared/src +// +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_BitVectorHelperTests_h +#define hifi_BitVectorHelperTests_h + +#include + +class BitVectorHelperTests : public QObject { + Q_OBJECT +private slots: + void sizeTest(); + void readWriteTest(); +}; + +#endif // hifi_BitVectorHelperTests_h From 21c1e3249013b65716b3b3ebb6a50362bdb598e6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 25 Jan 2018 15:57:48 -0800 Subject: [PATCH 08/42] Bug fix for avatar neck cauterization The basic dual-quaternion skinning algorithm does not handle non-rigid transformations like scale well. Because we only use scaling for head cauterization, we special case this by passing in a cauterization factor, as well as a cauterization position to the vertex shader. If a vertex is flagged as cauterized, we slam it to equal the cauterization position. Although, not as smooth as the previous method, it seems to work well enough on the avatar's I've tested. (cherry picked from commit faf8350369e26b627a1c6b574cbac2578061bef8) --- .../render-utils/src/CauterizedModel.cpp | 2 + libraries/render-utils/src/Model.h | 10 +++- libraries/render-utils/src/Skinning.slh | 50 +++++++++++++++---- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index e3f26a43d8..0b8c636678 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -115,6 +115,7 @@ void CauterizedModel::updateClusterMatrices() { Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); state.clusterTransforms[j] = Model::TransformDualQuaternion(clusterTransform); + state.clusterTransforms[j].setCauterizationParameters(0.0f, jointPose.trans()); #else auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]); @@ -151,6 +152,7 @@ void CauterizedModel::updateClusterMatrices() { Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); state.clusterTransforms[j] = Model::TransformDualQuaternion(clusterTransform); + state.clusterTransforms[j].setCauterizationParameters(1.0f, cauterizePose.trans()); #else glm_mat4u_mul(cauterizeMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]); #endif diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 560aa82f0c..17ac251459 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -263,26 +263,34 @@ public: _scale.x = p.scale().x; _scale.y = p.scale().y; _scale.z = p.scale().z; + _scale.w = 0.0f; _dq = DualQuaternion(p.rot(), p.trans()); } TransformDualQuaternion(const glm::vec3& scale, const glm::quat& rot, const glm::vec3& trans) { _scale.x = scale.x; _scale.y = scale.y; _scale.z = scale.z; + _scale.w = 0.0f; _dq = DualQuaternion(rot, trans); } TransformDualQuaternion(const Transform& transform) { _scale = glm::vec4(transform.getScale(), 0.0f); + _scale.w = 0.0f; _dq = DualQuaternion(transform.getRotation(), transform.getTranslation()); } glm::vec3 getScale() const { return glm::vec3(_scale); } glm::quat getRotation() const { return _dq.getRotation(); } glm::vec3 getTranslation() const { return _dq.getTranslation(); } glm::mat4 getMatrix() const { return createMatFromScaleQuatAndPos(getScale(), getRotation(), getTranslation()); }; + + void setCauterizationParameters(float cauterizationAmount, const glm::vec3& cauterizedPosition) { + _scale.w = cauterizationAmount; + _cauterizedPosition = glm::vec4(cauterizedPosition, 1.0f); + } protected: glm::vec4 _scale { 1.0f, 1.0f, 1.0f, 0.0f }; DualQuaternion _dq; - glm::vec4 _padding; + glm::vec4 _cauterizedPosition { 0.0f, 0.0f, 0.0f, 1.0f }; }; #endif diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 49d0df3d2c..095e210bca 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -58,17 +58,19 @@ mat4 dualQuatToMat4(vec4 real, vec4 dual) { void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) { // linearly blend scale and dual quaternion components - vec3 sAccum = vec3(0.0, 0.0, 0.0); + vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0); + vec4 cAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1]; for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; - vec3 scale = vec3(clusterMatrix[0]); + vec4 scale = clusterMatrix[0]; vec4 real = clusterMatrix[1]; vec4 dual = clusterMatrix[2]; + vec4 cauterizedPos = clusterMatrix[3]; // to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity. float dqClusterWeight = clusterWeight; @@ -79,6 +81,7 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio sAccum += scale * clusterWeight; rAccum += real * dqClusterWeight; dAccum += dual * dqClusterWeight; + cAccum += cauterizedPos * clusterWeight; } // normalize dual quaternion @@ -88,25 +91,34 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - skinnedPosition = m * (vec4(sAccum, 1) * inPosition); + + // an sAccum.w of > 0 indicates that this joint is cauterized. + if (sAccum.w > 0.1) { + skinnedPosition = cAccum; + } else { + sAccum.w = 1.0; + skinnedPosition = m * (sAccum * inPosition); + } } void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, out vec4 skinnedPosition, out vec3 skinnedNormal) { // linearly blend scale and dual quaternion components - vec3 sAccum = vec3(0.0, 0.0, 0.0); + vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0); + vec4 cAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1]; for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; - vec3 scale = vec3(clusterMatrix[0]); + vec4 scale = clusterMatrix[0]; vec4 real = clusterMatrix[1]; vec4 dual = clusterMatrix[2]; + vec4 cauterizedPos = clusterMatrix[3]; // to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity. float dqClusterWeight = clusterWeight; @@ -117,6 +129,7 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP sAccum += scale * clusterWeight; rAccum += real * dqClusterWeight; dAccum += dual * dqClusterWeight; + cAccum += cauterizedPos * clusterWeight; } // normalize dual quaternion @@ -126,7 +139,15 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - skinnedPosition = m * (vec4(sAccum, 1) * inPosition); + + // an sAccum.w of > 0 indicates that this joint is cauterized. + if (sAccum.w > 0.1) { + skinnedPosition = cAccum; + } else { + sAccum.w = 1.0; + skinnedPosition = m * (sAccum * inPosition); + } + skinnedNormal = vec3(m * vec4(inNormal, 0)); } @@ -134,18 +155,20 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) { // linearly blend scale and dual quaternion components - vec3 sAccum = vec3(0.0, 0.0, 0.0); + vec4 sAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0); + vec4 cAccum = vec4(0.0, 0.0, 0.0, 0.0); vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1]; for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; - vec3 scale = vec3(clusterMatrix[0]); + vec4 scale = clusterMatrix[0]; vec4 real = clusterMatrix[1]; vec4 dual = clusterMatrix[2]; + vec4 cauterizedPos = clusterMatrix[3]; // to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity. float dqClusterWeight = clusterWeight; @@ -156,6 +179,7 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v sAccum += scale * clusterWeight; rAccum += real * dqClusterWeight; dAccum += dual * dqClusterWeight; + cAccum += cauterizedPos * clusterWeight; } // normalize dual quaternion @@ -165,7 +189,15 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - skinnedPosition = m * (vec4(sAccum, 1) * inPosition); + + // an sAccum.w of > 0 indicates that this vertex is cauterized. + if (sAccum.w > 0.1) { + skinnedPosition = cAccum; + } else { + sAccum.w = 1.0; + skinnedPosition = m * (sAccum * inPosition); + } + skinnedNormal = vec3(m * vec4(inNormal, 0)); skinnedTangent = vec3(m * vec4(inTangent, 0)); } From 1ad65b8da5bb3e862c2d985689d2bf6078c18044 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 23 Jan 2018 16:05:43 -0800 Subject: [PATCH 09/42] Bug fix for twisted knees on some avatars. The FBXReader inverse bind pose calculation can sometimes introduce floating point fuzz into the bottom row of the matrix. The Transform class checks this bottom row before doing decomposition into translation, rotation and scale. If it detects that this row is not exactly (0, 0, 0, 1) it aborts. And returns identity. To guarantee that it preforms the decomposition correctly slam the row to (0, 0, 0, 1), before conversion to a Transform instance. (cherry picked from commit 991ba7f1951db5043dd8fbf73ba6403b193f38eb) --- libraries/fbx/src/FBXReader.cpp | 14 ++++++++++++-- libraries/render-utils/src/Skinning.slh | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 4bc5eb1b6d..171fc88443 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1733,8 +1733,18 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS qCDebug(modelformat) << "Joint not in model list: " << jointID; fbxCluster.jointIndex = 0; } + fbxCluster.inverseBindMatrix = glm::inverse(cluster.transformLink) * modelTransform; + + // slam bottom row to (0, 0, 0, 1), we KNOW this is not a perspective matrix and + // sometimes floating point fuzz can be introduced after the inverse. + fbxCluster.inverseBindMatrix[0][3] = 0.0f; + fbxCluster.inverseBindMatrix[1][3] = 0.0f; + fbxCluster.inverseBindMatrix[2][3] = 0.0f; + fbxCluster.inverseBindMatrix[3][3] = 1.0f; + fbxCluster.inverseBindTransform = Transform(fbxCluster.inverseBindMatrix); + extracted.mesh.clusters.append(fbxCluster); // override the bind rotation with the transform link @@ -1836,13 +1846,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } // now that we've accumulated the most relevant weights for each vertex - // normalize and compress to 8-bits + // normalize and compress to 16-bits extracted.mesh.clusterWeights.fill(0, numClusterIndices); int numVertices = extracted.mesh.vertices.size(); for (int i = 0; i < numVertices; ++i) { int j = i * WEIGHTS_PER_VERTEX; - // normalize weights into uint8_t + // normalize weights into uint16_t float totalWeight = weightAccumulators[j]; for (int k = j + 1; k < j + WEIGHTS_PER_VERTEX; ++k) { totalWeight += weightAccumulators[k]; diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 49d0df3d2c..e85ee75c58 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -39,12 +39,12 @@ mat4 dualQuatToMat4(vec4 real, vec4 dual) { twoRealXZ - twoRealYW, 0.0); vec4 col1 = vec4(twoRealXY - twoRealZW, - 1 - twoRealXSq - twoRealZSq, + 1.0 - twoRealXSq - twoRealZSq, twoRealYZ + twoRealXW, 0.0); vec4 col2 = vec4(twoRealXZ + twoRealYW, twoRealYZ - twoRealXW, - 1 - twoRealXSq - twoRealYSq, + 1.0 - twoRealXSq - twoRealYSq, 0.0); vec4 col3 = vec4(2.0 * (-dual.w * real.x + dual.x * real.w - dual.y * real.z + dual.z * real.y), 2.0 * (-dual.w * real.y + dual.x * real.z + dual.y * real.w - dual.z * real.x), From ced5aad1d17efe7b9818f093330b350755cb3783 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Nov 2017 11:14:35 -0700 Subject: [PATCH 10/42] backtrace for rc-63 --- cmake/externals/crashpad/CMakeLists.txt | 35 ++++++++ cmake/macros/AddCrashpad.cmake | 41 +++++++++ .../macros/PackageCrashpadForDeployment.cmake | 30 +++++++ cmake/modules/FindCrashpad.cmake | 41 +++++++++ interface/CMakeLists.txt | 2 + libraries/shared/CMakeLists.txt | 8 +- libraries/shared/src/shared/Crashpad.cpp | 87 +++++++++++++++++++ libraries/shared/src/shared/Crashpad.h | 17 ++++ 8 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 cmake/externals/crashpad/CMakeLists.txt create mode 100644 cmake/macros/AddCrashpad.cmake create mode 100644 cmake/macros/PackageCrashpadForDeployment.cmake create mode 100644 cmake/modules/FindCrashpad.cmake create mode 100644 libraries/shared/src/shared/Crashpad.cpp create mode 100644 libraries/shared/src/shared/Crashpad.h diff --git a/cmake/externals/crashpad/CMakeLists.txt b/cmake/externals/crashpad/CMakeLists.txt new file mode 100644 index 0000000000..c464dcbc1b --- /dev/null +++ b/cmake/externals/crashpad/CMakeLists.txt @@ -0,0 +1,35 @@ +include(ExternalProject) +set(EXTERNAL_NAME crashpad) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +if (WIN32) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://backtrace.io/download/crashpad_062317.zip + URL_MD5 65817e564b3628492abfc1dbd2a1e98b + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) + + ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE PATH "List of Crashpad include directories") + + set(LIB_EXT "lib") + + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}crashpad_client.${LIB_EXT} CACHE FILEPATH "Path to Crashpad release library") + set(${EXTERNAL_NAME_UPPER}_BASE_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}base.${LIB_EXT} CACHE FILEPATH "Path to Crashpad base release library") + set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}crashpad_util.${LIB_EXT} CACHE FILEPATH "Path to Crashpad util release library") + + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}crashpad_client.${LIB_EXT} CACHE FILEPATH "Path to Crashpad debug library") + set(${EXTERNAL_NAME_UPPER}_BASE_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}base.${LIB_EXT} CACHE FILEPATH "Path to Crashpad base debug library") + set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}crashpad_util.${LIB_EXT} CACHE FILEPATH "Path to Crashpad util debug library") + + set(CRASHPAD_HANDLER_EXE_PATH ${SOURCE_DIR}/out/Release_x64/crashpad_handler.exe CACHE FILEPATH "Path to the Crashpad handler executable") +endif () + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") diff --git a/cmake/macros/AddCrashpad.cmake b/cmake/macros/AddCrashpad.cmake new file mode 100644 index 0000000000..573e13c8a2 --- /dev/null +++ b/cmake/macros/AddCrashpad.cmake @@ -0,0 +1,41 @@ +# +# AddCrashpad.cmake +# cmake/macros +# +# Created by Clement Brisset on 01/19/18. +# Copyright 2018 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +macro(add_crashpad) + get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE) + + set (USE_CRASHPAD TRUE) + if ("$ENV{CMAKE_BACKTRACE_URL}" STREQUAL "") + set (USE_CRASHPAD FALSE) + else() + set (CMAKE_BACKTRACE_URL $ENV{CMAKE_BACKTRACE_URL}) + endif() + + if ("$ENV{CMAKE_BACKTRACE_TOKEN}" STREQUAL "") + set (USE_CRASHPAD FALSE) + else() + set (CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN}) + endif() + + if (WIN32 AND USE_CRASHPAD AND NOT CRASHPAD_CHECKED) + set_property(GLOBAL PROPERTY HAS_CRASHPAD TRUE) + add_definitions(-DHAS_CRASHPAD) + add_definitions(-DCMAKE_BACKTRACE_URL=\"${CMAKE_BACKTRACE_URL}\") + add_definitions(-DCMAKE_BACKTRACE_TOKEN=\"${CMAKE_BACKTRACE_TOKEN}\") + + add_dependency_external_projects(crashpad) + find_package(crashpad REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY}) + + set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) + endif () +endmacro() diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake new file mode 100644 index 0000000000..adee7a79e6 --- /dev/null +++ b/cmake/macros/PackageCrashpadForDeployment.cmake @@ -0,0 +1,30 @@ +# +# PackageCrashpadForDeployment.cmake +# cmake/macros +# +# Copyright 2018 High Fidelity, Inc. +# Created by Clement Brisset on 01/19/18 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) + get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) + + if (HAS_CRASHPAD) + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" + ) + install( + PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/crashpad_handler.exe" + DESTINATION ${CLIENT_COMPONENT} + COMPONENT ${INTERFACE_INSTALL_DIR} + ) + + message(STATUS "CRASHPAD_HANDLER_EXE_PATH: ${CRASHPAD_HANDLER_EXE_PATH}") + message(STATUS "Target: $") + endif () +endmacro() diff --git a/cmake/modules/FindCrashpad.cmake b/cmake/modules/FindCrashpad.cmake new file mode 100644 index 0000000000..5095a0b0c9 --- /dev/null +++ b/cmake/modules/FindCrashpad.cmake @@ -0,0 +1,41 @@ +# +# FindCrashpad.cmake +# +# Try to find Crashpad libraries and include path. +# Once done this will define +# +# CRASHPAD_FOUND +# DRACO_INCLUDE_DIRS +# CRASHPAD_LIBRARY +# CRASHPAD_BASE_LIBRARY +# CRASHPAD_UTIL_LIBRARY +# +# Created on 01/19/2018 by Clement Brisset +# Copyright 2018 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("crashpad") + +find_path(CRASHPAD_INCLUDE_DIRS base/macros.h PATH_SUFFIXES include HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_library(CRASHPAD_LIBRARY_RELEASE crashpad PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_BASE_LIBRARY_RELEASE base PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_UTIL_LIBRARY_RELEASE util PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_library(CRASHPAD_LIBRARY_DEBUG crashpad PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_BASE_LIBRARY_DEBUG base PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_UTIL_LIBRARY_DEBUG util PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_file(CRASHPAD_HANDLER_EXE_PATH NAME "crashpad_handler.exe" PATH_SUFFIXES "Release_x64" HINTS ${CRASHPAD_SEARCH_DIRS}) + +include(SelectLibraryConfigurations) +select_library_configurations(CRASHPAD) +select_library_configurations(CRASHPAD_BASE) +select_library_configurations(CRASHPAD_UTIL) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CRASHPAD DEFAULT_MSG CRASHPAD_INCLUDE_DIRS CRASHPAD_LIBRARY CRASHPAD_BASE_LIBRARY CRASHPAD_UTIL_LIBRARY) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 21225756b4..caa812e133 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -349,6 +349,8 @@ endif() add_bugsplat() +package_crashpad_for_deployment() + if (WIN32) set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"") diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index f9b835df5c..379c15c999 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -5,7 +5,13 @@ setup_hifi_library(Gui Network Script Widgets) if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) + + add_crashpad() +endif() + +if (ANDROID) + target_link_libraries(${TARGET_NAME} android) endif() target_zlib() -target_nsight() \ No newline at end of file +target_nsight() diff --git a/libraries/shared/src/shared/Crashpad.cpp b/libraries/shared/src/shared/Crashpad.cpp new file mode 100644 index 0000000000..a655ddec4b --- /dev/null +++ b/libraries/shared/src/shared/Crashpad.cpp @@ -0,0 +1,87 @@ +// +// Crashpad.cpp +// shared/src/shared +// +// Created by Clement Brisset on 01/19/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "Crashpad.h" + +#include + +#if HAS_CRASHPAD + +#include +#include + +#include + +#include +#include +#include + +using namespace crashpad; + +static const std::string BACKTRACE_URL { CMAKE_BACKTRACE_URL }; +static const std::string BACKTRACE_TOKEN { CMAKE_BACKTRACE_TOKEN }; + +extern QString qAppFileName(); + +bool startCrashHandler() { + if (BACKTRACE_URL.empty() || BACKTRACE_TOKEN.empty()) { + return false; + } + + CrashpadClient client; + std::map annotations; + std::vector arguments; + + annotations["token"] = BACKTRACE_TOKEN; + annotations["format"] = "minidump"; + annotations["service-name"] = BuildInfo::INTERFACE_NAME.toStdString(); + annotations["version"] = BuildInfo::VERSION.toStdString(); + + arguments.push_back("--no-rate-limit"); + + // Setup Crashpad DB directory + const auto crashpadDbName = "crashpad-db"; + const auto crashpadDbDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); + QDir(crashpadDbDir).mkpath(crashpadDbName); // Make sure the directory exists + const auto crashpadDbPath = crashpadDbDir.toStdString() + "/" + crashpadDbName; + + // Locate Crashpad handler + const std::string CRASHPAD_HANDLER_PATH = QFileInfo(qAppFileName()).absolutePath().toStdString() + "/crashpad_handler.exe"; + + // Setup different file paths + base::FilePath::StringType dbPath; + base::FilePath::StringType handlerPath; + dbPath.assign(crashpadDbPath.cbegin(), crashpadDbPath.cend()); + handlerPath.assign(CRASHPAD_HANDLER_PATH.cbegin(), CRASHPAD_HANDLER_PATH.cend()); + + base::FilePath db(dbPath); + base::FilePath handler(handlerPath); + + auto database = crashpad::CrashReportDatabase::Initialize(db); + if (database == nullptr || database->GetSettings() == nullptr) { + return false; + } + + // Enable automated uploads. + database->GetSettings()->SetUploadsEnabled(true); + + return client.StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true); +} + +#else + + +bool startCrashHandler() { + qDebug() << "No crash handler available."; + return false; +} + +#endif \ No newline at end of file diff --git a/libraries/shared/src/shared/Crashpad.h b/libraries/shared/src/shared/Crashpad.h new file mode 100644 index 0000000000..a40503a703 --- /dev/null +++ b/libraries/shared/src/shared/Crashpad.h @@ -0,0 +1,17 @@ +// +// Crashpad.h +// shared/src/shared +// +// Created by Clement Brisset on 01/19/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_Crashpad_h +#define hifi_Crashpad_h + +bool startCrashHandler(); + +#endif // hifi_Crashpad_h From 47f44eb21fc1f40cb7123c47f7acd46b51d9d3e7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 22 Jan 2018 11:12:45 -0800 Subject: [PATCH 11/42] extirpate bugsplat --- cmake/macros/AddBugSplat.cmake | 34 ------- cmake/modules/FindBugSplat.cmake | 30 ------ interface/CMakeLists.txt | 2 - interface/src/CrashReporter.cpp | 166 ------------------------------- interface/src/CrashReporter.h | 32 ------ interface/src/main.cpp | 36 +------ 6 files changed, 2 insertions(+), 298 deletions(-) delete mode 100644 cmake/macros/AddBugSplat.cmake delete mode 100644 cmake/modules/FindBugSplat.cmake delete mode 100644 interface/src/CrashReporter.cpp delete mode 100644 interface/src/CrashReporter.h diff --git a/cmake/macros/AddBugSplat.cmake b/cmake/macros/AddBugSplat.cmake deleted file mode 100644 index 979dcfe817..0000000000 --- a/cmake/macros/AddBugSplat.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# -# AddBugSplat.cmake -# cmake/macros -# -# Created by Ryan Huffman on 02/09/16. -# Copyright 2016 High Fidelity, Inc. -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html -# - -macro(add_bugsplat) - get_property(BUGSPLAT_CHECKED GLOBAL PROPERTY CHECKED_FOR_BUGSPLAT_ONCE) - - if (NOT BUGSPLAT_CHECKED) - find_package(BugSplat) - set_property(GLOBAL PROPERTY CHECKED_FOR_BUGSPLAT_ONCE TRUE) - endif () - - if (BUGSPLAT_FOUND) - add_definitions(-DHAS_BUGSPLAT) - - target_include_directories(${TARGET_NAME} PRIVATE ${BUGSPLAT_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${BUGSPLAT_LIBRARIES}) - add_paths_to_fixup_libs(${BUGSPLAT_DLL_PATH}) - - add_custom_command(TARGET ${TARGET_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUGSPLAT_RC_DLL_PATH} "$/") - add_custom_command(TARGET ${TARGET_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUGSPLAT_EXE_PATH} "$/") - endif () -endmacro() diff --git a/cmake/modules/FindBugSplat.cmake b/cmake/modules/FindBugSplat.cmake deleted file mode 100644 index 8bea1cb1e1..0000000000 --- a/cmake/modules/FindBugSplat.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# -# FindBugSplat.cmake -# cmake/modules -# -# Created by Ryan Huffman on 02/09/16. -# Copyright 2016 High Fidelity, Inc. -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html -# - -if (WIN32) - include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") - hifi_library_search_hints("BugSplat") - - find_path(BUGSPLAT_INCLUDE_DIRS NAMES BugSplat.h PATH_SUFFIXES inc HINTS ${BUGSPLAT_SEARCH_DIRS}) - - find_library(BUGSPLAT_LIBRARY_RELEASE "BugSplat64.lib" PATH_SUFFIXES "lib64" HINTS ${BUGSPLAT_SEARCH_DIRS}) - find_path(BUGSPLAT_DLL_PATH NAMES "BugSplat64.dll" PATH_SUFFIXES "bin64" HINTS ${BUGSPLAT_SEARCH_DIRS}) - find_file(BUGSPLAT_RC_DLL_PATH NAMES "BugSplatRc64.dll" PATH_SUFFIXES "bin64" HINTS ${BUGSPLAT_SEARCH_DIRS}) - find_file(BUGSPLAT_EXE_PATH NAMES "BsSndRpt64.exe" PATH_SUFFIXES "bin64" HINTS ${BUGSPLAT_SEARCH_DIRS}) - - include(SelectLibraryConfigurations) - select_library_configurations(BUGSPLAT) - - set(BUGSPLAT_LIBRARIES ${BUGSPLAT_LIBRARY_RELEASE}) -endif () - -set(BUGSPLAT_REQUIREMENTS BUGSPLAT_INCLUDE_DIRS BUGSPLAT_LIBRARIES BUGSPLAT_DLL_PATH BUGSPLAT_RC_DLL_PATH BUGSPLAT_EXE_PATH) -find_package_handle_standard_args(BugSplat DEFAULT_MSG ${BUGSPLAT_REQUIREMENTS}) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index caa812e133..6cb1c352c7 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -347,8 +347,6 @@ if (SCRIPTS_INSTALL_DIR) ) endif() -add_bugsplat() - package_crashpad_for_deployment() if (WIN32) diff --git a/interface/src/CrashReporter.cpp b/interface/src/CrashReporter.cpp deleted file mode 100644 index 596c34ca92..0000000000 --- a/interface/src/CrashReporter.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// -// CrashReporter.cpp -// interface/src -// -// Created by Ryan Huffman on 11 April 2016. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -#include "Application.h" -#include "CrashReporter.h" - -#ifdef _WIN32 -#include -#include -#include - -#include -#include - - -#pragma comment(lib, "Dbghelp.lib") - -// SetUnhandledExceptionFilter can be overridden by the CRT at the point that an error occurs. More information -// can be found here: http://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li -// A fairly common approach is to patch the SetUnhandledExceptionFilter so that it cannot be overridden and so -// that the applicaiton can handle it itself. -// The CAPIHook class referenced in the above article is not openly available, but a similar implementation -// can be found here: http://blog.kalmbach-software.de/2008/04/02/unhandled-exceptions-in-vc8-and-above-for-x86-and-x64/ -// The below has been adapted to work with different library and functions. -BOOL redirectLibraryFunctionToFunction(char* library, char* function, void* fn) -{ - HMODULE lib = LoadLibrary(library); - if (lib == NULL) return FALSE; - void *pOrgEntry = GetProcAddress(lib, function); - if (pOrgEntry == NULL) return FALSE; - - DWORD dwOldProtect = 0; - SIZE_T jmpSize = 5; -#ifdef _M_X64 - jmpSize = 13; -#endif - BOOL bProt = VirtualProtect(pOrgEntry, jmpSize, - PAGE_EXECUTE_READWRITE, &dwOldProtect); - BYTE newJump[20]; - void *pNewFunc = fn; -#ifdef _M_IX86 - DWORD dwOrgEntryAddr = (DWORD)pOrgEntry; - dwOrgEntryAddr += jmpSize; // add 5 for 5 op-codes for jmp rel32 - DWORD dwNewEntryAddr = (DWORD)pNewFunc; - DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; - // JMP rel32: Jump near, relative, displacement relative to next instruction. - newJump[0] = 0xE9; // JMP rel32 - memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc)); -#elif _M_X64 - // We must use R10 or R11, because these are "scratch" registers - // which need not to be preserved accross function calls - // For more info see: Register Usage for x64 64-Bit - // http://msdn.microsoft.com/en-us/library/ms794547.aspx - // Thanks to Matthew Smith!!! - newJump[0] = 0x49; // MOV R11, ... - newJump[1] = 0xBB; // ... - memcpy(&newJump[2], &pNewFunc, sizeof(pNewFunc)); - //pCur += sizeof (ULONG_PTR); - newJump[10] = 0x41; // JMP R11, ... - newJump[11] = 0xFF; // ... - newJump[12] = 0xE3; // ... -#endif - SIZE_T bytesWritten; - BOOL bRet = WriteProcessMemory(GetCurrentProcess(), - pOrgEntry, newJump, jmpSize, &bytesWritten); - - if (bProt != FALSE) - { - DWORD dwBuf; - VirtualProtect(pOrgEntry, jmpSize, dwOldProtect, &dwBuf); - } - return bRet; -} - -void printStackTrace(ULONG framesToSkip = 1) { - HANDLE process = GetCurrentProcess(); - SymInitialize(process, NULL, TRUE); - void* stack[100]; - uint16_t frames = CaptureStackBackTrace(framesToSkip, 100, stack, NULL); - SYMBOL_INFO* symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); - symbol->MaxNameLen = 255; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - - for (uint16_t i = 0; i < frames; ++i) { - SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); - qWarning() << QString("%1: %2 - 0x%0X").arg(QString::number(frames - i - 1), QString(symbol->Name), QString::number(symbol->Address, 16)); - } - - free(symbol); - - // Try to force the log to sync to the filesystem - auto app = qApp; - if (app && app->getLogger()) { - app->getLogger()->sync(); - } -} - -void handleSignal(int signal) { - // Throw so BugSplat can handle - throw(signal); -} - -void __cdecl handlePureVirtualCall() { - qWarning() << "Pure virtual function call detected"; - printStackTrace(2); - // Throw so BugSplat can handle - throw("ERROR: Pure virtual call"); -} - -void handleInvalidParameter(const wchar_t * expression, const wchar_t * function, const wchar_t * file, - unsigned int line, uintptr_t pReserved ) { - // Throw so BugSplat can handle - throw("ERROR: Invalid parameter"); -} - -int handleNewError(size_t size) { - // Throw so BugSplat can handle - throw("ERROR: Errors calling new"); -} - -LPTOP_LEVEL_EXCEPTION_FILTER WINAPI noop_SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { - return nullptr; -} - -_purecall_handler __cdecl noop_set_purecall_handler(_purecall_handler pNew) { - return nullptr; -} - -#ifdef HAS_BUGSPLAT - -static const DWORD BUG_SPLAT_FLAGS = MDSF_PREVENTHIJACKING | MDSF_USEGUARDMEMORY; - -CrashReporter::CrashReporter(QString bugSplatDatabase, QString bugSplatApplicationName, QString version) - : mpSender(qPrintable(bugSplatDatabase), qPrintable(bugSplatApplicationName), qPrintable(version), nullptr, BUG_SPLAT_FLAGS) -{ - signal(SIGSEGV, handleSignal); - signal(SIGABRT, handleSignal); - _set_purecall_handler(handlePureVirtualCall); - _set_invalid_parameter_handler(handleInvalidParameter); - _set_new_mode(1); - _set_new_handler(handleNewError); - - // Disable WER popup - //SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); - //_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - - // QtWebEngineCore internally sets its own purecall handler, overriding our own error handling. This disables that. - if (!redirectLibraryFunctionToFunction("msvcr120.dll", "_set_purecall_handler", &noop_set_purecall_handler)) { - qWarning() << "Failed to patch _set_purecall_handler"; - } - // Patch SetUnhandledExceptionFilter to keep the CRT from overriding our own error handling. - if (!redirectLibraryFunctionToFunction("kernel32.dll", "SetUnhandledExceptionFilter", &noop_SetUnhandledExceptionFilter)) { - qWarning() << "Failed to patch setUnhandledExceptionFilter"; - } -} -#endif -#endif diff --git a/interface/src/CrashReporter.h b/interface/src/CrashReporter.h deleted file mode 100644 index 5f02066a74..0000000000 --- a/interface/src/CrashReporter.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// CrashReporter.h -// interface/src -// -// Created by Ryan Huffman on 11 April 2016. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#pragma once - -#ifndef hifi_CrashReporter_h -#define hifi_CrashReporter_h - -#include - -#ifdef HAS_BUGSPLAT - -#include - -class CrashReporter { -public: - CrashReporter(QString bugSplatDatabase, QString bugSplatApplicationName, QString version); - - MiniDmpSender mpSender; -}; - -#endif - -#endif // hifi_CrashReporter_h \ No newline at end of file diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 5c07bebc23..ad43bf45c1 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -31,11 +31,6 @@ #include "UserActivityLogger.h" #include "MainWindow.h" -#ifdef HAS_BUGSPLAT -#include -#include -#endif - #ifdef Q_OS_WIN extern "C" { typedef int(__stdcall * CHECKMINSPECPROC) (); @@ -43,11 +38,6 @@ extern "C" { #endif int main(int argc, const char* argv[]) { -#if HAS_BUGSPLAT - static QString BUG_SPLAT_DATABASE = "interface_alpha"; - static QString BUG_SPLAT_APPLICATION_NAME = "Interface"; - CrashReporter crashReporter { BUG_SPLAT_DATABASE, BUG_SPLAT_APPLICATION_NAME, BuildInfo::VERSION }; -#endif #ifdef Q_OS_LINUX QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); @@ -252,7 +242,6 @@ int main(int argc, const char* argv[]) { } } #endif - // Setup local server QLocalServer server { &app }; @@ -261,29 +250,8 @@ int main(int argc, const char* argv[]) { server.removeServer(applicationName); server.listen(applicationName); - QObject::connect(&server, &QLocalServer::newConnection, &app, &Application::handleLocalServerConnection, Qt::DirectConnection); - -#ifdef HAS_BUGSPLAT - auto accountManager = DependencyManager::get(); - crashReporter.mpSender.setDefaultUserName(qPrintable(accountManager->getAccountInfo().getUsername())); - QObject::connect(accountManager.data(), &AccountManager::usernameChanged, &app, [&crashReporter](const QString& newUsername) { - crashReporter.mpSender.setDefaultUserName(qPrintable(newUsername)); - }); - - // BugSplat WILL NOT work with file paths that do not use OS native separators. - auto logger = app.getLogger(); - auto logPath = QDir::toNativeSeparators(logger->getFilename()); - crashReporter.mpSender.sendAdditionalFile(qPrintable(logPath)); - - QMetaObject::Connection connection; - connection = QObject::connect(logger, &FileLogger::rollingLogFile, &app, [&crashReporter, &connection](QString newFilename) { - // We only want to add the first rolled log file (the "beginning" of the log) to BugSplat to ensure we don't exceed the 2MB - // zipped limit, so we disconnect here. - QObject::disconnect(connection); - auto rolledLogPath = QDir::toNativeSeparators(newFilename); - crashReporter.mpSender.sendAdditionalFile(qPrintable(rolledLogPath)); - }); -#endif + QObject::connect(&server, &QLocalServer::newConnection, + &app, &Application::handleLocalServerConnection, Qt::DirectConnection); printSystemInformation(); From 6c044316367ee9a66723e8991f596c15c67c3997 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 22 Jan 2018 11:50:07 -0800 Subject: [PATCH 12/42] call startCrashhandler from interface --- interface/src/main.cpp | 3 +++ libraries/shared/src/shared/Crashpad.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index ad43bf45c1..069aeb6775 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "AddressManager.h" #include "Application.h" @@ -45,6 +46,8 @@ int main(int argc, const char* argv[]) { disableQtBearerPoll(); // Fixes wifi ping spikes + startCrashHandler(); + QElapsedTimer startupTime; startupTime.start(); diff --git a/libraries/shared/src/shared/Crashpad.cpp b/libraries/shared/src/shared/Crashpad.cpp index a655ddec4b..7bc3ce7584 100644 --- a/libraries/shared/src/shared/Crashpad.cpp +++ b/libraries/shared/src/shared/Crashpad.cpp @@ -84,4 +84,4 @@ bool startCrashHandler() { return false; } -#endif \ No newline at end of file +#endif From 093fff9c9e3ae775aa639be6c90bc316804daadc Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Nov 2017 11:14:35 -0700 Subject: [PATCH 13/42] Add crashpad --- cmake/macros/PackageCrashpadForDeployment.cmake | 5 +---- interface/CMakeLists.txt | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake index adee7a79e6..1808ddc3d1 100644 --- a/cmake/macros/PackageCrashpadForDeployment.cmake +++ b/cmake/macros/PackageCrashpadForDeployment.cmake @@ -19,12 +19,9 @@ macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" ) install( - PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/crashpad_handler.exe" + PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH} DESTINATION ${CLIENT_COMPONENT} COMPONENT ${INTERFACE_INSTALL_DIR} ) - - message(STATUS "CRASHPAD_HANDLER_EXE_PATH: ${CRASHPAD_HANDLER_EXE_PATH}") - message(STATUS "Target: $") endif () endmacro() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6cb1c352c7..b64ad20239 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -349,6 +349,8 @@ endif() package_crashpad_for_deployment() +package_crashpad_for_deployment() + if (WIN32) set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"") From 88f66f03cc20ba85ec4e629b344ecefab4299bd1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 23 Jan 2018 12:02:37 -0800 Subject: [PATCH 14/42] remove merge mistake --- interface/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b64ad20239..6cb1c352c7 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -349,8 +349,6 @@ endif() package_crashpad_for_deployment() -package_crashpad_for_deployment() - if (WIN32) set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"") From 39f26e35f0733f396c98e07e0a1fdb32715e08fe Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 22 Jan 2018 17:17:48 -0800 Subject: [PATCH 15/42] backtrace for rc-63 --- interface/src/Application.cpp | 18 +++++++++- interface/src/main.cpp | 7 ++++ libraries/shared/src/SettingInterface.cpp | 41 ++++++++++++----------- libraries/shared/src/SharedUtil.cpp | 38 +++++++++++++++++++++ libraries/shared/src/SharedUtil.h | 26 ++++++++++++-- 5 files changed, 107 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5854501809..62dd1c97cd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -600,7 +600,23 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { qApp->setProperty(hifi::properties::APP_LOCAL_DATA_PATH, cacheDir); } - Setting::init(); + // FIXME fix the OSX installer to install the resources.rcc binary instead of resource files and remove + // this conditional exclusion +#if !defined(Q_OS_OSX) + { +#if defined(Q_OS_ANDROID) + const QString resourcesBinaryFile = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/resources.rcc"; +#else + const QString resourcesBinaryFile = QCoreApplication::applicationDirPath() + "/resources.rcc"; +#endif + if (!QFile::exists(resourcesBinaryFile)) { + throw std::runtime_error("Unable to find primary resources"); + } + if (!QResource::registerResource(resourcesBinaryFile)) { + throw std::runtime_error("Unable to load primary resources"); + } + } +#endif // Tell the plugin manager about our statically linked plugins auto pluginManager = PluginManager::getInstance(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 069aeb6775..6bede00558 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -57,6 +57,13 @@ int main(int argc, const char* argv[]) { QCoreApplication::setOrganizationDomain(BuildInfo::ORGANIZATION_DOMAIN); QCoreApplication::setApplicationVersion(BuildInfo::VERSION); + Setting::init(); + + // Instance UserActivityLogger now that the settings are loaded + auto& ual = UserActivityLogger::getInstance(); + + qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); + QStringList arguments; for (int i = 0; i < argc; ++i) { arguments << argv[i]; diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index 01b9f3884f..9dc126a6ce 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -20,12 +20,13 @@ #include "SettingHelpers.h" #include "SettingManager.h" #include "SharedLogging.h" +#include "SharedUtil.h" namespace Setting { static QSharedPointer globalManager; // cleans up the settings private instance. Should only be run once at closing down. - void cleanupPrivateInstance() { + static void cleanupPrivateInstance() { // grab the thread before we nuke the instance QThread* settingsManagerThread = DependencyManager::get()->thread(); @@ -34,12 +35,30 @@ namespace Setting { // globalManager.reset(); - + // quit the settings manager thread and wait on it to make sure it's gone settingsManagerThread->quit(); settingsManagerThread->wait(); } - + + static void setupPrivateInstance() { + // Let's set up the settings Private instance on its own thread + QThread* thread = new QThread(); + Q_CHECK_PTR(thread); + thread->setObjectName("Settings Thread"); + + QObject::connect(thread, SIGNAL(started()), globalManager.data(), SLOT(startTimer())); + QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + QObject::connect(thread, SIGNAL(finished()), globalManager.data(), SLOT(deleteLater())); + globalManager->moveToThread(thread); + thread->start(); + qCDebug(shared) << "Settings thread started."; + + // Register cleanupPrivateInstance to run inside QCoreApplication's destructor. + qAddPostRoutine(cleanupPrivateInstance); + } + FIXED_Q_COREAPP_STARTUP_FUNCTION(setupPrivateInstance) + // Sets up the settings private instance. Should only be run once at startup. preInit() must be run beforehand, void init() { // Set settings format @@ -59,23 +78,7 @@ namespace Setting { qCDebug(shared) << (deleted ? "Deleted" : "Failed to delete") << "settings lock file" << settingsLockFilename; } - - // Let's set up the settings Private instance on its own thread - QThread* thread = new QThread(); - Q_CHECK_PTR(thread); - thread->setObjectName("Settings Thread"); - globalManager = DependencyManager::set(); - - QObject::connect(thread, SIGNAL(started()), globalManager.data(), SLOT(startTimer())); - QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - QObject::connect(thread, SIGNAL(finished()), globalManager.data(), SLOT(deleteLater())); - globalManager->moveToThread(thread); - thread->start(); - qCDebug(shared) << "Settings thread started."; - - // Register cleanupPrivateInstance to run inside QCoreApplication's destructor. - qAddPostRoutine(cleanupPrivateInstance); } void Interface::init() { diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 2d2ec7c28f..8e5c30711c 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -62,6 +63,43 @@ extern "C" FILE * __cdecl __iob_func(void) { #include "OctalCode.h" #include "SharedLogging.h" +static std::unordered_map stagedGlobalInstances; + + +std::mutex& globalInstancesMutex() { + static std::mutex mutex; + return mutex; +} + +static void commitGlobalInstances() { + std::unique_lock lock(globalInstancesMutex()); + for (const auto& it : stagedGlobalInstances) { + qApp->setProperty(it.first.c_str(), it.second); + } + stagedGlobalInstances.clear(); +} +FIXED_Q_COREAPP_STARTUP_FUNCTION(commitGlobalInstances) + +QVariant getGlobalInstance(const char* propertyName) { + if (qApp) { + return qApp->property(propertyName); + } else { + auto it = stagedGlobalInstances.find(propertyName); + if (it != stagedGlobalInstances.end()) { + return it->second; + } + } + return QVariant(); +} + +void setGlobalInstance(const char* propertyName, const QVariant& variant) { + if (qApp) { + qApp->setProperty(propertyName, variant); + } else { + stagedGlobalInstances[propertyName] = variant; + } +} + static qint64 usecTimestampNowAdjust = 0; // in usec void usecTimestampNowForceClockSkew(qint64 clockSkew) { ::usecTimestampNowAdjust = clockSkew; diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 6cf5a4755d..940dc095b8 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -25,6 +25,22 @@ #include #include +// Workaround for https://bugreports.qt.io/browse/QTBUG-54479 +// Wrap target function inside another function that holds +// a unique string identifier and uses it to ensure it only runs once +// by storing a state within the qApp +// We cannot used std::call_once with a static once_flag because +// this is used in shared libraries that are linked by several DLLs +// (ie. plugins), meaning the static will be useless in that case +#define FIXED_Q_COREAPP_STARTUP_FUNCTION(AFUNC) \ + static void AFUNC ## _fixed() { \ + const auto propertyName = std::string(Q_FUNC_INFO) + __FILE__; \ + if (!qApp->property(propertyName.c_str()).toBool()) { \ + AFUNC(); \ + qApp->setProperty(propertyName.c_str(), QVariant(true)); \ + } \ + } \ + Q_COREAPP_STARTUP_FUNCTION(AFUNC ## _fixed) // When writing out avatarEntities to a QByteArray, if the parentID is the ID of MyAvatar, use this ID instead. This allows // the value to be reset when the sessionID changes. @@ -52,6 +68,10 @@ bool destroyGlobalInstance() { return false; } +std::mutex& globalInstancesMutex(); +QVariant getGlobalInstance(const char* propertyName); +void setGlobalInstance(const char* propertyName, const QVariant& variant); + // Provides efficient access to a named global type. By storing the value // in the QApplication by name we can implement the singleton pattern and // have the single instance function across DLL boundaries. @@ -60,9 +80,9 @@ T* globalInstance(const char* propertyName, Args&&... args) { static T* resultInstance { nullptr }; static std::mutex mutex; if (!resultInstance) { - std::unique_lock lock(mutex); + std::unique_lock lock(globalInstancesMutex()); if (!resultInstance) { - auto variant = qApp->property(propertyName); + auto variant = getGlobalInstance(propertyName); if (variant.isNull()) { std::unique_ptr& instancePtr = globalInstancePointer(); if (!instancePtr.get()) { @@ -72,7 +92,7 @@ T* globalInstance(const char* propertyName, Args&&... args) { } void* voidInstance = &(*instancePtr); variant = QVariant::fromValue(voidInstance); - qApp->setProperty(propertyName, variant); + setGlobalInstance(propertyName, variant); } void* returnedVoidInstance = variant.value(); resultInstance = static_cast(returnedVoidInstance); From e32089d3dd67f3a582eac5cb33e6711c7c3f18ee Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 23 Jan 2018 15:28:05 -0800 Subject: [PATCH 16/42] only start crash hanlder if UserActivityLogger::isEnabled() is true --- interface/src/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 6bede00558..b39bc96bf6 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -64,6 +64,11 @@ int main(int argc, const char* argv[]) { qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); + if (ual) { + auto crashHandlerStarted = startCrashHandler(); + qDebug() << "Crash handler started:" << crashHandlerStarted; + } + QStringList arguments; for (int i = 0; i < argc; ++i) { arguments << argv[i]; From c02ab28c60d05552f74b8ddef177275d63c8aea4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 23 Jan 2018 15:45:02 -0800 Subject: [PATCH 17/42] fix clang build --- libraries/shared/src/SettingInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index 9dc126a6ce..878a84da7c 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -26,7 +26,7 @@ namespace Setting { static QSharedPointer globalManager; // cleans up the settings private instance. Should only be run once at closing down. - static void cleanupPrivateInstance() { + void cleanupPrivateInstance() { // grab the thread before we nuke the instance QThread* settingsManagerThread = DependencyManager::get()->thread(); @@ -41,7 +41,7 @@ namespace Setting { settingsManagerThread->wait(); } - static void setupPrivateInstance() { + void setupPrivateInstance() { // Let's set up the settings Private instance on its own thread QThread* thread = new QThread(); Q_CHECK_PTR(thread); From 9eb10c09dab8ef295c4ffcf762b7dd373af8bb20 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 23 Jan 2018 16:32:16 -0800 Subject: [PATCH 18/42] oops --- interface/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b39bc96bf6..253f152bb3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -64,7 +64,7 @@ int main(int argc, const char* argv[]) { qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); - if (ual) { + if (ual.isEnabled()) { auto crashHandlerStarted = startCrashHandler(); qDebug() << "Crash handler started:" << crashHandlerStarted; } From df62ba88cb36535dde8eed795a0cb37a880b638e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 24 Jan 2018 14:31:11 -0800 Subject: [PATCH 19/42] Fix rebase error --- interface/src/main.cpp | 1 - libraries/shared/src/shared/Crashpad.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 253f152bb3..2b89c13ae7 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -61,7 +61,6 @@ int main(int argc, const char* argv[]) { // Instance UserActivityLogger now that the settings are loaded auto& ual = UserActivityLogger::getInstance(); - qDebug() << "UserActivityLogger is enabled:" << ual.isEnabled(); if (ual.isEnabled()) { diff --git a/libraries/shared/src/shared/Crashpad.cpp b/libraries/shared/src/shared/Crashpad.cpp index 7bc3ce7584..cd5262a5b0 100644 --- a/libraries/shared/src/shared/Crashpad.cpp +++ b/libraries/shared/src/shared/Crashpad.cpp @@ -42,7 +42,6 @@ bool startCrashHandler() { annotations["token"] = BACKTRACE_TOKEN; annotations["format"] = "minidump"; - annotations["service-name"] = BuildInfo::INTERFACE_NAME.toStdString(); annotations["version"] = BuildInfo::VERSION.toStdString(); arguments.push_back("--no-rate-limit"); From c550620cb4e51161c228820859977020a1323d5a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 24 Jan 2018 16:04:47 -0800 Subject: [PATCH 20/42] backtrace for rc-63 --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 62dd1c97cd..25c359573b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -865,6 +865,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _logger->setSessionID(accountManager->getSessionID()); +#if HAS_CRASHPAD + backtraceAnnotations->SetKeyValue("MetaverseSessionID", accountManager->getSessionID()); +#endif // HAS_CRASHPAD + if (steamClient) { qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index ddb8ce11e5..a501372598 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -707,5 +708,9 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; + +#if HAS_CRASHPAD + crashpad::SimpleStringDictionary* crashpadAnnotations { nullptr }; +#endif // HAS_CRASHPAD }; #endif // hifi_Application_h From dbe9fd290ea9b8c2399e8712f4e41132790cd187 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 24 Jan 2018 20:08:09 -0800 Subject: [PATCH 21/42] comment out code that would set annotations after StartHandler is called --- interface/src/Application.cpp | 4 +--- interface/src/Application.h | 4 ---- libraries/shared/src/shared/Crashpad.cpp | 19 +++++++++++++++++-- libraries/shared/src/shared/Crashpad.h | 3 +++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 25c359573b..e8950c6f12 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -865,9 +865,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _logger->setSessionID(accountManager->getSessionID()); -#if HAS_CRASHPAD - backtraceAnnotations->SetKeyValue("MetaverseSessionID", accountManager->getSessionID()); -#endif // HAS_CRASHPAD + setCrashAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString()); if (steamClient) { qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID(); diff --git a/interface/src/Application.h b/interface/src/Application.h index a501372598..8a19e69014 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -708,9 +708,5 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; - -#if HAS_CRASHPAD - crashpad::SimpleStringDictionary* crashpadAnnotations { nullptr }; -#endif // HAS_CRASHPAD }; #endif // hifi_Application_h diff --git a/libraries/shared/src/shared/Crashpad.cpp b/libraries/shared/src/shared/Crashpad.cpp index cd5262a5b0..f28cad2d18 100644 --- a/libraries/shared/src/shared/Crashpad.cpp +++ b/libraries/shared/src/shared/Crashpad.cpp @@ -23,6 +23,8 @@ #include #include #include +// #include +// #include using namespace crashpad; @@ -31,15 +33,17 @@ static const std::string BACKTRACE_TOKEN { CMAKE_BACKTRACE_TOKEN }; extern QString qAppFileName(); +// crashpad::AnnotationList* crashpadAnnotations { nullptr }; + bool startCrashHandler() { if (BACKTRACE_URL.empty() || BACKTRACE_TOKEN.empty()) { return false; } CrashpadClient client; - std::map annotations; std::vector arguments; + std::map annotations; annotations["token"] = BACKTRACE_TOKEN; annotations["format"] = "minidump"; annotations["version"] = BuildInfo::VERSION.toStdString(); @@ -75,12 +79,23 @@ bool startCrashHandler() { return client.StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true); } -#else +void setCrashAnnotation(std::string name, std::string value) { + // if (!crashpadAnnotations) { + // crashpadAnnotations = new crashpad::AnnotationList(); // don't free this, let it leak + // crashpad::CrashpadInfo* crashpad_info = crashpad::GetCrashpadInfo(); + // crashpad_info->set_simple_annotations(crashpadAnnotations); + // } + // crashpadAnnotations->SetKeyValue(name, value); +} +#else bool startCrashHandler() { qDebug() << "No crash handler available."; return false; } +void setCrashAnnotation(std::string name, std::string value) { +} + #endif diff --git a/libraries/shared/src/shared/Crashpad.h b/libraries/shared/src/shared/Crashpad.h index a40503a703..c4c559f459 100644 --- a/libraries/shared/src/shared/Crashpad.h +++ b/libraries/shared/src/shared/Crashpad.h @@ -12,6 +12,9 @@ #ifndef hifi_Crashpad_h #define hifi_Crashpad_h +#include + bool startCrashHandler(); +void setCrashAnnotation(std::string name, std::string value); #endif // hifi_Crashpad_h From cb5ca26600b10cc59c00fb66cc24cb48a66e3e5c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 07:22:07 -0800 Subject: [PATCH 22/42] quiet warnings --- interface/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6cb1c352c7..a06825cd51 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -175,6 +175,10 @@ else () add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) endif () +if (WIN32) + set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") +endif() + if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their # binary directories get added to the fixup path From 2962c8979ccde39c2666251b463dd993c4e910d7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 25 Jan 2018 15:15:59 -0800 Subject: [PATCH 23/42] print warnings if head position contains not-a-number --- interface/src/avatar/MyAvatar.cpp | 37 ++++++++++++++++++++++++------- libraries/animation/src/Rig.cpp | 25 ++++++++++++++------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e93b897013..57d7c7533e 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -561,6 +561,12 @@ void MyAvatar::simulate(float deltaTime) { if (!_skeletonModel->getHeadPosition(headPosition)) { headPosition = getWorldPosition(); } + + if (isNaN(headPosition)) { + qCDebug(interfaceapp) << "MyAvatar::simulate headPosition is NaN"; + headPosition = glm::vec3(0.0f); + } + head->setPosition(headPosition); head->setScale(getModelScale()); head->simulate(deltaTime); @@ -2700,27 +2706,42 @@ void MyAvatar::setWalkSpeed(float value) { } glm::vec3 MyAvatar::getPositionForAudio() { + glm::vec3 result; switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: - return getHead()->getPosition(); + result = getHead()->getPosition(); case AudioListenerMode::FROM_CAMERA: - return qApp->getCamera().getPosition(); + result = qApp->getCamera().getPosition(); case AudioListenerMode::CUSTOM: - return _customListenPosition; + result = _customListenPosition; } - return vec3(); + + if (isNaN(result)) { + qCDebug(interfaceapp) << "MyAvatar::getPositionForAudio produced NaN" << _audioListenerMode; + result = glm::vec3(0.0f); + } + + return result; } glm::quat MyAvatar::getOrientationForAudio() { + glm::quat result; + switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: - return getHead()->getFinalOrientationInWorldFrame(); + result = getHead()->getFinalOrientationInWorldFrame(); case AudioListenerMode::FROM_CAMERA: - return qApp->getCamera().getOrientation(); + result = qApp->getCamera().getOrientation(); case AudioListenerMode::CUSTOM: - return _customListenOrientation; + result = _customListenOrientation; } - return quat(); + + if (isNaN(result)) { + qCDebug(interfaceapp) << "MyAvatar::getOrientationForAudio produced NaN" << _audioListenerMode; + result = glm::quat(); + } + + return result; } void MyAvatar::setAudioListenerMode(AudioListenerMode audioListenerMode) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b1b41775a8..309bb59cff 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -445,22 +445,31 @@ void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, flo } bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { + bool success { false }; if (QThread::currentThread() == thread()) { if (isIndexValid(jointIndex)) { position = (rotation * _internalPoseSet._absolutePoses[jointIndex].trans()) + translation; - return true; + success = true; } else { - return false; + success = false; + } + } else { + QReadLocker readLock(&_externalPoseSetLock); + if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) { + position = (rotation * _externalPoseSet._absolutePoses[jointIndex].trans()) + translation; + success = true; + } else { + success = false; } } - QReadLocker readLock(&_externalPoseSetLock); - if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) { - position = (rotation * _externalPoseSet._absolutePoses[jointIndex].trans()) + translation; - return true; - } else { - return false; + if (isNaN(position)) { + qCWarning(animation) << "Rig::getJointPositionInWorldFrame produces NaN"; + success = false; + position = glm::vec3(0.0f); } + + return success; } bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const { From b8f3d8140deb46437fd667b4762ea6a29ff43799 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 10:34:43 -0800 Subject: [PATCH 24/42] add breaks in case statements that used to have returns --- interface/src/avatar/MyAvatar.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 57d7c7533e..b870c61f8f 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2710,10 +2710,13 @@ glm::vec3 MyAvatar::getPositionForAudio() { switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: result = getHead()->getPosition(); + break; case AudioListenerMode::FROM_CAMERA: result = qApp->getCamera().getPosition(); + break; case AudioListenerMode::CUSTOM: result = _customListenPosition; + break; } if (isNaN(result)) { @@ -2730,10 +2733,13 @@ glm::quat MyAvatar::getOrientationForAudio() { switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: result = getHead()->getFinalOrientationInWorldFrame(); + break; case AudioListenerMode::FROM_CAMERA: result = qApp->getCamera().getOrientation(); + break; case AudioListenerMode::CUSTOM: result = _customListenOrientation; + break; } if (isNaN(result)) { From 19409cc6ce4d56345732a92eca2394989154bbe8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 10:45:18 -0800 Subject: [PATCH 25/42] fix merge/cherry-pick error --- interface/src/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e8950c6f12..6aead4aa62 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include From b7303414f210c393b9e62a7f0ea43b32b5eb2ca2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 11:57:30 -0800 Subject: [PATCH 26/42] unmangle merges --- .../macros/PackageCrashpadForDeployment.cmake | 5 +++++ cmake/modules/FindCrashpad.cmake | 2 +- interface/src/Application.cpp | 18 ------------------ interface/src/main.cpp | 2 -- libraries/shared/CMakeLists.txt | 2 -- 5 files changed, 6 insertions(+), 23 deletions(-) diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake index 1808ddc3d1..024d1624fb 100644 --- a/cmake/macros/PackageCrashpadForDeployment.cmake +++ b/cmake/macros/PackageCrashpadForDeployment.cmake @@ -13,6 +13,11 @@ macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) if (HAS_CRASHPAD) + + if (WIN32) + set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") + endif() + add_custom_command( TARGET ${TARGET_NAME} POST_BUILD diff --git a/cmake/modules/FindCrashpad.cmake b/cmake/modules/FindCrashpad.cmake index 5095a0b0c9..283058336d 100644 --- a/cmake/modules/FindCrashpad.cmake +++ b/cmake/modules/FindCrashpad.cmake @@ -5,7 +5,7 @@ # Once done this will define # # CRASHPAD_FOUND -# DRACO_INCLUDE_DIRS +# CRASHPAD_INCLUDE_DIRS # CRASHPAD_LIBRARY # CRASHPAD_BASE_LIBRARY # CRASHPAD_UTIL_LIBRARY diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6aead4aa62..6c7093ff4d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -601,24 +601,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { qApp->setProperty(hifi::properties::APP_LOCAL_DATA_PATH, cacheDir); } - // FIXME fix the OSX installer to install the resources.rcc binary instead of resource files and remove - // this conditional exclusion -#if !defined(Q_OS_OSX) - { -#if defined(Q_OS_ANDROID) - const QString resourcesBinaryFile = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/resources.rcc"; -#else - const QString resourcesBinaryFile = QCoreApplication::applicationDirPath() + "/resources.rcc"; -#endif - if (!QFile::exists(resourcesBinaryFile)) { - throw std::runtime_error("Unable to find primary resources"); - } - if (!QResource::registerResource(resourcesBinaryFile)) { - throw std::runtime_error("Unable to load primary resources"); - } - } -#endif - // Tell the plugin manager about our statically linked plugins auto pluginManager = PluginManager::getInstance(); pluginManager->setInputPluginProvider([] { return getInputPlugins(); }); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 2b89c13ae7..94ac8b8008 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -46,8 +46,6 @@ int main(int argc, const char* argv[]) { disableQtBearerPoll(); // Fixes wifi ping spikes - startCrashHandler(); - QElapsedTimer startupTime; startupTime.start(); diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 379c15c999..a8fe14e23e 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -5,8 +5,6 @@ setup_hifi_library(Gui Network Script Widgets) if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) - - add_crashpad() endif() if (ANDROID) From 1237749628fa5c18ed8a209583cfc7bf6d822c81 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 12:05:26 -0800 Subject: [PATCH 27/42] oops --- interface/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index a06825cd51..6cb1c352c7 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -175,10 +175,6 @@ else () add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) endif () -if (WIN32) - set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") -endif() - if (WIN32) # These are external plugins, but we need to do the 'add dependency' here so that their # binary directories get added to the fixup path From d73538f233ac4cd375032c383a0f099069731815 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 26 Jan 2018 12:08:19 -0800 Subject: [PATCH 28/42] oops --- libraries/shared/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index a8fe14e23e..8456838fd3 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -5,10 +5,8 @@ setup_hifi_library(Gui Network Script Widgets) if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) -endif() -if (ANDROID) - target_link_libraries(${TARGET_NAME} android) + add_crashpad() endif() target_zlib() From 3be857567b58b20cae316a1890daa6fcdf5f63bb Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 26 Jan 2018 14:01:33 -0800 Subject: [PATCH 29/42] updated Skinning.slh comment and constant. (cherry picked from commit 43eaa02ef069f560b8fb1d5477b2c132722026da) --- libraries/render-utils/src/Skinning.slh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 095e210bca..cd839e2776 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -92,8 +92,11 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - // an sAccum.w of > 0 indicates that this joint is cauterized. - if (sAccum.w > 0.1) { + // sAccum.w indicates the amount of cauterization for this vertex. + // 0 indicates no cauterization and 1 indicates full cauterization. + // TODO: make this cauterization smoother or implement full dual-quaternion scale support. + const float CAUTERIZATION_THRESHOLD = 0.1; + if (sAccum.w > CAUTERIZATION_THRESHOLD) { skinnedPosition = cAccum; } else { sAccum.w = 1.0; @@ -140,8 +143,11 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - // an sAccum.w of > 0 indicates that this joint is cauterized. - if (sAccum.w > 0.1) { + // sAccum.w indicates the amount of cauterization for this vertex. + // 0 indicates no cauterization and 1 indicates full cauterization. + // TODO: make this cauterization smoother or implement full dual-quaternion scale support. + const float CAUTERIZATION_THRESHOLD = 0.1; + if (sAccum.w > CAUTERIZATION_THRESHOLD) { skinnedPosition = cAccum; } else { sAccum.w = 1.0; @@ -190,8 +196,11 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v // conversion from dual quaternion to 4x4 matrix. mat4 m = dualQuatToMat4(rAccum, dAccum); - // an sAccum.w of > 0 indicates that this vertex is cauterized. - if (sAccum.w > 0.1) { + // sAccum.w indicates the amount of cauterization for this vertex. + // 0 indicates no cauterization and 1 indicates full cauterization. + // TODO: make this cauterization smoother or implement full dual-quaternion scale support. + const float CAUTERIZATION_THRESHOLD = 0.1; + if (sAccum.w > CAUTERIZATION_THRESHOLD) { skinnedPosition = cAccum; } else { sAccum.w = 1.0; From 314c51ab3bb48c4bcb5e9c8267f5f4dc7bbbc82a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 26 Jan 2018 15:53:08 -0800 Subject: [PATCH 30/42] Fix settings init in all exe --- domain-server/src/DomainServer.cpp | 1 - domain-server/src/main.cpp | 2 ++ tests/qt59/src/main.cpp | 2 -- tools/ac-client/src/ACClientApp.cpp | 1 - tools/ac-client/src/main.cpp | 2 ++ tools/atp-client/src/ATPClientApp.cpp | 1 - tools/atp-client/src/main.cpp | 2 ++ tools/oven/src/Oven.cpp | 7 ------- tools/oven/src/main.cpp | 8 ++++++++ 9 files changed, 14 insertions(+), 12 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 290f4a7f53..22273ae85f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -157,7 +157,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : DependencyManager::set(); LogUtils::init(); - Setting::init(); qDebug() << "Setting up domain-server"; qDebug() << "[VERSION] Build sequence:" << qPrintable(applicationVersion()); diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 725a04ec46..dc3ee54fe7 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -29,6 +29,8 @@ int main(int argc, char* argv[]) { QCoreApplication::setOrganizationDomain(BuildInfo::ORGANIZATION_DOMAIN); QCoreApplication::setApplicationVersion(BuildInfo::VERSION); + Setting::init(); + #ifndef WIN32 setvbuf(stdout, NULL, _IOLBF, 0); #endif diff --git a/tests/qt59/src/main.cpp b/tests/qt59/src/main.cpp index c66a5e6f9a..7b95cabd6c 100644 --- a/tests/qt59/src/main.cpp +++ b/tests/qt59/src/main.cpp @@ -33,8 +33,6 @@ private: Qt59TestApp::Qt59TestApp(int argc, char* argv[]) : QCoreApplication(argc, argv) { - - Setting::init(); DependencyManager::registerInheritance(); DependencyManager::set([&] { return QString("Mozilla/5.0 (HighFidelityACClient)"); }); DependencyManager::set(); diff --git a/tools/ac-client/src/ACClientApp.cpp b/tools/ac-client/src/ACClientApp.cpp index 88884a4fee..9eadc1dec2 100644 --- a/tools/ac-client/src/ACClientApp.cpp +++ b/tools/ac-client/src/ACClientApp.cpp @@ -97,7 +97,6 @@ ACClientApp::ACClientApp(int argc, char* argv[]) : _password = pieces[1]; } - Setting::init(); DependencyManager::registerInheritance(); DependencyManager::set([&]{ return QString("Mozilla/5.0 (HighFidelityACClient)"); }); diff --git a/tools/ac-client/src/main.cpp b/tools/ac-client/src/main.cpp index 12c5e6f5f8..c9affde3b5 100644 --- a/tools/ac-client/src/main.cpp +++ b/tools/ac-client/src/main.cpp @@ -25,6 +25,8 @@ int main(int argc, char * argv[]) { QCoreApplication::setOrganizationDomain(BuildInfo::ORGANIZATION_DOMAIN); QCoreApplication::setApplicationVersion(BuildInfo::VERSION); + Setting::init(); + ACClientApp app(argc, argv); return app.exec(); diff --git a/tools/atp-client/src/ATPClientApp.cpp b/tools/atp-client/src/ATPClientApp.cpp index 9fd1bf8d4f..0e7f223f28 100644 --- a/tools/atp-client/src/ATPClientApp.cpp +++ b/tools/atp-client/src/ATPClientApp.cpp @@ -135,7 +135,6 @@ ATPClientApp::ATPClientApp(int argc, char* argv[]) : _domainServerAddress = domainURL.toString(); } - Setting::init(); DependencyManager::registerInheritance(); DependencyManager::set(); diff --git a/tools/atp-client/src/main.cpp b/tools/atp-client/src/main.cpp index 88119604cf..830c049bc7 100644 --- a/tools/atp-client/src/main.cpp +++ b/tools/atp-client/src/main.cpp @@ -25,6 +25,8 @@ int main(int argc, char * argv[]) { QCoreApplication::setOrganizationDomain(BuildInfo::ORGANIZATION_DOMAIN); QCoreApplication::setApplicationVersion(BuildInfo::VERSION); + Setting::init(); + ATPClientApp app(argc, argv); return app.exec(); diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index 9de06a35bb..69d2ef84ce 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -14,7 +14,6 @@ #include #include -#include #include "ui/OvenMainWindow.h" #include "Oven.h" @@ -29,12 +28,6 @@ static const QString CLI_TYPE_PARAMETER = "t"; Oven::Oven(int argc, char* argv[]) : QApplication(argc, argv) { - QCoreApplication::setOrganizationName("High Fidelity"); - QCoreApplication::setApplicationName("Oven"); - - // init the settings interface so we can save and load settings - Setting::init(); - // parse the command line parameters QCommandLineParser parser; diff --git a/tools/oven/src/main.cpp b/tools/oven/src/main.cpp index 9c778245b5..788470b75e 100644 --- a/tools/oven/src/main.cpp +++ b/tools/oven/src/main.cpp @@ -10,7 +10,15 @@ #include "Oven.h" +#include + int main (int argc, char** argv) { + QCoreApplication::setOrganizationName("High Fidelity"); + QCoreApplication::setApplicationName("Oven"); + + // init the settings interface so we can save and load settings + Setting::init(); + Oven app(argc, argv); return app.exec(); } From 3d9985fa6732e1a0a1f5431f866c56a34c65ab06 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sat, 27 Jan 2018 08:48:19 -0800 Subject: [PATCH 31/42] FIx the scattering ambient lighting diffuse which was too dark (got divided by PI) comparedd to non scattering --- libraries/render-utils/src/LightAmbient.slh | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/LightAmbient.slh b/libraries/render-utils/src/LightAmbient.slh index eb565d60e4..097b4f4335 100644 --- a/libraries/render-utils/src/LightAmbient.slh +++ b/libraries/render-utils/src/LightAmbient.slh @@ -99,7 +99,6 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie // Diffuse from ambient diffuse = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lowNormalCurvature.xyz).xyz; - diffuse /= 3.1415926; specular = vec3(0.0); } <@endif@> From 206927d72ac254f27cf7073ac122c0db34d9eca1 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 27 Jan 2018 11:42:17 -0800 Subject: [PATCH 32/42] Fix haze parameters uniform buffer size --- libraries/graphics/src/graphics/Haze.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/graphics/src/graphics/Haze.h b/libraries/graphics/src/graphics/Haze.h index 608449a97e..eda9f1e407 100644 --- a/libraries/graphics/src/graphics/Haze.h +++ b/libraries/graphics/src/graphics/Haze.h @@ -117,13 +117,14 @@ namespace graphics { // Amount of background (skybox) to display, overriding the haze effect for the background float hazeBackgroundBlend{ INITIAL_HAZE_BACKGROUND_BLEND }; - // The haze attenuation exponents used by both fragment and directional light attenuation float hazeRangeFactor{ convertHazeRangeToHazeRangeFactor(INITIAL_HAZE_RANGE) }; float hazeHeightFactor{ convertHazeAltitudeToHazeAltitudeFactor(INITIAL_HAZE_HEIGHT) }; - float hazeKeyLightRangeFactor{ convertHazeRangeToHazeRangeFactor(INITIAL_KEY_LIGHT_RANGE) }; + float hazeKeyLightAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(INITIAL_KEY_LIGHT_ALTITUDE) }; + // Padding required to align the structure to sizeof(vec4) + vec3 __padding; Parameters() {} }; From 6acec39e92b5684f69010b5cb93154ae72b27196 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 29 Jan 2018 10:05:23 -0800 Subject: [PATCH 33/42] HMD low LOD threshold changed: 45 --> 42 --- interface/src/LODManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index ca6be9380b..9e9871b4ad 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -20,7 +20,7 @@ #include const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; -const float DEFAULT_HMD_LOD_DOWN_FPS = 45.0f; +const float DEFAULT_HMD_LOD_DOWN_FPS = 42.0f; const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec const float MAX_LIKELY_DESKTOP_FPS = 59.0f; // this is essentially, V-synch - 1 fps From c2817fc09123ecbeac0d1e30de3c12da2d57ca30 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 29 Jan 2018 10:18:08 -0800 Subject: [PATCH 34/42] HMD low LOD threshold changed: 42 --> 34 --- interface/src/LODManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 9e9871b4ad..7b10579077 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -20,7 +20,7 @@ #include const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; -const float DEFAULT_HMD_LOD_DOWN_FPS = 42.0f; +const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f; const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec const float MAX_LIKELY_DESKTOP_FPS = 59.0f; // this is essentially, V-synch - 1 fps From 00555250a07bcc062f1ed5d77c70c65a7405e135 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 29 Jan 2018 12:07:07 -0800 Subject: [PATCH 35/42] 400 connections per page for Wallet and PAL --- scripts/system/commerce/wallet.js | 2 +- scripts/system/pal.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index ad864622ed..46672a3f66 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -78,7 +78,7 @@ }); } function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successful. (Logs otherwise) - url = METAVERSE_BASE + '/api/v1/users?' + url = METAVERSE_BASE + '/api/v1/users?per_page=400&' if (domain) { url += 'status=' + domain.slice(1, -1); // without curly braces } else { diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 1b93bdde32..5a656c4ba0 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -361,7 +361,7 @@ function getProfilePicture(username, callback) { // callback(url) if successfull }); } function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successfull. (Logs otherwise) - url = METAVERSE_BASE + '/api/v1/users?' + url = METAVERSE_BASE + '/api/v1/users?per_page=400&' if (domain) { url += 'status=' + domain.slice(1, -1); // without curly braces } else { From 061f9ea35953cd6c234d6f7d92d0ff3d70f0ee76 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 29 Jan 2018 11:52:43 -0800 Subject: [PATCH 36/42] Don't run settings preroutine when not initialized --- libraries/shared/src/SettingInterface.cpp | 30 +++++++++++++---------- libraries/shared/src/SharedUtil.h | 16 ++++++------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index 878a84da7c..327668574e 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -33,7 +33,6 @@ namespace Setting { // tell the private instance to clean itself up on its thread DependencyManager::destroy(); - // globalManager.reset(); // quit the settings manager thread and wait on it to make sure it's gone @@ -42,20 +41,23 @@ namespace Setting { } void setupPrivateInstance() { - // Let's set up the settings Private instance on its own thread - QThread* thread = new QThread(); - Q_CHECK_PTR(thread); - thread->setObjectName("Settings Thread"); + // Ensure Setting::init has already ran and qApp exists + if (qApp && globalManager) { + // Let's set up the settings Private instance on its own thread + QThread* thread = new QThread(); + Q_CHECK_PTR(thread); + thread->setObjectName("Settings Thread"); - QObject::connect(thread, SIGNAL(started()), globalManager.data(), SLOT(startTimer())); - QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - QObject::connect(thread, SIGNAL(finished()), globalManager.data(), SLOT(deleteLater())); - globalManager->moveToThread(thread); - thread->start(); - qCDebug(shared) << "Settings thread started."; + QObject::connect(thread, SIGNAL(started()), globalManager.data(), SLOT(startTimer())); + QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + QObject::connect(thread, SIGNAL(finished()), globalManager.data(), SLOT(deleteLater())); + globalManager->moveToThread(thread); + thread->start(); + qCDebug(shared) << "Settings thread started."; - // Register cleanupPrivateInstance to run inside QCoreApplication's destructor. - qAddPostRoutine(cleanupPrivateInstance); + // Register cleanupPrivateInstance to run inside QCoreApplication's destructor. + qAddPostRoutine(cleanupPrivateInstance); + } } FIXED_Q_COREAPP_STARTUP_FUNCTION(setupPrivateInstance) @@ -79,6 +81,8 @@ namespace Setting { } globalManager = DependencyManager::set(); + + setupPrivateInstance(); } void Interface::init() { diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 940dc095b8..5a1e48d9c0 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -32,14 +32,14 @@ // We cannot used std::call_once with a static once_flag because // this is used in shared libraries that are linked by several DLLs // (ie. plugins), meaning the static will be useless in that case -#define FIXED_Q_COREAPP_STARTUP_FUNCTION(AFUNC) \ - static void AFUNC ## _fixed() { \ - const auto propertyName = std::string(Q_FUNC_INFO) + __FILE__; \ - if (!qApp->property(propertyName.c_str()).toBool()) { \ - AFUNC(); \ - qApp->setProperty(propertyName.c_str(), QVariant(true)); \ - } \ - } \ +#define FIXED_Q_COREAPP_STARTUP_FUNCTION(AFUNC) \ + static void AFUNC ## _fixed() { \ + const auto propertyName = std::string(Q_FUNC_INFO) + __FILE__; \ + if (!qApp->property(propertyName.c_str()).toBool()) { \ + AFUNC(); \ + qApp->setProperty(propertyName.c_str(), QVariant(true)); \ + } \ + } \ Q_COREAPP_STARTUP_FUNCTION(AFUNC ## _fixed) // When writing out avatarEntities to a QByteArray, if the parentID is the ID of MyAvatar, use this ID instead. This allows From 08511a2a2ef779874154519c2c80ed0dc912903f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 29 Jan 2018 15:27:55 -0800 Subject: [PATCH 37/42] fix new model path --- scripts/system/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 92ccdf6565..00989d95f9 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -469,7 +469,7 @@ var toolBar = (function () { // tablet version of new-model dialog var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - tablet.pushOntoStack("NewModelDialog.qml"); + tablet.pushOntoStack("hifi/tablet/NewModelDialog.qml"); }); addButton("newCubeButton", "cube-01.svg", function () { From 2a6ff80911f49d350d90fd574b7168756ef40d50 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 30 Jan 2018 09:13:47 -0800 Subject: [PATCH 38/42] fix indentation --- .../macros/PackageCrashpadForDeployment.cmake | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake index 024d1624fb..65509c31d4 100644 --- a/cmake/macros/PackageCrashpadForDeployment.cmake +++ b/cmake/macros/PackageCrashpadForDeployment.cmake @@ -10,23 +10,23 @@ # macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) - get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) + get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) - if (HAS_CRASHPAD) + if (HAS_CRASHPAD) - if (WIN32) - set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") - endif() + if (WIN32) + set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") + endif() - add_custom_command( - TARGET ${TARGET_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" - ) - install( - PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH} - DESTINATION ${CLIENT_COMPONENT} - COMPONENT ${INTERFACE_INSTALL_DIR} - ) - endif () + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" + ) + install( + PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH} + DESTINATION ${CLIENT_COMPONENT} + COMPONENT ${INTERFACE_INSTALL_DIR} + ) + endif () endmacro() From 1e8a5485c1b407c9d69755d7d1cc91b8f2138b36 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Tue, 30 Jan 2018 10:03:19 -0800 Subject: [PATCH 39/42] 8x shader compilation optimization and watchdog disable addPlumberPipeline in RenderPipelines.cpp would recompile a single program 7 more times then necessary. This was causing startup times on Mac OS X to trigger the deadlock watchdog. Even with this fix, compiling shaders is still too slow, As a workaround, we disable the watchdog thread during rendering pipeline setup. --- interface/src/Application.cpp | 24 ++++++++++- libraries/render/src/render/ShapePipeline.cpp | 42 ++++++++++--------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5854501809..326575c6cc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -378,6 +378,7 @@ public: setObjectName("Deadlock Watchdog"); // Give the heartbeat an initial value _heartbeat = usecTimestampNow(); + _paused = false; connect(qApp, &QCoreApplication::aboutToQuit, [this] { _quit = true; }); @@ -395,11 +396,20 @@ public: *crashTrigger = 0xDEAD10CC; } + static void pause() { + _paused = true; + } + + static void resume() { + _paused = false; + updateHeartbeat(); + } + void run() override { while (!_quit) { QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); // Don't do heartbeat detection under nsight - if (nsightActive()) { + if (nsightActive() || _paused) { continue; } uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us @@ -455,6 +465,7 @@ public: } } + static std::atomic _paused; static std::atomic _heartbeat; static std::atomic _maxElapsed; static std::atomic _maxElapsedAverage; @@ -463,6 +474,7 @@ public: bool _quit { false }; }; +std::atomic DeadlockWatchdogThread::_paused; std::atomic DeadlockWatchdogThread::_heartbeat; std::atomic DeadlockWatchdogThread::_maxElapsed; std::atomic DeadlockWatchdogThread::_maxElapsedAverage; @@ -2206,6 +2218,11 @@ void Application::initializeGL() { initDisplay(); qCDebug(interfaceapp, "Initialized Display."); +#ifdef Q_OS_OSX + // FIXME: on mac os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread. + DeadlockWatchdogThread::pause(); +#endif + // Set up the render engine render::CullFunctor cullFunctor = LODManager::shouldRender; static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD"; @@ -2213,6 +2230,11 @@ void Application::initializeGL() { _renderEngine->addJob("UpdateScene"); _renderEngine->addJob("SecondaryCameraJob", cullFunctor); _renderEngine->addJob("RenderMainView", cullFunctor, isDeferred); + +#ifdef Q_OS_OSX + DeadlockWatchdogThread::resume(); +#endif + _renderEngine->load(); _renderEngine->registerScene(_main3DScene); diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 4cf1b306ab..b825a349ad 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -70,26 +70,30 @@ void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state, BatchSetter batchSetter, ItemSetter itemSetter) { - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), Slot::BUFFER::LIGHTING_MODEL)); - slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::BUFFER::SKINNING)); - slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::BUFFER::MATERIAL)); - slotBindings.insert(gpu::Shader::Binding(std::string("texMapArrayBuffer"), Slot::BUFFER::TEXMAPARRAY)); - slotBindings.insert(gpu::Shader::Binding(std::string("albedoMap"), Slot::MAP::ALBEDO)); - slotBindings.insert(gpu::Shader::Binding(std::string("roughnessMap"), Slot::MAP::ROUGHNESS)); - slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), Slot::MAP::NORMAL)); - slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::MAP::METALLIC)); - slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::MAP::EMISSIVE_LIGHTMAP)); - slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION)); - slotBindings.insert(gpu::Shader::Binding(std::string("scatteringMap"), Slot::MAP::SCATTERING)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER)); - slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT)); - slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK)); - slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS)); - slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), Slot::BUFFER::HAZE_MODEL)); - gpu::Shader::makeProgram(*program, slotBindings); + // don't call makeProgram on shaders that are already made. + if (program->getUniformBuffers().empty()) { + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), Slot::BUFFER::LIGHTING_MODEL)); + slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::BUFFER::SKINNING)); + slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::BUFFER::MATERIAL)); + slotBindings.insert(gpu::Shader::Binding(std::string("texMapArrayBuffer"), Slot::BUFFER::TEXMAPARRAY)); + slotBindings.insert(gpu::Shader::Binding(std::string("albedoMap"), Slot::MAP::ALBEDO)); + slotBindings.insert(gpu::Shader::Binding(std::string("roughnessMap"), Slot::MAP::ROUGHNESS)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), Slot::MAP::NORMAL)); + slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::MAP::METALLIC)); + slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::MAP::EMISSIVE_LIGHTMAP)); + slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION)); + slotBindings.insert(gpu::Shader::Binding(std::string("scatteringMap"), Slot::MAP::SCATTERING)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT)); + slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK)); + slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS)); + slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), Slot::BUFFER::HAZE_MODEL)); + + gpu::Shader::makeProgram(*program, slotBindings); + } auto locations = std::make_shared(); From db08f1dda67d95c869ca62cbc3f0ff69456112d4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 30 Jan 2018 11:39:48 -0800 Subject: [PATCH 40/42] Move backtrace to interface --- cmake/macros/AddCrashpad.cmake | 16 +++++++++- .../macros/PackageCrashpadForDeployment.cmake | 32 ------------------- interface/CMakeLists.txt | 3 +- interface/src/Application.cpp | 1 + interface/src/Application.h | 1 - .../src/shared => interface/src}/Crashpad.cpp | 0 .../src/shared => interface/src}/Crashpad.h | 0 interface/src/main.cpp | 2 +- libraries/shared/CMakeLists.txt | 2 -- 9 files changed, 18 insertions(+), 39 deletions(-) delete mode 100644 cmake/macros/PackageCrashpadForDeployment.cmake rename {libraries/shared/src/shared => interface/src}/Crashpad.cpp (100%) rename {libraries/shared/src/shared => interface/src}/Crashpad.h (100%) diff --git a/cmake/macros/AddCrashpad.cmake b/cmake/macros/AddCrashpad.cmake index 573e13c8a2..64c0216912 100644 --- a/cmake/macros/AddCrashpad.cmake +++ b/cmake/macros/AddCrashpad.cmake @@ -26,7 +26,6 @@ macro(add_crashpad) endif() if (WIN32 AND USE_CRASHPAD AND NOT CRASHPAD_CHECKED) - set_property(GLOBAL PROPERTY HAS_CRASHPAD TRUE) add_definitions(-DHAS_CRASHPAD) add_definitions(-DCMAKE_BACKTRACE_URL=\"${CMAKE_BACKTRACE_URL}\") add_definitions(-DCMAKE_BACKTRACE_TOKEN=\"${CMAKE_BACKTRACE_TOKEN}\") @@ -35,6 +34,21 @@ macro(add_crashpad) find_package(crashpad REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY}) + + if (WIN32) + set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") + endif() + + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" + ) + install( + PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH} + DESTINATION ${CLIENT_COMPONENT} + COMPONENT ${INTERFACE_INSTALL_DIR} + ) set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) endif () diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake deleted file mode 100644 index 65509c31d4..0000000000 --- a/cmake/macros/PackageCrashpadForDeployment.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# -# PackageCrashpadForDeployment.cmake -# cmake/macros -# -# Copyright 2018 High Fidelity, Inc. -# Created by Clement Brisset on 01/19/18 -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) - get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) - - if (HAS_CRASHPAD) - - if (WIN32) - set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") - endif() - - add_custom_command( - TARGET ${TARGET_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" - ) - install( - PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH} - DESTINATION ${CLIENT_COMPONENT} - COMPONENT ${INTERFACE_INSTALL_DIR} - ) - endif () -endmacro() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6cb1c352c7..db1ea6df9a 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -216,6 +216,7 @@ target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries target_bullet() target_opengl() +add_crashpad() # perform standard include and linking for found externals foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) @@ -347,8 +348,6 @@ if (SCRIPTS_INSTALL_DIR) ) endif() -package_crashpad_for_deployment() - if (WIN32) set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"") diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6c7093ff4d..92988267c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -145,6 +145,7 @@ #include "avatar/AvatarManager.h" #include "avatar/MyHead.h" #include "CrashHandler.h" +#include "Crashpad.h" #include "devices/DdeFaceTracker.h" #include "DiscoverabilityManager.h" #include "GLCanvas.h" diff --git a/interface/src/Application.h b/interface/src/Application.h index 8a19e69014..ddb8ce11e5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -47,7 +47,6 @@ #include #include #include -#include #include diff --git a/libraries/shared/src/shared/Crashpad.cpp b/interface/src/Crashpad.cpp similarity index 100% rename from libraries/shared/src/shared/Crashpad.cpp rename to interface/src/Crashpad.cpp diff --git a/libraries/shared/src/shared/Crashpad.h b/interface/src/Crashpad.h similarity index 100% rename from libraries/shared/src/shared/Crashpad.h rename to interface/src/Crashpad.h diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 94ac8b8008..fdc4f091f0 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -24,10 +24,10 @@ #include #include #include -#include #include "AddressManager.h" #include "Application.h" +#include "Crashpad.h" #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 8456838fd3..da345d1970 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -5,8 +5,6 @@ setup_hifi_library(Gui Network Script Widgets) if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) - - add_crashpad() endif() target_zlib() From edfffc575a07d4c8d8b3e54419d58535e18947c3 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 30 Jan 2018 11:48:01 -0800 Subject: [PATCH 41/42] Handle multiple targets for add_crashpad --- cmake/macros/AddCrashpad.cmake | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/cmake/macros/AddCrashpad.cmake b/cmake/macros/AddCrashpad.cmake index 64c0216912..8694c4968a 100644 --- a/cmake/macros/AddCrashpad.cmake +++ b/cmake/macros/AddCrashpad.cmake @@ -10,8 +10,6 @@ # macro(add_crashpad) - get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE) - set (USE_CRASHPAD TRUE) if ("$ENV{CMAKE_BACKTRACE_URL}" STREQUAL "") set (USE_CRASHPAD FALSE) @@ -25,13 +23,20 @@ macro(add_crashpad) set (CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN}) endif() - if (WIN32 AND USE_CRASHPAD AND NOT CRASHPAD_CHECKED) + if (WIN32 AND USE_CRASHPAD) + get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE) + if (NOT CRASHPAD_CHECKED) + + add_dependency_external_projects(crashpad) + find_package(crashpad REQUIRED) + + set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) + endif() + add_definitions(-DHAS_CRASHPAD) add_definitions(-DCMAKE_BACKTRACE_URL=\"${CMAKE_BACKTRACE_URL}\") add_definitions(-DCMAKE_BACKTRACE_TOKEN=\"${CMAKE_BACKTRACE_TOKEN}\") - add_dependency_external_projects(crashpad) - find_package(crashpad REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY}) @@ -49,7 +54,5 @@ macro(add_crashpad) DESTINATION ${CLIENT_COMPONENT} COMPONENT ${INTERFACE_INSTALL_DIR} ) - - set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) endif () endmacro() From 019a2d346c30525ea85df258b0e3341f1770d989 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 30 Jan 2018 12:00:24 -0800 Subject: [PATCH 42/42] Fix spaces --- cmake/macros/AddCrashpad.cmake | 18 +++++++++--------- interface/src/Crashpad.cpp | 2 +- interface/src/Crashpad.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cmake/macros/AddCrashpad.cmake b/cmake/macros/AddCrashpad.cmake index 8694c4968a..bf59418f37 100644 --- a/cmake/macros/AddCrashpad.cmake +++ b/cmake/macros/AddCrashpad.cmake @@ -12,25 +12,25 @@ macro(add_crashpad) set (USE_CRASHPAD TRUE) if ("$ENV{CMAKE_BACKTRACE_URL}" STREQUAL "") - set (USE_CRASHPAD FALSE) + set(USE_CRASHPAD FALSE) else() - set (CMAKE_BACKTRACE_URL $ENV{CMAKE_BACKTRACE_URL}) + set(CMAKE_BACKTRACE_URL $ENV{CMAKE_BACKTRACE_URL}) endif() if ("$ENV{CMAKE_BACKTRACE_TOKEN}" STREQUAL "") - set (USE_CRASHPAD FALSE) + set(USE_CRASHPAD FALSE) else() - set (CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN}) + set(CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN}) endif() if (WIN32 AND USE_CRASHPAD) get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE) if (NOT CRASHPAD_CHECKED) - - add_dependency_external_projects(crashpad) - find_package(crashpad REQUIRED) - set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) + add_dependency_external_projects(crashpad) + find_package(crashpad REQUIRED) + + set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) endif() add_definitions(-DHAS_CRASHPAD) @@ -39,7 +39,7 @@ macro(add_crashpad) target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY}) - + if (WIN32) set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "/ignore:4099") endif() diff --git a/interface/src/Crashpad.cpp b/interface/src/Crashpad.cpp index f28cad2d18..8ed3fc23bd 100644 --- a/interface/src/Crashpad.cpp +++ b/interface/src/Crashpad.cpp @@ -1,6 +1,6 @@ // // Crashpad.cpp -// shared/src/shared +// interface/src // // Created by Clement Brisset on 01/19/18. // Copyright 2018 High Fidelity, Inc. diff --git a/interface/src/Crashpad.h b/interface/src/Crashpad.h index c4c559f459..a815ed701a 100644 --- a/interface/src/Crashpad.h +++ b/interface/src/Crashpad.h @@ -1,6 +1,6 @@ // // Crashpad.h -// shared/src/shared +// interface/src // // Created by Clement Brisset on 01/19/18. // Copyright 2018 High Fidelity, Inc.